syms_t*	syms_new(bin_obj_t* obj)
{
  elfobj_t*	elfobj = NULL;
  char*		sections[] = { ".symtab", ".dynsym" , NULL };
  int		i;
  Elf_Shdr*	section;
  Elf_Sym*	start, * end;
  syms_t*	list = NULL;
  sym_t*	sym;

  elfobj = (elfobj_t*) obj->luse;
  for (i = 0; sections[i]; i++)
    {
      section = get_elfsection(obj, sections[i]);
      if (!section)
	continue;
      start = (Elf_Sym *) ((char*) elfobj->header + section->sh_offset);
      end   = (Elf_Sym *) ((char*) elfobj->header + section->sh_offset + section->sh_size);
      /*
      ** Add every symbol to the list.
      */
      for (; start < end; start++)
	{
	  /*
	  ** J'ai virer le alloc ?! (TODO)
	  */
	  if (ELF_ST_TYPE(start->st_info) != STT_FUNC && ELF_ST_TYPE(start->st_info) != STT_NOTYPE)
	    continue;
	  /*
	  ** Skip unusable symbol.
	  */
	  if (start->st_value == 0x0)
	    continue;
	  sym = malloc(sizeof(sym_t));
	  if (sym == NULL)
	    goto syms_new_failed;
	  sym->addr = start->st_value + elfobj->base;
	  sym->size = start->st_size;
	  sym->name = (char*) ((char*) elfobj->header +
			 elfobj->section_headers[section->sh_link]->sh_offset +
			 start->st_name);
	  /* printf("Add Sym 0x%x size: %d name: %s\n", sym->addr, sym->size, sym->name); */
	  list = list_add(list, sym);
	  if (list == NULL)
	    goto syms_new_failed;
	}
    }
  return (list);

 syms_new_failed:
  for (; list; )
    {
      sym = (sym_t*) list->value;
      list = list_del(list, sym);
      free(sym);
    }
  return (NULL);
}
Exemplo n.º 2
0
bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
  assert(stringtableIndex, "null string table index pointer");
  assert(posIndex, "null string table offset pointer");
  assert(offset, "null offset pointer");

  if (NullDecoder::is_error(m_status)) {
    return false;
  }

  address pc = 0;
  size_t  sym_size = sizeof(Elf_Sym);
  assert((m_shdr.sh_size % sym_size) == 0, "check size");
  int count = m_shdr.sh_size / sym_size;
  if (m_symbols != NULL) {
    for (int index = 0; index < count; index ++) {
      if (STT_FUNC == ELF_ST_TYPE(m_symbols[index].st_info)) {
        address sym_addr = (address)m_symbols[index].st_value;
        if (sym_addr < addr && (addr - sym_addr) < *offset) {
          pc = (address)m_symbols[index].st_value;
          *offset = (int)(addr - pc);
          *posIndex = m_symbols[index].st_name;
          *stringtableIndex = m_shdr.sh_link;
        }
      }
    }
  } else {
    long cur_pos;
    if ((cur_pos = ftell(m_file)) == -1 ||
      fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
      m_status = NullDecoder::file_invalid;
      return false;
    }

    Elf_Sym sym;
    for (int index = 0; index < count; index ++) {
      if (fread(&sym, sym_size, 1, m_file) == 1) {
        if (STT_FUNC == ELF_ST_TYPE(sym.st_info)) {
          address sym_addr = (address)sym.st_value;
          if (sym_addr < addr && (addr - sym_addr) < *offset) {
            pc = (address)sym.st_value;
            *offset = (int)(addr - pc);
            *posIndex = sym.st_name;
            *stringtableIndex = m_shdr.sh_link;
          }
        }
      } else {
        m_status = NullDecoder::file_invalid;
        return false;
      }
    }
    fseek(m_file, cur_pos, SEEK_SET);
  }
  return true;
}
Exemplo n.º 3
0
static inline int
_rtld_relocate_plt_object(const Obj_Entry *obj, Elf_Word sym, Elf_Addr *tp)
{
	Elf_Addr *got = obj->pltgot;
	const Elf_Sym *def;
	const Obj_Entry *defobj;
	Elf_Addr new_value;

	def = _rtld_find_plt_symdef(sym, obj, &defobj, tp != NULL);
	if (__predict_false(def == NULL))
		return -1;
	if (__predict_false(def == &_rtld_sym_zero))
		return 0;

	if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
		if (tp == NULL)
			return 0;
		new_value = _rtld_resolve_ifunc(defobj, def);
	} else {
		new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
	}
	rdbg(("bind now/fixup in %s --> new=%p",
	    defobj->strtab + def->st_name, (void *)new_value));
	got[obj->local_gotno + sym - obj->gotsym] = new_value;

	if (tp)
		*tp = new_value;
	return 0;
}
Exemplo n.º 4
0
    bool
    generic_get_symbol( Elf_Xword index,
                        std::string& name, Elf64_Addr& value,
                        Elf_Xword& size,
                        unsigned char& bind, unsigned char& type,
                        Elf_Half& section_index,
                        unsigned char& other ) const
    {
        bool ret = false;

        if ( index < get_symbols_num() ) {
            const T* pSym = reinterpret_cast<const T*>(
                symbol_section->get_data() +
                    index * symbol_section->get_entry_size() );

            const endianess_convertor& convertor = elf_file.get_convertor();

            section* string_section = elf_file.sections[get_string_table_index()];
            string_section_accessor str_reader( string_section );
            const char* pStr = str_reader.get_string( convertor( pSym->st_name ) );
            if ( 0 != pStr ) {
                name = pStr;
            }
            value   = convertor( pSym->st_value );
            size    = convertor( pSym->st_size );
            bind    = ELF_ST_BIND( pSym->st_info );
            type    = ELF_ST_TYPE( pSym->st_info );
            section_index = convertor( pSym->st_shndx );
            other   = pSym->st_other;

            ret = true;
        }

        return ret;
    }
