Ejemplo n.º 1
0
static BOOL DLSYM_lookup_symtab(const char *sym_name, struct Elf32_Sym *symtab,
                                Elf32_Word symnum, Elf32_Addr *sym_value,
                                BOOL require_local_binding)
{
   Elf32_Addr sym_idx;
   for (sym_idx = 0; sym_idx < symnum; sym_idx++)
   {
#if LOADER_DEBUG
      if (debugging_on)
         DLIF_trace("DLSYM_lookup_symtab %s\n",
                    (char *)symtab[sym_idx].st_name);
#endif

      if ((symtab[sym_idx].st_shndx != SHN_UNDEF) &&
          ((require_local_binding &&
            (ELF32_ST_BIND(symtab[sym_idx].st_info) == STB_LOCAL)) ||
	   (!require_local_binding &&
	    (ELF32_ST_BIND(symtab[sym_idx].st_info) != STB_LOCAL))) &&
          !strcmp(sym_name,(char*)(symtab[sym_idx].st_name)))
      {
         if (sym_value) *sym_value = symtab[sym_idx].st_value;
         return TRUE;

      }
   }
   if (sym_value) *sym_value = 0;
   return FALSE;
}
Ejemplo n.º 2
0
Archivo: section.c Proyecto: Dieken/jff
void dump_SHT_SYMTAB_section(void* data, size_t length, int i) {
    Elf32_Ehdr* ehdr = (Elf32_Ehdr*)data;
    Elf32_Shdr* shdrs = (Elf32_Shdr*)((char*)data + ehdr->e_shoff);
    Elf32_Sym* symbols = (Elf32_Sym*)((char*)data + shdrs[i].sh_offset);
    int shnum = ehdr->e_shnum;
    int shentsize = ehdr->e_shentsize;
    int entnum;
    unsigned char st_info;
    char info[3];   /* local/global/weak, data/function/section/file */
    int j;

    assert(sizeof(Elf32_Shdr) == ehdr->e_shentsize &&
            sizeof(Elf32_Sym) == shdrs[i].sh_entsize);

    entnum = shdrs[i].sh_size / shdrs[i].sh_entsize;
    assert(entnum > 0);
    
    info[2] = '\0';
    printf("entnum=%d\n", entnum);
    puts("    [ Nr]  value size  info  other   shndx   name");
    for (j = 0; j < entnum; ++j) {
        st_info = symbols[j].st_info;
        if (ELF32_ST_BIND(st_info) == STB_LOCAL)
            info[0] = 'l';
        else if (ELF32_ST_BIND(st_info) == STB_GLOBAL)
            info[0] = 'g';
        else if (ELF32_ST_BIND(st_info) == STB_WEAK)
            info[0] = 'w';
        else
            info[0] = '?';

        if (ELF32_ST_TYPE(st_info) == STT_OBJECT)
            info[1] = 'd';
        else if (ELF32_ST_TYPE(st_info) == STT_FUNC)
            info[1] = 'F';
        else if (ELF32_ST_TYPE(st_info) == STT_SECTION)
            info[1] = 's';
        else if (ELF32_ST_TYPE(st_info) == STT_FILE)
            info[1] = 'f';
        else if (ELF32_ST_TYPE(st_info) == STT_NOTYPE)
            info[1] = ' ';
        else
            info[1] = '?';

        printf("    [%3d] %6d %4d  [%2s]    %2d   %6d  %-12s\n",
                j,
                symbols[j].st_value,
                symbols[j].st_size,
                info,
                symbols[j].st_other,
                symbols[j].st_shndx,
                (symbols[j].st_name == 0) ? "<UNNAMED>" :
                    get_str(data, shdrs[i].sh_link, symbols[j].st_name));
    }
}
Ejemplo n.º 3
0
/**
 * Get the binding of a symbol.
 * @param infos		Information about the symbol.
 * @return			Binding as a string.
 */
