コード例 #1
0
static char		get_symbol_type(Elf64_Sym *sym, t_elf *nm)
{
  unsigned int		i;
  Elf64_Shdr		*sec;
  char			*str;
  int			glob;

  i = 0;
  glob = (ELF64_ST_BIND(sym->st_info) == STB_GLOBAL ? 1 : 2);
  if (strcmp(nm->string_symbol_table + sym->st_name, "data_start") == 0)
    return ('W');
  if (ELF64_ST_BIND(sym->st_info) == STB_WEAK)
    return (glob == 1 ? 'W' : 'w');
  sec = &(*nm).section_header[sym->st_shndx];
  str = nm->string_table + sec->sh_name;
  while (i < SIZE - 1)
    {
      if (strncmp(str, g_db[i][0], strlen(g_db[i][0])) == 0)
	return (g_db[i][glob][0]);
      ++i;
    }
  if (sym->st_shndx == SHN_UNDEF)
    return (glob == 1 ? 'U' : 'u');
  return ('?');
}
コード例 #2
0
ファイル: Elf64Output.cpp プロジェクト: mfichman/jogo
void Elf64Output::sort_symtab() {
    // With ELF, the local symbols must come first in the symbol table.
    // Annoying, but true.  As a result, this function is necessary to 
    // reorder the symbols with the local ones first.

    std::vector<Elf64_Sym> symtmp;
    std::vector<size_t> redirect(sym_.size());
    // Mapping from old => new position of the symbol in the symbol table.
    for (int i = 0; i < sym_.size(); ++i) {
        if (ELF64_ST_BIND(sym_[i].st_info) == STB_LOCAL) {
            redirect[i] = symtmp.size(); 
            symtmp.push_back(sym_[i]);
        }
    } 
    local_syms_ = symtmp.size();
    for (int i = 0; i < sym_.size(); ++i) {
        if (ELF64_ST_BIND(sym_[i].st_info) == STB_GLOBAL) {
            redirect[i] = symtmp.size();
            symtmp.push_back(sym_[i]);
        }
    }
    for (int i = 0; i < text_reloc_.size(); ++i) {
        Elf64_Word type = ELF64_R_TYPE(text_reloc_[i].r_info);
        Elf64_Word sym = redirect[ELF64_R_SYM(text_reloc_[i].r_info)];
        text_reloc_[i].r_info = ELF64_R_INFO(sym, type);
    }
    for (int i = 0; i < data_reloc_.size(); ++i) {
        Elf64_Word type = ELF64_R_TYPE(data_reloc_[i].r_info);
        Elf64_Word sym = redirect[ELF64_R_SYM(data_reloc_[i].r_info)];
        assert(sym<sym_.size());
        data_reloc_[i].r_info = ELF64_R_INFO(sym, type);
    }
    sym_ = symtmp;
}
コード例 #3
0
ファイル: getsym.c プロジェクト: till-s/cexpsh
int
pmelf_getsym64(Elf_Stream s, Elf64_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_swap16( &psym->st_shndx);
		elf_swap64( &psym->st_value);
		elf_swap64( &psym->st_size);
#endif
	}
