Пример #1
0
/* Output the object file's symbol table, containing one section
 * symbol, one file symbol for each input file, and one exported
 * symbol for each binary object.
 */
static void outputsymtab(void)
{
    Elf64_Sym sym;
    int i;

    sym.st_name = 0;
    sym.st_info = 0;
    sym.st_other = 0;
    sym.st_shndx = SHN_UNDEF;
    sym.st_value = 0;
    sym.st_size = 0;
    if (!elfrw_write_Sym(destfile, &sym))
	ferr();
    sym.st_info = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
    sym.st_shndx = piece_data->shndx;
    if (!elfrw_write_Sym(destfile, &sym))
	ferr();
    sym.st_shndx = SHN_UNDEF;
    for (i = 0 ; i < objectcount ; ++i) {
	sym.st_name = objects[i].filenamestrpos;
	sym.st_info = ELF64_ST_INFO(STB_LOCAL, STT_FILE);
	if (!elfrw_write_Sym(destfile, &sym))
	    ferr();
    }
    for (i = 0 ; i < objectcount ; ++i) {
	sym.st_name = objects[i].objectnamestrpos;
	sym.st_info = ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT);
	sym.st_shndx = piece_data->shndx;
	sym.st_value = objects[i].offset;
	sym.st_size = objects[i].size;
	if (!elfrw_write_Sym(destfile, &sym))
	    ferr();
    }
}
Пример #2
0
void Elf64Output::sym(String* label, SymType type) {
    // Finds the symbol table entry for 'label' and updates it to the current
    // offset of the text or data segment.
    std::map<String::Ptr,size_t>::iterator i = symbol_.find(label);
    Elf64_Sym* sym = 0;
    if (i == symbol_.end()) {
        symbol_.insert(std::make_pair(label, sym_.size()));
        sym_.resize(sym_.size()+1);
        sym = &sym_.back();
        sym->st_name = string_->bytes();
        sym->st_other = 0;
        sym->st_size = 0; // FixMe: May need to set this explicitly
        // Offset to name in string table (+4 for strtab size header)
        string_->buffer(label->string().c_str(), label->string().size()+1);
    } else {
        sym = &sym_[i->second];
        assert("Duplicate label"&&(sym->st_shndx==0)); 
    }
    if (type & SYM_TEXT) {
        sym->st_value = text_->bytes();
        sym->st_shndx = OUT_SECT_TEXT;
    } else if (type & SYM_DATA) {
        sym->st_value = data_->bytes();
        sym->st_shndx = OUT_SECT_DATA;
    } else {
        assert(!"Unknown section type");
    }
    if (type & SYM_LOCAL) {
        sym->st_info = ELF64_ST_INFO(STB_LOCAL, STT_NOTYPE);
    } else {
        sym->st_info = ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE);
    } 
}
Пример #3
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);
}
Пример #4
0
static void add_symtab(Elf *elf) {
    String *symtabb = make_string();
    String *strtabb = make_string();
    o1(strtabb, 0);
    // Null symbol
    for (int i = 0; i < 24; i++) o1(symtabb, 0);
    // File symbol
    o4(symtabb, STRING_LEN(strtabb)); // st_name
    ostr(strtabb, "noname");
    o1(symtabb, ELF64_ST_INFO(STB_LOCAL, STT_FILE)); // st_info
    o1(symtabb, 0); // other
    o2(symtabb, SHN_ABS); // st_shndx
    o8(symtabb, 0); // st_value
    o8(symtabb, 0); // st_size

    int index = 2;
    write_sym_to_buf(elf, &index, symtabb, strtabb, true);
    int localidx = index;
    write_section_sym(elf, &index, symtabb, strtabb);
    write_sym_to_buf(elf, &index, symtabb, strtabb, false);
    elf->symtabnum = LIST_LEN(elf->sections) + 1;

    Section *symtab = make_section(".symtab", SHT_SYMTAB);
    symtab->body = symtabb;
    symtab->link = LIST_LEN(elf->sections) + 2;
    symtab->info = localidx + 2;
    symtab->entsize = 24;
    symtab->align = 4;
    add_section(elf, symtab);

    Section *strtab = make_section(".strtab", SHT_STRTAB);
    strtab->body = strtabb;
    add_section(elf, strtab);
}
uint32_t SymbolTable::addSymbol(uint32_t name, uint64_t value, uint64_t size, uint8_t bind, uint8_t type, uint32_t other, uint16_t shndx){

    if (elfFile->is64Bit()){
        Symbol64* sym = new Symbol64(this, NULL, symbols.size());
        Elf64_Sym symEntry;
        symEntry.st_name = name;
        symEntry.st_value = value;
        symEntry.st_size = size;
        symEntry.st_info = ELF64_ST_INFO(bind,type);
        symEntry.st_other = other;
        symEntry.st_shndx = shndx;

        memcpy(sym->charStream(), &symEntry, Size__64_bit_Symbol);
        symbols.append(sym);
        sizeInBytes += Size__64_bit_Symbol;
    } else {
        Symbol32* sym = new Symbol32(this, NULL, symbols.size());
        Elf32_Sym symEntry;
        symEntry.st_name = name;
        symEntry.st_value = (uint32_t)value;
        symEntry.st_size = (uint32_t)size;
        symEntry.st_info = ELF32_ST_INFO(bind,type);
        symEntry.st_other = other;
        symEntry.st_shndx = shndx;

        memcpy(sym->charStream(), &symEntry, Size__32_bit_Symbol);
        symbols.append(sym);
        sizeInBytes += Size__32_bit_Symbol;
    }

    //    sortSymbols();
    verify();
    return symbols.size()-1;
}
Пример #6
0
static Elf64_Sym *
sym_to_gelf_macho_64(const ctf_sect_t *sp, const Elf32_Sym *src, Elf64_Sym * sym, const char *base)
{
	const struct nlist_64 *nsym = (const struct nlist_64 *)src;
	const char *name = base + nsym->n_un.n_strx;
	char *tmp;
		
	if (0 == nsym->n_un.n_strx) { // iff a null, "", name.
		sym->st_name = 0;
		return sym;
	}

	if ('_' == name[0])
		name++; // Lop off omnipresent underscore to match DWARF convention

	sym->st_name = (Elf64_Word)(name - base);
	sym->st_value = nsym->n_value;
	sym->st_size = 0;
	sym->st_info = STT_NOTYPE;
	sym->st_other = 0;
	sym->st_shndx = SHN_MACHO_64;
	
	if (nsym->n_type & N_STAB) {
	
		switch(nsym->n_type) {
		case N_FUN:
			sym->st_info = ELF64_ST_INFO((STB_GLOBAL), (STT_FUNC));
			break;
		case N_GSYM:
			sym->st_info = ELF64_ST_INFO((STB_GLOBAL), (STT_OBJECT));
			break;
		default:
			break;
		}
		
	} else if ((N_ABS | N_EXT) == (nsym->n_type & (N_TYPE | N_EXT)) ||
		(N_SECT | N_EXT) == (nsym->n_type & (N_TYPE | N_EXT))) {

		sym->st_info = ELF64_ST_INFO((STB_GLOBAL), (nsym->n_desc)); 
	} else if ((N_UNDF | N_EXT) == (nsym->n_type & (N_TYPE | N_EXT)) &&
				nsym->n_sect == NO_SECT) {
		sym->st_info = ELF64_ST_INFO((STB_GLOBAL), (STT_OBJECT)); /* Common */
	}
	
	return sym;
}
Пример #7
0
static void newSym64(char *name,elfull value,elfull size,uint8_t bind,
                     uint8_t type,unsigned shndx)
{
  struct Symbol64Node *elfsym = addSymbol64(name);

  setval(be,elfsym->s.st_value,8,value);
  setval(be,elfsym->s.st_size,8,size);
  elfsym->s.st_info[0] = ELF64_ST_INFO(bind,type);
  setval(be,elfsym->s.st_shndx,2,shndx);
}
Пример #8
0
void prepare_symentry(Sym *symentry) {
	symentry->st_name = 1;
	symentry->st_value = 0;
	symentry->st_size = fs.st_size;
#ifdef BIT32
	symentry->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
#else
	symentry->st_info = ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT);