const char *get_binding(const gel_sym_info_t *infos) {
	static char buf[32];
	switch(ELF32_ST_BIND(infos->info)) {
	case STB_LOCAL: return "local";
	case STB_GLOBAL: return "global";
	case STB_WEAK: return "weak";
	default:
		sprintf(buf, "%d", ELF32_ST_BIND(infos->info));
		return buf;
	}
}
Ejemplo n.º 4
0
int add_global( char *name, Elf32_Sym *sym, object *parent )
{
   DEBUG(( stderr, "add_global(%s, %p, %p): ", name, sym, parent ));

   global *g = root_global;

   while( g )
   {
      if( strcmp( name, g->name ) == 0 ) break;
      g = g->next;
   }

   if( !g )
   {
      // such global does not yet exists, add to list
      g = new global;
      g->next = root_global;
      root_global = g;
      g->name = name;
      g->sym = sym;
      g->parent = parent;
      DEBUG(( stderr, "created global definition of '%s' at %p [weak: %d, value: %d]\n", name, g, ELF32_ST_BIND(sym->st_info) == STB_WEAK, sym->st_value ));
   }
   else
   {
      if( ELF32_ST_BIND(g->sym->st_info) == ELF32_ST_BIND(sym->st_info) ) // equal binding
      {
         if( ELF32_ST_BIND(sym->st_info) == STB_WEAK )
         {
            DEBUG(( stderr, "duplicate weak symbol, discarding\n" ));
            return 0;
         }

         if( g->sym->st_value == sym->st_value )
         {
            warning( "global symbol '%s' is redefined in '%s'", name, parent->filename );
            return 0;
         }

         error( "global symbol '%s' defined in '%s' conflicts with global symbol already defined in '%s'", name, parent->filename, g->parent->filename );
         return 1;
      }

      if( ELF32_ST_BIND(sym->st_info) == STB_GLOBAL )
      {
         g->sym = sym;
         g->parent = parent;
         DEBUG(( stderr, "replacing old weak definition of '%s' at %p\n", name, g ));
      }
   }

   return 0;
}
Ejemplo n.º 5
0
static int
relocate_section_rel(Elf32_Sym *sym_table, Elf32_Rel *rel,
		     char *target_sect, int nr_reloc, char *strtab)
{
	Elf32_Sym *sym;
	Elf32_Addr sym_val;
	int i;

	for (i = 0; i < nr_reloc; i++) {
		sym = &sym_table[ELF32_R_SYM(rel->r_info)];
		ELFDBG(("%s\n", strtab + sym->st_name));
		if (sym->st_shndx != STN_UNDEF) {
			sym_val = (Elf32_Addr)sect_addr[sym->st_shndx]
				+ sym->st_value;
			if (relocate_rel(rel, sym_val, target_sect) != 0)
				return -1;
		} else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
			DPRINTF(("Undefined symbol for rel[%x] sym=%lx\n",
				 i, (long)sym));
			return -1;
		} else {
			DPRINTF(("Undefined weak symbol for rel[%x]\n", i));
		}
		rel++;
	}
	return 0;
}
Ejemplo n.º 6
0
int
pmelf_getsym32(Elf_Stream s, Elf32_Sym *psym)
{
	if ( 1 != SREAD(psym, sizeof(*psym), 1, s) ) {
		return -1;
	}
	if ( s->needswap ) {
#ifdef PMELF_CONFIG_NO_SWAPSUPPORT
		return -2;
#else
		elf_swap32( &psym->st_name);
		elf_swap32( &psym->st_value);
		elf_swap32( &psym->st_size);
		elf_swap16( &psym->st_shndx);
#endif
	}
#ifdef PARANOIA_ON
	{
	int x;
	if ( (x = ELF32_ST_TYPE( psym->st_info )) > STT_MAXSUP ) {
		PMELF_PRINTF( pmelf_err, PMELF_PRE"pmelf_getsym - paranoia: unsupported type %i\n", x);
		return -1;
	}
	if ( (x = ELF32_ST_BIND( psym->st_info )) > STB_MAXSUP ) {
		PMELF_PRINTF( pmelf_err, PMELF_PRE"pmelf_getsym - paranoia: unsupported binding %i\n", x);
		return -1;
	}
	}
#endif
	return 0;
}
Ejemplo n.º 7
0
/**
 * Get information about a symbol.
 * @param loader	Current loader.
 * @param sym		Symbol index.
 * @param data		Dat structure to store information in.
 */