#ifdef PARANOIA_ON
	{
	int x;
	if ( (x = ELF64_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 = ELF64_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;
}
コード例 #4
0
static uint_t
dt_module_syminit64(dt_module_t *dmp)
{
	const Elf64_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 = ELF64_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 &&
		    (ELF64_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);
}
コード例 #5
0
ファイル: print_reloc.c プロジェクト: Akheon23/nvopencc
static SYM64 *
read_64_syms(Elf64_Sym *data, size_t num, Elf *elf, Elf64_Word link)
{
#ifdef HAVE_ELF64_GETEHDR

    SYM64 *s, *buf;
    size_t i;
    if( (buf = (SYM64 *)calloc(num, sizeof(SYM64)) ) == 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 = ELF64_ST_TYPE(data->st_info);
	buf->bind = ELF64_ST_BIND(data->st_info);
	buf->other = data->st_other;
	buf->shndx = data->st_shndx;
    }	/* end for loop */
    return(s);
#else
    return 0;
#endif /* HAVE_ELF64_GETEHDR */
}
コード例 #6
0
ファイル: dsl_elf.c プロジェクト: 7za/divers
static int dls_get_external_syms(char *base, struct dls_external_symlist *out)
{
    dls_shdr *s4 = dls_get_shdr_by_name(base, ".dynsym");
    dls_shdr *s5 = dls_get_shdr_by_name(base, ".dynstr");
    int nr_sym = s4->sh_size / sizeof(dls_sym);
    int i, count;
    dls_shdr *first_section = (dls_shdr *)(base + ((dls_ehdr*)base)->e_shoff);

    char *u = base + s5->sh_offset;
    dls_sym *sym = (dls_sym *)(base + s4->sh_offset);
    out->des_array = malloc(sizeof(struct dls_external_sym) * nr_sym);
    out->des_len = 0;
    for(i = 0; i < nr_sym; ++i, ++sym) {
        if(ELF64_ST_BIND(sym->st_info) == 1 &&
           ELF64_ST_TYPE(sym->st_info) == 0) {
            out->des_array[out->des_len].de_sym  = sym;
            out->des_array[out->des_len].de_name = u + sym->st_name;
            out->des_array[out->des_len].de_rel  =
                    (void*)dls_get_rel_sym(base, s4 - first_section, i);
            out->des_len++; 
        }
    }
    out->des_array = realloc(out->des_array,
                             out->des_len * sizeof(struct dls_external_sym));
    return out->des_len;
}
コード例 #7
0
char *symbol_binding(unsigned char st_info)
{
    switch (ELF64_ST_BIND(st_info)) {
    case STB_LOCAL: return "STB_LOCAL";
    case STB_GLOBAL: return "STB_GLOBAL";
    case STB_WEAK: return "STB_WEAK";
    case STB_NUM: return "STB_NUM";
    case STB_LOOS: return "STB_LOOS STB_GNU_UNIQUE";
    case STB_HIOS: return "STB_HIOS";
    case STB_LOPROC: return "STB_LOPROC";
    case STB_HIPROC: return "STB_HIPROC";
    default: return "unknown";
    }
}
コード例 #8
0
ファイル: dt_module.c プロジェクト: DataIX/src
/*
 * Sort comparison function for 64-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_symcomp64(const void *lp, const void *rp)
{
	Elf64_Sym *lhs = *((Elf64_Sym **)lp);
	Elf64_Sym *rhs = *((Elf64_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 ((ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
	    (ELF64_ST_TYPE(rhs->st_info) == STT_NOTYPE))
		return (ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);

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

	return (strcmp(dt_module_strtab + lhs->st_name,
	    dt_module_strtab + rhs->st_name));
}
コード例 #9
0
char		get_the_type(int type, int flags, int shndx,
			    int info, int value)
{
  char        res;

  res = 'U';
  if (type == SHT_NOBITS && flags == (SHF_WRITE + SHF_ALLOC))
    res = 'B';
  if ( (type == SHT_PROGBITS || type == SHT_DYNAMIC)
       && flags == (SHF_WRITE + SHF_ALLOC))
    res = 'D';
  if (type == SHT_PROGBITS && flags == (SHF_ALLOC + SHF_EXECINSTR))
    res = 'T';
  if (type == SHT_PROGBITS && flags == SHF_ALLOC)
    res = 'R';
  if (ELF64_ST_BIND(info) == STB_WEAK)
    res = 'W';
  if (type > SHT_DYNSYM)
    res = 'T';
  if ((ELF64_ST_BIND(info) == STB_LOCAL || value == 0) && res != 'U')
    res += 32;
  return (res);
}
コード例 #10
0
ファイル: print.c プロジェクト: kassisdion/Epitech_year_2
static void	get_info_sym(Elf64_Sym *sym)
{
  int		info;
  int		bind;
  int		type;
  int		index;
  char		c;

  info = sym->st_info;
  bind = ELF64_ST_BIND(info);
  type = ELF64_ST_TYPE(info);
  index = sym->st_shndx;
  c = get_carac(index, type, bind);
  printf("%c ", c);
}
コード例 #11
0
ファイル: dt_module.c プロジェクト: DataIX/src
static uint_t
dt_module_syminit64(dt_module_t *dmp)
{
#if STT_NUM != (STT_TLS + 1)
#error "STT_NUM has grown. update dt_module_syminit64()"
#endif

	Elf64_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 = ELF64_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 &&
		    (ELF64_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);
}
コード例 #12
0
ファイル: elfsyms.c プロジェクト: SayCV/rtems-slac-cexp-gesys
static void
assign64(void *symp, CexpSym cesp, void *closure)
{
Elf64_Sym	*sp=symp;
CexpType	t;
int 		s=sp->st_size;

	cesp->size = s;

	t=TVoid;

	switch (ELF64_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(ELF64_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;
}
コード例 #13
0
ファイル: elfsyms.c プロジェクト: SayCV/rtems-slac-cexp-gesys
static const char *
filter64(void *ext_sym, void *closure)
{
Elf64_Sym	*sp=ext_sym;
char		*strtab=closure;

	if ( STB_LOCAL == ELF64_ST_BIND(sp->st_info) )
		return 0;

	switch (ELF64_ST_TYPE(sp->st_info)) {
	case STT_OBJECT:
	case STT_FUNC:
	case STT_NOTYPE:
	return strtab + sp->st_name;

	default:
	break;
	}

	return 0;
}
コード例 #14
0
ファイル: dt_module.c プロジェクト: DataIX/src
static void
dt_module_symsort64(dt_module_t *dmp)
{
	Elf64_Sym *symtab = (Elf64_Sym *)dmp->dm_symtab.cts_data;
	Elf64_Sym **sympp = (Elf64_Sym **)dmp->dm_asmap;
	const dt_sym_t *dsp = dmp->dm_symchains + 1;
	uint_t i, n = dmp->dm_symfree;

	for (i = 1; i < n; i++, dsp++) {
		Elf64_Sym *sym = symtab + dsp->ds_symid;
		if (sym->st_value != 0 &&
		    (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
			*sympp++ = sym;
	}

	dmp->dm_aslen = (uint_t)(sympp - (Elf64_Sym **)dmp->dm_asmap);
	assert(dmp->dm_aslen <= dmp->dm_asrsv);

	dt_module_strtab = dmp->dm_strtab.cts_data;
	qsort(dmp->dm_asmap, dmp->dm_aslen,
	    sizeof (Elf64_Sym *), dt_module_symcomp64);
	dt_module_strtab = NULL;
}
コード例 #15
0
int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t)
{
	Elf64_Phdr *dynamic = NULL, *load = NULL;
	Elf64_Ehdr *ehdr = (void *)mem;
	Elf64_Dyn *dyn_strtab = NULL;
	Elf64_Dyn *dyn_symtab = NULL;
	Elf64_Dyn *dyn_strsz = NULL;
	Elf64_Dyn *dyn_syment = NULL;
	Elf64_Dyn *dyn_hash = NULL;
	Elf64_Word *hash = NULL;
	Elf64_Phdr *phdr;
	Elf64_Dyn *d;

	Elf64_Word *bucket, *chain;
	Elf64_Word nbucket, nchain;

	/*
	 * See Elf specification for this magic values.
	 */
	static const char elf_ident[] = {
		0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	};

	char *dynsymbol_names;
	unsigned int i, j, k;

	BUILD_BUG_ON(sizeof(elf_ident) != sizeof(ehdr->e_ident));

	pr_debug("Parsing at %lx %lx\n", (long)mem, (long)mem + (long)size);

	/*
	 * Make sure it's a file we support.
	 */
	if (builtin_memcmp(ehdr->e_ident, elf_ident, sizeof(elf_ident))) {
		pr_err("Elf header magic mismatch\n");
		return -EINVAL;
	}

	/*
	 * We need PT_LOAD and PT_DYNAMIC here. Each once.
	 */
	phdr = (void *)&mem[ehdr->e_phoff];
	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
		if (__ptr_oob(phdr, mem, size))
			goto err_oob;
		switch (phdr->p_type) {
		case PT_DYNAMIC:
			if (dynamic) {
				pr_err("Second PT_DYNAMIC header\n");
				return -EINVAL;
			}
			dynamic = phdr;
			break;
		case PT_LOAD:
			if (load) {
				pr_err("Second PT_LOAD header\n");
				return -EINVAL;
			}
			load = phdr;
			break;
		}
	}

	if (!load || !dynamic) {
		pr_err("One of obligated program headers is missed\n");
		return -EINVAL;
	}

	pr_debug("PT_LOAD p_vaddr: %lx\n", (unsigned long)load->p_vaddr);

	/*
	 * Dynamic section tags should provide us the rest of information
	 * needed. Note that we're interested in a small set of tags.
	 */
	d = (void *)&mem[dynamic->p_offset];
	for (i = 0; i < dynamic->p_filesz / sizeof(*d); i++, d++) {
		if (__ptr_oob(d, mem, size))
			goto err_oob;

		if (d->d_tag == DT_NULL) {
			break;
		} else if (d->d_tag == DT_STRTAB) {
			dyn_strtab = d;
			pr_debug("DT_STRTAB: %lx\n", (unsigned long)d->d_un.d_ptr);
		} else if (d->d_tag == DT_SYMTAB) {
			dyn_symtab = d;
			pr_debug("DT_SYMTAB: %lx\n", (unsigned long)d->d_un.d_ptr);
		} else if (d->d_tag == DT_STRSZ) {
			dyn_strsz = d;
			pr_debug("DT_STRSZ: %lx\n", (unsigned long)d->d_un.d_val);
		} else if (d->d_tag == DT_SYMENT) {
			dyn_syment = d;
			pr_debug("DT_SYMENT: %lx\n", (unsigned long)d->d_un.d_val);
		} else if (d->d_tag == DT_HASH) {
			dyn_hash = d;
			pr_debug("DT_HASH: %lx\n", (unsigned long)d->d_un.d_ptr);
		}
	}

	if (!dyn_strtab || !dyn_symtab || !dyn_strsz || !dyn_syment || !dyn_hash) {
		pr_err("Not all dynamic entries are present\n");
		return -EINVAL;
	}

	dynsymbol_names = &mem[dyn_strtab->d_un.d_val - load->p_vaddr];
	if (__ptr_oob(dynsymbol_names, mem, size))
		goto err_oob;

	hash = (void *)&mem[(unsigned long)dyn_hash->d_un.d_ptr - (unsigned long)load->p_vaddr];
	if (__ptr_oob(hash, mem, size))
		goto err_oob;

	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]) {
			Elf64_Sym *sym = (void *)&mem[dyn_symtab->d_un.d_ptr - load->p_vaddr];
			char *name;

			sym = &sym[j];
			if (__ptr_oob(sym, mem, size))
				continue;

			if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC &&
			    ELF64_ST_BIND(sym->st_info) != STB_GLOBAL)
				continue;

			name = &dynsymbol_names[sym->st_name];
			if (__ptr_oob(name, mem, size))
				continue;

			if (builtin_strcmp(name, symbol))
				continue;

			builtin_memcpy(t->symbols[i].name, name, sizeof(t->symbols[i].name));
			t->symbols[i].offset = (unsigned long)sym->st_value - load->p_vaddr;
			break;
		}
	}

	return 0;