Exemplo n.º 5
0
static __init void reloc_symtab(Elf32_Ehdr *ehdr,
                                unsigned offset, unsigned size)
{
    Elf32_Sym *sym = (void *)ehdr + offset;
    unsigned nsym = size / sizeof(*sym);
    unsigned i;

    for(i = 0; i < nsym; i++, sym++) {
        if (sym->st_shndx == SHN_UNDEF ||
                sym->st_shndx == SHN_ABS)
            continue;  /* skip */

        if (sym->st_shndx > SHN_LORESERVE) {
            printk(KERN_INFO "VDSO: unexpected st_shndx %x\n",
                   sym->st_shndx);
            continue;
        }

        switch(ELF_ST_TYPE(sym->st_info)) {
        case STT_OBJECT:
        case STT_FUNC:
        case STT_SECTION:
        case STT_FILE:
            sym->st_value += VDSO_ADDR_ADJUST;
        }
    }
}
Exemplo n.º 6
0
static int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
                          Elf_Addr *tp)
{
    Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
    Elf_Addr new_value;
    const Elf_Sym  *def;
    const Obj_Entry *defobj;
    unsigned long info = rel->r_info;

    assert(ELF_R_TYPE(info) == R_TYPE(JUMP_SLOT));

    def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
    if (__predict_false(def == NULL))
        return -1;
    if (__predict_false(def == &_rtld_sym_zero))
        return 0;

    if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
        if (tp == NULL)
            return 0;
        new_value = _rtld_resolve_ifunc(defobj, def);
    } else {
        new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
    }
    rdbg(("bind now/fixup in %s --> old=%p new=%p",
          defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
    if (*where != new_value)
        *where = new_value;
    if (tp)
        *tp = new_value;

    return 0;
}
Exemplo n.º 7
0
int
reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
    const Elf_Rela *relalim;
    const Elf_Rela *rela;

    if (!obj->gnu_ifunc)
	return (0);
    relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
    for (rela = obj->pltrela;  rela < relalim;  rela++) {
	Elf_Addr *where, target;
	const Elf_Sym *def;
	const Obj_Entry *defobj;

	switch (ELF_R_TYPE(rela->r_info)) {
	case R_X86_64_JMP_SLOT:
	  where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
	  def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
		SYMLOOK_IN_PLT | flags, NULL, lockstate);
	  if (def == NULL)
	      return (-1);
	  if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
	      continue;
	  lock_release(rtld_bind_lock, lockstate);
	  target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
	  wlock_acquire(rtld_bind_lock, lockstate);
	  reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
	  break;
	}
    }
    obj->gnu_ifunc = false;
    return (0);
}
Exemplo n.º 8
0
static bool
wantsym(const Elf_Sym *sym, const char *strtab)
{
    int type;
    int bind;

    type = ELF_ST_TYPE(sym->st_info);
    bind = ELF_ST_BIND(sym->st_info);

    if (type != STT_FUNC || (aflag && bind == STB_LOCAL))
#if 0
 ||
      (uflag && strchr(strtab + sym->st_name, '.') != NULL))