void gliss_loader_sym(gliss_loader_t *loader, int sym, gliss_loader_sym_t *data) {
	assert(sym < gliss_loader_count_syms(loader));
	Elf32_Sym *s;

	/* get the descriptor */
	assert(sym < gliss_loader_count_syms(loader));
	s = &loader->Tables.sym_tbl[sym];

	/* get name */
	data->name = loader->Tables.symstr_tbl + loader->Tables.sym_tbl[sym].st_name;

	/* get value and section */
	data->value = s->st_value;
	data->sect = s->st_shndx;
	data->size = s->st_size;

	/* get the binding */
	switch(ELF32_ST_BIND(s->st_info)) {
	case STB_LOCAL: data->bind = GLISS_LOADER_LOCAL; break;
	case STB_GLOBAL: data->bind = GLISS_LOADER_GLOBAL; break;
	case STB_WEAK: data->bind = GLISS_LOADER_WEAK; break;
	default: data->bind = GLISS_LOADER_NO_BINDING; break;
	}

	/* get the type */
	switch(ELF32_ST_TYPE(s->st_info)) {
	case STT_FUNC: data->type = GLISS_LOADER_SYM_CODE; break;
	case STT_OBJECT: data->type = GLISS_LOADER_SYM_DATA; break;
	default: data->type = GLISS_LOADER_SYM_NO_TYPE; break;
	}
}
Ejemplo n.º 8
0
GElf_Sym *
gelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst)
{
	int ec;
	Elf *e;
	Elf_Scn *scn;
	Elf32_Sym *sym32;
	Elf64_Sym *sym64;
	size_t msz;
	uint32_t sh_type;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	ec = e->e_class;
	assert(ec == ELFCLASS32 || ec == ELFCLASS64);

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);

	assert(msz > 0);

	if (msz * ndx >= d->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {

		sym32 = (Elf32_Sym *) d->d_buf + ndx;

		dst->st_name  = sym32->st_name;
		dst->st_value = (Elf64_Addr) sym32->st_value;
		dst->st_size  = (Elf64_Xword) sym32->st_size;
		dst->st_info  = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info),
		    ELF32_ST_TYPE(sym32->st_info));
		dst->st_other = sym32->st_other;
		dst->st_shndx = sym32->st_shndx;
	} else {

		sym64 = (Elf64_Sym *) d->d_buf + ndx;

		*dst = *sym64;
	}

	return (dst);
}
Ejemplo n.º 9
0
static uint_t
dt_module_syminit32(dt_module_t *dmp)
{
	const Elf32_Sym *sym = dmp->dm_symtab.cts_data;
	const char *base = dmp->dm_strtab.cts_data;
	size_t ss_size = dmp->dm_strtab.cts_size;
	uint_t i, n = dmp->dm_nsymelems;
	uint_t asrsv = 0;

	for (i = 0; i < n; i++, sym++) {
		const char *name = base + sym->st_name;
		uchar_t type = ELF32_ST_TYPE(sym->st_info);

		if (type >= STT_NUM || type == STT_SECTION)
			continue; /* skip sections and unknown types */

		if (sym->st_name == 0 || sym->st_name >= ss_size)
			continue; /* skip null or invalid names */

		if (sym->st_value != 0 &&
		    (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
			asrsv++; /* reserve space in the address map */

		dt_module_symhash_insert(dmp, name, i);
	}

	return (asrsv);
}
Ejemplo n.º 10
0
static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
			Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
{
	int reloc_type;
	int symtab_index;
	char *symname;
	unsigned long *reloc_addr;
	unsigned long symbol_addr;
#if defined(__SUPPORT_LD_DEBUG__)
	unsigned long old_val;
#endif

	reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
	reloc_type = ELF32_R_TYPE(rpnt->r_info);
	symtab_index = ELF32_R_SYM(rpnt->r_info);
	symbol_addr = 0;
	symname = strtab + symtab[symtab_index].st_name;

	if (symtab_index) {
		symbol_addr = (unsigned long)
			_dl_find_hash(strtab + symtab[symtab_index].st_name,
				      tpnt->symbol_scope, tpnt,
				      elf_machine_type_class(reloc_type));

		/* Allow undefined references to weak symbols */
		if (!symbol_addr &&
		    ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
			_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
				    _dl_progname, symname);
			return 0;
		}
	}

#if defined(__SUPPORT_LD_DEBUG__)
	old_val = *reloc_addr;
#endif
	switch (reloc_type) {
	case R_AVR32_NONE:
		break;
	case R_AVR32_GLOB_DAT:
	case R_AVR32_JMP_SLOT:
		*reloc_addr = symbol_addr + rpnt->r_addend;
		break;
	case R_AVR32_RELATIVE:
		*reloc_addr = (unsigned long)tpnt->loadaddr
			+ rpnt->r_addend;
		break;
	default:
		return -1;
	}

#if defined(__SUPPORT_LD_DEBUG__)
	if (_dl_debug_reloc && _dl_debug_detail)
		_dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
			    old_val, *reloc_addr);
#endif

	return 0;
}
Ejemplo n.º 11
0
/*
 *  ======== print_symbol_info ========
 */