err_oob:
	pr_err("Corrupted Elf data\n");
	return -EFAULT;
}
コード例 #16
0
ファイル: elf-loader.c プロジェクト: tom3333/tcf.agent
static int get_global_symbol_address(Context * ctx, ELF_File * file, const char * name, ContextAddress * addr) {
    unsigned i, j;

    for (i = 1; i < file->section_cnt; i++) {
        ELF_Section * sec = file->sections + i;
        if (sec->size == 0) continue;
        if (sec->type == SHT_SYMTAB) {
            ELF_Section * str = NULL;
            if (sec->link == 0 || sec->link >= file->section_cnt) {
                errno = EINVAL;
                return -1;
            }
            str = file->sections + sec->link;
            if (elf_load(sec) < 0) return -1;
            if (elf_load(str) < 0) return -1;
            if (file->elf64) {
                unsigned cnt = (unsigned)(sec->size / sizeof(Elf64_Sym));
                for (j = 0; j < cnt; j++) {
                    Elf64_Sym sym = *((Elf64_Sym *)sec->data + j);
                    if (ELF64_ST_BIND(sym.st_info) != STB_GLOBAL) continue;
                    if (file->byte_swap) SWAP(sym.st_name);
                    if (sym_name_cmp((char *)str->data + sym.st_name, name) != 0) continue;
                    switch (ELF64_ST_TYPE(sym.st_info)) {
                    case STT_NOTYPE:
                        /* Check if the NOTYPE symbol is for a section allocated in memory */
                        if (file->byte_swap) SWAP(sym.st_shndx);
                        if (sym.st_shndx <= 0 || sym.st_shndx >= file->section_cnt || ((file->sections + sym.st_shndx)->flags & SHF_ALLOC) == 0) break;
                    /* fall through */
                    case STT_OBJECT:
                    case STT_FUNC:
                        if (file->byte_swap) SWAP(sym.st_value);
                        *addr = elf_map_to_run_time_address(ctx, file, NULL, (ContextAddress)sym.st_value);
                        if (errno == 0) return 0;
                    }
                }
            }
            else {
                unsigned cnt = (unsigned)(sec->size / sizeof(Elf32_Sym));
                for (j = 0; j < cnt; j++) {
                    Elf32_Sym sym = *((Elf32_Sym *)sec->data + j);
                    if (ELF32_ST_BIND(sym.st_info) != STB_GLOBAL) continue;
                    if (file->byte_swap) SWAP(sym.st_name);
                    if (sym_name_cmp((char *)str->data + sym.st_name, name) != 0) continue;
                    switch (ELF32_ST_TYPE(sym.st_info)) {
                    case STT_NOTYPE:
                        /* Check if the NOTYPE symbol is for a section allocated in memory */
                        if (file->byte_swap) SWAP(sym.st_shndx);
                        if (sym.st_shndx <= 0 || sym.st_shndx >= file->section_cnt || ((file->sections + sym.st_shndx)->flags & SHF_ALLOC) == 0) break;
                    /* fall through */
                    case STT_OBJECT:
                    case STT_FUNC:
                        if (file->byte_swap) SWAP(sym.st_value);
                        *addr = elf_map_to_run_time_address(ctx, file, NULL, (ContextAddress)sym.st_value);
                        if (errno == 0) return 0;
                    }
                }
            }
        }
    }
    errno = ENOENT;
    return -1;
}
コード例 #17
0
ファイル: smap.c プロジェクト: JunhanPark/rtos
int main(int argc, char* argv[]) {
	if(argc < 3) {
		printf("Usage: smap [kernel elf] [system map]\n");
		return 0;
	}
	
	int fd = open(argv[1], O_RDONLY);
	if(fd < 0) {
		printf("Cannot open file: %s\n", argv[1]);
		return 1;
	}
	
	struct stat state;
	if(stat(argv[1], &state) != 0) {
		printf("Cannot get state of file: %s\n", argv[1]);
		return 2;
	}
	
	Elf64_Ehdr* ehdr = mmap(NULL, state.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if(ehdr == (void*)-1) {
		printf("Cannot open file: %s\n", argv[1]);
		return 1;
	}
	
	if(ehdr->e_ident[0] != ELFMAG0 || ehdr->e_ident[1] != ELFMAG1 || ehdr->e_ident[2] != ELFMAG2 || ehdr->e_ident[3] != ELFMAG3) {
		printf("Illegal file format: %s\n", argv[1]);
		return 3;
	}
	
	Elf64_Shdr* shdr = (Elf64_Shdr*)((uint8_t*)ehdr + ehdr->e_shoff);
	char* strs = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
	Elf64_Shdr* get_shdr(char* name) {
		for(int i = 0; i < ehdr->e_shnum; i++) {
			if(strcmp(name, strs + shdr[i].sh_name) == 0)
				return &shdr[i];
		}
		return NULL;
	}
	
	Elf64_Shdr* strtab = get_shdr(".strtab");
	char* str = (char*)ehdr + strtab->sh_offset;
	char* name(int offset) {
		return str + offset;
	}
	
	int count = 0;
	int text_size = 0;
	
	Elf64_Shdr* symtab = get_shdr(".symtab");
	Elf64_Sym* sym = (void*)ehdr + symtab->sh_offset;
	int size = symtab->sh_size / sizeof(Elf64_Sym);
	for(int i = 0; i < size; i++) {
		if(ELF64_ST_BIND(sym[i].st_info) != STB_GLOBAL)
			continue;
		
		int type = ELF64_ST_TYPE(sym[i].st_info);
		switch(type) {
			case STT_NOTYPE:
			case STT_OBJECT:
			case STT_FUNC:
				break;
			default:
				printf("Unknown symbol type: %d for %s\n", type, name(sym[i].st_name));
				return 4;
		}
		
		count++;
		text_size += strlen(name(sym[i].st_name)) + 1;
	}
	
	// Make data structure
	int total = sizeof(Symbol) * (count + 1) + text_size;
	Symbol* symbols = malloc(total);
	char* text = (void*)symbols + total - text_size;
	int j = 0;
	for(int i = 0; i < size; i++) {
		if(ELF64_ST_BIND(sym[i].st_info) != STB_GLOBAL)
			continue;
		
		int type = ELF64_ST_TYPE(sym[i].st_info);
		switch(type) {
			case STT_NOTYPE:
				type = SYMBOL_TYPE_NONE;
				break;
			case STT_OBJECT:
				type = SYMBOL_TYPE_DATA;
				break;
			case STT_FUNC:
				type = SYMBOL_TYPE_FUNC;
				break;
			default:
				;// Not possible
		}
		
		symbols[j].name = (void*)((void*)text - (void*)symbols);
		symbols[j].type = type;
		symbols[j].address = (void*)(uint64_t)sym[i].st_value;
		j++;
		
		char* symname = name(sym[i].st_name);
		int len = strlen(symname) + 1;
		memcpy(text, symname, len);
		text += len;
	}
	close(fd);
	
	// Write
	int fd2 = open(argv[2], O_RDWR | O_CREAT, 0644);
	if(fd2 < 0) {
		printf("Cannot open file: %s\n", argv[2]);
		return 1;
	}
	
	// Write symbols
	int len = write(fd2, symbols, total);
	if(len != total) {
		printf("Cannot write fully: %d < %d\n", len, total);
		return 5;
	}
	
	close(fd2);
	
	return 0;
}
コード例 #18
0
unsigned char Symbol64::getSymbolBinding(){
    return ELF64_ST_BIND(entry.st_info);
}
コード例 #19
0
ファイル: ltrace-elf.c プロジェクト: KapJlcoH/ltrace
struct library_symbol *
read_elf(Process *proc) {
	struct ltelf lte[MAX_LIBRARIES + 1];
	size_t i;
	struct opt_x_t *xptr;
	struct opt_x_t *opt_x_loc = opt_x;
	struct library_symbol **lib_tail = NULL;
	int exit_out = 0;
	int count = 0;

	debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename);

	memset(lte, 0, sizeof(lte));
	library_symbols = NULL;
	library_num = 0;
	proc->libdl_hooked = 0;

	if (do_init_elf(lte, proc->filename))
		return NULL;

	memcpy(&main_lte, lte, sizeof(struct ltelf));

	if (opt_p && opt_p->pid > 0) {
		linkmap_init(proc, lte);
		proc->libdl_hooked = 1;
	}

	proc->e_machine = lte->ehdr.e_machine;

	for (i = 0; i < library_num; ++i) {
		if (do_init_elf(&lte[i + 1], library[i]))
			error(EXIT_FAILURE, errno, "Can't open \"%s\"",
			      library[i]);
	}

	if (!options.no_plt) {
#ifdef __mips__
		// MIPS doesn't use the PLT and the GOT entries get changed
		// on startup.
		proc->need_to_reinitialize_breakpoints = 1;
		for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){
			GElf_Sym sym;
			const char *name;
			GElf_Addr addr = arch_plt_sym_val(lte, i, 0);
			if (gelf_getsym(lte->dynsym, i, &sym) == NULL){
				error(EXIT_FAILURE, 0,
						"Couldn't get relocation from \"%s\"",
						proc->filename);
			}
			name=lte->dynstr+sym.st_name;
			if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){
				debug(2,"sym %s not a function",name);
				continue;
			}
			add_library_symbol(addr, name, &library_symbols, 0,
					ELF64_ST_BIND(sym.st_info) != 0);
			if (!lib_tail)
				lib_tail = &(library_symbols->next);
		}