#endif
	symentry->st_other = STV_DEFAULT;
	symentry->st_shndx = IDX_DATA;
}
Пример #9
0
void Elf64Output::ref(String* label, RelocType rtype) {
    // Refer to a symbol by name at the current text/data output location.
    // This function adds an entry to the relocation table.  The size can be
    // either 4 or 8 bytes.  A 4-byte entry indicates the instruction uses
    // RIP-relative addressing for x64.
    std::map<String::Ptr,size_t>::iterator i = symbol_.find(label);
    size_t symnum = 0;
    if (i == symbol_.end()) {
        symbol_.insert(std::make_pair(label, sym_.size()));
        sym_.resize(sym_.size()+1);
        Elf64_Sym* const sym = &sym_.back();
        sym->st_name = string_->bytes();
        sym->st_info = ELF64_ST_INFO(STB_GLOBAL, STT_NOTYPE);
        sym->st_other = 0;
        sym->st_shndx = SHN_UNDEF;
        sym->st_value = 0;
        sym->st_size = 0; // Unknown size
        string_->buffer(label->string().c_str(), label->string().size()+1);
        symnum = sym_.size()-1;
    } else {
        symnum = i->second;
    }

    Elf64_Rela reloc;
    if (REF_TEXT == rtype) {
        reloc.r_offset = text_->bytes();
        reloc.r_info = ELF64_R_INFO(symnum, R_X86_64_64);
        reloc.r_addend = 0;
        text_reloc_.push_back(reloc);
    } else if (REF_DATA == rtype || REF_VTABLE == rtype) {
        reloc.r_offset = data_->bytes();
        reloc.r_info = ELF64_R_INFO(symnum, R_X86_64_64);
        reloc.r_addend = 0;
        data_reloc_.push_back(reloc);
    } else if (REF_BRANCH == rtype || REF_CALL == rtype) {
        reloc.r_offset = text_->bytes();
        reloc.r_info = ELF64_R_INFO(symnum, R_X86_64_PC32);
        reloc.r_addend = -sizeof(uint32_t);
        text_reloc_.push_back(reloc);
    } else if (REF_SIGNED == rtype) {
        reloc.r_offset = text_->bytes();
        reloc.r_info = ELF64_R_INFO(symnum, R_X86_64_PC32);
        reloc.r_addend = -sizeof(uint32_t);
        text_reloc_.push_back(reloc);
    } 
}
Пример #10
0
static void write_one_symbol(Symbol *sym, int *index, String *symtab, String *strtab) {
    if (sym->name) {
        o4(symtab, STRING_LEN(strtab)); // st_name
        ostr(strtab, STRING_BODY(sym->name));
    } else {
        o4(symtab, 0); // st_name
    }
    o1(symtab, ELF64_ST_INFO(sym->bind, sym->type)); // st_info;
    o1(symtab, 0); // st_other;
    if (sym->defined) {
        o2(symtab, sym->section->shndx); // st_shndx
    } else {
        o2(symtab, 0); // st_shndx
    }
    o8(symtab, sym->value); // st_value
    o8(symtab, 0); // st_size
    sym->index = (*index)++;
}
Пример #11
0
static void
elf_x86_amd64_write_symtab_entry(unsigned char *bufp,
                                 elf_symtab_entry *entry,
                                 yasm_intnum *value_intn,
                                 yasm_intnum *size_intn)
{
    YASM_WRITE_32_L(bufp, entry->name ? entry->name->index : 0);
    YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
    YASM_WRITE_8(bufp, ELF64_ST_OTHER(entry->vis));
    if (entry->sect) {
        elf_secthead *shead =
            yasm_section_get_data(entry->sect, &elf_section_data);
        if (!shead)
            yasm_internal_error(N_("symbol references section without data"));
        YASM_WRITE_16_L(bufp, shead->index);
    } else {
        YASM_WRITE_16_L(bufp, entry->index);
    }
    YASM_WRITE_64I_L(bufp, value_intn);
    YASM_WRITE_64I_L(bufp, size_intn);
}