static void print_symbol_info(struct Elf32_Sym *sym)
{
    DEBUG_PRINT("Name-Offset = 0x%.8x Value = 0x%.8x Size = 0x%.8x "
                "Bind = %d Type = %d Visibility = %d Index = %d\n",
                sym->st_name, sym->st_value, sym->st_size,
                ELF32_ST_BIND(sym->st_info), ELF32_ST_TYPE(sym->st_info),
                sym->st_other, sym->st_shndx);
}
Ejemplo n.º 12
0
// this function first tries to see if the first image and it's already resolved symbol is okay, otherwise
// it tries to link against the shared_image
// XXX gross hack and needs to be done better
int elf_resolve_symbol(struct elf_image_info *image, struct Elf32_Sym *sym, struct elf_image_info *shared_image, const char *sym_prepend,addr_t *sym_addr)
{
	struct Elf32_Sym *sym2;
	char new_symname[512];

	switch(sym->st_shndx) {
		case SHN_UNDEF:
			// patch the symbol name
			strlcpy(new_symname, sym_prepend, sizeof(new_symname));
			strlcat(new_symname, SYMNAME(image, sym), sizeof(new_symname));

			// it's undefined, must be outside this image, try the other image
			sym2 = elf_find_symbol(shared_image, new_symname);
			if(!sym2) {
				dprintf("elf_resolve_symbol: could not resolve symbol '%s'\n", new_symname);
				return ERR_ELF_RESOLVING_SYMBOL;
			}

			// make sure they're the same type
			if(ELF32_ST_TYPE(sym->st_info) != ELF32_ST_TYPE(sym2->st_info)) {
				dprintf("elf_resolve_symbol: found symbol '%s' in shared image but wrong type\n", new_symname);
				return ERR_ELF_RESOLVING_SYMBOL;
			}

			if(ELF32_ST_BIND(sym2->st_info) != STB_GLOBAL && ELF32_ST_BIND(sym2->st_info) != STB_WEAK) {
				dprintf("elf_resolve_symbol: found symbol '%s' but not exported\n", new_symname);
				return ERR_ELF_RESOLVING_SYMBOL;
			}

			*sym_addr = sym2->st_value + shared_image->regions[0].delta;
			return NO_ERROR;
		case SHN_ABS:
			*sym_addr = sym->st_value;
			return NO_ERROR;
		case SHN_COMMON:
			// XXX finish this
			dprintf("elf_resolve_symbol: COMMON symbol, finish me!\n");
			return ERR_NOT_IMPLEMENTED;
		default:
			// standard symbol
			*sym_addr = sym->st_value + image->regions[0].delta;
			return NO_ERROR;
	}
}
Ejemplo n.º 13
0
BOOL DLSYM_canonical_lookup(DLOAD_HANDLE handle, int sym_index, 
                            DLIMP_Dynamic_Module *dyn_module, 
                            Elf32_Addr *sym_value)
{
   /*------------------------------------------------------------------------*/
   /* Lookup the symbol table to get the symbol characteristics.             */
   /*------------------------------------------------------------------------*/
   struct Elf32_Sym *sym = &dyn_module->symtab[sym_index];
   int32_t           st_bind = ELF32_ST_BIND(sym->st_info);
   int32_t           st_vis  = ELF32_ST_VISIBILITY(sym->st_other);
   BOOL              is_def  = (sym->st_shndx != SHN_UNDEF && 
                               (sym->st_shndx < SHN_LORESERVE || 
                                sym->st_shndx == SHN_ABS || 
                                sym->st_shndx == SHN_COMMON || 
                                sym->st_shndx == SHN_XINDEX));
   const char *sym_name = (char *)sym->st_name; 

#if LOADER_DEBUG
   if (debugging_on)
      DLIF_trace("DLSYM_canonical_lookup: %d, %s\n", sym_index, sym_name);
#endif

   /*------------------------------------------------------------------------*/
   /* Local symbols and symbol definitions that cannot be pre-empted         */
   /* are resolved by the definition in the same module.                     */
   /*------------------------------------------------------------------------*/
   if (st_bind == STB_LOCAL || st_vis != STV_DEFAULT)
   {
      /*---------------------------------------------------------------------*/
      /* If it is a local symbol or non-local that cannot be preempted,      */
      /* the definition should be found in the same module. If we don't      */
      /* find the definition it is an error.                                 */
      /*---------------------------------------------------------------------*/
      if (!is_def)
      {
         DLIF_error(DLET_SYMBOL, 
                    "Local/non-imported symbol %s definition is not found "
                    "in module %s!\n", sym_name, dyn_module->name);
         return FALSE;
      }
      else
      {
         if (sym_value) *sym_value = sym->st_value;
         return TRUE; 
      }
   }
   /*------------------------------------------------------------------------*/
   /* Else we have either pre-emptable defintion or undef symbol. We need    */
   /* to do global look up.                                                  */
   /*------------------------------------------------------------------------*/
   else 
   {
      return DLSYM_global_lookup(handle, sym_name, dyn_module->loaded_module, 
                                 sym_value);
   }
}
Ejemplo n.º 14
0
db_sym_t
elf_db_search_symbol (db_symtab_t *stab,
		      db_addr_t off,
		      db_strategy_t strategy,
		      db_expr_t *diffp)	/* in/out */
{
  struct db_symtab_elf *self = (struct db_symtab_elf *) stab;
  unsigned long	diff = *diffp;
  Elf32_Sym *s, *symp = NULL;

  for (s = self->start; s < self->end; s++) {
    if (s->st_name == 0)
      continue;

    if (strategy == DB_STGY_XTRN && (ELF32_ST_BIND(s->st_info) != STB_GLOBAL))
      continue;

    if (off >= s->st_value) {
      if (ELF32_ST_TYPE(s->st_info) == STT_FUNC)
	continue;

      if (off - s->st_value < diff) {
	diff = off - s->st_value;
	symp = s;
	if (diff == 0 && (ELF32_ST_BIND(s->st_info) == STB_GLOBAL))
	  break;
      } else if (off - s->st_value == diff) {
	if (symp == NULL)
	  symp = s;
	else if ((ELF32_ST_BIND(symp->st_info) != STB_GLOBAL)
		 && (ELF32_ST_BIND(s->st_info) == STB_GLOBAL))
	  symp = s;	/* pick the external symbol */
      }
    }
  }

  if (symp == NULL)
    *diffp = off;
  else
    *diffp = diff;

  return (db_sym_t) symp;
}
Ejemplo n.º 15
0
static
int elf_search_section_sym(WadFrame *f, char *secname, char *strname) {
  int         nsymtab;
  int         nstrtab;
  int         symtab_size;
  Elf32_Sym  *sym;
  int         nsym;
  char       *str;
  int         i;
  unsigned long vaddr, base;
  char        *name;
  char        *localfile = 0;

  vaddr = (unsigned long) f->pc;
  base  = (unsigned long) f->segment->base;

  nsymtab = wad_elf_section_byname(f->object,secname);
  if (nsymtab < 0) return 0;
  nstrtab = wad_elf_section_byname(f->object,strname);
  if (nstrtab < 0) return 0;
  
  symtab_size = wad_elf_section_size(f->object,nsymtab);
  sym = (Elf32_Sym *) wad_elf_section_data(f->object,nsymtab);
  str = (char *) wad_elf_section_data(f->object,nstrtab);

  nsym = (symtab_size/sizeof(Elf32_Sym));
  for (i = 0; i < nsym; i++) {
    name = str + sym[i].st_name;
    /* Look for filename in case the symbol maps to a local symbol */
    if (ELF32_ST_TYPE(sym[i].st_info) == STT_FILE) {
      localfile = name;
    }
    if (wad_debug_mode & DEBUG_SYMBOL_SEARCH) {
      wad_printf("%x(%x): %s   %x + %x, %x, %x\n", base, vaddr, name, sym[i].st_value, sym[i].st_size, sym[i].st_info, sym[i].st_shndx);
    }
    if (((base + sym[i].st_value) <= vaddr) && (vaddr <= (base+sym[i].st_value + sym[i].st_size))) {
#ifdef WAD_LINUX
      /* If the section index is 0, the symbol is undefined */
      if (sym[i].st_shndx == 0) continue;
#endif
      f->sym_name = name;
      f->sym_nlen = strlen(name);
      f->sym_base = base + sym[i].st_value;
      f->sym_size = sym[i].st_size;
      if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) {
	f->sym_file = localfile;
	f->sym_bind = SYM_LOCAL;
      } else {
	f->sym_bind = SYM_GLOBAL;
      }
      return 1;
    }
  }
  return 0;
}
Ejemplo n.º 16
0
void *__wrap_dlsym(void *handle, const char *symbol)
{
    if (extractLibs)
        return dlsym(handle, symbol);

    soinfo *found;
    Elf32_Sym *sym;
    unsigned bind;

    pthread_mutex_lock(&dl_lock);

    if(unlikely(handle == 0)) { 
        set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE);
        goto err;
    }
    if(unlikely(symbol == 0)) {
        set_dlerror(DL_ERR_BAD_SYMBOL_NAME);
        goto err;
    }

    if(handle == RTLD_DEFAULT) {
        sym = lookup(symbol, &found, NULL);
    } else if(handle == RTLD_NEXT) {
        void *ret_addr = __builtin_return_address(0);
        soinfo *si = find_containing_library(ret_addr);

        sym = NULL;
        if(si && si->next) {
            sym = lookup(symbol, &found, si->next);
        }
    } else {
        found = (soinfo*)handle;
        sym = lookup_in_library(found, symbol);
    }

    if(likely(sym != 0)) {
        bind = ELF32_ST_BIND(sym->st_info);

        if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) {
            unsigned ret = sym->st_value + found->base;
            pthread_mutex_unlock(&dl_lock);
            return (void*)ret;
        }

        set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL);
    }
    else
        set_dlerror(DL_ERR_SYMBOL_NOT_FOUND);