#else
		for (i = 0; i < lte->relplt_count; ++i) {
			GElf_Rel rel;
			GElf_Rela rela;
			GElf_Sym sym;
			GElf_Addr addr;
			void *ret;
			const char *name;

			if (lte->relplt->d_type == ELF_T_REL) {
				ret = gelf_getrel(lte->relplt, i, &rel);
				rela.r_offset = rel.r_offset;
				rela.r_info = rel.r_info;
				rela.r_addend = 0;
			} else
				ret = gelf_getrela(lte->relplt, i, &rela);

			if (ret == NULL
					|| ELF64_R_SYM(rela.r_info) >= lte->dynsym_count
					|| gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info),
						&sym) == NULL)
				error(EXIT_FAILURE, 0,
						"Couldn't get relocation from \"%s\"",
						proc->filename);

#ifdef PLT_REINITALISATION_BP
			if (!sym.st_value && PLTs_initialized_by_here)
				proc->need_to_reinitialize_breakpoints = 1;
#endif

			name = lte->dynstr + sym.st_name;
			count = library_num ? library_num+1 : 0;

			if (in_load_libraries(name, lte, count, NULL)) {
				enum toplt pltt;
				if (sym.st_value == 0 && lte->plt_stub_vma != 0) {
					pltt = LS_TOPLT_EXEC;
					addr = lte->plt_stub_vma + PPC_PLT_STUB_SIZE * i;
				}
				else {
					pltt = PLTS_ARE_EXECUTABLE(lte)
						?  LS_TOPLT_EXEC : LS_TOPLT_POINT;
					addr = arch_plt_sym_val(lte, i, &rela);
				}

				add_library_symbol(addr, name, &library_symbols, pltt,
						ELF64_ST_BIND(sym.st_info) == STB_WEAK);
				if (!lib_tail)
					lib_tail = &(library_symbols->next);
			}
		}
