mirror of
https://github.com/intel/llvm.git
synced 2026-01-15 04:17:17 +08:00
Revert "[NFC] Refactor symbol table parsing."
This reverts commit 951b107eed.
Buildbots were failing, there is a deadlock in /Users/gclayton/Documents/src/llvm/clean/llvm-project/lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s when ELF files try to relocate things.
This commit is contained in:
@@ -322,26 +322,12 @@ public:
|
||||
/// Gets the symbol table for the currently selected architecture (and
|
||||
/// object for archives).
|
||||
///
|
||||
/// This function will manage when ParseSymtab(...) is called to actually do
|
||||
/// the symbol table parsing in each plug-in. This function will take care of
|
||||
/// taking all the necessary locks and finalizing the symbol table when the
|
||||
/// symbol table does get parsed.
|
||||
/// Symbol table parsing can be deferred by ObjectFile instances until this
|
||||
/// accessor is called the first time.
|
||||
///
|
||||
/// \return
|
||||
/// The symbol table for this object file.
|
||||
Symtab *GetSymtab();
|
||||
|
||||
/// Parse the symbol table into the provides symbol table object.
|
||||
///
|
||||
/// Symbol table parsing will be done once when this function is called by
|
||||
/// each object file plugin. All of the necessary locks will already be
|
||||
/// acquired before this function is called and the symbol table object to
|
||||
/// populate is supplied as an argument and doesn't need to be created by
|
||||
/// each plug-in.
|
||||
///
|
||||
/// \param
|
||||
/// The symbol table to populate.
|
||||
virtual void ParseSymtab(Symtab &symtab) = 0;
|
||||
virtual Symtab *GetSymtab() = 0;
|
||||
|
||||
/// Perform relocations on the section if necessary.
|
||||
///
|
||||
|
||||
@@ -119,13 +119,20 @@ public:
|
||||
lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
|
||||
void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
|
||||
SymbolContextList &sc_list);
|
||||
void CalculateSymbolSizes();
|
||||
|
||||
void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
|
||||
bool remove_duplicates) const;
|
||||
|
||||
static void DumpSymbolHeader(Stream *s);
|
||||
|
||||
void Finalize();
|
||||
void Finalize() {
|
||||
// Shrink to fit the symbols so we don't waste memory
|
||||
if (m_symbols.capacity() > m_symbols.size()) {
|
||||
collection new_symbols(m_symbols.begin(), m_symbols.end());
|
||||
m_symbols.swap(new_symbols);
|
||||
}
|
||||
}
|
||||
|
||||
void AppendSymbolNamesToMap(const IndexCollection &indexes,
|
||||
bool add_demangled, bool add_mangled,
|
||||
|
||||
@@ -116,10 +116,9 @@ bool ObjectFileBreakpad::ParseHeader() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectFileBreakpad::ParseSymtab(Symtab &symtab) {
|
||||
// Nothing to do for breakpad files, all information is parsed as debug info
|
||||
// which means "lldb_private::Function" objects are used, or symbols are added
|
||||
// by the SymbolFileBreakpad::AddSymbols(...) function in the symbol file.
|
||||
Symtab *ObjectFileBreakpad::GetSymtab() {
|
||||
// TODO
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
return AddressClass::eInvalid;
|
||||
}
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override;
|
||||
Symtab *GetSymtab() override;
|
||||
|
||||
bool IsStripped() override { return false; }
|
||||
|
||||
|
||||
@@ -2687,132 +2687,155 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
|
||||
Symtab *ObjectFileELF::GetSymtab() {
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (!module_sp)
|
||||
return;
|
||||
|
||||
Progress progress(
|
||||
llvm::formatv("Parsing symbol table for {0}",
|
||||
m_file.GetFilename().AsCString("<Unknown>")));
|
||||
ElapsedTime elapsed(module_sp->GetSymtabParseTime());
|
||||
return nullptr;
|
||||
|
||||
// We always want to use the main object file so we (hopefully) only have one
|
||||
// cached copy of our symtab, dynamic sections, etc.
|
||||
ObjectFile *module_obj_file = module_sp->GetObjectFile();
|
||||
if (module_obj_file && module_obj_file != this)
|
||||
return module_obj_file->ParseSymtab(lldb_symtab);
|
||||
return module_obj_file->GetSymtab();
|
||||
|
||||
SectionList *section_list = module_sp->GetSectionList();
|
||||
if (!section_list)
|
||||
return;
|
||||
if (m_symtab_up == nullptr) {
|
||||
Progress progress(
|
||||
llvm::formatv("Parsing symbol table for {0}",
|
||||
m_file.GetFilename().AsCString("<Unknown>")));
|
||||
ElapsedTime elapsed(module_sp->GetSymtabParseTime());
|
||||
SectionList *section_list = module_sp->GetSectionList();
|
||||
if (!section_list)
|
||||
return nullptr;
|
||||
|
||||
uint64_t symbol_id = 0;
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
uint64_t symbol_id = 0;
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
|
||||
// Sharable objects and dynamic executables usually have 2 distinct symbol
|
||||
// tables, one named ".symtab", and the other ".dynsym". The dynsym is a
|
||||
// smaller version of the symtab that only contains global symbols. The
|
||||
// information found in the dynsym is therefore also found in the symtab,
|
||||
// while the reverse is not necessarily true.
|
||||
Section *symtab =
|
||||
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
|
||||
if (symtab)
|
||||
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
|
||||
|
||||
// The symtab section is non-allocable and can be stripped, while the
|
||||
// .dynsym section which should always be always be there. To support the
|
||||
// minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
|
||||
// section, nomatter if .symtab was already parsed or not. This is because
|
||||
// minidebuginfo normally removes the .symtab symbols which have their
|
||||
// matching .dynsym counterparts.
|
||||
if (!symtab ||
|
||||
GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
|
||||
Section *dynsym =
|
||||
section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
|
||||
.get();
|
||||
if (dynsym)
|
||||
symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
|
||||
}
|
||||
|
||||
// DT_JMPREL
|
||||
// If present, this entry's d_ptr member holds the address of
|
||||
// relocation
|
||||
// entries associated solely with the procedure linkage table.
|
||||
// Separating
|
||||
// these relocation entries lets the dynamic linker ignore them during
|
||||
// process initialization, if lazy binding is enabled. If this entry is
|
||||
// present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
|
||||
// also be present.
|
||||
const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
|
||||
if (symbol) {
|
||||
// Synthesize trampoline symbols to help navigate the PLT.
|
||||
addr_t addr = symbol->d_ptr;
|
||||
Section *reloc_section =
|
||||
section_list->FindSectionContainingFileAddress(addr).get();
|
||||
if (reloc_section) {
|
||||
user_id_t reloc_id = reloc_section->GetID();
|
||||
const ELFSectionHeaderInfo *reloc_header =
|
||||
GetSectionHeaderByIndex(reloc_id);
|
||||
if (reloc_header)
|
||||
ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
|
||||
// Sharable objects and dynamic executables usually have 2 distinct symbol
|
||||
// tables, one named ".symtab", and the other ".dynsym". The dynsym is a
|
||||
// smaller version of the symtab that only contains global symbols. The
|
||||
// information found in the dynsym is therefore also found in the symtab,
|
||||
// while the reverse is not necessarily true.
|
||||
Section *symtab =
|
||||
section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
|
||||
if (symtab) {
|
||||
m_symtab_up = std::make_unique<Symtab>(symtab->GetObjectFile());
|
||||
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
|
||||
}
|
||||
}
|
||||
|
||||
if (DWARFCallFrameInfo *eh_frame =
|
||||
GetModule()->GetUnwindTable().GetEHFrameInfo()) {
|
||||
ParseUnwindSymbols(&lldb_symtab, eh_frame);
|
||||
}
|
||||
|
||||
// In the event that there's no symbol entry for the entry point we'll
|
||||
// artificially create one. We delegate to the symtab object the figuring
|
||||
// out of the proper size, this will usually make it span til the next
|
||||
// symbol it finds in the section. This means that if there are missing
|
||||
// symbols the entry point might span beyond its function definition.
|
||||
// We're fine with this as it doesn't make it worse than not having a
|
||||
// symbol entry at all.
|
||||
if (CalculateType() == eTypeExecutable) {
|
||||
ArchSpec arch = GetArchitecture();
|
||||
auto entry_point_addr = GetEntryPointAddress();
|
||||
bool is_valid_entry_point =
|
||||
entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
|
||||
addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
|
||||
if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
|
||||
entry_point_file_addr)) {
|
||||
uint64_t symbol_id = lldb_symtab.GetNumSymbols();
|
||||
// Don't set the name for any synthetic symbols, the Symbol
|
||||
// object will generate one if needed when the name is accessed
|
||||
// via accessors.
|
||||
SectionSP section_sp = entry_point_addr.GetSection();
|
||||
Symbol symbol(
|
||||
/*symID=*/symbol_id,
|
||||
/*name=*/llvm::StringRef(), // Name will be auto generated.
|
||||
/*type=*/eSymbolTypeCode,
|
||||
/*external=*/true,
|
||||
/*is_debug=*/false,
|
||||
/*is_trampoline=*/false,
|
||||
/*is_artificial=*/true,
|
||||
/*section_sp=*/section_sp,
|
||||
/*offset=*/0,
|
||||
/*size=*/0, // FDE can span multiple symbols so don't use its size.
|
||||
/*size_is_valid=*/false,
|
||||
/*contains_linker_annotations=*/false,
|
||||
/*flags=*/0);
|
||||
// When the entry point is arm thumb we need to explicitly set its
|
||||
// class address to reflect that. This is important because expression
|
||||
// evaluation relies on correctly setting a breakpoint at this
|
||||
// address.
|
||||
if (arch.GetMachine() == llvm::Triple::arm &&
|
||||
(entry_point_file_addr & 1)) {
|
||||
symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
|
||||
m_address_class_map[entry_point_file_addr ^ 1] =
|
||||
AddressClass::eCodeAlternateISA;
|
||||
} else {
|
||||
m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
|
||||
// The symtab section is non-allocable and can be stripped, while the
|
||||
// .dynsym section which should always be always be there. To support the
|
||||
// minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
|
||||
// section, nomatter if .symtab was already parsed or not. This is because
|
||||
// minidebuginfo normally removes the .symtab symbols which have their
|
||||
// matching .dynsym counterparts.
|
||||
if (!symtab ||
|
||||
GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
|
||||
Section *dynsym =
|
||||
section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
|
||||
.get();
|
||||
if (dynsym) {
|
||||
if (!m_symtab_up)
|
||||
m_symtab_up = std::make_unique<Symtab>(dynsym->GetObjectFile());
|
||||
symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
|
||||
}
|
||||
lldb_symtab.AddSymbol(symbol);
|
||||
}
|
||||
|
||||
// DT_JMPREL
|
||||
// If present, this entry's d_ptr member holds the address of
|
||||
// relocation
|
||||
// entries associated solely with the procedure linkage table.
|
||||
// Separating
|
||||
// these relocation entries lets the dynamic linker ignore them during
|
||||
// process initialization, if lazy binding is enabled. If this entry is
|
||||
// present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
|
||||
// also be present.
|
||||
const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
|
||||
if (symbol) {
|
||||
// Synthesize trampoline symbols to help navigate the PLT.
|
||||
addr_t addr = symbol->d_ptr;
|
||||
Section *reloc_section =
|
||||
section_list->FindSectionContainingFileAddress(addr).get();
|
||||
if (reloc_section) {
|
||||
user_id_t reloc_id = reloc_section->GetID();
|
||||
const ELFSectionHeaderInfo *reloc_header =
|
||||
GetSectionHeaderByIndex(reloc_id);
|
||||
if (reloc_header) {
|
||||
if (m_symtab_up == nullptr)
|
||||
m_symtab_up =
|
||||
std::make_unique<Symtab>(reloc_section->GetObjectFile());
|
||||
|
||||
ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
|
||||
reloc_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DWARFCallFrameInfo *eh_frame =
|
||||
GetModule()->GetUnwindTable().GetEHFrameInfo()) {
|
||||
if (m_symtab_up == nullptr)
|
||||
m_symtab_up = std::make_unique<Symtab>(this);
|
||||
ParseUnwindSymbols(m_symtab_up.get(), eh_frame);
|
||||
}
|
||||
|
||||
// If we still don't have any symtab then create an empty instance to avoid
|
||||
// do the section lookup next time.
|
||||
if (m_symtab_up == nullptr)
|
||||
m_symtab_up = std::make_unique<Symtab>(this);
|
||||
|
||||
// In the event that there's no symbol entry for the entry point we'll
|
||||
// artificially create one. We delegate to the symtab object the figuring
|
||||
// out of the proper size, this will usually make it span til the next
|
||||
// symbol it finds in the section. This means that if there are missing
|
||||
// symbols the entry point might span beyond its function definition.
|
||||
// We're fine with this as it doesn't make it worse than not having a
|
||||
// symbol entry at all.
|
||||
if (CalculateType() == eTypeExecutable) {
|
||||
ArchSpec arch = GetArchitecture();
|
||||
auto entry_point_addr = GetEntryPointAddress();
|
||||
bool is_valid_entry_point =
|
||||
entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
|
||||
addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
|
||||
if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
|
||||
entry_point_file_addr)) {
|
||||
uint64_t symbol_id = m_symtab_up->GetNumSymbols();
|
||||
// Don't set the name for any synthetic symbols, the Symbol
|
||||
// object will generate one if needed when the name is accessed
|
||||
// via accessors.
|
||||
SectionSP section_sp = entry_point_addr.GetSection();
|
||||
Symbol symbol(
|
||||
/*symID=*/symbol_id,
|
||||
/*name=*/llvm::StringRef(), // Name will be auto generated.
|
||||
/*type=*/eSymbolTypeCode,
|
||||
/*external=*/true,
|
||||
/*is_debug=*/false,
|
||||
/*is_trampoline=*/false,
|
||||
/*is_artificial=*/true,
|
||||
/*section_sp=*/section_sp,
|
||||
/*offset=*/0,
|
||||
/*size=*/0, // FDE can span multiple symbols so don't use its size.
|
||||
/*size_is_valid=*/false,
|
||||
/*contains_linker_annotations=*/false,
|
||||
/*flags=*/0);
|
||||
// When the entry point is arm thumb we need to explicitly set its
|
||||
// class address to reflect that. This is important because expression
|
||||
// evaluation relies on correctly setting a breakpoint at this
|
||||
// address.
|
||||
if (arch.GetMachine() == llvm::Triple::arm &&
|
||||
(entry_point_file_addr & 1)) {
|
||||
symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
|
||||
m_address_class_map[entry_point_file_addr ^ 1] =
|
||||
AddressClass::eCodeAlternateISA;
|
||||
} else {
|
||||
m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
|
||||
}
|
||||
m_symtab_up->AddSymbol(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
m_symtab_up->CalculateSymbolSizes();
|
||||
}
|
||||
|
||||
return m_symtab_up.get();
|
||||
}
|
||||
|
||||
void ObjectFileELF::RelocateSection(lldb_private::Section *section)
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override;
|
||||
lldb_private::Symtab *GetSymtab() override;
|
||||
|
||||
bool IsStripped() override;
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
lldb_private::UUID GetUUID() override;
|
||||
|
||||
/// Return the contents of the .gnu_debuglink section, if the object file
|
||||
/// contains it.
|
||||
/// contains it.
|
||||
llvm::Optional<lldb_private::FileSpec> GetDebugLink();
|
||||
|
||||
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
|
||||
@@ -384,7 +384,7 @@ private:
|
||||
lldb_private::UUID &uuid);
|
||||
|
||||
bool AnySegmentHasPhysicalAddress();
|
||||
|
||||
|
||||
/// Takes the .gnu_debugdata and returns the decompressed object file that is
|
||||
/// stored within that section.
|
||||
///
|
||||
|
||||
@@ -106,10 +106,23 @@ uint32_t ObjectFileJIT::GetAddressByteSize() const {
|
||||
return m_data.GetAddressByteSize();
|
||||
}
|
||||
|
||||
void ObjectFileJIT::ParseSymtab(Symtab &symtab) {
|
||||
ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
|
||||
if (delegate_sp)
|
||||
delegate_sp->PopulateSymtab(this, symtab);
|
||||
Symtab *ObjectFileJIT::GetSymtab() {
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (module_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
if (m_symtab_up == nullptr) {
|
||||
ElapsedTime elapsed(module_sp->GetSymtabParseTime());
|
||||
m_symtab_up = std::make_unique<Symtab>(this);
|
||||
std::lock_guard<std::recursive_mutex> symtab_guard(
|
||||
m_symtab_up->GetMutex());
|
||||
ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
|
||||
if (delegate_sp)
|
||||
delegate_sp->PopulateSymtab(this, *m_symtab_up);
|
||||
// TODO: get symbols from delegate
|
||||
m_symtab_up->Finalize();
|
||||
}
|
||||
}
|
||||
return m_symtab_up.get();
|
||||
}
|
||||
|
||||
bool ObjectFileJIT::IsStripped() {
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
|
||||
uint32_t GetAddressByteSize() const override;
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override;
|
||||
lldb_private::Symtab *GetSymtab() override;
|
||||
|
||||
bool IsStripped() override;
|
||||
|
||||
|
||||
@@ -1311,6 +1311,22 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
|
||||
return AddressClass::eUnknown;
|
||||
}
|
||||
|
||||
Symtab *ObjectFileMachO::GetSymtab() {
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (module_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
if (m_symtab_up == nullptr) {
|
||||
ElapsedTime elapsed(module_sp->GetSymtabParseTime());
|
||||
m_symtab_up = std::make_unique<Symtab>(this);
|
||||
std::lock_guard<std::recursive_mutex> symtab_guard(
|
||||
m_symtab_up->GetMutex());
|
||||
ParseSymtab();
|
||||
m_symtab_up->Finalize();
|
||||
}
|
||||
}
|
||||
return m_symtab_up.get();
|
||||
}
|
||||
|
||||
bool ObjectFileMachO::IsStripped() {
|
||||
if (m_dysymtab.cmd == 0) {
|
||||
ModuleSP module_sp(GetModule());
|
||||
@@ -2217,12 +2233,12 @@ ParseNList(DataExtractor &nlist_data, lldb::offset_t &nlist_data_offset,
|
||||
|
||||
enum { DebugSymbols = true, NonDebugSymbols = false };
|
||||
|
||||
void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
size_t ObjectFileMachO::ParseSymtab() {
|
||||
LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s",
|
||||
m_file.GetFilename().AsCString(""));
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (!module_sp)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
Progress progress(llvm::formatv("Parsing symbol table for {0}",
|
||||
m_file.GetFilename().AsCString("<Unknown>")));
|
||||
@@ -2272,7 +2288,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// Read in the rest of the symtab load command
|
||||
if (m_data.GetU32(&offset, &symtab_load_command.symoff, 4) ==
|
||||
nullptr) // fill in symoff, nsyms, stroff, strsize fields
|
||||
return;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case LC_DYLD_INFO:
|
||||
@@ -2331,11 +2347,12 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
}
|
||||
|
||||
if (!symtab_load_command.cmd)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
Symtab *symtab = m_symtab_up.get();
|
||||
SectionList *section_list = GetSectionList();
|
||||
if (section_list == nullptr)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
|
||||
const ByteOrder byte_order = m_data.GetByteOrder();
|
||||
@@ -2472,7 +2489,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
|
||||
// We shouldn't have exports data from both the LC_DYLD_INFO command
|
||||
// AND the LC_DYLD_EXPORTS_TRIE command in the same binary:
|
||||
lldbassert(!((dyld_info.export_size > 0)
|
||||
lldbassert(!((dyld_info.export_size > 0)
|
||||
&& (exports_trie_load_command.datasize > 0)));
|
||||
if (dyld_info.export_size > 0) {
|
||||
dyld_trie_data.SetData(m_data, dyld_info.export_off,
|
||||
@@ -2864,10 +2881,10 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
|
||||
// The normal nlist code cannot correctly size the Symbols
|
||||
// array, we need to allocate it here.
|
||||
sym = symtab.Resize(
|
||||
sym = symtab->Resize(
|
||||
symtab_load_command.nsyms + m_dysymtab.nindirectsyms +
|
||||
unmapped_local_symbols_found - m_dysymtab.nlocalsym);
|
||||
num_syms = symtab.GetNumSymbols();
|
||||
num_syms = symtab->GetNumSymbols();
|
||||
|
||||
nlist_data_offset =
|
||||
local_symbols_info.nlistOffset +
|
||||
@@ -2999,7 +3016,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// original
|
||||
// STAB entry so we don't have
|
||||
// to hunt for it later
|
||||
symtab.SymbolAtIndex(N_FUN_indexes.back())
|
||||
symtab->SymbolAtIndex(N_FUN_indexes.back())
|
||||
->SetByteSize(nlist.n_value);
|
||||
N_FUN_indexes.pop_back();
|
||||
// We don't really need the end function STAB as
|
||||
@@ -3079,7 +3096,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// index of this N_SO so that we can always skip
|
||||
// the entire N_SO if we need to navigate more
|
||||
// quickly at the source level when parsing STABS
|
||||
symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
|
||||
symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
|
||||
symbol_ptr->SetByteSize(sym_idx);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
}
|
||||
@@ -3186,7 +3203,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// quickly at the source level when parsing STABS
|
||||
if (!N_INCL_indexes.empty()) {
|
||||
symbol_ptr =
|
||||
symtab.SymbolAtIndex(N_INCL_indexes.back());
|
||||
symtab->SymbolAtIndex(N_INCL_indexes.back());
|
||||
symbol_ptr->SetByteSize(sym_idx + 1);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
N_INCL_indexes.pop_back();
|
||||
@@ -3251,7 +3268,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
nlist.n_value);
|
||||
if (!N_BRAC_indexes.empty()) {
|
||||
symbol_ptr =
|
||||
symtab.SymbolAtIndex(N_BRAC_indexes.back());
|
||||
symtab->SymbolAtIndex(N_BRAC_indexes.back());
|
||||
symbol_ptr->SetByteSize(sym_idx + 1);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
N_BRAC_indexes.pop_back();
|
||||
@@ -3289,7 +3306,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// parsing STABS
|
||||
if (!N_COMM_indexes.empty()) {
|
||||
symbol_ptr =
|
||||
symtab.SymbolAtIndex(N_COMM_indexes.back());
|
||||
symtab->SymbolAtIndex(N_COMM_indexes.back());
|
||||
symbol_ptr->SetByteSize(sym_idx + 1);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
N_COMM_indexes.pop_back();
|
||||
@@ -3789,8 +3806,8 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// symbols, create it now.
|
||||
if (sym == nullptr) {
|
||||
sym =
|
||||
symtab.Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
|
||||
num_syms = symtab.GetNumSymbols();
|
||||
symtab->Resize(symtab_load_command.nsyms + m_dysymtab.nindirectsyms);
|
||||
num_syms = symtab->GetNumSymbols();
|
||||
}
|
||||
|
||||
if (unmapped_local_symbols_found) {
|
||||
@@ -3924,7 +3941,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
if (!N_FUN_indexes.empty()) {
|
||||
// Copy the size of the function into the original STAB entry
|
||||
// so we don't have to hunt for it later
|
||||
symtab.SymbolAtIndex(N_FUN_indexes.back())
|
||||
symtab->SymbolAtIndex(N_FUN_indexes.back())
|
||||
->SetByteSize(nlist.n_value);
|
||||
N_FUN_indexes.pop_back();
|
||||
// We don't really need the end function STAB as it contains
|
||||
@@ -3998,7 +4015,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// N_SO so that we can always skip the entire N_SO if we need
|
||||
// to navigate more quickly at the source level when parsing
|
||||
// STABS
|
||||
symbol_ptr = symtab.SymbolAtIndex(N_SO_index);
|
||||
symbol_ptr = symtab->SymbolAtIndex(N_SO_index);
|
||||
symbol_ptr->SetByteSize(sym_idx);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
}
|
||||
@@ -4092,7 +4109,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// N_EINCL so that we can always skip the entire symbol if we need
|
||||
// to navigate more quickly at the source level when parsing STABS
|
||||
if (!N_INCL_indexes.empty()) {
|
||||
symbol_ptr = symtab.SymbolAtIndex(N_INCL_indexes.back());
|
||||
symbol_ptr = symtab->SymbolAtIndex(N_INCL_indexes.back());
|
||||
symbol_ptr->SetByteSize(sym_idx + 1);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
N_INCL_indexes.pop_back();
|
||||
@@ -4151,7 +4168,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// quickly at the source level when parsing STABS
|
||||
symbol_section = section_info.GetSection(nlist.n_sect, nlist.n_value);
|
||||
if (!N_BRAC_indexes.empty()) {
|
||||
symbol_ptr = symtab.SymbolAtIndex(N_BRAC_indexes.back());
|
||||
symbol_ptr = symtab->SymbolAtIndex(N_BRAC_indexes.back());
|
||||
symbol_ptr->SetByteSize(sym_idx + 1);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
N_BRAC_indexes.pop_back();
|
||||
@@ -4185,7 +4202,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// we need to navigate more quickly at the source level when
|
||||
// parsing STABS
|
||||
if (!N_COMM_indexes.empty()) {
|
||||
symbol_ptr = symtab.SymbolAtIndex(N_COMM_indexes.back());
|
||||
symbol_ptr = symtab->SymbolAtIndex(N_COMM_indexes.back());
|
||||
symbol_ptr->SetByteSize(sym_idx + 1);
|
||||
symbol_ptr->SetSizeIsSibling(true);
|
||||
N_COMM_indexes.pop_back();
|
||||
@@ -4641,7 +4658,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
|
||||
if (num_syms < sym_idx + trie_symbol_table_augment_count) {
|
||||
num_syms = sym_idx + trie_symbol_table_augment_count;
|
||||
sym = symtab.Resize(num_syms);
|
||||
sym = symtab->Resize(num_syms);
|
||||
}
|
||||
uint32_t synthetic_sym_id = symtab_load_command.nsyms;
|
||||
|
||||
@@ -4690,7 +4707,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
if (num_synthetic_function_symbols > 0) {
|
||||
if (num_syms < sym_idx + num_synthetic_function_symbols) {
|
||||
num_syms = sym_idx + num_synthetic_function_symbols;
|
||||
sym = symtab.Resize(num_syms);
|
||||
sym = symtab->Resize(num_syms);
|
||||
}
|
||||
for (i = 0; i < function_starts_count; ++i) {
|
||||
const FunctionStarts::Entry *func_start_entry =
|
||||
@@ -4745,7 +4762,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// symbols.
|
||||
if (sym_idx < num_syms) {
|
||||
num_syms = sym_idx;
|
||||
sym = symtab.Resize(num_syms);
|
||||
sym = symtab->Resize(num_syms);
|
||||
}
|
||||
|
||||
// Now synthesize indirect symbols
|
||||
@@ -4790,11 +4807,11 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
if (index_pos != end_index_pos) {
|
||||
// We have a remapping from the original nlist index to a
|
||||
// current symbol index, so just look this up by index
|
||||
stub_symbol = symtab.SymbolAtIndex(index_pos->second);
|
||||
stub_symbol = symtab->SymbolAtIndex(index_pos->second);
|
||||
} else {
|
||||
// We need to lookup a symbol using the original nlist symbol
|
||||
// index since this index is coming from the S_SYMBOL_STUBS
|
||||
stub_symbol = symtab.FindSymbolByID(stub_sym_id);
|
||||
stub_symbol = symtab->FindSymbolByID(stub_sym_id);
|
||||
}
|
||||
|
||||
if (stub_symbol) {
|
||||
@@ -4817,7 +4834,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
// Make a synthetic symbol to describe the trampoline stub
|
||||
Mangled stub_symbol_mangled_name(stub_symbol->GetMangled());
|
||||
if (sym_idx >= num_syms) {
|
||||
sym = symtab.Resize(++num_syms);
|
||||
sym = symtab->Resize(++num_syms);
|
||||
stub_symbol = nullptr; // this pointer no longer valid
|
||||
}
|
||||
sym[sym_idx].SetID(synthetic_sym_id++);
|
||||
@@ -4856,7 +4873,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
indirect_symbol_names.end()) {
|
||||
// Make a synthetic symbol to describe re-exported symbol.
|
||||
if (sym_idx >= num_syms)
|
||||
sym = symtab.Resize(++num_syms);
|
||||
sym = symtab->Resize(++num_syms);
|
||||
sym[sym_idx].SetID(synthetic_sym_id++);
|
||||
sym[sym_idx].GetMangled() = Mangled(e.entry.name);
|
||||
sym[sym_idx].SetType(eSymbolTypeReExported);
|
||||
@@ -4871,6 +4888,18 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StreamFile s(stdout, false);
|
||||
// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
|
||||
// symtab->Dump(&s, NULL, eSortOrderNone);
|
||||
// Set symbol byte sizes correctly since mach-o nlist entries don't have
|
||||
// sizes
|
||||
symtab->CalculateSymbolSizes();
|
||||
|
||||
// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
|
||||
// symtab->Dump(&s, NULL, eSortOrderNone);
|
||||
|
||||
return symtab->GetNumSymbols();
|
||||
}
|
||||
|
||||
void ObjectFileMachO::Dump(Stream *s) {
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
|
||||
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override;
|
||||
lldb_private::Symtab *GetSymtab() override;
|
||||
|
||||
bool IsStripped() override;
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
bool IsExecutable() const override { return false; }
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override {}
|
||||
Symtab *GetSymtab() override { return nullptr; }
|
||||
|
||||
bool IsStripped() override { return false; }
|
||||
|
||||
|
||||
@@ -589,125 +589,139 @@ llvm::StringRef ObjectFilePECOFF::GetSectionName(const section_header_t §) {
|
||||
return hdr_name;
|
||||
}
|
||||
|
||||
void ObjectFilePECOFF::ParseSymtab(Symtab &symtab) {
|
||||
SectionList *sect_list = GetSectionList();
|
||||
const uint32_t num_syms = m_coff_header.nsyms;
|
||||
if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
|
||||
const uint32_t symbol_size = 18;
|
||||
const size_t symbol_data_size = num_syms * symbol_size;
|
||||
// Include the 4-byte string table size at the end of the symbols
|
||||
DataExtractor symtab_data =
|
||||
ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
|
||||
lldb::offset_t offset = symbol_data_size;
|
||||
const uint32_t strtab_size = symtab_data.GetU32(&offset);
|
||||
if (strtab_size > 0) {
|
||||
DataExtractor strtab_data = ReadImageData(
|
||||
m_coff_header.symoff + symbol_data_size, strtab_size);
|
||||
// GetNListSymtab
|
||||
Symtab *ObjectFilePECOFF::GetSymtab() {
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (module_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
if (m_symtab_up == nullptr) {
|
||||
ElapsedTime elapsed(module_sp->GetSymtabParseTime());
|
||||
SectionList *sect_list = GetSectionList();
|
||||
m_symtab_up = std::make_unique<Symtab>(this);
|
||||
std::lock_guard<std::recursive_mutex> guard(m_symtab_up->GetMutex());
|
||||
|
||||
offset = 0;
|
||||
std::string symbol_name;
|
||||
Symbol *symbols = symtab.Resize(num_syms);
|
||||
for (uint32_t i = 0; i < num_syms; ++i) {
|
||||
coff_symbol_t symbol;
|
||||
const uint32_t symbol_offset = offset;
|
||||
const char *symbol_name_cstr = nullptr;
|
||||
// If the first 4 bytes of the symbol string are zero, then they
|
||||
// are followed by a 4-byte string table offset. Else these
|
||||
// 8 bytes contain the symbol name
|
||||
if (symtab_data.GetU32(&offset) == 0) {
|
||||
// Long string that doesn't fit into the symbol table name, so
|
||||
// now we must read the 4 byte string table offset
|
||||
uint32_t strtab_offset = symtab_data.GetU32(&offset);
|
||||
symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
|
||||
symbol_name.assign(symbol_name_cstr);
|
||||
} else {
|
||||
// Short string that fits into the symbol table name which is 8
|
||||
// bytes
|
||||
offset += sizeof(symbol.name) - 4; // Skip remaining
|
||||
symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
|
||||
if (symbol_name_cstr == nullptr)
|
||||
break;
|
||||
symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
|
||||
}
|
||||
symbol.value = symtab_data.GetU32(&offset);
|
||||
symbol.sect = symtab_data.GetU16(&offset);
|
||||
symbol.type = symtab_data.GetU16(&offset);
|
||||
symbol.storage = symtab_data.GetU8(&offset);
|
||||
symbol.naux = symtab_data.GetU8(&offset);
|
||||
symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
|
||||
if ((int16_t)symbol.sect >= 1) {
|
||||
Address symbol_addr(sect_list->FindSectionByID(symbol.sect),
|
||||
symbol.value);
|
||||
symbols[i].GetAddressRef() = symbol_addr;
|
||||
symbols[i].SetType(MapSymbolType(symbol.type));
|
||||
}
|
||||
const uint32_t num_syms = m_coff_header.nsyms;
|
||||
|
||||
if (symbol.naux > 0) {
|
||||
i += symbol.naux;
|
||||
offset += symbol.naux * symbol_size;
|
||||
if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
|
||||
const uint32_t symbol_size = 18;
|
||||
const size_t symbol_data_size = num_syms * symbol_size;
|
||||
// Include the 4-byte string table size at the end of the symbols
|
||||
DataExtractor symtab_data =
|
||||
ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
|
||||
lldb::offset_t offset = symbol_data_size;
|
||||
const uint32_t strtab_size = symtab_data.GetU32(&offset);
|
||||
if (strtab_size > 0) {
|
||||
DataExtractor strtab_data = ReadImageData(
|
||||
m_coff_header.symoff + symbol_data_size, strtab_size);
|
||||
|
||||
offset = 0;
|
||||
std::string symbol_name;
|
||||
Symbol *symbols = m_symtab_up->Resize(num_syms);
|
||||
for (uint32_t i = 0; i < num_syms; ++i) {
|
||||
coff_symbol_t symbol;
|
||||
const uint32_t symbol_offset = offset;
|
||||
const char *symbol_name_cstr = nullptr;
|
||||
// If the first 4 bytes of the symbol string are zero, then they
|
||||
// are followed by a 4-byte string table offset. Else these
|
||||
// 8 bytes contain the symbol name
|
||||
if (symtab_data.GetU32(&offset) == 0) {
|
||||
// Long string that doesn't fit into the symbol table name, so
|
||||
// now we must read the 4 byte string table offset
|
||||
uint32_t strtab_offset = symtab_data.GetU32(&offset);
|
||||
symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
|
||||
symbol_name.assign(symbol_name_cstr);
|
||||
} else {
|
||||
// Short string that fits into the symbol table name which is 8
|
||||
// bytes
|
||||
offset += sizeof(symbol.name) - 4; // Skip remaining
|
||||
symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
|
||||
if (symbol_name_cstr == nullptr)
|
||||
break;
|
||||
symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
|
||||
}
|
||||
symbol.value = symtab_data.GetU32(&offset);
|
||||
symbol.sect = symtab_data.GetU16(&offset);
|
||||
symbol.type = symtab_data.GetU16(&offset);
|
||||
symbol.storage = symtab_data.GetU8(&offset);
|
||||
symbol.naux = symtab_data.GetU8(&offset);
|
||||
symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
|
||||
if ((int16_t)symbol.sect >= 1) {
|
||||
Address symbol_addr(sect_list->FindSectionByID(symbol.sect),
|
||||
symbol.value);
|
||||
symbols[i].GetAddressRef() = symbol_addr;
|
||||
symbols[i].SetType(MapSymbolType(symbol.type));
|
||||
}
|
||||
|
||||
if (symbol.naux > 0) {
|
||||
i += symbol.naux;
|
||||
offset += symbol.naux * symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read export header
|
||||
if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
|
||||
m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
|
||||
m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
|
||||
export_directory_entry export_table;
|
||||
uint32_t data_start =
|
||||
m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
|
||||
|
||||
DataExtractor symtab_data = ReadImageDataByRVA(
|
||||
data_start, m_coff_header_opt.data_dirs[0].vmsize);
|
||||
lldb::offset_t offset = 0;
|
||||
|
||||
// Read export_table header
|
||||
export_table.characteristics = symtab_data.GetU32(&offset);
|
||||
export_table.time_date_stamp = symtab_data.GetU32(&offset);
|
||||
export_table.major_version = symtab_data.GetU16(&offset);
|
||||
export_table.minor_version = symtab_data.GetU16(&offset);
|
||||
export_table.name = symtab_data.GetU32(&offset);
|
||||
export_table.base = symtab_data.GetU32(&offset);
|
||||
export_table.number_of_functions = symtab_data.GetU32(&offset);
|
||||
export_table.number_of_names = symtab_data.GetU32(&offset);
|
||||
export_table.address_of_functions = symtab_data.GetU32(&offset);
|
||||
export_table.address_of_names = symtab_data.GetU32(&offset);
|
||||
export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
|
||||
|
||||
bool has_ordinal = export_table.address_of_name_ordinals != 0;
|
||||
|
||||
lldb::offset_t name_offset = export_table.address_of_names - data_start;
|
||||
lldb::offset_t name_ordinal_offset =
|
||||
export_table.address_of_name_ordinals - data_start;
|
||||
|
||||
Symbol *symbols = m_symtab_up->Resize(export_table.number_of_names);
|
||||
|
||||
std::string symbol_name;
|
||||
|
||||
// Read each export table entry
|
||||
for (size_t i = 0; i < export_table.number_of_names; ++i) {
|
||||
uint32_t name_ordinal =
|
||||
has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
|
||||
uint32_t name_address = symtab_data.GetU32(&name_offset);
|
||||
|
||||
const char *symbol_name_cstr =
|
||||
symtab_data.PeekCStr(name_address - data_start);
|
||||
symbol_name.assign(symbol_name_cstr);
|
||||
|
||||
lldb::offset_t function_offset = export_table.address_of_functions -
|
||||
data_start +
|
||||
sizeof(uint32_t) * name_ordinal;
|
||||
uint32_t function_rva = symtab_data.GetU32(&function_offset);
|
||||
|
||||
Address symbol_addr(m_coff_header_opt.image_base + function_rva,
|
||||
sect_list);
|
||||
symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
|
||||
symbols[i].GetAddressRef() = symbol_addr;
|
||||
symbols[i].SetType(lldb::eSymbolTypeCode);
|
||||
symbols[i].SetDebug(true);
|
||||
}
|
||||
}
|
||||
m_symtab_up->CalculateSymbolSizes();
|
||||
}
|
||||
}
|
||||
|
||||
// Read export header
|
||||
if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
|
||||
m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
|
||||
m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
|
||||
export_directory_entry export_table;
|
||||
uint32_t data_start =
|
||||
m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
|
||||
|
||||
DataExtractor symtab_data = ReadImageDataByRVA(
|
||||
data_start, m_coff_header_opt.data_dirs[0].vmsize);
|
||||
lldb::offset_t offset = 0;
|
||||
|
||||
// Read export_table header
|
||||
export_table.characteristics = symtab_data.GetU32(&offset);
|
||||
export_table.time_date_stamp = symtab_data.GetU32(&offset);
|
||||
export_table.major_version = symtab_data.GetU16(&offset);
|
||||
export_table.minor_version = symtab_data.GetU16(&offset);
|
||||
export_table.name = symtab_data.GetU32(&offset);
|
||||
export_table.base = symtab_data.GetU32(&offset);
|
||||
export_table.number_of_functions = symtab_data.GetU32(&offset);
|
||||
export_table.number_of_names = symtab_data.GetU32(&offset);
|
||||
export_table.address_of_functions = symtab_data.GetU32(&offset);
|
||||
export_table.address_of_names = symtab_data.GetU32(&offset);
|
||||
export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);
|
||||
|
||||
bool has_ordinal = export_table.address_of_name_ordinals != 0;
|
||||
|
||||
lldb::offset_t name_offset = export_table.address_of_names - data_start;
|
||||
lldb::offset_t name_ordinal_offset =
|
||||
export_table.address_of_name_ordinals - data_start;
|
||||
|
||||
Symbol *symbols = symtab.Resize(export_table.number_of_names);
|
||||
|
||||
std::string symbol_name;
|
||||
|
||||
// Read each export table entry
|
||||
for (size_t i = 0; i < export_table.number_of_names; ++i) {
|
||||
uint32_t name_ordinal =
|
||||
has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
|
||||
uint32_t name_address = symtab_data.GetU32(&name_offset);
|
||||
|
||||
const char *symbol_name_cstr =
|
||||
symtab_data.PeekCStr(name_address - data_start);
|
||||
symbol_name.assign(symbol_name_cstr);
|
||||
|
||||
lldb::offset_t function_offset = export_table.address_of_functions -
|
||||
data_start +
|
||||
sizeof(uint32_t) * name_ordinal;
|
||||
uint32_t function_rva = symtab_data.GetU32(&function_offset);
|
||||
|
||||
Address symbol_addr(m_coff_header_opt.image_base + function_rva,
|
||||
sect_list);
|
||||
symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
|
||||
symbols[i].GetAddressRef() = symbol_addr;
|
||||
symbols[i].SetType(lldb::eSymbolTypeCode);
|
||||
symbols[i].SetDebug(true);
|
||||
}
|
||||
}
|
||||
return m_symtab_up.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<CallFrameInfo> ObjectFilePECOFF::CreateCallFrameInfo() {
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
// virtual lldb_private::AddressClass
|
||||
// GetAddressClass (lldb::addr_t file_addr);
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override;
|
||||
lldb_private::Symtab *GetSymtab() override;
|
||||
|
||||
bool IsStripped() override;
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ bool ObjectFileWasm::ParseHeader() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectFileWasm::ParseSymtab(Symtab &symtab) {}
|
||||
Symtab *ObjectFileWasm::GetSymtab() { return nullptr; }
|
||||
|
||||
static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
|
||||
if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) {
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
return AddressClass::eInvalid;
|
||||
}
|
||||
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override;
|
||||
Symtab *GetSymtab() override;
|
||||
|
||||
bool IsStripped() override { return !!GetExternalDebugInfoFileSpec(); }
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
bool IsExecutable() const override { return false; }
|
||||
ArchSpec GetArchitecture() override { return m_arch; }
|
||||
UUID GetUUID() override { return m_uuid; }
|
||||
void ParseSymtab(lldb_private::Symtab &symtab) override {}
|
||||
Symtab *GetSymtab() override { return m_symtab_up.get(); }
|
||||
bool IsStripped() override { return true; }
|
||||
ByteOrder GetByteOrder() const override { return m_arch.GetByteOrder(); }
|
||||
|
||||
|
||||
@@ -500,7 +500,7 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
|
||||
|
||||
for (Symbol &symbol : symbols)
|
||||
symtab.AddSymbol(std::move(symbol));
|
||||
symtab.Finalize();
|
||||
symtab.CalculateSymbolSizes();
|
||||
}
|
||||
|
||||
llvm::Expected<lldb::addr_t>
|
||||
@@ -927,3 +927,4 @@ uint64_t SymbolFileBreakpad::GetDebugInfoSize() {
|
||||
// Breakpad files are all debug info.
|
||||
return m_objfile_sp->GetByteSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -1421,6 +1421,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
|
||||
));
|
||||
}
|
||||
|
||||
symtab.CalculateSymbolSizes();
|
||||
symtab.Finalize();
|
||||
}
|
||||
|
||||
|
||||
@@ -715,20 +715,3 @@ void llvm::format_provider<ObjectFile::Strata>::format(
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Symtab *ObjectFile::GetSymtab() {
|
||||
ModuleSP module_sp(GetModule());
|
||||
if (module_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
|
||||
if (!m_symtab_up) {
|
||||
ElapsedTime elapsed(module_sp->GetSymtabParseTime());
|
||||
m_symtab_up = std::make_unique<Symtab>(this);
|
||||
std::lock_guard<std::recursive_mutex> symtab_guard(
|
||||
m_symtab_up->GetMutex());
|
||||
ParseSymtab(*m_symtab_up);
|
||||
m_symtab_up->Finalize();
|
||||
}
|
||||
}
|
||||
return m_symtab_up.get();
|
||||
}
|
||||
|
||||
@@ -997,15 +997,10 @@ void Symtab::InitAddressIndexes() {
|
||||
}
|
||||
}
|
||||
|
||||
void Symtab::Finalize() {
|
||||
void Symtab::CalculateSymbolSizes() {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||
// Calculate the size of symbols inside InitAddressIndexes.
|
||||
// Size computation happens inside InitAddressIndexes.
|
||||
InitAddressIndexes();
|
||||
// Shrink to fit the symbols so we don't waste memory
|
||||
if (m_symbols.capacity() > m_symbols.size()) {
|
||||
collection new_symbols(m_symbols.begin(), m_symbols.end());
|
||||
m_symbols.swap(new_symbols);
|
||||
}
|
||||
}
|
||||
|
||||
Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) {
|
||||
|
||||
Reference in New Issue
Block a user