err:
    pthread_mutex_unlock(&dl_lock);
    return 0;
}
Ejemplo n.º 17
0
/* Change all symbols so that sh_value encodes the pointer directly. */
static int simplify_symbols(Elf32_Shdr *sechdrs,
			    unsigned int symindex,
			    const char *strtab)
{
	Elf32_Sym *sym = (void *)sechdrs[symindex].sh_addr;
	unsigned long secbase;
	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf32_Sym);
	int ret = 0;

	for (i = 1; i < n; i++) {
		switch (sym[i].st_shndx) {
		case SHN_COMMON:
			/* We compiled with -fno-common.  These are not
			   supposed to happen.  */
			printf("Common symbol: %s\n", strtab + sym[i].st_name);
			printf("please compile with -fno-common\n");
			ret = -1;
			break;

		case SHN_ABS:
			/* Don't need to do anything */
			debug("Absolute symbol: 0x%08lx\n",
			       (long)sym[i].st_value);
			break;

		case SHN_UNDEF:
			sym[i].st_value
			  = resolve_symbol(sechdrs,
					   strtab + sym[i].st_name);
			debug("undef  : %20s 0x%08x 0x%08lx\n", strtab + sym[i].st_name, sym[i].st_value);

			/* Ok if resolved.  */
			if (sym[i].st_value != 0)
				break;
			/* Ok if weak.  */
			if (ELF32_ST_BIND(sym[i].st_info) == STB_WEAK)
				break;

			printf("Unknown symbol %s\n",
			       strtab + sym[i].st_name);
			ret = -1;
			break;

		default:
			secbase = sechdrs[sym[i].st_shndx].sh_addr;
			debug("default: %20s 0x%08x 0x%08lx\n", strtab + sym[i].st_name, sym[i].st_value, secbase);
			sym[i].st_value += secbase;
			break;
		}
	}

	return ret;
}
Ejemplo n.º 18
0
/*
 * Sort comparison function for 32-bit symbol address-to-name lookups.  We sort
 * symbols by value.  If values are equal, we prefer the symbol that is
 * non-zero sized, typed, not weak, or lexically first, in that order.
 */