#endif // !__mips__
#ifdef PLT_REINITALISATION_BP
		struct opt_x_t *main_cheat;

		if (proc->need_to_reinitialize_breakpoints) {
			/* Add "PLTs_initialized_by_here" to opt_x list, if not
				 already there. */
			main_cheat = (struct opt_x_t *)malloc(sizeof(struct opt_x_t));
			if (main_cheat == NULL)
				error(EXIT_FAILURE, 0, "Couldn't allocate memory");
			main_cheat->next = opt_x_loc;
			main_cheat->found = 0;
			main_cheat->name = PLTs_initialized_by_here;

			for (xptr = opt_x_loc; xptr; xptr = xptr->next)
				if (strcmp(xptr->name, PLTs_initialized_by_here) == 0
						&& main_cheat) {
					free(main_cheat);
					main_cheat = NULL;
					break;
				}
			if (main_cheat)
				opt_x_loc = main_cheat;
		}
#endif
	} else {
		lib_tail = &library_symbols;
	}

	for (i = 0; i < lte->symtab_count; ++i) {
		GElf_Sym sym;
		GElf_Addr addr;
		const char *name;

		if (gelf_getsym(lte->symtab, i, &sym) == NULL)
			error(EXIT_FAILURE, 0,
			      "Couldn't get symbol from \"%s\"",
			      proc->filename);

		name = lte->strtab + sym.st_name;
		addr = sym.st_value;
		if (!addr)
			continue;

		for (xptr = opt_x_loc; xptr; xptr = xptr->next)
			if (xptr->name && strcmp(xptr->name, name) == 0) {
				/* FIXME: Should be able to use &library_symbols as above.  But
				   when you do, none of the real library symbols cause breaks. */
				add_library_symbol(opd2addr(lte, addr),
						   name, lib_tail, LS_TOPLT_NONE, 0);
				xptr->found = 1;
				break;
			}
	}

	unsigned found_count = 0;

	for (xptr = opt_x_loc; xptr; xptr = xptr->next) {
		if (xptr->found)
			continue;

		GElf_Sym sym;
		GElf_Addr addr;
		if (in_load_libraries(xptr->name, lte, library_num+1, &sym)) {
			debug(2, "found symbol %s @ %#" PRIx64 ", adding it.",
					xptr->name, sym.st_value);
			addr = sym.st_value;
			if (ELF32_ST_TYPE (sym.st_info) == STT_FUNC) {
				add_library_symbol(addr, xptr->name, lib_tail, LS_TOPLT_NONE, 0);
				xptr->found = 1;
				found_count++;
			}
		}
		if (found_count == opt_x_cnt){
			debug(2, "done, found everything: %d\n", found_count);
			break;
		}
	}

	for (xptr = opt_x_loc; xptr; xptr = xptr->next)
		if ( ! xptr->found) {
			char *badthing = "WARNING";
#ifdef PLT_REINITALISATION_BP
			if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
				if (lte->ehdr.e_entry) {
					add_library_symbol (
						opd2addr (lte, lte->ehdr.e_entry),
						PLTs_initialized_by_here,
						lib_tail, 1, 0);
					fprintf (stderr, "WARNING: Using e_ent"
						 "ry from elf header (%p) for "
						 "address of \"%s\"\n", (void*)
						 (long) lte->ehdr.e_entry,
						 PLTs_initialized_by_here);
					continue;
				}
				badthing = "ERROR";
				exit_out = 1;
			}