#endif
	return 0;

#ifdef __arm__
    /* ignore what gas calls "mapping symbols" */
    {
	const char *c = strtab + sym->st_name;
	if (c[0] == '$')
	    return 0;
    }
#endif

    return 1;
}
Exemplo n.º 9
0
int sym7(void)
{
	if(ELF_ST_TYPE(orcSYM->st_info) != STT_FILE)
		return 0;

	if(mode & REL)
		if(rand() % 2)
			return 0;

	unsigned char st_info = orcSYM->st_info;
	Elf_Section st_shndx;

	if(rand() % 2)
		do
			st_info = ELF_ST_INFO(rand() & 0x0f, STT_FILE);
		while(ELF_ST_BIND(st_info) == STB_LOCAL);

	if(rand() % 4 < 3){
		while((st_shndx = rand() % orcHDR->e_shnum))
			if(st_shndx != SHN_ABS)
				break;
	} else
		while((st_shndx = getElf_Section()))
			if(st_shndx != SHN_ABS)
				break;

	orcSYM->st_info  = st_info;
	orcSYM->st_shndx = st_shndx;

	fprintf(logfp, "(SYM[%d]->st_info = 0x%.2x,", entry, orcSYM->st_info);
	fprintf(logfp, " st_shndx = 0x%x)", orcSYM->st_shndx);

	return 1;
}
Exemplo n.º 10
0
/*
 * Convert an Elf_Sym into an nlist structure.  This fills in only the
 * n_value and n_type members.
 */
