Exemple #1
0
/* for the -run option: dynamically load symbol from dll */
void *resolve_sym(struct TCCState *s1, const char *symbol, int type)
{
    char buffer[100];
    int sym_index, dll_index;
    void *addr, **m;
    DLLReference *dllref;

    sym_index = pe_find_import(s1, symbol);
    if (0 == sym_index)
        return NULL;
    dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value;
    dllref = s1->loaded_dlls[dll_index-1];
    if ( !dllref->handle )
    {
        dllref->handle = LoadLibrary(dllref->name);
    }
    addr = GetProcAddress(dllref->handle, symbol);
    if (NULL == addr)
        addr = GetProcAddress(dllref->handle, get_alt_symbol(buffer, symbol));

    if (addr && STT_OBJECT == type) {
        /* need to return a pointer to the address for data objects */
        m = (void**)tcc_malloc(sizeof addr), *m = addr, addr = m;
#ifdef MEM_DEBUG
        /* yep, we don't free it */
        mem_cur_size -= sizeof (void*);
#endif
    }
    return addr;
}
Exemple #2
0
static int pe_check_symbols(struct pe_info *pe) {
  Elf32_Sym *sym;
  int sym_index, sym_end;
  int ret = 0;

  pe_align_section(text_section, 8);

  sym_end = symtab_section->data_offset / sizeof(Elf32_Sym);
  for (sym_index = 1; sym_index < sym_end; ++sym_index) {
    sym = (Elf32_Sym *) symtab_section->data + sym_index;
    if (sym->st_shndx == SHN_UNDEF) {
      const char *name = symtab_section->link->data + sym->st_name;
      unsigned type = ELF32_ST_TYPE(sym->st_info);
      int imp_sym = pe_find_import(pe->s1, name);
      struct import_symbol *is;

      if (imp_sym == 0) goto not_found;
      is = pe_add_import(pe, imp_sym);
      if (!is) goto not_found;

      if (type == STT_FUNC) {
        unsigned long offset = is->thk_offset;
        if (offset) {
          // Got aliased symbol, like stricmp and _stricmp
        } else {
          char buffer[100];

          offset = text_section->data_offset;
          // Add the 'jmp IAT[x]' instruction
          *(WORD *) section_ptr_add(text_section, 8) = 0x25FF;

          // Add a helper symbol, will be patched later in pe_build_imports
          sprintf(buffer, "IAT.%s", name);
          is->iat_index = put_elf_sym(symtab_section, 0, sizeof(DWORD),
                                      ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
                                      0, SHN_UNDEF, buffer);
          put_elf_reloc(symtab_section, text_section, offset + 2, R_386_32, is->iat_index);
          is->thk_offset = offset;
        }

        // tcc_realloc might have altered sym's address
        sym = (Elf32_Sym *) symtab_section->data + sym_index;

        // Patch the original symbol
        sym->st_value = offset;
        sym->st_shndx = text_section->sh_num;
        sym->st_other &= ~1; // Do not export
        continue;
      }

      if (type == STT_OBJECT) { 
        if (is->iat_index == 0) {
          // Original symbol will be patched later in pe_build_imports
          is->iat_index = sym_index;
          continue;
        }
      }

    not_found:
      error_noabort("undefined symbol '%s'", name);
      ret = 1;
    } else if (pe->s1->rdynamic && ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
      // If -rdynamic option, then export all non local symbols
      sym->st_other |= 1;
    }
  }
  return ret;
}