ElfSymbol::ElfSymbol(const ElfConfig& config, const llvm::MemoryBuffer& in, const ElfSection& symtab_sect, ElfSymbolIndex index, Section* sections[], Diagnostic& diags) : m_sect(0) , m_name_index(0) , m_value(0) , m_symindex(index) , m_in_table(true) , m_weak_ref(false) , m_weak_refr(false) { InputBuffer inbuf(in); ElfSize symsize = symtab_sect.getEntSize(); inbuf.setPosition(symtab_sect.getFileOffset() + index * symsize); if (inbuf.getReadableSize() < symsize) { diags.Report(SourceLocation(), diag::err_symbol_unreadable); return; } config.setEndian(inbuf); m_name_index = ReadU32(inbuf); if (config.cls == ELFCLASS32) { m_value = ReadU32(inbuf); m_size = Expr(ReadU32(inbuf)); } unsigned char info = ReadU8(inbuf); m_bind = ELF_ST_BIND(info); m_type = ELF_ST_TYPE(info); m_vis = ELF_ST_VISIBILITY(ReadU8(inbuf)); m_index = static_cast<ElfSectionIndex>(ReadU16(inbuf)); if (m_index != SHN_UNDEF && m_index < config.secthead_count) m_sect = sections[m_index]; if (config.cls == ELFCLASS64) { m_value = ReadU64(inbuf); m_size = Expr(ReadU64(inbuf)); } }
bool ElfConfig::ReadSymbolTable(const MemoryBuffer& in, const ElfSection& symtab_sect, ElfSymtab& symtab, Object& object, const StringTable& strtab, Section* sections[], DiagnosticsEngine& diags) const { ElfSize symsize = symtab_sect.getEntSize(); if (symsize == 0) { diags.Report(SourceLocation(), diag::err_symbol_entity_size_zero); return false; } unsigned long size = symtab_sect.getSize().getUInt(); // Symbol table always starts with null entry symtab.push_back(SymbolRef(0)); ElfSymbolIndex index = 1; for (unsigned long pos=symsize; pos<size; pos += symsize, ++index) { std::auto_ptr<ElfSymbol> elfsym( new ElfSymbol(*this, in, symtab_sect, index, sections, diags)); if (diags.hasErrorOccurred()) return false; SymbolRef sym = elfsym->CreateSymbol(object, strtab); symtab.push_back(sym); if (sym) sym->AddAssocData(elfsym); // Associate symbol data with symbol } return true; }