static int
dt_module_symcomp32(const void *lp, const void *rp)
{
	Elf32_Sym *lhs = *((Elf32_Sym **)lp);
	Elf32_Sym *rhs = *((Elf32_Sym **)rp);

	if (lhs->st_value != rhs->st_value)
		return (lhs->st_value > rhs->st_value ? 1 : -1);

	if ((lhs->st_size == 0) != (rhs->st_size == 0))
		return (lhs->st_size == 0 ? 1 : -1);

	if ((ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
	    (ELF32_ST_TYPE(rhs->st_info) == STT_NOTYPE))
		return (ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);

	if ((ELF32_ST_BIND(lhs->st_info) == STB_WEAK) !=
	    (ELF32_ST_BIND(rhs->st_info) == STB_WEAK))
		return (ELF32_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);

	return (strcmp(dt_module_strtab + lhs->st_name,
	    dt_module_strtab + rhs->st_name));
}
Ejemplo n.º 19
0
int elf_rel_find_symbol(struct mem_ehdr *ehdr,
	const char *name, struct mem_sym *ret_sym)
{
	struct mem_shdr *shdr, *shdr_end;

	if (!ehdr->e_shdr) {
		/* "No section header? */
		return  -1;
	}
	/* Walk through the sections and find the symbol table */
	shdr_end = &ehdr->e_shdr[ehdr->e_shnum];
	for (shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) {
		const char *strtab;
		size_t sym_size;
		const unsigned char *ptr, *sym_end;
		if (shdr->sh_type != SHT_SYMTAB) {
			continue;
		}
		if (shdr->sh_link > ehdr->e_shnum) {
			/* Invalid strtab section number? */
			continue;
		}
		strtab = (char *)ehdr->e_shdr[shdr->sh_link].sh_data;
		/* Walk through the symbol table and find the symbol */
		sym_size = elf_sym_size(ehdr);
		sym_end = shdr->sh_data + shdr->sh_size;
		for(ptr = shdr->sh_data; ptr < sym_end; ptr += sym_size) {
			struct mem_sym sym;
			sym = elf_sym(ehdr, ptr);
			if (ELF32_ST_BIND(sym.st_info) != STB_GLOBAL) {
				continue;
			}
			if (strcmp(strtab + sym.st_name, name) != 0) {
				continue;
			}
			if ((sym.st_shndx == STN_UNDEF) ||
				(sym.st_shndx > ehdr->e_shnum))
			{
				die("Symbol: %s has Bad section index %d\n",
					name, sym.st_shndx);
			}
			*ret_sym = sym;
			return 0;
		}
	}
	/* I did not find it :( */
	return -1;

}
Ejemplo n.º 20
0
static uint_t
dt_module_syminit32(dt_module_t *dmp)
{
#if STT_NUM != (STT_TLS + 1)
#error "STT_NUM has grown. update dt_module_syminit32()"
#endif

	Elf32_Sym *sym = dmp->dm_symtab.cts_data;
	const char *base = dmp->dm_strtab.cts_data;
	size_t ss_size = dmp->dm_strtab.cts_size;
	uint_t i, n = dmp->dm_nsymelems;
	uint_t asrsv = 0;

#if defined(__FreeBSD__)
	GElf_Ehdr ehdr;
	int is_elf_obj;

	gelf_getehdr(dmp->dm_elf, &ehdr);
	is_elf_obj = (ehdr.e_type == ET_REL);
#endif

	for (i = 0; i < n; i++, sym++) {
		const char *name = base + sym->st_name;
		uchar_t type = ELF32_ST_TYPE(sym->st_info);

		if (type >= STT_NUM || type == STT_SECTION)
			continue; /* skip sections and unknown types */

		if (sym->st_name == 0 || sym->st_name >= ss_size)
			continue; /* skip null or invalid names */

		if (sym->st_value != 0 &&
		    (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) {
			asrsv++; /* reserve space in the address map */

#if defined(__FreeBSD__)
			sym->st_value += (Elf_Addr) dmp->dm_reloc_offset;
			if (is_elf_obj && sym->st_shndx != SHN_UNDEF &&
			    sym->st_shndx < ehdr.e_shnum)
				sym->st_value +=
				    dmp->dm_sec_offsets[sym->st_shndx];
#endif
		}

		dt_module_symhash_insert(dmp, name, i);
	}

	return (asrsv);
}
Ejemplo n.º 21
0
Archivo: sym.c Proyecto: boz/elfcrunch
char * symbol_bind2str( Elf32_Sym * sym )
{
   char * ret;
   if( ! sym )
      error_ret("null arg",NULL);
   switch( ELF32_ST_BIND( sym->st_info ) ) {
     case STB_LOCAL  : ret = "STB_LOCAL "; break;
     case STB_GLOBAL : ret = "STB_GLOBAL"; break;
     case STB_WEAK   : ret = "STB_WEAK  "; break;
     case STB_LOPROC : ret = "STB_LOPROC"; break;
     case STB_HIPROC : ret = "STB_HIPROC"; break;
     default         : ret = "unknown   "; break;
   }
   return( ret );
}
Ejemplo n.º 22
0
Elf32_Sym elflink_getsym( const char *name, elfinfo_t *elf, int elfcount ) {
	int n, has_weak = 0, weak_n, bind, weak_s;
	Elf32_Sym *weak;
	Elf32_Word sym;
	Elf32_Sym *sym_p;
	Elf32_Sym notfound;
	for ( n = 0; n < elfcount; n++ ) {
		sym = elf_findsym(	elf[n].hash_p, 
					elf[n].symtab_p,
					elf[n].strtab_p,
					name );
		
		if ( sym == STN_UNDEF )
			continue;		

		sym_p = ( Elf32_Sym *) (((uintptr_t)elf[n].symtab_p) + 
					( elf[n].syment * sym ));

		if ( sym_p->st_shndx == SHN_UNDEF )
			continue;

		bind = ELF32_ST_BIND( sym_p->st_info );
		
		if ( bind == STB_GLOBAL ) {
			printf("Bound symbol %s to image %i symbol %i\n", 
				name, n, sym );
			return *sym_p;
		} else if ( bind == STB_WEAK ) {
			weak = sym_p;
			weak_n = n;
			weak_s = sym;
			has_weak = 1;
		}

	}
	
	if ( has_weak ) {
		printf("Weakly bound symbol %s to image %i symbol %i\n",
			name, weak_n, weak_s);
		return *weak;
	}

	notfound.st_shndx = SHN_UNDEF;

	printf("Unresolved symbol %s\n", name);

	return notfound;
}
Ejemplo n.º 23
0
static Elf32_Sym *elf_find_func(struct elf_obj *obj, unsigned int func)
{
  int i, j;
  Elf32_Sym *cur;

  for(i = 0, j = 0, cur = obj->e_syms; i < obj->e_sym_num; i++, cur++) {
    if(ELF32_ST_BIND(cur->st_info) != STB_GLOBAL)
      continue;
    if(ELF32_ST_TYPE(cur->st_info) != STT_FUNC)
      continue;
    if(j == func)
      return cur;
    j++;
  }
  return NULL;
}
Ejemplo n.º 24
0
static void
assign32(void *symp, CexpSym cesp, void *closure)
{
Elf32_Sym	*sp=symp;
CexpType	t;
int 		s=sp->st_size;

	cesp->size = s;

	t=TVoid;

	switch (ELF32_ST_TYPE(sp->st_info)) {
	case STT_OBJECT:
		/* determine the type of variable */
		t = cexpTypeGuessFromSize(s);
	break;

	case STT_FUNC:
		t=TFuncP;
	break;

	case STT_NOTYPE:
		t=TVoid;
	break;

	case STT_SECTION:
		t=TVoid;
		cesp->flags|=CEXP_SYMFLG_SECT;
	break;

	default:
	break;

	}

	cesp->value.type = t;

	switch(ELF32_ST_BIND(sp->st_info)) {
		case STB_GLOBAL: cesp->flags|=CEXP_SYMFLG_GLBL; break;
		case STB_WEAK  : cesp->flags|=CEXP_SYMFLG_WEAK; break;
		default:
			break;
	}

	cesp->value.ptv  = (CexpVal)(uintptr_t)sp->st_value;
}
void StELFFile::dumpSymbolTable()
{
    const char *symbolTypes[5] = { "NOTYPE", "OBJECT", "FUNC", "SECTION", "FILE" };
    const char *symbolBinding[3] = { "LOCAL", "GLOBAL", "WEAK" };

    unsigned count = getSymbolCount();
    unsigned i = 0;

    for (; i < count; ++i)
    {
        const Elf32_Sym &symbol = getSymbolAtIndex(i);
        std::string name = getSymbolName(symbol);

        printf("'%s': %s, %s, 0x%08x, 0x%08x, %d. 0x%08x\n", name.c_str(), symbolTypes[ELF32_ST_TYPE(symbol.st_info)],
               symbolBinding[ELF32_ST_BIND(symbol.st_info)], symbol.st_value, symbol.st_size, symbol.st_shndx,
               symbol.st_other);
    }
}
Ejemplo n.º 26
0
  /* Finds a defined version of the symbol looking through 
     all loaded libraries. If exclude_root is true, skips
     root file symbols when looking for the symbol.
   */
  Elf32_Sym * link_node::find_symbol(unsigned char *name, char *vername, Elf32_Word verhash, 
                                     bool exclude_root)
  {
    link_node *p = root;
    unsigned int symhash = dyn_table.elf_hash(name);
    Elf32_Sym *the_symbol = NULL, *weak_sym = NULL;
    symbol_wrapper *symbol;

    if (exclude_root == true)
      p = p->get_next();
    
    while (p != NULL)
      {
	the_symbol = p->lookup_local_symbol(symhash, name, vername, verhash);
        if (the_symbol != NULL) {
          symbol = new symbol_wrapper(the_symbol, match_endian);
          if (ELF32_ST_BIND(symbol->read_info()) == STB_WEAK) {
            if (weak_sym == NULL)
              weak_sym = the_symbol;
            the_symbol = NULL;
          }
          delete symbol;
        }
	if (the_symbol != NULL)
	  break;
	p = p->get_next();
      }

    /* Hook for special symbols */
    if (the_symbol != NULL) {
      symbol = new symbol_wrapper(the_symbol, match_endian);

      if(strcmp("_rtld_global", (char*)name)==0) {
        patch_rtld_global(symbol);
      }

      delete symbol;
    }

    
    if (the_symbol == NULL && weak_sym != NULL)
      return weak_sym;
    return the_symbol;
  }
Ejemplo n.º 27
0
void *dlsym(void *handle, const char *symbol)
{
    soinfo *found;
    Elf32_Sym *sym;
    unsigned bind;

    pthread_mutex_lock(&dl_lock);

    if(unlikely(handle == 0)) { 
        set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE);
        goto err;
    }
    if(unlikely(symbol == 0)) {
        set_dlerror(DL_ERR_BAD_SYMBOL_NAME);
        goto err;
    }

    if(handle == RTLD_DEFAULT) {
        sym = lookup(symbol, &found);
    } else if(handle == RTLD_NEXT) {
        sym = lookup(symbol, &found);
    } else {
        found = (soinfo*)handle;
        sym = lookup_in_library(found, symbol);
    }

    if(likely(sym != 0)) {
        bind = ELF32_ST_BIND(sym->st_info);

        if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) {
            unsigned ret = sym->st_value + found->base;
            pthread_mutex_unlock(&dl_lock);
            return (void*)ret;
        }

        set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL);
    }
    else
        set_dlerror(DL_ERR_SYMBOL_NOT_FOUND);

