diff options
author | Greg Clayton <gclayton@apple.com> | 2013-07-10 01:23:25 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-07-10 01:23:25 +0000 |
commit | 3046e668301ec9df4ead087fdc906877b9dcbf82 (patch) | |
tree | ff149c296cddf3415649f2571282ef53b3554fbd /lldb/source/Plugins/ObjectFile | |
parent | 8978a9dd0a42139809f56b6df47a0663f341918b (diff) | |
download | bcm5719-llvm-3046e668301ec9df4ead087fdc906877b9dcbf82.tar.gz bcm5719-llvm-3046e668301ec9df4ead087fdc906877b9dcbf82.zip |
Cleanup on the unified section list changes. Main changes are:
- ObjectFile::GetSymtab() and ObjectFile::ClearSymtab() no longer takes any flags
- Module coordinates with the object files and contain a unified section list so that object file and symbol file can share sections when they need to, yet contain their own sections.
Other cleanups:
- Fixed Symbol::GetByteSize() to not have the symbol table compute the byte sizes on the fly
- Modified the ObjectFileMachO class to compute symbol sizes all at once efficiently
- Modified the Symtab class to store a file address lookup table for more efficient lookups
- Removed Section::Finalize() and SectionList::Finalize() as they did nothing
- Improved performance of the detection of symbol files that have debug maps by excluding stripped files and core files, debug files, object files and stubs
- Added the ability to tell if an ObjectFile has been stripped with ObjectFile::IsStripped() (used this for the above performance improvement)
llvm-svn: 185990
Diffstat (limited to 'lldb/source/Plugins/ObjectFile')
6 files changed, 667 insertions, 685 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 1045332f0fe..fde83fb43c1 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -513,22 +513,6 @@ ObjectFileELF::GetDependentModules(FileSpecList &files) return num_specs; } -user_id_t -ObjectFileELF::GetSectionIndexByType(unsigned type) -{ - if (!ParseSectionHeaders()) - return 0; - - for (SectionHeaderCollIter sh_pos = m_section_headers.begin(); - sh_pos != m_section_headers.end(); ++sh_pos) - { - if (sh_pos->sh_type == type) - return SectionIndex(sh_pos); - } - - return 0; -} - Address ObjectFileELF::GetImageInfoAddress() { @@ -539,28 +523,27 @@ ObjectFileELF::GetImageInfoAddress() if (!section_list) return Address(); - user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC); - if (!dynsym_id) + // Find the SHT_DYNAMIC (.dynamic) section. + SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true)); + if (!dynsym_section_sp) return Address(); + assert (dynsym_section_sp->GetObjectFile() == this); + user_id_t dynsym_id = dynsym_section_sp->GetID(); const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id); if (!dynsym_hdr) return Address(); - SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id)); - if (dynsym_section_sp) + for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) { - for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) - { - ELFDynamic &symbol = m_dynamic_symbols[i]; + ELFDynamic &symbol = m_dynamic_symbols[i]; - if (symbol.d_tag == DT_DEBUG) - { - // Compute the offset as the number of previous entries plus the - // size of d_tag. - addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); - return Address(dynsym_section_sp, offset); - } + if (symbol.d_tag == DT_DEBUG) + { + // Compute the offset as the number of previous entries plus the + // size of d_tag. + addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); + return Address(dynsym_section_sp, offset); } } @@ -570,26 +553,19 @@ ObjectFileELF::GetImageInfoAddress() lldb_private::Address ObjectFileELF::GetEntryPointAddress () { - SectionList *sections; - addr_t offset; - if (m_entry_point_address.IsValid()) return m_entry_point_address; if (!ParseHeader() || !IsExecutable()) return m_entry_point_address; - sections = GetSectionList(); - offset = m_header.e_entry; + SectionList *section_list = GetSectionList(); + addr_t offset = m_header.e_entry; - if (!sections) - { + if (!section_list) m_entry_point_address.SetOffset(offset); - return m_entry_point_address; - } - - m_entry_point_address.ResolveAddressUsingFileSections(offset, sections); - + else + m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); return m_entry_point_address; } @@ -607,32 +583,22 @@ ObjectFileELF::ParseDependentModules() if (!ParseSectionHeaders()) return 0; - // Locate the dynamic table. - user_id_t dynsym_id = 0; - user_id_t dynstr_id = 0; - for (SectionHeaderCollIter sh_pos = m_section_headers.begin(); - sh_pos != m_section_headers.end(); ++sh_pos) - { - if (sh_pos->sh_type == SHT_DYNAMIC) - { - dynsym_id = SectionIndex(sh_pos); - dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based. - break; - } - } - - if (!(dynsym_id && dynstr_id)) - return 0; - SectionList *section_list = GetSectionList(); if (!section_list) return 0; - // Resolve and load the dynamic table entries and corresponding string - // table. - Section *dynsym = section_list->FindSectionByID(dynsym_id).get(); - Section *dynstr = section_list->FindSectionByID(dynstr_id).get(); - if (!(dynsym && dynstr)) + // Find the SHT_DYNAMIC section. + Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get(); + if (!dynsym) + return 0; + assert (dynsym->GetObjectFile() == this); + + const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID()); + if (!header) + return 0; + // sh_link: section header index of string table used by entries in the section. + Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get(); + if (!dynstr) return 0; DataExtractor dynsym_data; @@ -844,30 +810,6 @@ ObjectFileELF::ParseSectionHeaders() return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc); } -lldb::user_id_t -ObjectFileELF::GetSectionIndexByName(const char *name) -{ - if (!ParseSectionHeaders()) - return 0; - - // Search the collection of section headers for one with a matching name. - for (SectionHeaderCollIter I = m_section_headers.begin(); - I != m_section_headers.end(); ++I) - { - const char *sectionName = I->section_name.AsCString(); - - if (!sectionName) - return 0; - - if (strcmp(name, sectionName) != 0) - continue; - - return SectionIndex(I); - } - - return 0; -} - const ObjectFileELF::ELFSectionHeaderInfo * ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { @@ -880,14 +822,10 @@ ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) return NULL; } - -SectionList * -ObjectFileELF::GetSectionList() +void +ObjectFileELF::CreateSections(SectionList &unified_section_list) { - if (m_sections_ap.get()) - return m_sections_ap.get(); - - if (ParseSectionHeaders()) + if (!m_sections_ap.get() && ParseSectionHeaders()) { m_sections_ap.reset(new SectionList()); @@ -982,40 +920,75 @@ ObjectFileELF::GetSectionList() break; } - SectionSP section_sp(new Section( - GetModule(), // Module to which this section belongs. - this, // ObjectFile to which this section belongs and should read section data from. - SectionIndex(I), // Section ID. - name, // Section name. - sect_type, // Section type. - header.sh_addr, // VM address. - vm_size, // VM size in bytes of this section. - header.sh_offset, // Offset of this section in the file. - file_size, // Size of the section as found in the file. - header.sh_flags)); // Flags for this section. + SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs. + this, // ObjectFile to which this section belongs and should read section data from. + SectionIndex(I), // Section ID. + name, // Section name. + sect_type, // Section type. + header.sh_addr, // VM address. + vm_size, // VM size in bytes of this section. + header.sh_offset, // Offset of this section in the file. + file_size, // Size of the section as found in the file. + header.sh_flags)); // Flags for this section. if (is_thread_specific) section_sp->SetIsThreadSpecific (is_thread_specific); m_sections_ap->AddSection(section_sp); } - - m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches } - return m_sections_ap.get(); + if (m_sections_ap.get()) + { + if (GetType() == eTypeDebugInfo) + { + static const SectionType g_sections[] = + { + eSectionTypeDWARFDebugAranges, + eSectionTypeDWARFDebugInfo, + eSectionTypeDWARFDebugAbbrev, + eSectionTypeDWARFDebugFrame, + eSectionTypeDWARFDebugLine, + eSectionTypeDWARFDebugStr, + eSectionTypeDWARFDebugLoc, + eSectionTypeDWARFDebugMacInfo, + eSectionTypeDWARFDebugPubNames, + eSectionTypeDWARFDebugPubTypes, + eSectionTypeDWARFDebugRanges, + eSectionTypeELFSymbolTable, + }; + SectionList *elf_section_list = m_sections_ap.get(); + for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx) + { + SectionType section_type = g_sections[idx]; + SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true)); + if (section_sp) + { + SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true)); + if (module_section_sp) + unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp); + else + unified_section_list.AddSection (section_sp); + } + } + } + else + { + unified_section_list = *m_sections_ap; + } + } } +// private unsigned -ObjectFileELF::ParseSymbols(Symtab *symtab, - user_id_t start_id, - SectionList *section_list, - const ELFSectionHeaderInfo *symtab_shdr, - const DataExtractor &symtab_data, - const DataExtractor &strtab_data) +ObjectFileELF::ParseSymbols (Symtab *symtab, + user_id_t start_id, + SectionList *section_list, + const size_t num_symbols, + const DataExtractor &symtab_data, + const DataExtractor &strtab_data) { ELFSymbol symbol; lldb::offset_t offset = 0; - const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize; static ConstString text_section_name(".text"); static ConstString init_section_name(".init"); @@ -1128,21 +1101,18 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, } } - // If the symbol section we've found has no data (SHT_NOBITS), then check the module - // for the main object file and use the section there if it has data. This can happen - // if we're parsing the debug file and the it has no .text section, for example. + // If the symbol section we've found has no data (SHT_NOBITS), then check the module section + // list. This can happen if we're parsing the debug file and it has no .text section, for example. if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0)) { ModuleSP module_sp(GetModule()); if (module_sp) { - ObjectFile *obj_file = module_sp->GetObjectFile(); - // Check if we've got a different object file than ourselves. - if (obj_file && (obj_file != this)) + SectionList *module_section_list = module_sp->GetSectionList(); + if (module_section_list && module_section_list != section_list) { const ConstString §_name = symbol_section_sp->GetName(); - SectionList *obj_file_section_list = obj_file->GetSectionList(); - lldb::SectionSP section_sp (obj_file_section_list->FindSectionByName (sect_name)); + lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name)); if (section_sp && section_sp->GetFileSize()) { symbol_section_sp = section_sp; @@ -1178,32 +1148,46 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, } unsigned -ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, user_id_t symtab_id) +ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab) { - // Parse in the section list if needed. - SectionList *section_list = GetSectionList(); + if (symtab->GetObjectFile() != this) + { + // If the symbol table section is owned by a different object file, have it do the + // parsing. + ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile()); + return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab); + } + + // Get section list for this object file. + SectionList *section_list = m_sections_ap.get(); if (!section_list) return 0; - const ELFSectionHeaderInfo *symtab_hdr = &m_section_headers[symtab_id - 1]; + user_id_t symtab_id = symtab->GetID(); + const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id); assert(symtab_hdr->sh_type == SHT_SYMTAB || symtab_hdr->sh_type == SHT_DYNSYM); + // sh_link: section header index of associated string table. // Section ID's are ones based. user_id_t strtab_id = symtab_hdr->sh_link + 1; - - Section *symtab = section_list->FindSectionByID(symtab_id).get(); Section *strtab = section_list->FindSectionByID(strtab_id).get(); + unsigned num_symbols = 0; if (symtab && strtab) { + assert (symtab->GetObjectFile() == this); + assert (strtab->GetObjectFile() == this); + DataExtractor symtab_data; DataExtractor strtab_data; if (ReadSectionData(symtab, symtab_data) && ReadSectionData(strtab, strtab_data)) { + size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize; + num_symbols = ParseSymbols(symbol_table, start_id, - section_list, symtab_hdr, + section_list, num_symbols, symtab_data, strtab_data); } } @@ -1217,17 +1201,15 @@ ObjectFileELF::ParseDynamicSymbols() if (m_dynamic_symbols.size()) return m_dynamic_symbols.size(); - user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC); - if (!dyn_id) - return 0; - SectionList *section_list = GetSectionList(); if (!section_list) return 0; - Section *dynsym = section_list->FindSectionByID(dyn_id).get(); + // Find the SHT_DYNAMIC section. + Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get(); if (!dynsym) return 0; + assert (dynsym->GetObjectFile() == this); ELFDynamic symbol; DataExtractor dynsym_data; @@ -1360,7 +1342,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, { assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); - // The link field points to the associated symbol table. The info field + // The link field points to the associated symbol table. The info field // points to the section holding the plt. user_id_t symtab_id = rel_hdr->sh_link; user_id_t plt_id = rel_hdr->sh_info; @@ -1380,7 +1362,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, if (!sym_hdr) return 0; - SectionList *section_list = GetSectionList(); + SectionList *section_list = m_sections_ap.get(); if (!section_list) return 0; @@ -1396,6 +1378,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, if (!symtab) return 0; + // sh_link points to associated string table. Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get(); if (!strtab) return 0; @@ -1430,82 +1413,68 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, } Symtab * -ObjectFileELF::GetSymtab(uint32_t flags) +ObjectFileELF::GetSymtab() { ModuleSP module_sp(GetModule()); - if (module_sp) - { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (!module_sp) + return NULL; - bool from_unified_section_list = !!(flags & eSymtabFromUnifiedSectionList); - SectionList *section_list = from_unified_section_list ? module_sp->GetUnifiedSectionList() : GetSectionList(); + // 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->GetSymtab(); + + if (m_symtab_ap.get() == NULL) + { + SectionList *section_list = GetSectionList(); if (!section_list) return NULL; - // If we're doing the unified section list and it has been modified, then clear our - // cache and reload the symbols. If needed, we could check on only the sections that - // we use to create the symbol table... - std::unique_ptr<lldb_private::Symtab> &symtab_ap = from_unified_section_list ? m_symtab_unified_ap : m_symtab_ap; - if (from_unified_section_list && (m_symtab_unified_revisionid != section_list->GetRevisionID())) - { - symtab_ap.reset(); - m_symtab_unified_revisionid = section_list->GetRevisionID(); - } - else if (symtab_ap.get()) - { - return symtab_ap.get(); - } + uint64_t symbol_id = 0; + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); - Symtab *symbol_table = new Symtab(this); - symtab_ap.reset(symbol_table); + m_symtab_ap.reset(new Symtab(this)); // 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 *section_sym = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get(); - if (!section_sym) + Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get(); + if (!symtab) { // The symtab section is non-allocable and can be stripped, so if it doesn't exist // then use the dynsym section which should always be there. - section_sym = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get(); + symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get(); } + if (symtab) + symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab); - uint64_t symbol_id = 0; - if (section_sym) + // Synthesize trampoline symbols to help navigate the PLT. + const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); + if (symbol) { - user_id_t section_id = section_sym->GetID(); - ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section_sym->GetObjectFile()); - - symbol_id += obj_file_elf->ParseSymbolTable (symbol_table, symbol_id, section_id); - } - - Section *section = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get(); - if (section) - { - ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section->GetObjectFile()); - - // Synthesize trampoline symbols to help navigate the PLT. - const ELFDynamic *symbol = obj_file_elf->FindDynamicSymbol(DT_JMPREL); - if (symbol) + addr_t addr = symbol->d_ptr; + Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get(); + if (reloc_section) { - 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 = obj_file_elf->GetSectionHeaderByIndex(reloc_id); - assert(reloc_header); + user_id_t reloc_id = reloc_section->GetID(); + const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id); + assert(reloc_header); - obj_file_elf->ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id); - } + ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id); } } - - return symbol_table; } - return NULL; + return m_symtab_ap.get(); +} + +bool +ObjectFileELF::IsStripped () +{ + // TODO: determine this for ELF + return false; } //===----------------------------------------------------------------------===// diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index a6e3cbb3fd9..e186fc310ac 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -100,10 +100,13 @@ public: GetAddressByteSize() const; virtual lldb_private::Symtab * - GetSymtab(uint32_t flags = 0); + GetSymtab(); - virtual lldb_private::SectionList * - GetSectionList(); + virtual bool + IsStripped (); + + virtual void + CreateSections (lldb_private::SectionList &unified_section_list); virtual void Dump(lldb_private::Stream *s); @@ -232,14 +235,14 @@ private: unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id, - lldb::user_id_t symtab_id); + lldb_private::Section *symtab); /// Helper routine for ParseSymbolTable(). unsigned ParseSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id, lldb_private::SectionList *section_list, - const ELFSectionHeaderInfo *symtab_shdr, + const size_t num_symbols, const lldb_private::DataExtractor &symtab_data, const lldb_private::DataExtractor &strtab_data); @@ -252,17 +255,6 @@ private: const ELFSectionHeaderInfo *rela_hdr, lldb::user_id_t section_id); - /// Utility method for looking up a section given its name. Returns the - /// index of the corresponding section or zero if no section with the given - /// name can be found (note that section indices are always 1 based, and so - /// section index 0 is never valid). - lldb::user_id_t - GetSectionIndexByName(const char *name); - - // Returns the ID of the first section that has the given type. - lldb::user_id_t - GetSectionIndexByType(unsigned type); - /// Returns the section header with the given id or NULL. const ELFSectionHeaderInfo * GetSectionHeaderByIndex(lldb::user_id_t id); diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index c59da7b16a1..bbe2aacd280 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -895,7 +895,7 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr) } Symtab * -ObjectFileMachO::GetSymtab(uint32_t flags) +ObjectFileMachO::GetSymtab() { ModuleSP module_sp(GetModule()); if (module_sp) @@ -905,409 +905,462 @@ ObjectFileMachO::GetSymtab(uint32_t flags) { m_symtab_ap.reset(new Symtab(this)); Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); - ParseSymtab (true); + ParseSymtab (); m_symtab_ap->Finalize (); } } return m_symtab_ap.get(); } - -SectionList * -ObjectFileMachO::GetSectionList() +bool +ObjectFileMachO::IsStripped () { - ModuleSP module_sp(GetModule()); - if (module_sp) + if (m_dysymtab.cmd == 0) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); - if (m_sections_ap.get() == NULL) + ModuleSP module_sp(GetModule()); + if (module_sp) { - m_sections_ap.reset(new SectionList()); - ParseSections(); + lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); + for (uint32_t i=0; i<m_header.ncmds; ++i) + { + const lldb::offset_t load_cmd_offset = offset; + + load_command lc; + if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL) + break; + if (lc.cmd == LoadCommandDynamicSymtabInfo) + { + m_dysymtab.cmd = lc.cmd; + m_dysymtab.cmdsize = lc.cmdsize; + if (m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2) == NULL) + { + // Clear m_dysymtab if we were unable to read all items from the load command + ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); + } + } + offset = load_cmd_offset + lc.cmdsize; + } } } - return m_sections_ap.get(); + if (m_dysymtab.cmd) + return m_dysymtab.nlocalsym == 0; + return false; } - -size_t -ObjectFileMachO::ParseSections () +void +ObjectFileMachO::CreateSections (SectionList &unified_section_list) { - lldb::user_id_t segID = 0; - lldb::user_id_t sectID = 0; - lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); - uint32_t i; - const bool is_core = GetType() == eTypeCoreFile; - //bool dump_sections = false; - ModuleSP module_sp (GetModule()); - // First look up any LC_ENCRYPTION_INFO load commands - typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges; - EncryptedFileRanges encrypted_file_ranges; - encryption_info_command encryption_cmd; - for (i=0; i<m_header.ncmds; ++i) + if (!m_sections_ap.get()) { - const lldb::offset_t load_cmd_offset = offset; - if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL) - break; - - if (encryption_cmd.cmd == LoadCommandEncryptionInfo) + m_sections_ap.reset(new SectionList()); + + const bool is_dsym = (m_header.filetype == HeaderFileTypeDSYM); + lldb::user_id_t segID = 0; + lldb::user_id_t sectID = 0; + lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); + uint32_t i; + const bool is_core = GetType() == eTypeCoreFile; + //bool dump_sections = false; + ModuleSP module_sp (GetModule()); + // First look up any LC_ENCRYPTION_INFO load commands + typedef RangeArray<uint32_t, uint32_t, 8> EncryptedFileRanges; + EncryptedFileRanges encrypted_file_ranges; + encryption_info_command encryption_cmd; + for (i=0; i<m_header.ncmds; ++i) { - if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) + const lldb::offset_t load_cmd_offset = offset; + if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL) + break; + + if (encryption_cmd.cmd == LoadCommandEncryptionInfo) { - if (encryption_cmd.cryptid != 0) + if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3)) { - EncryptedFileRanges::Entry entry; - entry.SetRangeBase(encryption_cmd.cryptoff); - entry.SetByteSize(encryption_cmd.cryptsize); - encrypted_file_ranges.Append(entry); + if (encryption_cmd.cryptid != 0) + { + EncryptedFileRanges::Entry entry; + entry.SetRangeBase(encryption_cmd.cryptoff); + entry.SetByteSize(encryption_cmd.cryptsize); + encrypted_file_ranges.Append(entry); + } } } + offset = load_cmd_offset + encryption_cmd.cmdsize; } - offset = load_cmd_offset + encryption_cmd.cmdsize; - } - - offset = MachHeaderSizeFromMagic(m_header.magic); - struct segment_command_64 load_cmd; - for (i=0; i<m_header.ncmds; ++i) - { - const lldb::offset_t load_cmd_offset = offset; - if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) - break; + offset = MachHeaderSizeFromMagic(m_header.magic); - if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64) + struct segment_command_64 load_cmd; + for (i=0; i<m_header.ncmds; ++i) { - if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16)) + const lldb::offset_t load_cmd_offset = offset; + if (m_data.GetU32(&offset, &load_cmd, 2) == NULL) + break; + + if (load_cmd.cmd == LoadCommandSegment32 || load_cmd.cmd == LoadCommandSegment64) { - load_cmd.vmaddr = m_data.GetAddress(&offset); - load_cmd.vmsize = m_data.GetAddress(&offset); - load_cmd.fileoff = m_data.GetAddress(&offset); - load_cmd.filesize = m_data.GetAddress(&offset); - if (m_length != 0 && load_cmd.filesize != 0) + if (m_data.GetU8(&offset, (uint8_t*)load_cmd.segname, 16)) { - if (load_cmd.fileoff > m_length) + bool add_section = true; + bool add_to_unified = true; + ConstString const_segname (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname))); + + SectionSP unified_section_sp(unified_section_list.FindSectionByName(const_segname)); + if (is_dsym && unified_section_sp) { - // We have a load command that says it extends past the end of hte file. This is likely - // a corrupt file. We don't have any way to return an error condition here (this method - // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do - // is null out the SectionList vector and if a process has been set up, dump a message - // to stdout. The most common case here is core file debugging with a truncated file. - const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; - GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")", - i, - lc_segment_name, - load_cmd.fileoff, - m_length); - - load_cmd.fileoff = 0; - load_cmd.filesize = 0; + if (const_segname == GetSegmentNameLINKEDIT()) + { + // We need to keep the __LINKEDIT segment private to this object file only + add_to_unified = false; + } + else + { + // This is the dSYM file and this section has already been created by + // the object file, no need to create it. + add_section = false; + } } - - if (load_cmd.fileoff + load_cmd.filesize > m_length) + load_cmd.vmaddr = m_data.GetAddress(&offset); + load_cmd.vmsize = m_data.GetAddress(&offset); + load_cmd.fileoff = m_data.GetAddress(&offset); + load_cmd.filesize = m_data.GetAddress(&offset); + if (m_length != 0 && load_cmd.filesize != 0) { - // We have a load command that says it extends past the end of hte file. This is likely - // a corrupt file. We don't have any way to return an error condition here (this method - // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do - // is null out the SectionList vector and if a process has been set up, dump a message - // to stdout. The most common case here is core file debugging with a truncated file. - const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; - GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated", - i, - lc_segment_name, - load_cmd.fileoff + load_cmd.filesize, - m_length); + if (load_cmd.fileoff > m_length) + { + // We have a load command that says it extends past the end of hte file. This is likely + // a corrupt file. We don't have any way to return an error condition here (this method + // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do + // is null out the SectionList vector and if a process has been set up, dump a message + // to stdout. The most common case here is core file debugging with a truncated file. + const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; + GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 ")", + i, + lc_segment_name, + load_cmd.fileoff, + m_length); + + load_cmd.fileoff = 0; + load_cmd.filesize = 0; + } - // Tuncase the length - load_cmd.filesize = m_length - load_cmd.fileoff; + if (load_cmd.fileoff + load_cmd.filesize > m_length) + { + // We have a load command that says it extends past the end of hte file. This is likely + // a corrupt file. We don't have any way to return an error condition here (this method + // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do + // is null out the SectionList vector and if a process has been set up, dump a message + // to stdout. The most common case here is core file debugging with a truncated file. + const char *lc_segment_name = load_cmd.cmd == LoadCommandSegment64 ? "LC_SEGMENT_64" : "LC_SEGMENT"; + GetModule()->ReportError("is a corrupt mach-o file: load command %u %s has a fileoff + filesize (0x%" PRIx64 ") that extends beyond the end of the file (0x%" PRIx64 "), the segment will be truncated", + i, + lc_segment_name, + load_cmd.fileoff + load_cmd.filesize, + m_length); + + // Tuncase the length + load_cmd.filesize = m_length - load_cmd.fileoff; + } } - } - if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) - { + if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) + { - const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0; + const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0; - // Keep a list of mach segments around in case we need to - // get at data that isn't stored in the abstracted Sections. - m_mach_segments.push_back (load_cmd); + // Keep a list of mach segments around in case we need to + // get at data that isn't stored in the abstracted Sections. + m_mach_segments.push_back (load_cmd); - ConstString segment_name (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname))); - // Use a segment ID of the segment index shifted left by 8 so they - // never conflict with any of the sections. - SectionSP segment_sp; - if (segment_name || is_core) - { - segment_sp.reset(new Section (module_sp, // Module to which this section belongs - this, // Object file to which this sections belongs - ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible - segment_name, // Name of this section - eSectionTypeContainer, // This section is a container of other sections. - load_cmd.vmaddr, // File VM address == addresses as they are found in the object file - load_cmd.vmsize, // VM size in bytes of this section - load_cmd.fileoff, // Offset to the data for this section in the file - load_cmd.filesize, // Size in bytes of this section as found in the the file - load_cmd.flags)); // Flags for this section - - segment_sp->SetIsEncrypted (segment_is_encrypted); - m_sections_ap->AddSection(segment_sp); - } + // Use a segment ID of the segment index shifted left by 8 so they + // never conflict with any of the sections. + SectionSP segment_sp; + if (add_section && (const_segname || is_core)) + { + segment_sp.reset(new Section (module_sp, // Module to which this section belongs + this, // Object file to which this sections belongs + ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible + const_segname, // Name of this section + eSectionTypeContainer, // This section is a container of other sections. + load_cmd.vmaddr, // File VM address == addresses as they are found in the object file + load_cmd.vmsize, // VM size in bytes of this section + load_cmd.fileoff, // Offset to the data for this section in the file + load_cmd.filesize, // Size in bytes of this section as found in the the file + load_cmd.flags)); // Flags for this section + + segment_sp->SetIsEncrypted (segment_is_encrypted); + m_sections_ap->AddSection(segment_sp); + if (add_to_unified) + unified_section_list.AddSection(segment_sp); + } + else if (unified_section_sp) + { + m_sections_ap->AddSection(unified_section_sp); + } - struct section_64 sect64; - ::memset (§64, 0, sizeof(sect64)); - // Push a section into our mach sections for the section at - // index zero (NListSectionNoSection) if we don't have any - // mach sections yet... - if (m_mach_sections.empty()) - m_mach_sections.push_back(sect64); - uint32_t segment_sect_idx; - const lldb::user_id_t first_segment_sectID = sectID + 1; + struct section_64 sect64; + ::memset (§64, 0, sizeof(sect64)); + // Push a section into our mach sections for the section at + // index zero (NListSectionNoSection) if we don't have any + // mach sections yet... + if (m_mach_sections.empty()) + m_mach_sections.push_back(sect64); + uint32_t segment_sect_idx; + const lldb::user_id_t first_segment_sectID = sectID + 1; - const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8; - for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx) - { - if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL) - break; - if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL) - break; - sect64.addr = m_data.GetAddress(&offset); - sect64.size = m_data.GetAddress(&offset); + const uint32_t num_u32s = load_cmd.cmd == LoadCommandSegment32 ? 7 : 8; + for (segment_sect_idx=0; segment_sect_idx<load_cmd.nsects; ++segment_sect_idx) + { + if (m_data.GetU8(&offset, (uint8_t*)sect64.sectname, sizeof(sect64.sectname)) == NULL) + break; + if (m_data.GetU8(&offset, (uint8_t*)sect64.segname, sizeof(sect64.segname)) == NULL) + break; + sect64.addr = m_data.GetAddress(&offset); + sect64.size = m_data.GetAddress(&offset); - if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL) - break; + if (m_data.GetU32(&offset, §64.offset, num_u32s) == NULL) + break; - // Keep a list of mach sections around in case we need to - // get at data that isn't stored in the abstracted Sections. - m_mach_sections.push_back (sect64); + // Keep a list of mach sections around in case we need to + // get at data that isn't stored in the abstracted Sections. + m_mach_sections.push_back (sect64); - ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname))); - if (!segment_name) - { - // We have a segment with no name so we need to conjure up - // segments that correspond to the section's segname if there - // isn't already such a section. If there is such a section, - // we resize the section so that it spans all sections. - // We also mark these sections as fake so address matches don't - // hit if they land in the gaps between the child sections. - segment_name.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname)); - segment_sp = m_sections_ap->FindSectionByName (segment_name); - if (segment_sp.get()) + if (add_section) { - Section *segment = segment_sp.get(); - // Grow the section size as needed. - const lldb::addr_t sect64_min_addr = sect64.addr; - const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size; - const lldb::addr_t curr_seg_byte_size = segment->GetByteSize(); - const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress(); - const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size; - if (sect64_min_addr >= curr_seg_min_addr) + ConstString section_name (sect64.sectname, std::min<size_t>(strlen(sect64.sectname), sizeof(sect64.sectname))); + if (!const_segname) { - const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr; - // Only grow the section size if needed - if (new_seg_byte_size > curr_seg_byte_size) - segment->SetByteSize (new_seg_byte_size); + // We have a segment with no name so we need to conjure up + // segments that correspond to the section's segname if there + // isn't already such a section. If there is such a section, + // we resize the section so that it spans all sections. + // We also mark these sections as fake so address matches don't + // hit if they land in the gaps between the child sections. + const_segname.SetTrimmedCStringWithLength(sect64.segname, sizeof(sect64.segname)); + segment_sp = unified_section_list.FindSectionByName (const_segname); + if (segment_sp.get()) + { + Section *segment = segment_sp.get(); + // Grow the section size as needed. + const lldb::addr_t sect64_min_addr = sect64.addr; + const lldb::addr_t sect64_max_addr = sect64_min_addr + sect64.size; + const lldb::addr_t curr_seg_byte_size = segment->GetByteSize(); + const lldb::addr_t curr_seg_min_addr = segment->GetFileAddress(); + const lldb::addr_t curr_seg_max_addr = curr_seg_min_addr + curr_seg_byte_size; + if (sect64_min_addr >= curr_seg_min_addr) + { + const lldb::addr_t new_seg_byte_size = sect64_max_addr - curr_seg_min_addr; + // Only grow the section size if needed + if (new_seg_byte_size > curr_seg_byte_size) + segment->SetByteSize (new_seg_byte_size); + } + else + { + // We need to change the base address of the segment and + // adjust the child section offsets for all existing children. + const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr; + segment->Slide(slide_amount, false); + segment->GetChildren().Slide(-slide_amount, false); + segment->SetByteSize (curr_seg_max_addr - sect64_min_addr); + } + + // Grow the section size as needed. + if (sect64.offset) + { + const lldb::addr_t segment_min_file_offset = segment->GetFileOffset(); + const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize(); + + const lldb::addr_t section_min_file_offset = sect64.offset; + const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size; + const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset); + const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset; + segment->SetFileOffset (new_file_offset); + segment->SetFileSize (new_file_size); + } + } + else + { + // Create a fake section for the section's named segment + segment_sp.reset(new Section (segment_sp, // Parent section + module_sp, // Module to which this section belongs + this, // Object file to which this section belongs + ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible + const_segname, // Name of this section + eSectionTypeContainer, // This section is a container of other sections. + sect64.addr, // File VM address == addresses as they are found in the object file + sect64.size, // VM size in bytes of this section + sect64.offset, // Offset to the data for this section in the file + sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file + load_cmd.flags)); // Flags for this section + segment_sp->SetIsFake(true); + + m_sections_ap->AddSection(segment_sp); + if (add_to_unified) + unified_section_list.AddSection(segment_sp); + segment_sp->SetIsEncrypted (segment_is_encrypted); + } } - else + assert (segment_sp.get()); + + uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType; + static ConstString g_sect_name_objc_data ("__objc_data"); + static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs"); + static ConstString g_sect_name_objc_selrefs ("__objc_selrefs"); + static ConstString g_sect_name_objc_classrefs ("__objc_classrefs"); + static ConstString g_sect_name_objc_superrefs ("__objc_superrefs"); + static ConstString g_sect_name_objc_const ("__objc_const"); + static ConstString g_sect_name_objc_classlist ("__objc_classlist"); + static ConstString g_sect_name_cfstring ("__cfstring"); + + static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev"); + static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges"); + static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame"); + static ConstString g_sect_name_dwarf_debug_info ("__debug_info"); + static ConstString g_sect_name_dwarf_debug_line ("__debug_line"); + static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc"); + static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo"); + static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames"); + static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes"); + static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges"); + static ConstString g_sect_name_dwarf_debug_str ("__debug_str"); + static ConstString g_sect_name_dwarf_apple_names ("__apple_names"); + static ConstString g_sect_name_dwarf_apple_types ("__apple_types"); + static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac"); + static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc"); + static ConstString g_sect_name_eh_frame ("__eh_frame"); + static ConstString g_sect_name_DATA ("__DATA"); + static ConstString g_sect_name_TEXT ("__TEXT"); + + SectionType sect_type = eSectionTypeOther; + + if (section_name == g_sect_name_dwarf_debug_abbrev) + sect_type = eSectionTypeDWARFDebugAbbrev; + else if (section_name == g_sect_name_dwarf_debug_aranges) + sect_type = eSectionTypeDWARFDebugAranges; + else if (section_name == g_sect_name_dwarf_debug_frame) + sect_type = eSectionTypeDWARFDebugFrame; + else if (section_name == g_sect_name_dwarf_debug_info) + sect_type = eSectionTypeDWARFDebugInfo; + else if (section_name == g_sect_name_dwarf_debug_line) + sect_type = eSectionTypeDWARFDebugLine; + else if (section_name == g_sect_name_dwarf_debug_loc) + sect_type = eSectionTypeDWARFDebugLoc; + else if (section_name == g_sect_name_dwarf_debug_macinfo) + sect_type = eSectionTypeDWARFDebugMacInfo; + else if (section_name == g_sect_name_dwarf_debug_pubnames) + sect_type = eSectionTypeDWARFDebugPubNames; + else if (section_name == g_sect_name_dwarf_debug_pubtypes) + sect_type = eSectionTypeDWARFDebugPubTypes; + else if (section_name == g_sect_name_dwarf_debug_ranges) + sect_type = eSectionTypeDWARFDebugRanges; + else if (section_name == g_sect_name_dwarf_debug_str) + sect_type = eSectionTypeDWARFDebugStr; + else if (section_name == g_sect_name_dwarf_apple_names) + sect_type = eSectionTypeDWARFAppleNames; + else if (section_name == g_sect_name_dwarf_apple_types) + sect_type = eSectionTypeDWARFAppleTypes; + else if (section_name == g_sect_name_dwarf_apple_namespaces) + sect_type = eSectionTypeDWARFAppleNamespaces; + else if (section_name == g_sect_name_dwarf_apple_objc) + sect_type = eSectionTypeDWARFAppleObjC; + else if (section_name == g_sect_name_objc_selrefs) + sect_type = eSectionTypeDataCStringPointers; + else if (section_name == g_sect_name_objc_msgrefs) + sect_type = eSectionTypeDataObjCMessageRefs; + else if (section_name == g_sect_name_eh_frame) + sect_type = eSectionTypeEHFrame; + else if (section_name == g_sect_name_cfstring) + sect_type = eSectionTypeDataObjCCFStrings; + else if (section_name == g_sect_name_objc_data || + section_name == g_sect_name_objc_classrefs || + section_name == g_sect_name_objc_superrefs || + section_name == g_sect_name_objc_const || + section_name == g_sect_name_objc_classlist) { - // We need to change the base address of the segment and - // adjust the child section offsets for all existing children. - const lldb::addr_t slide_amount = sect64_min_addr - curr_seg_min_addr; - segment->Slide(slide_amount, false); - segment->GetChildren().Slide(-slide_amount, false); - segment->SetByteSize (curr_seg_max_addr - sect64_min_addr); + sect_type = eSectionTypeDataPointers; } - // Grow the section size as needed. - if (sect64.offset) + if (sect_type == eSectionTypeOther) { - const lldb::addr_t segment_min_file_offset = segment->GetFileOffset(); - const lldb::addr_t segment_max_file_offset = segment_min_file_offset + segment->GetFileSize(); - - const lldb::addr_t section_min_file_offset = sect64.offset; - const lldb::addr_t section_max_file_offset = section_min_file_offset + sect64.size; - const lldb::addr_t new_file_offset = std::min (section_min_file_offset, segment_min_file_offset); - const lldb::addr_t new_file_size = std::max (section_max_file_offset, segment_max_file_offset) - new_file_offset; - segment->SetFileOffset (new_file_offset); - segment->SetFileSize (new_file_size); + switch (mach_sect_type) + { + // TODO: categorize sections by other flags for regular sections + case SectionTypeRegular: + if (segment_sp->GetName() == g_sect_name_TEXT) + sect_type = eSectionTypeCode; + else if (segment_sp->GetName() == g_sect_name_DATA) + sect_type = eSectionTypeData; + else + sect_type = eSectionTypeOther; + break; + case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break; + case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings + case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals + case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals + case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals + case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers + case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers + case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field + case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization + case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination + case SectionTypeCoalesced: sect_type = eSectionTypeOther; break; + case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break; + case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing + case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals + case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break; + case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break; + default: break; + } } - } - else - { - // Create a fake section for the section's named segment - segment_sp.reset(new Section (segment_sp, // Parent section - module_sp, // Module to which this section belongs - this, // Object file to which this section belongs - ++segID << 8, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible - segment_name, // Name of this section - eSectionTypeContainer, // This section is a container of other sections. - sect64.addr, // File VM address == addresses as they are found in the object file - sect64.size, // VM size in bytes of this section - sect64.offset, // Offset to the data for this section in the file - sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file - load_cmd.flags)); // Flags for this section - segment_sp->SetIsFake(true); - m_sections_ap->AddSection(segment_sp); - segment_sp->SetIsEncrypted (segment_is_encrypted); - } - } - assert (segment_sp.get()); - - uint32_t mach_sect_type = sect64.flags & SectionFlagMaskSectionType; - static ConstString g_sect_name_objc_data ("__objc_data"); - static ConstString g_sect_name_objc_msgrefs ("__objc_msgrefs"); - static ConstString g_sect_name_objc_selrefs ("__objc_selrefs"); - static ConstString g_sect_name_objc_classrefs ("__objc_classrefs"); - static ConstString g_sect_name_objc_superrefs ("__objc_superrefs"); - static ConstString g_sect_name_objc_const ("__objc_const"); - static ConstString g_sect_name_objc_classlist ("__objc_classlist"); - static ConstString g_sect_name_cfstring ("__cfstring"); - - static ConstString g_sect_name_dwarf_debug_abbrev ("__debug_abbrev"); - static ConstString g_sect_name_dwarf_debug_aranges ("__debug_aranges"); - static ConstString g_sect_name_dwarf_debug_frame ("__debug_frame"); - static ConstString g_sect_name_dwarf_debug_info ("__debug_info"); - static ConstString g_sect_name_dwarf_debug_line ("__debug_line"); - static ConstString g_sect_name_dwarf_debug_loc ("__debug_loc"); - static ConstString g_sect_name_dwarf_debug_macinfo ("__debug_macinfo"); - static ConstString g_sect_name_dwarf_debug_pubnames ("__debug_pubnames"); - static ConstString g_sect_name_dwarf_debug_pubtypes ("__debug_pubtypes"); - static ConstString g_sect_name_dwarf_debug_ranges ("__debug_ranges"); - static ConstString g_sect_name_dwarf_debug_str ("__debug_str"); - static ConstString g_sect_name_dwarf_apple_names ("__apple_names"); - static ConstString g_sect_name_dwarf_apple_types ("__apple_types"); - static ConstString g_sect_name_dwarf_apple_namespaces ("__apple_namespac"); - static ConstString g_sect_name_dwarf_apple_objc ("__apple_objc"); - static ConstString g_sect_name_eh_frame ("__eh_frame"); - static ConstString g_sect_name_DATA ("__DATA"); - static ConstString g_sect_name_TEXT ("__TEXT"); - - SectionType sect_type = eSectionTypeOther; - - if (section_name == g_sect_name_dwarf_debug_abbrev) - sect_type = eSectionTypeDWARFDebugAbbrev; - else if (section_name == g_sect_name_dwarf_debug_aranges) - sect_type = eSectionTypeDWARFDebugAranges; - else if (section_name == g_sect_name_dwarf_debug_frame) - sect_type = eSectionTypeDWARFDebugFrame; - else if (section_name == g_sect_name_dwarf_debug_info) - sect_type = eSectionTypeDWARFDebugInfo; - else if (section_name == g_sect_name_dwarf_debug_line) - sect_type = eSectionTypeDWARFDebugLine; - else if (section_name == g_sect_name_dwarf_debug_loc) - sect_type = eSectionTypeDWARFDebugLoc; - else if (section_name == g_sect_name_dwarf_debug_macinfo) - sect_type = eSectionTypeDWARFDebugMacInfo; - else if (section_name == g_sect_name_dwarf_debug_pubnames) - sect_type = eSectionTypeDWARFDebugPubNames; - else if (section_name == g_sect_name_dwarf_debug_pubtypes) - sect_type = eSectionTypeDWARFDebugPubTypes; - else if (section_name == g_sect_name_dwarf_debug_ranges) - sect_type = eSectionTypeDWARFDebugRanges; - else if (section_name == g_sect_name_dwarf_debug_str) - sect_type = eSectionTypeDWARFDebugStr; - else if (section_name == g_sect_name_dwarf_apple_names) - sect_type = eSectionTypeDWARFAppleNames; - else if (section_name == g_sect_name_dwarf_apple_types) - sect_type = eSectionTypeDWARFAppleTypes; - else if (section_name == g_sect_name_dwarf_apple_namespaces) - sect_type = eSectionTypeDWARFAppleNamespaces; - else if (section_name == g_sect_name_dwarf_apple_objc) - sect_type = eSectionTypeDWARFAppleObjC; - else if (section_name == g_sect_name_objc_selrefs) - sect_type = eSectionTypeDataCStringPointers; - else if (section_name == g_sect_name_objc_msgrefs) - sect_type = eSectionTypeDataObjCMessageRefs; - else if (section_name == g_sect_name_eh_frame) - sect_type = eSectionTypeEHFrame; - else if (section_name == g_sect_name_cfstring) - sect_type = eSectionTypeDataObjCCFStrings; - else if (section_name == g_sect_name_objc_data || - section_name == g_sect_name_objc_classrefs || - section_name == g_sect_name_objc_superrefs || - section_name == g_sect_name_objc_const || - section_name == g_sect_name_objc_classlist) - { - sect_type = eSectionTypeDataPointers; - } - if (sect_type == eSectionTypeOther) - { - switch (mach_sect_type) - { - // TODO: categorize sections by other flags for regular sections - case SectionTypeRegular: - if (segment_sp->GetName() == g_sect_name_TEXT) - sect_type = eSectionTypeCode; - else if (segment_sp->GetName() == g_sect_name_DATA) - sect_type = eSectionTypeData; - else - sect_type = eSectionTypeOther; - break; - case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break; - case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings - case SectionType4ByteLiterals: sect_type = eSectionTypeData4; break; // section with only 4 byte literals - case SectionType8ByteLiterals: sect_type = eSectionTypeData8; break; // section with only 8 byte literals - case SectionTypeLiteralPointers: sect_type = eSectionTypeDataPointers; break; // section with only pointers to literals - case SectionTypeNonLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only non-lazy symbol pointers - case SectionTypeLazySymbolPointers: sect_type = eSectionTypeDataPointers; break; // section with only lazy symbol pointers - case SectionTypeSymbolStubs: sect_type = eSectionTypeCode; break; // section with only symbol stubs, byte size of stub in the reserved2 field - case SectionTypeModuleInitFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for initialization - case SectionTypeModuleTermFunctionPointers: sect_type = eSectionTypeDataPointers; break; // section with only function pointers for termination - case SectionTypeCoalesced: sect_type = eSectionTypeOther; break; - case SectionTypeZeroFillLarge: sect_type = eSectionTypeZeroFill; break; - case SectionTypeInterposing: sect_type = eSectionTypeCode; break; // section with only pairs of function pointers for interposing - case SectionType16ByteLiterals: sect_type = eSectionTypeData16; break; // section with only 16 byte literals - case SectionTypeDTraceObjectFormat: sect_type = eSectionTypeDebug; break; - case SectionTypeLazyDylibSymbolPointers: sect_type = eSectionTypeDataPointers; break; - default: break; + SectionSP section_sp(new Section (segment_sp, + module_sp, + this, + ++sectID, + section_name, + sect_type, + sect64.addr - segment_sp->GetFileAddress(), + sect64.size, + sect64.offset, + sect64.offset == 0 ? 0 : sect64.size, + sect64.flags)); + // Set the section to be encrypted to match the segment + + bool section_is_encrypted = false; + if (!segment_is_encrypted && load_cmd.filesize != 0) + section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL; + + section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted); + segment_sp->GetChildren().AddSection(section_sp); + + if (segment_sp->IsFake()) + { + segment_sp.reset(); + const_segname.Clear(); + } } } - - SectionSP section_sp(new Section (segment_sp, - module_sp, - this, - ++sectID, - section_name, - sect_type, - sect64.addr - segment_sp->GetFileAddress(), - sect64.size, - sect64.offset, - sect64.offset == 0 ? 0 : sect64.size, - sect64.flags)); - // Set the section to be encrypted to match the segment - - bool section_is_encrypted = false; - if (!segment_is_encrypted && load_cmd.filesize != 0) - section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL; - - section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted); - segment_sp->GetChildren().AddSection(section_sp); - - if (segment_sp->IsFake()) + if (segment_sp && is_dsym) { - segment_sp.reset(); - segment_name.Clear(); - } - } - if (segment_sp && m_header.filetype == HeaderFileTypeDSYM) - { - if (first_segment_sectID <= sectID) - { - lldb::user_id_t sect_uid; - for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid) + if (first_segment_sectID <= sectID) { - SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid)); - SectionSP next_section_sp; - if (sect_uid + 1 <= sectID) - next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1); - - if (curr_section_sp.get()) + lldb::user_id_t sect_uid; + for (sect_uid = first_segment_sectID; sect_uid <= sectID; ++sect_uid) { - if (curr_section_sp->GetByteSize() == 0) + SectionSP curr_section_sp(segment_sp->GetChildren().FindSectionByID (sect_uid)); + SectionSP next_section_sp; + if (sect_uid + 1 <= sectID) + next_section_sp = segment_sp->GetChildren().FindSectionByID (sect_uid+1); + + if (curr_section_sp.get()) { - if (next_section_sp.get() != NULL) - curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() ); - else - curr_section_sp->SetByteSize ( load_cmd.vmsize ); + if (curr_section_sp->GetByteSize() == 0) + { + if (next_section_sp.get() != NULL) + curr_section_sp->SetByteSize ( next_section_sp->GetFileAddress() - curr_section_sp->GetFileAddress() ); + else + curr_section_sp->SetByteSize ( load_cmd.vmsize ); + } } } } @@ -1315,22 +1368,20 @@ ObjectFileMachO::ParseSections () } } } - } - else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo) - { - m_dysymtab.cmd = load_cmd.cmd; - m_dysymtab.cmdsize = load_cmd.cmdsize; - m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2); - } + else if (load_cmd.cmd == LoadCommandDynamicSymtabInfo) + { + m_dysymtab.cmd = load_cmd.cmd; + m_dysymtab.cmdsize = load_cmd.cmdsize; + m_data.GetU32 (&offset, &m_dysymtab.ilocalsym, (sizeof(m_dysymtab) / sizeof(uint32_t)) - 2); + } - offset = load_cmd_offset + load_cmd.cmdsize; + offset = load_cmd_offset + load_cmd.cmdsize; + } + +// StreamFile s(stdout, false); // REMOVE THIS LINE +// s.Printf ("Sections for %s:\n", m_file.GetPath().c_str());// REMOVE THIS LINE +// m_sections_ap->Dump(&s, NULL, true, UINT32_MAX);// REMOVE THIS LINE } -// if (dump_sections) -// { -// StreamFile s(stdout); -// m_sections_ap->Dump(&s, true); -// } - return sectID; // Return the number of sections we registered with the module } class MachSymtabSectionInfo @@ -1403,7 +1454,7 @@ protected: }; size_t -ObjectFileMachO::ParseSymtab (bool minimize) +ObjectFileMachO::ParseSymtab () { Timer scoped_timer(__PRETTY_FUNCTION__, "ObjectFileMachO::ParseSymtab () module = %s", @@ -2044,8 +2095,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) // We don't really need the end function STAB as it contains the size which // we already placed with the original symbol, so don't add it if we want a // minimal symbol table - if (minimize) - add_nlist = false; + add_nlist = false; } } break; @@ -2067,17 +2117,8 @@ ObjectFileMachO::ParseSymtab (bool minimize) // N_BNSYM // We use the current number of symbols in the symbol table in lieu of // using nlist_idx in case we ever start trimming entries out - if (minimize) - { - // Skip these if we want minimal symbol tables - add_nlist = false; - } - else - { - symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - N_NSYM_indexes.push_back(sym_idx); - type = eSymbolTypeScopeBegin; - } + // Skip these if we want minimal symbol tables + add_nlist = false; break; case StabEndSymbol: @@ -2085,22 +2126,8 @@ ObjectFileMachO::ParseSymtab (bool minimize) // Set the size of the N_BNSYM to the terminating index of this N_ENSYM // so that we can always skip the entire symbol if we need to navigate // more quickly at the source level when parsing STABS - if (minimize) - { - // Skip these if we want minimal symbol tables - add_nlist = false; - } - else - { - if ( !N_NSYM_indexes.empty() ) - { - symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back()); - symbol_ptr->SetByteSize(sym_idx + 1); - symbol_ptr->SetSizeIsSibling(true); - N_NSYM_indexes.pop_back(); - } - type = eSymbolTypeScopeEnd; - } + // Skip these if we want minimal symbol tables + add_nlist = false; break; @@ -2130,15 +2157,14 @@ ObjectFileMachO::ParseSymtab (bool minimize) type = eSymbolTypeSourceFile; if (symbol_name == NULL) { - if (minimize) - add_nlist = false; + add_nlist = false; if (N_SO_index != UINT32_MAX) { // Set the size of the N_SO to the terminating 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->SetByteSize(sym_idx + (minimize ? 0 : 1)); + symbol_ptr->SetByteSize(sym_idx); symbol_ptr->SetSizeIsSibling(true); } N_NSYM_indexes.clear(); @@ -2155,7 +2181,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) const bool N_SO_has_full_path = symbol_name[0] == '/'; if (N_SO_has_full_path) { - if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) + if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) { // We have two consecutive N_SO entries where the first contains a directory // and the second contains a full path. @@ -2170,7 +2196,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) N_SO_index = sym_idx; } } - else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) + else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) { // This is usually the second N_SO entry that contains just the filename, // so here we combine it with the first one if we are minimizing the symbol table @@ -2253,8 +2279,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) type = eSymbolTypeHeaderFile; // We currently don't use the header files on darwin - if (minimize) - add_nlist = false; + add_nlist = false; break; case StabCompilerParameters: @@ -2503,8 +2528,6 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (add_nlist) { uint64_t symbol_value = nlist.n_value; - bool symbol_name_is_mangled = false; - if (symbol_name_non_abi_mangled) { sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled)); @@ -2512,6 +2535,8 @@ ObjectFileMachO::ParseSymtab (bool minimize) } else { + bool symbol_name_is_mangled = false; + if (symbol_name && symbol_name[0] == '_') { symbol_name_is_mangled = symbol_name[1] == '_'; @@ -2521,9 +2546,9 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (symbol_name) { ConstString const_symbol_name(symbol_name); - if (is_gsym) - N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx; sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); + if (is_gsym && is_debug) + N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx; } } if (symbol_section) @@ -2590,8 +2615,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value); if (pos != N_FUN_addr_to_sym_idx.end()) { - if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) || - (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName())) + if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled)) { m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags @@ -2611,8 +2635,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value); if (pos != N_STSYM_addr_to_sym_idx.end()) { - if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) || - (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName())) + if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled)) { m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags @@ -2625,7 +2648,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) else { // Combine N_GSYM stab entries with the non stab symbol - ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetMangledName().GetCString()); + ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()); if (pos != N_GSYM_name_to_sym_idx.end()) { const uint32_t GSYM_sym_idx = pos->second; @@ -2811,8 +2834,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) // We don't really need the end function STAB as it contains the size which // we already placed with the original symbol, so don't add it if we want a // minimal symbol table - if (minimize) - add_nlist = false; + add_nlist = false; } } break; @@ -2834,17 +2856,8 @@ ObjectFileMachO::ParseSymtab (bool minimize) // N_BNSYM // We use the current number of symbols in the symbol table in lieu of // using nlist_idx in case we ever start trimming entries out - if (minimize) - { - // Skip these if we want minimal symbol tables - add_nlist = false; - } - else - { - symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - N_NSYM_indexes.push_back(sym_idx); - type = eSymbolTypeScopeBegin; - } + // Skip these if we want minimal symbol tables + add_nlist = false; break; case StabEndSymbol: @@ -2852,22 +2865,8 @@ ObjectFileMachO::ParseSymtab (bool minimize) // Set the size of the N_BNSYM to the terminating index of this N_ENSYM // so that we can always skip the entire symbol if we need to navigate // more quickly at the source level when parsing STABS - if (minimize) - { - // Skip these if we want minimal symbol tables - add_nlist = false; - } - else - { - if ( !N_NSYM_indexes.empty() ) - { - symbol_ptr = symtab->SymbolAtIndex(N_NSYM_indexes.back()); - symbol_ptr->SetByteSize(sym_idx + 1); - symbol_ptr->SetSizeIsSibling(true); - N_NSYM_indexes.pop_back(); - } - type = eSymbolTypeScopeEnd; - } + // Skip these if we want minimal symbol tables + add_nlist = false; break; @@ -2897,15 +2896,14 @@ ObjectFileMachO::ParseSymtab (bool minimize) type = eSymbolTypeSourceFile; if (symbol_name == NULL) { - if (minimize) - add_nlist = false; + add_nlist = false; if (N_SO_index != UINT32_MAX) { // Set the size of the N_SO to the terminating 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->SetByteSize(sym_idx + (minimize ? 0 : 1)); + symbol_ptr->SetByteSize(sym_idx); symbol_ptr->SetSizeIsSibling(true); } N_NSYM_indexes.clear(); @@ -2922,7 +2920,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) const bool N_SO_has_full_path = symbol_name[0] == '/'; if (N_SO_has_full_path) { - if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) + if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) { // We have two consecutive N_SO entries where the first contains a directory // and the second contains a full path. @@ -2937,7 +2935,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) N_SO_index = sym_idx; } } - else if (minimize && (N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) + else if ((N_SO_index == sym_idx - 1) && ((sym_idx - 1) < num_syms)) { // This is usually the second N_SO entry that contains just the filename, // so here we combine it with the first one if we are minimizing the symbol table @@ -3021,8 +3019,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) type = eSymbolTypeHeaderFile; // We currently don't use the header files on darwin - if (minimize) - add_nlist = false; + add_nlist = false; break; case StabCompilerParameters: @@ -3275,7 +3272,6 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (add_nlist) { uint64_t symbol_value = nlist.n_value; - bool symbol_name_is_mangled = false; if (symbol_name_non_abi_mangled) { @@ -3284,6 +3280,8 @@ ObjectFileMachO::ParseSymtab (bool minimize) } else { + bool symbol_name_is_mangled = false; + if (symbol_name && symbol_name[0] == '_') { symbol_name_is_mangled = symbol_name[1] == '_'; @@ -3293,9 +3291,11 @@ ObjectFileMachO::ParseSymtab (bool minimize) if (symbol_name) { ConstString const_symbol_name(symbol_name); - if (is_gsym) - N_GSYM_name_to_sym_idx[const_symbol_name.GetCString()] = sym_idx; sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); + if (is_gsym && is_debug) + { + N_GSYM_name_to_sym_idx[sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()] = sym_idx; + } } } if (symbol_section) @@ -3357,8 +3357,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) ValueToSymbolIndexMap::const_iterator pos = N_FUN_addr_to_sym_idx.find (nlist.n_value); if (pos != N_FUN_addr_to_sym_idx.end()) { - if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) || - (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName())) + if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled)) { m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags @@ -3378,8 +3377,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) ValueToSymbolIndexMap::const_iterator pos = N_STSYM_addr_to_sym_idx.find (nlist.n_value); if (pos != N_STSYM_addr_to_sym_idx.end()) { - if ((symbol_name_is_mangled == true && sym[sym_idx].GetMangled().GetMangledName() == sym[pos->second].GetMangled().GetMangledName()) || - (symbol_name_is_mangled == false && sym[sym_idx].GetMangled().GetDemangledName() == sym[pos->second].GetMangled().GetDemangledName())) + if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled)) { m_nlist_idx_to_sym_idx[nlist_idx] = pos->second; // We just need the flags from the linker symbol, so put these flags @@ -3392,7 +3390,7 @@ ObjectFileMachO::ParseSymtab (bool minimize) else { // Combine N_GSYM stab entries with the non stab symbol - ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetMangledName().GetCString()); + ConstNameToSymbolIndexMap::const_iterator pos = N_GSYM_name_to_sym_idx.find(sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString()); if (pos != N_GSYM_name_to_sym_idx.end()) { const uint32_t GSYM_sym_idx = pos->second; @@ -3639,6 +3637,16 @@ ObjectFileMachO::ParseSymtab (bool minimize) } } } + +// 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(); } return 0; @@ -3663,8 +3671,9 @@ ObjectFileMachO::Dump (Stream *s) *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; - if (m_sections_ap.get()) - m_sections_ap->Dump(s, NULL, true, UINT32_MAX); + SectionList *sections = GetSectionList(); + if (sections) + sections->Dump(s, NULL, true, UINT32_MAX); if (m_symtab_ap.get()) m_symtab_ap->Dump(s, NULL, eSortOrderNone); diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 65874533ed3..1c0d2ce7e13 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -102,10 +102,13 @@ public: GetAddressClass (lldb::addr_t file_addr); virtual lldb_private::Symtab * - GetSymtab(uint32_t flags = 0); + GetSymtab(); - virtual lldb_private::SectionList * - GetSectionList(); + virtual bool + IsStripped (); + + virtual void + CreateSections (lldb_private::SectionList &unified_section_list); virtual void Dump (lldb_private::Stream *s); @@ -195,10 +198,7 @@ protected: bool m_thread_context_offsets_valid; size_t - ParseSections (); - - size_t - ParseSymtab (bool minimize); + ParseSymtab (); }; diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index ec1aef784c2..7afcd6f49a7 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -511,7 +511,7 @@ ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& // GetNListSymtab //---------------------------------------------------------------------- Symtab * -ObjectFilePECOFF::GetSymtab(uint32_t flags) +ObjectFilePECOFF::GetSymtab() { ModuleSP module_sp(GetModule()); if (module_sp) @@ -597,16 +597,26 @@ ObjectFilePECOFF::GetSymtab(uint32_t flags) } -SectionList * -ObjectFilePECOFF::GetSectionList() +bool +ObjectFilePECOFF::IsStripped () { - ModuleSP module_sp(GetModule()); - if (module_sp) + // TODO: determine this for COFF + return false; +} + + + +void +ObjectFilePECOFF::CreateSections (SectionList &unified_section_list) +{ + if (!m_sections_ap.get()) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); - if (m_sections_ap.get() == NULL) + m_sections_ap.reset(new SectionList()); + + ModuleSP module_sp(GetModule()); + if (module_sp) { - m_sections_ap.reset(new SectionList()); + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); const uint32_t nsects = m_sect_headers.size(); ModuleSP module_sp (GetModule()); for (uint32_t idx = 0; idx<nsects; ++idx) @@ -710,13 +720,11 @@ ObjectFilePECOFF::GetSectionList() //section_sp->SetIsEncrypted (segment_is_encrypted); - m_sections_ap->AddSection(section_sp); + unified_section_list.AddSection(section_sp); + m_sections_ap->AddSection (section_sp); } - - m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches } } - return m_sections_ap.get(); } bool @@ -754,8 +762,9 @@ ObjectFilePECOFF::Dump(Stream *s) *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; - if (m_sections_ap.get()) - m_sections_ap->Dump(s, NULL, true, UINT32_MAX); + SectionList *sections = GetSectionList(); + if (sections) + sections->Dump(s, NULL, true, UINT32_MAX); if (m_symtab_ap.get()) m_symtab_ap->Dump(s, NULL, eSortOrderNone); diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index c12c7b9c5e2..4a41ba86fbe 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -86,10 +86,13 @@ public: // GetAddressClass (lldb::addr_t file_addr); // virtual lldb_private::Symtab * - GetSymtab(uint32_t flags = 0); + GetSymtab (); - virtual lldb_private::SectionList * - GetSectionList(); + virtual bool + IsStripped (); + + virtual void + CreateSections (lldb_private::SectionList &unified_section_list); virtual void Dump (lldb_private::Stream *s); |