static void
elf_sym_to_nlist(struct nlist *nl, Elf_Sym *s, Elf_Shdr *shdr, int shnum)
{
	nl->n_value = s->st_value;

	switch (s->st_shndx) {
	case SHN_UNDEF:
	case SHN_COMMON:
		nl->n_type = N_UNDF;
		break;
	case SHN_ABS:
		nl->n_type = ELF_ST_TYPE(s->st_info) == STT_FILE ?
		    N_FN : N_ABS;
		break;
	default:
		if (s->st_shndx >= shnum)
			nl->n_type = N_UNDF;
		else {
			Elf_Shdr *sh = shdr + s->st_shndx;

			nl->n_type = sh->sh_type == SHT_PROGBITS ?
			    (sh->sh_flags & SHF_WRITE ? N_DATA : N_TEXT) :
			    (sh->sh_type == SHT_NOBITS ? N_BSS : N_UNDF);
		}
		break;
	}

	if (ELF_ST_BIND(s->st_info) == STB_GLOBAL ||
	    ELF_ST_BIND(s->st_info) == STB_WEAK)
		nl->n_type |= N_EXT;
}
Exemplo n.º 11
0
//--------------------------------------------------------------------------
//lint -e{1764} could be declared const ref
static int handle_symbol(
        reader_t &reader,
        int shndx,
        int _info,
        uint32 st_name,
        uval_t st_value,
        int namsec,
        symbol_visitor_t &sv)
{
  if ( shndx == SHN_UNDEF
    || shndx == SHN_LOPROC
    || shndx == SHN_HIPROC
    || shndx == SHN_ABS )
  {
    return 0;
  }

  int type = ELF_ST_TYPE(_info);
  if ( type != STT_OBJECT && type != STT_FUNC )
    return 0;

  if ( st_name == 0 )
    return 0;

  if ( imagebase != uval_t(-1) )
    st_value -= imagebase;

  qstring name;
  reader.sections.get_name(&name, namsec, st_name);
  return sv.visit_symbol(st_value, name.c_str());
}
Exemplo n.º 12
0
Arquivo: elfload.c Projeto: nmav/cspim
Elf32_Sym *mips_elf_find_address(struct mips_cpu *pcpu, Elf32_Addr addr)
{
	Elf32_Shdr *shsymtab = pcpu->shsymtab;
	unsigned    n = shsymtab->sh_size / shsymtab->sh_entsize;
	Elf32_Addr  min = (unsigned)-1;
	Elf32_Sym  *ret = NULL;
	unsigned    i;

	if((shsymtab->sh_offset  + shsymtab->sh_size > pcpu->elfsz)
	|| (addr >= pcpu->memsz))
		return NULL;
	
	for(i = 0; i < n; i++) {
		Elf32_Sym  *sym = get_sym(pcpu->elf, pcpu->elfsz, shsymtab, i);

		if(!sym)
			return NULL;
		if((ELF_ST_BIND(sym->st_info) != STB_GLOBAL) ||
				(ELF_ST_TYPE(sym->st_info) >= STT_SECTION))
			continue;
		
		if(sym->st_value <= addr) {
			Elf32_Addr diff = addr - sym->st_value;
			
			if(diff < min) {
				min = diff;
				ret = sym;
				if(diff == 0)
					break;
			}
		}
	}
	return ret;
}
Exemplo n.º 13
0
void
dump_info(struct elf_object *object)
{
	int numrel, numrela, i;
	const Elf_Sym	*symt;
	const char	*strt;
	Elf_Word *needed_list;

	symt = object->dyn.symtab;
	strt = object->dyn.strtab;

	for (i = 0; i < object->nchains; i++) {
		const Elf_Sym *sym = symt + i;
		char *type;

		switch (ELF_ST_TYPE(sym->st_info)) {
		case STT_FUNC:
			type = "func";
			break;
		case STT_OBJECT:
			type = "object";
			break;
		case STT_NOTYPE:
			type = "notype";
			break;
		default:
			type = "UNKNOWN";
		}
		printf("symbol %d [%s] type %s value %x\n", i,
		    strt + sym->st_name,
		    type, sym->st_value);
	}

	numrel = object->dyn.relsz / sizeof(Elf_Rel);
	numrela = object->dyn.relasz / sizeof(Elf_RelA);
	printf("numrel %d numrela %d\n", numrel, numrela);

	printf("rel relocations:\n");
	for (i = 0; i < numrel ; i++) {
		Elf_Rel *rel = object->dyn.rel;

		printf("%d: %x sym %x type %d\n", i, rel[i].r_offset,
		    ELF_R_SYM(rel[i].r_info), ELF_R_TYPE(rel[i].r_info));
	}
	printf("rela relocations:\n");
	for (i = 0; i < numrela ; i++) {
		Elf_RelA *rela = object->dyn.rela;

		printf("%d: %x sym %x type %d\n", i, rela[i].r_offset,
		    ELF_R_SYM(rela[i].r_info), ELF_R_TYPE(rela[i].r_info));
	}
	needed_list = (Elf_Addr *)object->dyn.needed;
	for (i = 0; needed_list[i] != NULL; i++)
		printf("NEEDED %s\n", needed_list[i] + strt);

}
Exemplo n.º 14
0
static void parse_elf_symbols(uintptr_t mem, size_t size, Phdr_t *load,
		struct vdso_symtable *t, uintptr_t dynsymbol_names,
		Hash_t *hash, Dyn_t *dyn_symtab)
{
	const char *vdso_symbols[VDSO_SYMBOL_MAX] = {
		ARCH_VDSO_SYMBOLS
	};
	const size_t vdso_symbol_length = sizeof(t->symbols[0].name);

	Hash_t nbucket, nchain;
	Hash_t *bucket, *chain;

	unsigned int i, j, k;
	uintptr_t addr;

	nbucket = hash[0];
	nchain = hash[1];
	bucket = &hash[2];
	chain = &hash[nbucket + 2];

	pr_debug("nbucket %lx nchain %lx bucket %lx chain %lx\n",
		 (long)nbucket, (long)nchain, (unsigned long)bucket, (unsigned long)chain);

	for (i = 0; i < VDSO_SYMBOL_MAX; i++) {
		const char * symbol = vdso_symbols[i];
		k = elf_hash((const unsigned char *)symbol);

		for (j = bucket[k % nbucket]; j < nchain && chain[j] != STN_UNDEF; j = chain[j]) {
			addr = mem + dyn_symtab->d_un.d_ptr - load->p_vaddr;
			Sym_t *sym;
			char *name;

			addr += sizeof(Sym_t)*j;
			if (__ptr_struct_oob(addr, sizeof(Sym_t), mem, size))
				continue;
			sym = (void *)addr;

			if (ELF_ST_TYPE(sym->st_info) != STT_FUNC &&
			    ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
				continue;

			addr = dynsymbol_names + sym->st_name;
			if (__ptr_struct_oob(addr, vdso_symbol_length, mem, size))
				continue;
			name = (void *)addr;

			if (std_strncmp(name, symbol, vdso_symbol_length))
				continue;

			memcpy(t->symbols[i].name, name, vdso_symbol_length);
			t->symbols[i].offset = (unsigned long)sym->st_value - load->p_vaddr;
			break;
		}
	}
}
Exemplo n.º 15
0
int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
	const Elf_Sym *sym = obj->symtab + obj->gotsym;
	Elf_Word i;

	for (i = obj->gotsym; i < obj->symtabno; i++, sym++) {
		if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
			if (_rtld_relocate_plt_object(obj, i, NULL) < 0)
				return -1;
	}

	return 0;
}
Exemplo n.º 16
0
const char *arch_loader_symbol_lookup(addr_t addr, struct section_data *sd)
{
	elf64_symtab_entry_t *symtab = (elf64_symtab_entry_t *)(sd->vbase[sd->symtab]);
	addr_t strtab = sd->vbase[sd->strtab];
	if(!symtab || !strtab)
		return NULL;
	for(unsigned i=0;i<(sd->symlen / sizeof(elf64_symtab_entry_t));i++) {
		if(ELF_ST_TYPE(symtab[i].info) == ELF_ST_TYPE_FUNCTION) {
			if(addr >= symtab[i].address && addr < (symtab[i].address + symtab[i].size)) {
				return (const char *)(strtab + symtab[i].name);
			}
		}
	}
	return NULL;
}
Exemplo n.º 17
0
static void * _sym_lookup(DL * dl, Elf_Shdr * shdr, char const * name,
		char const * strtab, size_t strtab_cnt)
{
	size_t i;
	Elf_Sym * sym;
	char const * p;

	for(i = 0; i < dl->symtab_cnt; i++)
	{
		sym = &dl->symtab[i];
		if((p = _dl_strtab_string(strtab, strtab_cnt, sym->st_name))
				== NULL)
			return NULL;
		if(strcmp(p, name) != 0)
			continue;
		/* found the symbol */
		if(sym->st_shndx >= dl->ehdr.e_shnum)
		{
			_dl_error_set(DE_INVALID_FORMAT, 0);
			return NULL;
		}
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s() symbol: %s, section: %u, type=%x"
				", value: 0x%x, size: 0x%x\n", __func__,
				&strtab[sym->st_name],
				sym->st_shndx, ELF_ST_TYPE(sym->st_info),
				sym->st_value, sym->st_size);
#endif
		/* FIXME handle only known types */
		if(ELF_ST_TYPE(sym->st_info) == STT_FUNC)
			return (void*)(sym->st_value + dl->text_addr);
		return (void*)(sym->st_value + dl->data_addr);
	}
	_dl_error_set(DE_SYMBOL_NOT_FOUND, 0);
	return NULL;
}
Exemplo n.º 18
0
Arquivo: elf.c Projeto: coyizumi/cs111
static bool
wantsym(const Elf_Sym *sym, const char *strtab)
{
    int type;
    int bind;

    type = ELF_ST_TYPE(sym->st_info);
    bind = ELF_ST_BIND(sym->st_info);

    if (type != STT_FUNC ||
      (aflag && bind == STB_LOCAL) ||
      (uflag && strchr(strtab + sym->st_name, '.') != NULL))
	return 0;

    return 1;
}
Exemplo n.º 19
0
static int
link_elf_each_function_name(linker_file_t file,
    int (*callback)(const char *, void *), void *opaque)
{
	elf_file_t ef = (elf_file_t)file;
	const Elf_Sym *symp;
	int i, error;
	
	/* Exhaustive search */
	for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
		if (symp->st_value != 0 &&
		    ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
			error = callback(ef->ddbstrtab + symp->st_name, opaque);
			if (error)
				return (error);
		}
	}
	return (0);
}
Exemplo n.º 20
0
bool ElfSymbolTable::compare(const Elf_Sym* sym, address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable) {
  if (STT_FUNC == ELF_ST_TYPE(sym->st_info)) {
    Elf_Word st_size = sym->st_size;
    address sym_addr;
    if (funcDescTable != NULL && funcDescTable->get_index() == sym->st_shndx) {
      // We need to go another step trough the function descriptor table (currently PPC64 only)
      sym_addr = funcDescTable->lookup(sym->st_value);
    } else {
      sym_addr = (address)sym->st_value;
    }
    if (sym_addr <= addr && (Elf_Word)(addr - sym_addr) < st_size) {
      *offset = (int)(addr - sym_addr);
      *posIndex = sym->st_name;
      *stringtableIndex = m_shdr.sh_link;
      return true;
    }
  }
  return false;
}
Exemplo n.º 21
0
/*
**
** Get symbol from section.
**
*/
Elf_Sym*		get_elfsym_frm_section(elfobj* obj, Elf_Addr addr, Elf_Shdr* section, int type)
{
  Elf_Sym*	start, * end, * ret = NULL;
  int		stop = 0;

  start = (Elf_Sym *) ((char*) obj->header + section->sh_offset);
  end   = (Elf_Sym *) ((char*) obj->header + section->sh_offset + section->sh_size);

  /*
  ** Try to find a symbol whose virtual range includes the target address
  ** else take a symbol with the highest address less than or equal to the
  ** target
  */
  for (; !stop && start < end; start++)
    {
      /*
      ** SHF_ALLOC from the man: If the file has a loadable segment that includes
      ** the symbol table, the section's attributes will include the SHF_ALLOC bit;
      ** otherwise, that bit will be off.
      */
      if (!(
	    (type == STT_NOTYPE || ELF_ST_TYPE(start->st_info) == type) &&
	    start->st_value <= addr &&
	    (obj->section_headers[start->st_shndx]->sh_flags & SHF_ALLOC))
	  )
	continue;

      if (start->st_size)
	{
	  if (start->st_size + start->st_value > addr)
	    {
	      ret = start;
	      stop = 1;
	    }
	}
      else
	{
	  if (ret == NULL || ret->st_value < start->st_value)
	    ret = start;
	}
    }
  return (ret);
}
Exemplo n.º 22
0
/* Relocate the jump slots in an object. */
int
reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
    const Elf_Rel *rellim;
    const Elf_Rel *rel;

    if (obj->jmpslots_done)
	return 0;
    rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
    for (rel = obj->pltrel;  rel < rellim;  rel++) {
	Elf_Addr *where, target;
	const Elf_Sym *def;
	const Obj_Entry *defobj;

	switch (ELF_R_TYPE(rel->r_info)) {
	case R_386_JMP_SLOT:
	  where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
	  def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
		SYMLOOK_IN_PLT | flags, NULL, lockstate);
	  if (def == NULL)
	      return (-1);
	  if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
	      obj->gnu_ifunc = true;
	      continue;
	  }
	  target = (Elf_Addr)(defobj->relocbase + def->st_value);
	  reloc_jmpslot(where, target, defobj, obj, rel);
	  break;

	case R_386_IRELATIVE:
	  break;

	default:
	  _rtld_error("Unknown relocation type %x in PLT",
	    ELF_R_TYPE(rel->r_info));
	  return (-1);
	}
    }

    obj->jmpslots_done = true;
    return 0;
}
Exemplo n.º 23
0
const char *arch_loader_lookup_module_symbol(struct module *mq, addr_t addr, char **modname)
{
	/* okay, look up the symbol */
	for (unsigned int i = 0; i < (mq->sd.symlen/sizeof (elf64_symtab_entry_t)); i++)
	{
		elf64_symtab_entry_t *st;
		st = &((elf64_symtab_entry_t *)mq->sd.vbase[mq->sd.symtab])[i];
		if (ELF_ST_TYPE(st->info) != 0x2)
			continue;
		if ( (addr >= st->address) 
				&& (addr < (st->address + st->size)) )
		{
			const char *name = (const char *) ((uint64_t)(mq->sd.vbase[mq->sd.strtab])
					+ st->name);
			*modname = mq->name;
			return name;
		}
	}
	return 0;
}
Exemplo n.º 24
0
/** Convert symbol address to name.
 *
 * This function finds the symbol which starts at the highest address
 * less than or equal to @a addr.
 *
 * @param st	Symbol table.
 * @param addr	Address for lookup.
 * @param name	Place to store pointer name of symbol, if found.
 *		This is valid while @a st exists.
 *
 * @return	EOK on success or ENOENT if no matching symbol was found.
 */