err:
    pthread_mutex_unlock(&dl_lock);
    return 0;
}
Ejemplo n.º 28
0
void* dlsym(void* handle, const char* symbol) {
  ScopedPthreadMutexLocker locker(&gDlMutex);

  if (handle == NULL) {
    __bionic_format_dlerror("dlsym library handle is null", NULL);
    return NULL;
  }
  if (symbol == NULL) {
    __bionic_format_dlerror("dlsym symbol name is null", NULL);
    return NULL;
  }

  soinfo* found = NULL;
  Elf32_Sym* sym = NULL;
  if (handle == RTLD_DEFAULT) {
    sym = lookup(symbol, &found, NULL);
  } else if (handle == RTLD_NEXT) {
    void* ret_addr = __builtin_return_address(0);
    soinfo* si = find_containing_library(ret_addr);

    sym = NULL;
    if (si && si->next) {
      sym = lookup(symbol, &found, si->next);
    }
  } else {
    found = (soinfo*) handle;
    sym = soinfo_lookup(found, symbol);
  }

  if (sym != NULL) {
    unsigned bind = ELF32_ST_BIND(sym->st_info);

    if (bind == STB_GLOBAL && sym->st_shndx != 0) {
      unsigned ret = sym->st_value + found->load_bias;
      return (void*) ret;
    }

    __bionic_format_dlerror("symbol found but not global", symbol);
    return NULL;
  } else {
    __bionic_format_dlerror("undefined symbol", symbol);
    return NULL;
  }
}
Ejemplo n.º 29
0
/* changesymbols() finds all symbols in a given symbol table that
 * appear in the namelist with the specified binding and alters their
 * binding strength.
 */