#endif
			fprintf (stderr,
				 "%s: Couldn't find symbol \"%s\" in file \"%s\" assuming it will be loaded by libdl!"
				 "\n", badthing, xptr->name, proc->filename);
		}
	if (exit_out) {
		exit (1);
	}

	for (i = 0; i < library_num + 1; ++i)
		do_close_elf(&lte[i]);

	return library_symbols;
}
コード例 #20
0
ファイル: ELFManager.cpp プロジェクト: fast01/baiduhook
int ELFManager::elf_canonicalize_symbol(esymbol **symbol_table, int unsigned type)
{
	int ret;
	Elf_Shdr shdrs[_ehdr.e_shnum];

	ret = elf_read_shdrs(shdrs, _ehdr.e_shnum);
	if (ret < 0) {
		return -1;
	}
	unsigned int i = 0;
	for (; i<_ehdr.e_shnum; i++) {
		if (shdrs[i].sh_type == type) {
			break;
		}
	}
	if (i == _ehdr.e_shnum) {
		return -1;
	}
	Elf_Shdr *symtab = &shdrs[i];
	//读取name
	Elf_Shdr *link = &shdrs[symtab->sh_link];
	char *sym_name = (char *)malloc(link->sh_size);
	if (sym_name == NULL) {
		fprintf(stderr, "malloc error!\n");
		return -1;
	}
	ret = elf_read(link->sh_offset, sym_name, link->sh_size);
	if (ret < 0) {
		return -1;
	}
	//读取符号表
	int count = symtab->sh_size/symtab->sh_entsize;

	esymbol *esym = (esymbol *)&symbol_table[count];
	if(_is_32_bit) {
		Elf32_Sym syms[count];
		ret = elf_read(symtab->sh_offset, syms, symtab->sh_size);
		if (ret < 0) {
			return -1;
		}
		for (int idx=0; idx<count; idx++) {
			symbol_table[idx] = &esym[idx];
			//printf("name:%s!, symbol_table:%llx\n", &sym_name[syms[idx].st_name], symbol_table[idx]);
			symbol_table[idx]->name = &sym_name[syms[idx].st_name];
			//printf("debug3!\n");
			symbol_table[idx]->bind = ELF32_ST_BIND(syms[idx].st_info);
			symbol_table[idx]->type = ELF32_ST_TYPE(syms[idx].st_info);
			symbol_table[idx]->shndx = syms[idx].st_shndx;
			symbol_table[idx]->value = syms[idx].st_value;
			symbol_table[idx]->size = syms[idx].st_size;
		}
	} else {
		Elf64_Sym syms[count];
		ret = elf_read(symtab->sh_offset, syms, symtab->sh_size);
		if (ret < 0) {
			return -1;
		}
		for (int idx=0; idx<count; idx++) {
			symbol_table[idx] = &esym[idx];
			//printf("name:%s!, symbol_table:%llx\n", &sym_name[syms[idx].st_name], symbol_table[idx]);
			symbol_table[idx]->name = &sym_name[syms[idx].st_name];
			//printf("debug3!\n");
			symbol_table[idx]->bind = ELF64_ST_BIND(syms[idx].st_info);
			symbol_table[idx]->type = ELF64_ST_TYPE(syms[idx].st_info);
			symbol_table[idx]->shndx = syms[idx].st_shndx;
			symbol_table[idx]->value = syms[idx].st_value;
			symbol_table[idx]->size = syms[idx].st_size;
		}
	}
	return count;
}
コード例 #21
0
ファイル: rtld_machine.c プロジェクト: sofuture/bitrig
int
_dl_md_reloc(elf_object_t *object, int rel, int relsz)
{
	int	i;
	int	numrel;
	int	fails = 0;
	struct load_list *load_list;
	Elf64_Addr loff;
	Elf64_Addr ooff;
	Elf64_Addr got_start, got_end;
	Elf64_Rel  *relocs;
	const Elf64_Sym *sym, *this;

	loff = object->obj_base;
	numrel = object->Dyn.info[relsz] / sizeof(Elf64_Rel);
	relocs = (Elf64_Rel *)(object->Dyn.info[rel]);

	if (relocs == NULL)
		return(0);

	/*
	 * Change protection of all write protected segments in the
	 * object so we can do relocations in the .rodata section.
	 * After relocation restore protection.
	 */
	load_list = object->load_list;
	while (load_list != NULL) {
		if ((load_list->prot & PROT_WRITE) == 0)
			_dl_mprotect(load_list->start, load_list->size,
			    load_list->prot|PROT_WRITE);
		load_list = load_list->next;
	}

	/* XXX We need the got limits to know if reloc is in got. */
	/* XXX Relocs against the got should not include the STUB address! */
	this = NULL;
	got_start = 0;
	got_end = 0;
	ooff = _dl_find_symbol("__got_start", &this,
	    SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, object, NULL);
	if (this != NULL)
		got_start = ooff + this->st_value;
	this = NULL;
	ooff = _dl_find_symbol("__got_end", &this,
	    SYM_SEARCH_OBJ|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, object, NULL);
	if (this != NULL)
		got_end = ooff + this->st_value;

	DL_DEB(("relocating %d\n", numrel));
	for (i = 0; i < numrel; i++, relocs++) {
		Elf64_Addr r_addr = relocs->r_offset + loff;
		const char *symn;
		int type;

		if (ELF64_R_SYM(relocs->r_info) == 0xffffff)
			continue;

		ooff = 0;
		sym = object->dyn.symtab;
		sym += ELF64_R_SYM(relocs->r_info);
		symn = object->dyn.strtab + sym->st_name;
		type = ELF64_R_TYPE(relocs->r_info);

		this = NULL;
		if (ELF64_R_SYM(relocs->r_info) &&
		    !(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
		    ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
			ooff = _dl_find_symbol(symn, &this,
			SYM_SEARCH_ALL | SYM_WARNNOTFOUND | SYM_PLT,
			sym, object, NULL);

			if (this == NULL) {
				if (ELF_ST_BIND(sym->st_info) != STB_WEAK)
					fails++;
				continue;
			}
		}

		switch (ELF64_R_TYPE(relocs->r_info)) {
			/* XXX Handle non aligned relocs. .eh_frame
			 * XXX in libstdc++ seems to have them... */
			u_int64_t robj;

		case R_MIPS_REL32_64:
			if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
			    (ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
			    ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
				if ((long)r_addr & 7) {
					_dl_bcopy((char *)r_addr, &robj, sizeof(robj));
					robj += loff + sym->st_value;
					_dl_bcopy(&robj, (char *)r_addr, sizeof(robj));
				} else {
					*(u_int64_t *)r_addr += loff + sym->st_value;
				}
			} else if (this && ((long)r_addr & 7)) {
				_dl_bcopy((char *)r_addr, &robj, sizeof(robj));
				robj += this->st_value + ooff;
				_dl_bcopy(&robj, (char *)r_addr, sizeof(robj));
			} else if (this) {
				*(u_int64_t *)r_addr += this->st_value + ooff;
			}
			break;

		case R_MIPS_NONE:
			break;

		default:
			_dl_printf("%s: unsupported relocation '%d'\n",
			    _dl_progname, ELF64_R_TYPE(relocs->r_info));
			_dl_exit(1);
		}
	}
	DL_DEB(("done %d fails\n", fails));
	load_list = object->load_list;
	while (load_list != NULL) {
		if ((load_list->prot & PROT_WRITE) == 0)
			_dl_mprotect(load_list->start, load_list->size,
			    load_list->prot);
		load_list = load_list->next;
	}
	return(fails);
}
コード例 #22
0
ファイル: elf_module.c プロジェクト: Celelibi/syslinux
int perform_relocation(struct elf_module *module, Elf_Rel *rel) {
	Elf64_Xword *dest = module_get_absolute(rel->r_offset, module);

	// The symbol reference index
	Elf64_Word sym = ELF64_R_SYM(rel->r_info);
	unsigned char type = ELF64_R_TYPE(rel->r_info);

	// The symbol definition (if applicable)
	Elf64_Sym *sym_def = NULL;
	struct elf_module *sym_module = NULL;
	Elf64_Addr sym_addr = 0x0;

	if (sym > 0) {
		// Find out details about the symbol

		// The symbol reference
		Elf64_Sym *sym_ref = symbol_get_entry(module, sym);

		// The symbol definition
		sym_def =
			global_find_symbol(module->str_table + sym_ref->st_name,
					&sym_module);

		if (sym_def == NULL) {
			DBG_PRINT("Cannot perform relocation for symbol %s\n",
					module->str_table + sym_ref->st_name);

			if (ELF64_ST_BIND(sym_ref->st_info) != STB_WEAK)
				return -1;

			// This must be a derivative-specific
			// function. We're OK as long as we never
			// execute the function.
			sym_def = global_find_symbol("undefined_symbol", &sym_module);
		}

		// Compute the absolute symbol virtual address
		sym_addr = (Elf64_Addr)module_get_absolute(sym_def->st_value, sym_module);

		if (sym_module != module) {
			// Create a dependency
			enforce_dependency(sym_module, module);
		}
	}

	switch (type) {
	case R_X86_64_NONE:
		// Do nothing
		break;
	case R_X86_64_64:
		*dest += sym_addr;
		break;
	case R_X86_64_PC32:
		*dest += sym_addr - (Elf32_Addr)dest;
		break;
	case R_X86_64_COPY:
		if (sym_addr > 0) {
			memcpy((void*)dest, (void*)sym_addr, sym_def->st_size);
		}
		break;
	case R_X86_64_GLOB_DAT:
	case R_X86_64_JUMP_SLOT:
		 //Maybe TODO: Keep track of the GOT entries allocations
		*dest = sym_addr;
		break;
	case R_X86_64_RELATIVE:
		*dest += module->base_addr;
		break;
	default:
		DBG_PRINT("Relocation type %d not supported\n", type);
		return -1;
	}

	return 0;
}