int symtab_addr_to_name(symtab_t *st, uintptr_t addr, char **name,
    size_t *offs)
{
	size_t i;
	uintptr_t saddr, best_addr;
	char *sname, *best_name;
	unsigned stype;

	best_name = NULL;
	best_addr = 0;

	for (i = 0; i < st->sym_size / sizeof(elf_symbol_t); ++i) {
		if (st->sym[i].st_name == 0)
			continue;

		stype = ELF_ST_TYPE(st->sym[i].st_info);
		if (stype != STT_OBJECT && stype != STT_FUNC &&
		    stype != STT_NOTYPE) {
			continue;
		}

		saddr = st->sym[i].st_value;
		sname = st->strtab + st->sym[i].st_name;

		/* An ugly hack to filter out some special ARM symbols. */
		if (sname[0] == '$')
			continue;

		if (best_name == NULL || (saddr <= addr && saddr > best_addr)) {
			best_name = sname;
			best_addr = saddr;
		}
	}

	if (best_name == NULL)
		return ENOENT;

	*name = best_name;
	*offs = addr - best_addr;
	return EOK;
}
Exemplo n.º 25
0
int sym6(void)
{
	if(ELF_ST_TYPE(orcSYM->st_info) != STT_SECTION)
		return 0;

	if(mode & REL)
		if(rand() % 2)
			return 0;

	unsigned char st_info;

	do
		st_info = ELF_ST_INFO(rand() & 0x0f, STT_SECTION);
	while(ELF_ST_BIND(st_info) == STB_LOCAL);

	orcSYM->st_info = st_info;

	fprintf(logfp, "(SYM[%d]->st_info = 0x%.2x)", entry, orcSYM->st_info);

	return 1;
}
Exemplo n.º 26
0
int
__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, const char* name,
		  Elf_Sym *symp)
{
    Elf_Hashelt symnum;
    Elf_Sym sym;
    char *strp;
    unsigned long hash;

    hash = elf_hash(name);
    COPYOUT(&ef->buckets[hash % ef->nbuckets], &symnum, sizeof(symnum));

    while (symnum != STN_UNDEF) {
	if (symnum >= ef->nchains) {
	    printf(__elfN(bad_symtable));
	    return ENOENT;
	}

	COPYOUT(ef->symtab + symnum, &sym, sizeof(sym));
	if (sym.st_name == 0) {
	    printf(__elfN(bad_symtable));
	    return ENOENT;
	}

	strp = strdupout((vm_offset_t)(ef->strtab + sym.st_name));
	if (strcmp(name, strp) == 0) {
	    free(strp);
	    if (sym.st_shndx != SHN_UNDEF ||
		(sym.st_value != 0 &&
		 ELF_ST_TYPE(sym.st_info) == STT_FUNC)) {
		*symp = sym;
		return 0;
	    }
	    return ENOENT;
	}
	free(strp);
	COPYOUT(&ef->chains[symnum], &symnum, sizeof(symnum));
    }
    return ENOENT;
}
Exemplo n.º 27
0
static int
link_elf_each_function_nameval(linker_file_t file,
    linker_function_nameval_callback_t callback, void *opaque)
{
	linker_symval_t symval;
	elf_file_t ef = (elf_file_t)file;
	const Elf_Sym* symp;
	int i, error;

	/* Exhaustive search */
	for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
		if (symp->st_value != 0 &&
		    ELF_ST_TYPE(symp->st_info) == STT_FUNC) {
			error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval);
			if (error)
				return (error);
			error = callback(file, i, &symval, opaque);
			if (error)
				return (error);
		}
	}
	return (0);
}
Exemplo n.º 28
0
static Elf_Addr
SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section,
                      struct image_target_desc *image_target)
{
    Elf_Word symtab_size, sym_size, num_syms;
    Elf_Off symtab_offset;
    Elf_Sym *sym;
    Elf_Word i;
    int ret = 0;