static int changesymbols(Elf32_Sym *symtab, char const *strtab, int count)
{
    Elf32_Sym  *sym;
    char const *name;
    int		touched;
    int		i;

    touched = FALSE;
    for (i = 0, sym = symtab ; i < count ; ++i, ++sym) {
	if (ELF32_ST_BIND(sym->st_info) != fromstrength)
	    continue;
	name = strtab + sym->st_name;
	if (!bsearch(&name, namelist, namecount, sizeof *namelist, qstrcmp))
	    continue;
	sym->st_info = ELF32_ST_INFO(tostrength, ELF32_ST_TYPE(sym->st_info));
	printf("%s \"%s\".\n", tostrengthtext, name);
	touched = TRUE;
    }
    return touched;
}
Ejemplo n.º 30
0
static SYM *
readsyms(Elf32_Sym *data, size_t num, Elf *elf, Elf32_Word link)
{
    SYM *s, *buf;
    size_t i;
    if((buf = (SYM *)calloc(num, sizeof(SYM)) ) == NULL) {
	return NULL;
    }
    s = buf;	/* save pointer to head of array */
    for(i=1; i<num; i++,data++,buf++) {
	buf->indx = i;
	buf->name = (char *)elf_strptr(elf, link, data->st_name);
	buf->value = data->st_value;
	buf->size = data->st_size;
	buf->type = ELF32_ST_TYPE(data->st_info);
	buf->bind = ELF32_ST_BIND(data->st_info);
	buf->other = data->st_other;
	buf->shndx = data->st_shndx;
    }	/* end for loop */
    return(s);
}