    symtab_size = grub_target_to_host (symtab_section->sh_size);
    sym_size = grub_target_to_host (symtab_section->sh_entsize);
    symtab_offset = grub_target_to_host (symtab_section->sh_offset);
    num_syms = symtab_size / sym_size;

    for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
            i < num_syms;
            i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
        if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
            ret++;

    return ret;
}
Exemplo n.º 29
0
/*
 * LD_BIND_NOW was set - force relocation for all jump slots
 */
int
reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
{
	const Obj_Entry *defobj;
	const Elf_Rela *relalim;
	const Elf_Rela *rela;
	const Elf_Sym *def;

	if (obj->jmpslots_done)
		return (0);

	relalim = (const Elf_Rela *)((const char *)obj->pltrela +
	    obj->pltrelasize);
	for (rela = obj->pltrela; rela < relalim; rela++) {
		Elf_Addr *where, target;

		where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
		switch(ELF_R_TYPE(rela->r_info)) {
		case R_AARCH64_JUMP_SLOT:
			def = find_symdef(ELF_R_SYM(rela->r_info), obj,
			    &defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
			if (def == NULL)
				return (-1);
			if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
				obj->gnu_ifunc = true;
				continue;
			}
			target = (Elf_Addr)(defobj->relocbase + def->st_value);
			reloc_jmpslot(where, target, defobj, obj,
			    (const Elf_Rel *)rela);
			break;
		}
	}
	obj->jmpslots_done = true;

	return (0);
}
Exemplo n.º 30
0
/** Convert symbol name to address.
 *
 * @param st	Symbol table.
 * @param name	Name of the symbol.
 * @param addr	Place to store address for symbol, if found.
 *
 * @return	EOK on success, ENOENT if no such symbol was found.
 */
int symtab_name_to_addr(symtab_t *st, char *name, uintptr_t *addr)
{
	size_t i;
	char *sname;
	unsigned stype;

	for (i = 0; i < st->sym_size / sizeof(elf_symbol_t); ++i) {
		if (st->sym[i].st_name == 0)
			continue;

		stype = ELF_ST_TYPE(st->sym[i].st_info);
		if (stype != STT_OBJECT && stype != STT_FUNC)
			continue;

		sname = st->strtab + st->sym[i].st_name;

		if (str_cmp(sname, name) == 0) {
			*addr = st->sym[i].st_value;
			return EOK;
		}
	}

	return ENOENT;
}