diff options
Diffstat (limited to 'source/Plugins/ObjectFile')
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 3 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/ELF/Makefile | 14 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 458 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 26 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/JIT/Makefile | 14 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp | 6 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/Mach-O/Makefile | 14 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 109 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 5 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/PECOFF/Makefile | 14 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 35 | ||||
-rw-r--r-- | source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h | 5 |
12 files changed, 489 insertions, 214 deletions
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index 641a7cc3e0e29..625cce3c10627 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -198,6 +198,9 @@ ELFHeader::GetRelocationJumpSlotType() const case EM_MIPS: slot = R_MIPS_JUMP_SLOT; break; + case EM_S390: + slot = R_390_JMP_SLOT; + break; } return slot; diff --git a/source/Plugins/ObjectFile/ELF/Makefile b/source/Plugins/ObjectFile/ELF/Makefile deleted file mode 100644 index 470660bb78619..0000000000000 --- a/source/Plugins/ObjectFile/ELF/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/ObjectFile/ELF/Makefile --------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginObjectFileELF -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index b16a2cda10f70..68e4e50a96e55 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -31,7 +31,9 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/MipsABIFlags.h" #define CASE_AND_STREAM(s, def, width) \ case def: s->Printf("%-*s", width, #def); break; @@ -283,7 +285,7 @@ ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) } } - const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment (n_namesz, 4)); + const char *cstr = data.GetCStr(offset, llvm::alignTo (n_namesz, 4)); if (cstr == NULL) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS)); @@ -729,7 +731,10 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, SectionHeaderColl section_headers; lldb_private::UUID &uuid = spec.GetUUID(); - GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ()); + using namespace std::placeholders; + const SetDataFunction set_data = std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3); + GetSectionHeaderInfo(section_headers, set_data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ()); + llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple (); @@ -759,7 +764,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file, data.SetData(data_sp); } ProgramHeaderColl program_headers; - GetProgramHeaderInfo(program_headers, data, header); + GetProgramHeaderInfo(program_headers, set_data, header); size_t segment_data_end = 0; for (ProgramHeaderCollConstIter I = program_headers.begin(); @@ -918,10 +923,14 @@ ObjectFileELF::SetLoadAddress (Target &target, // Iterate through the object file sections to find all // of the sections that have SHF_ALLOC in their flag bits. SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); - // if (section_sp && !section_sp->IsThreadSpecific()) if (section_sp && section_sp->Test(SHF_ALLOC)) { - lldb::addr_t load_addr = section_sp->GetFileAddress() + value; + lldb::addr_t load_addr = section_sp->GetFileAddress(); + // We don't want to update the load address of a section with type + // eSectionTypeAbsoluteAddress as they already have the absolute load address + // already specified + if (section_sp->GetType() != eSectionTypeAbsoluteAddress) + load_addr += value; // On 32-bit systems the load address have to fit into 4 bytes. The rest of // the bytes are the overflow from the addition. @@ -1256,7 +1265,7 @@ ObjectFileELF::ParseDependentModules() //---------------------------------------------------------------------- size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, - DataExtractor &object_data, + const SetDataFunction &set_data, const ELFHeader &header) { // We have already parsed the program headers @@ -1274,7 +1283,7 @@ ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, const size_t ph_size = header.e_phnum * header.e_phentsize; const elf_off ph_offset = header.e_phoff; DataExtractor data; - if (data.SetData(object_data, ph_offset, ph_size) != ph_size) + if (set_data(data, ph_offset, ph_size) != ph_size) return 0; uint32_t idx; @@ -1298,7 +1307,10 @@ ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, size_t ObjectFileELF::ParseProgramHeaders() { - return GetProgramHeaderInfo(m_program_headers, m_data, m_header); + using namespace std::placeholders; + return GetProgramHeaderInfo(m_program_headers, + std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3), + m_header); } lldb_private::Error @@ -1400,8 +1412,9 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l // Only bother processing this if we don't already have the uuid set. if (!uuid.IsValid()) { - // 16 bytes is UUID|MD5, 20 bytes is SHA1 - if ((note.n_descsz == 16 || note.n_descsz == 20)) + // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a build-id of a different + // length. Accept it as long as it's at least 4 bytes as it will be better than our own crc32. + if (note.n_descsz >= 4 && note.n_descsz <= 20) { uint8_t uuidbuf[20]; if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == nullptr) @@ -1449,7 +1462,7 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l // this ELF targets. if(note.n_descsz) { - const char *cstr = data.GetCStr(&offset, llvm::RoundUpToAlignment (note.n_descsz, 4)); + const char *cstr = data.GetCStr(&offset, llvm::alignTo (note.n_descsz, 4)); (void)cstr; } } @@ -1505,13 +1518,87 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l return error; } +void +ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, ArchSpec &arch_spec) +{ + lldb::offset_t Offset = 0; + + uint8_t FormatVersion = data.GetU8(&Offset); + if (FormatVersion != llvm::ARMBuildAttrs::Format_Version) + return; + + Offset = Offset + sizeof(uint32_t); // Section Length + llvm::StringRef VendorName = data.GetCStr(&Offset); + + if (VendorName != "aeabi") + return; + + if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) + arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); + + while (Offset < length) + { + uint8_t Tag = data.GetU8(&Offset); + uint32_t Size = data.GetU32(&Offset); + + if (Tag != llvm::ARMBuildAttrs::File || Size == 0) + continue; + + while (Offset < length) + { + uint64_t Tag = data.GetULEB128(&Offset); + switch (Tag) + { + default: + if (Tag < 32) + data.GetULEB128(&Offset); + else if (Tag % 2 == 0) + data.GetULEB128(&Offset); + else + data.GetCStr(&Offset); + + break; + + case llvm::ARMBuildAttrs::CPU_raw_name: + case llvm::ARMBuildAttrs::CPU_name: + data.GetCStr(&Offset); + + break; + + case llvm::ARMBuildAttrs::ABI_VFP_args: + { + uint64_t VFPArgs = data.GetULEB128(&Offset); + + if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) + { + if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment || + arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF) + arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); + + arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); + } + else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) + { + if (arch_spec.GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment || + arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI) + arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF); + + arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); + } + + break; + } + } + } + } +} //---------------------------------------------------------------------- // GetSectionHeaderInfo //---------------------------------------------------------------------- size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, - lldb_private::DataExtractor &object_data, + const SetDataFunction &set_data, const elf::ELFHeader &header, lldb_private::UUID &uuid, std::string &gnu_debuglink_file, @@ -1556,6 +1643,15 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, } } + if (arch_spec.GetMachine() == llvm::Triple::arm || + arch_spec.GetMachine() == llvm::Triple::thumb) + { + if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT) + arch_spec.SetFlags (ArchSpec::eARM_abi_soft_float); + else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT) + arch_spec.SetFlags (ArchSpec::eARM_abi_hard_float); + } + // If there are no section headers we are done. if (header.e_shnum == 0) return 0; @@ -1569,7 +1665,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, const size_t sh_size = header.e_shnum * header.e_shentsize; const elf_off sh_offset = header.e_shoff; DataExtractor sh_data; - if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size) + if (set_data (sh_data, sh_offset, sh_size) != sh_size) return 0; uint32_t idx; @@ -1590,7 +1686,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, const Elf64_Off offset = sheader.sh_offset; lldb_private::DataExtractor shstr_data; - if (shstr_data.SetData (object_data, offset, byte_size) == byte_size) + if (set_data (shstr_data, offset, byte_size) == byte_size) { for (SectionHeaderCollIter I = section_headers.begin(); I != section_headers.end(); ++I) @@ -1602,40 +1698,93 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, I->section_name = name; - if (arch_spec.GetMachine() == llvm::Triple::mips || arch_spec.GetMachine() == llvm::Triple::mipsel - || arch_spec.GetMachine() == llvm::Triple::mips64 || arch_spec.GetMachine() == llvm::Triple::mips64el) + if (arch_spec.IsMIPS()) { uint32_t arch_flags = arch_spec.GetFlags (); DataExtractor data; if (sheader.sh_type == SHT_MIPS_ABIFLAGS) { - if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size)) + if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size)) { - lldb::offset_t ase_offset = 12; // MIPS ABI Flags Version: 0 - arch_flags |= data.GetU32 (&ase_offset); + // MIPS ASE Mask is at offset 12 in MIPS.abiflags section + lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0 + arch_flags |= data.GetU32 (&offset); + + // The floating point ABI is at offset 7 + offset = 7; + switch (data.GetU8 (&offset)) + { + case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64 : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_64 : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64; + break; + case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A : + arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A; + break; + } } } // Settings appropriate ArchSpec ABI Flags - if (header.e_flags & llvm::ELF::EF_MIPS_ABI2) + switch(header.e_flags & llvm::ELF::EF_MIPS_ABI) { - arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32; - } - else if (header.e_flags & llvm::ELF::EF_MIPS_ABI_O32) - { - arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32; + case llvm::ELF::EF_MIPS_ABI_O32: + arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32; + break; + case EF_MIPS_ABI_O64: + arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64; + break; + case EF_MIPS_ABI_EABI32: + arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32; + break; + case EF_MIPS_ABI_EABI64: + arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64; + break; + default: + // ABI Mask doesn't cover N32 and N64 ABI. + if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64) + arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64; + else if (header.e_flags && llvm::ELF::EF_MIPS_ABI2) + arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32; + break; } arch_spec.SetFlags (arch_flags); } + if (arch_spec.GetMachine() == llvm::Triple::arm || arch_spec.GetMachine() == llvm::Triple::thumb) + { + DataExtractor data; + + if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 && + set_data(data, sheader.sh_offset, section_size) == section_size) + ParseARMAttributes(data, section_size, arch_spec); + } + if (name == g_sect_name_gnu_debuglink) { DataExtractor data; - if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size)) + if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size)) { lldb::offset_t gnu_debuglink_offset = 0; gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset); - gnu_debuglink_offset = llvm::RoundUpToAlignment (gnu_debuglink_offset, 4); + gnu_debuglink_offset = llvm::alignTo (gnu_debuglink_offset, 4); data.GetU32 (&gnu_debuglink_offset, &gnu_debuglink_crc, 1); } } @@ -1653,7 +1802,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, { // Allow notes to refine module info. DataExtractor data; - if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size)) + if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size)) { Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid); if (error.Fail ()) @@ -1719,7 +1868,41 @@ ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const size_t ObjectFileELF::ParseSectionHeaders() { - return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec); + using namespace std::placeholders; + + return GetSectionHeaderInfo(m_section_headers, + std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3), + m_header, + m_uuid, + m_gnu_debuglink_file, + m_gnu_debuglink_crc, + m_arch_spec); +} + +lldb::offset_t +ObjectFileELF::SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length) +{ + return dst.SetData(src, offset, length); +} + +lldb::offset_t +ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length) +{ + if (offset + length <= m_data.GetByteSize()) + return dst.SetData(m_data, offset, length); + + const auto process_sp = m_process_wp.lock(); + if (process_sp != nullptr) + { + addr_t file_size = offset + length; + + DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size); + if (!data_sp) + return false; + m_data.SetData(data_sp, 0, file_size); + } + + return dst.SetData(m_data, offset, length); } const ObjectFileELF::ELFSectionHeaderInfo * @@ -1849,6 +2032,9 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list) else if (name == g_sect_name_arm_extab) sect_type = eSectionTypeARMextab; else if (name == g_sect_name_go_symtab) sect_type = eSectionTypeGoSymtab; + const uint32_t permissions = ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0) | + ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0) | + ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0); switch (header.sh_type) { case SHT_SYMTAB: @@ -1900,6 +2086,7 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list) header.sh_flags, // Flags for this section. target_bytes_size));// Number of host bytes per target byte + section_sp->SetPermissions(permissions); if (is_thread_specific) section_sp->SetIsThreadSpecific (is_thread_specific); m_sections_ap->AddSection(section_sp); @@ -1997,7 +2184,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, static ConstString bss_section_name(".bss"); static ConstString opd_section_name(".opd"); // For ppc64 - // On Android the oatdata and the oatexec symbols in system@framework@boot.oat covers the full + // On Android the oatdata and the oatexec symbols in the oat and odex files covers the full // .text section what causes issues with displaying unusable symbol name to the user and very // slow unwinding speed because the instruction emulation based unwind plans try to emulate all // instructions in these symbols. Don't add these symbols to the symbol list as they have no @@ -2005,10 +2192,13 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, // Filtering can't be restricted to Android because this special object file don't contain the // note section specifying the environment to Android but the custom extension and file name // makes it highly unlikely that this will collide with anything else. - bool skip_oatdata_oatexec = m_file.GetFilename() == ConstString("system@framework@boot.oat"); + ConstString file_extension = m_file.GetFileNameExtension(); + bool skip_oatdata_oatexec = file_extension == ConstString("oat") || file_extension == ConstString("odex"); ArchSpec arch; GetArchitecture(arch); + ModuleSP module_sp(GetModule()); + SectionList* module_section_list = module_sp ? module_sp->GetSectionList() : nullptr; // Local cache to avoid doing a FindSectionByName for each symbol. The "const char*" key must // came from a ConstString object so they can be compared by pointer @@ -2034,9 +2224,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, SectionSP symbol_section_sp; SymbolType symbol_type = eSymbolTypeInvalid; - Elf64_Half symbol_idx = symbol.st_shndx; + Elf64_Half section_idx = symbol.st_shndx; - switch (symbol_idx) + switch (section_idx) { case SHN_ABS: symbol_type = eSymbolTypeAbsolute; @@ -2045,7 +2235,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, symbol_type = eSymbolTypeUndefined; break; default: - symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx); + symbol_section_sp = section_list->GetSectionAtIndex(section_idx); break; } @@ -2092,7 +2282,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, } } - if (symbol_type == eSymbolTypeInvalid) + if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) { if (symbol_section_sp) { @@ -2229,30 +2419,44 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, } } - // symbol_value_offset may contain 0 for ARM symbols or -1 for - // THUMB symbols. See above for more details. + // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB symbols. See above for + // more details. uint64_t symbol_value = symbol.st_value + symbol_value_offset; + + if (symbol_section_sp == nullptr && section_idx == SHN_ABS && symbol.st_size != 0) + { + // We don't have a section for a symbol with non-zero size. Create a new section for it + // so the address range covered by the symbol is also covered by the module (represented + // through the section list). It is needed so module lookup for the addresses covered + // by this symbol will be successfull. This case happens for absolute symbols. + ConstString fake_section_name(std::string(".absolute.") + symbol_name); + symbol_section_sp = std::make_shared<Section>(module_sp, + this, + SHN_ABS, + fake_section_name, + eSectionTypeAbsoluteAddress, + symbol_value, + symbol.st_size, + 0, 0, 0, + SHF_ALLOC); + + module_section_list->AddSection(symbol_section_sp); + section_list->AddSection(symbol_section_sp); + } + if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile) symbol_value -= symbol_section_sp->GetFileAddress(); - if (symbol_section_sp) + if (symbol_section_sp && module_section_list && module_section_list != section_list) { - ModuleSP module_sp(GetModule()); - if (module_sp) - { - SectionList *module_section_list = module_sp->GetSectionList(); - if (module_section_list && module_section_list != section_list) - { - const ConstString §_name = symbol_section_sp->GetName(); - auto section_it = section_name_to_section.find(sect_name.GetCString()); - if (section_it == section_name_to_section.end()) - section_it = section_name_to_section.emplace( - sect_name.GetCString(), - module_section_list->FindSectionByName (sect_name)).first; - if (section_it->second && section_it->second->GetFileSize()) - symbol_section_sp = section_it->second; - } - } + const ConstString §_name = symbol_section_sp->GetName(); + auto section_it = section_name_to_section.find(sect_name.GetCString()); + if (section_it == section_name_to_section.end()) + section_it = section_name_to_section.emplace( + sect_name.GetCString(), + module_section_list->FindSectionByName (sect_name)).first; + if (section_it->second && section_it->second->GetFileSize()) + symbol_section_sp = section_it->second; } bool is_global = symbol.getBinding() == STB_GLOBAL; @@ -2283,6 +2487,12 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) ); } + // In ELF all symbol should have a valid size but it is not true for some function symbols + // coming from hand written assembly. As none of the function symbol should have 0 size we + // try to calculate the size for these symbols in the symtab with saying that their original + // size is not valid. + bool symbol_size_valid = symbol.st_size != 0 || symbol.getType() != STT_FUNC; + Symbol dc_symbol( i + start_id, // ID is the original symbol table index. mangled, @@ -2295,7 +2505,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, symbol_section_sp, // Section in which this symbol is defined or null. symbol_value, // Offset in section or symbol value. symbol.st_size), // Size in bytes of this symbol. - symbol.st_size != 0, // Size is valid if it is not 0 + symbol_size_valid, // Symbol size is valid has_suffix, // Contains linker annotations? flags); // Symbol flags. symtab->AddSymbol(dc_symbol); @@ -2304,7 +2514,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, } unsigned -ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab) +ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, + user_id_t start_id, + lldb_private::Section *symtab) { if (symtab->GetObjectFile() != this) { @@ -2430,9 +2642,12 @@ GetPltEntrySizeAndOffset(const ELFSectionHeader* rel_hdr, const ELFSectionHeader // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 bytes. // So round the entsize up by the alignment if addralign is set. elf_xword plt_entsize = plt_hdr->sh_addralign ? - llvm::RoundUpToAlignment (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize; + llvm::alignTo (plt_hdr->sh_entsize, plt_hdr->sh_addralign) : plt_hdr->sh_entsize; - if (plt_entsize == 0) + // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly. + // PLT entries relocation code in general requires multiple instruction and + // should be greater than 4 bytes in most cases. Try to guess correct size just in case. + if (plt_entsize <= 4) { // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the size of the plt // entries based on the number of entries and the size of the plt section with the @@ -2533,17 +2748,17 @@ 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 - // points to the section holding the plt. + // The link field points to the associated symbol table. user_id_t symtab_id = rel_hdr->sh_link; - user_id_t plt_id = rel_hdr->sh_info; // If the link field doesn't point to the appropriate symbol name table then // try to find it by name as some compiler don't fill in the link fields. if (!symtab_id) symtab_id = GetSectionIndexByName(".dynsym"); - if (!plt_id) - plt_id = GetSectionIndexByName(".plt"); + + // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers + // point that to the .got.plt or .got section instead of .plt. + user_id_t plt_id = GetSectionIndexByName(".plt"); if (!symtab_id || !plt_id) return 0; @@ -2760,7 +2975,7 @@ ObjectFileELF::GetSymtab() return NULL; uint64_t symbol_id = 0; - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + 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 @@ -2806,6 +3021,14 @@ ObjectFileELF::GetSymtab() } } + DWARFCallFrameInfo* eh_frame = GetUnwindTable().GetEHFrameInfo(); + if (eh_frame) + { + if (m_symtab_ap == nullptr) + m_symtab_ap.reset(new Symtab(this)); + ParseUnwindSymbols (m_symtab_ap.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_ap == nullptr) @@ -2835,57 +3058,64 @@ ObjectFileELF::GetSymtab() return m_symtab_ap.get(); } -Symbol * -ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique) +void +ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, DWARFCallFrameInfo* eh_frame) { - if (!m_symtab_ap.get()) - return nullptr; // GetSymtab() should be called first. - - const SectionList *section_list = GetSectionList(); + SectionList* section_list = GetSectionList(); if (!section_list) - return nullptr; + return; - if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo()) - { - AddressRange range; - if (eh_frame->GetAddressRange (so_addr, range)) + // First we save the new symbols into a separate list and add them to the symbol table after + // we colleced all symbols we want to add. This is neccessary because adding a new symbol + // invalidates the internal index of the symtab what causing the next lookup to be slow because + // it have to recalculate the index first. + std::vector<Symbol> new_symbols; + + eh_frame->ForEachFDEEntries( + [this, symbol_table, section_list, &new_symbols](lldb::addr_t file_addr, + uint32_t size, + dw_offset_t) { + Symbol* symbol = symbol_table->FindSymbolAtFileAddress(file_addr); + if (symbol) { - const addr_t file_addr = range.GetBaseAddress().GetFileAddress(); - Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr; - if (symbol) - return symbol; - - // Note that a (stripped) symbol won't be found by GetSymtab()... - lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr); - if (eh_sym_section_sp.get()) + if (!symbol->GetByteSizeIsValid()) { - addr_t section_base = eh_sym_section_sp->GetFileAddress(); - addr_t offset = file_addr - section_base; - uint64_t symbol_id = m_symtab_ap->GetNumSymbols(); - + symbol->SetByteSize(size); + symbol->SetSizeIsSynthesized(true); + } + } + else + { + SectionSP section_sp = section_list->FindSectionContainingFileAddress(file_addr); + if (section_sp) + { + addr_t offset = file_addr - section_sp->GetFileAddress(); + const char* symbol_name = GetNextSyntheticSymbolName().GetCString(); + uint64_t symbol_id = symbol_table->GetNumSymbols(); Symbol eh_symbol( - symbol_id, // Symbol table index. - "???", // Symbol name. - false, // Is the symbol name mangled? - eSymbolTypeCode, // Type of this symbol. - true, // Is this globally visible? - false, // Is this symbol debug info? - false, // Is this symbol a trampoline? - true, // Is this symbol artificial? - eh_sym_section_sp, // Section in which this symbol is defined or null. - offset, // Offset in section or symbol value. - range.GetByteSize(), // Size in bytes of this symbol. - true, // Size is valid. - false, // Contains linker annotations? - 0); // Symbol flags. - if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol)) - return m_symtab_ap->SymbolAtIndex(symbol_id); + symbol_id, // Symbol table index. + symbol_name, // Symbol name. + false, // Is the symbol name mangled? + eSymbolTypeCode, // Type of this symbol. + true, // Is this globally visible? + false, // Is this symbol debug info? + false, // Is this symbol a trampoline? + true, // Is this symbol artificial? + section_sp, // Section in which this symbol is defined or null. + offset, // Offset in section or symbol value. + 0, // Size: Don't specify the size as an FDE can + false, // Size is valid: cover multiple symbols. + false, // Contains linker annotations? + 0); // Symbol flags. + new_symbols.push_back(eh_symbol); } } - } - return nullptr; -} + return true; + }); + for (const Symbol& s : new_symbols) + symbol_table->AddSymbol(s); +} bool ObjectFileELF::IsStripped () @@ -2903,6 +3133,22 @@ ObjectFileELF::IsStripped () void ObjectFileELF::Dump(Stream *s) { + ModuleSP module_sp(GetModule()); + if (!module_sp) + { + return; + } + + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); + s->Printf("%p: ", static_cast<void *>(this)); + s->Indent(); + s->PutCString("ObjectFileELF"); + + ArchSpec header_arch; + GetArchitecture(header_arch); + + *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; + DumpELFHeader(s, m_header); s->EOL(); DumpELFProgramHeaders(s); diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 4b97f92c6c5c8..e2f73f53ec63e 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -14,6 +14,7 @@ #include <stdint.h> // C++ Includes +#include <functional> #include <vector> // Other libraries and framework includes @@ -56,7 +57,7 @@ struct ELFNote size_t GetByteSize() const { - return 12 + llvm::RoundUpToAlignment (n_namesz, 4) + llvm::RoundUpToAlignment (n_descsz, 4); + return 12 + llvm::alignTo (n_namesz, 4) + llvm::alignTo (n_descsz, 4); } }; @@ -149,9 +150,6 @@ public: lldb_private::Symtab * GetSymtab() override; - lldb_private::Symbol * - ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique) override; - bool IsStripped () override; @@ -231,6 +229,7 @@ private: typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter; typedef std::map<lldb::addr_t, lldb::AddressClass> FileAddressToAddressClassMap; + typedef std::function<lldb::offset_t (lldb_private::DataExtractor &, lldb::offset_t, lldb::offset_t)> SetDataFunction; /// Version of this reader common to all plugins based on this class. static const uint32_t m_plugin_version = 1; @@ -279,7 +278,7 @@ private: // Parses the ELF program headers. static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers, - lldb_private::DataExtractor &data, + const SetDataFunction &set_data, const elf::ELFHeader &header); // Finds PT_NOTE segments and calculates their crc sum. @@ -299,10 +298,14 @@ private: size_t ParseSectionHeaders(); + static void + ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length, + lldb_private::ArchSpec &arch_spec); + /// Parses the elf section headers and returns the uuid, debug link name, crc, archspec. static size_t GetSectionHeaderInfo(SectionHeaderColl §ion_headers, - lldb_private::DataExtractor &data, + const SetDataFunction &set_data, const elf::ELFHeader &header, lldb_private::UUID &uuid, std::string &gnu_debuglink_file, @@ -347,6 +350,10 @@ private: const ELFSectionHeaderInfo *rela_hdr, lldb::user_id_t section_id); + void + ParseUnwindSymbols(lldb_private::Symtab *symbol_table, + lldb_private::DWARFCallFrameInfo* eh_frame); + /// Relocates debug sections unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id); @@ -437,6 +444,13 @@ private: static lldb_private::Error RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid); + + + static lldb::offset_t + SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length); + + lldb::offset_t + SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length); }; #endif // liblldb_ObjectFileELF_h_ diff --git a/source/Plugins/ObjectFile/JIT/Makefile b/source/Plugins/ObjectFile/JIT/Makefile deleted file mode 100644 index 2af3521777a15..0000000000000 --- a/source/Plugins/ObjectFile/JIT/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/ObjectFile/JIT/Makefile --------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginObjectFileJIT -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index 3103ed8fb8fee..e3d8383337119 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -158,11 +158,11 @@ ObjectFileJIT::GetSymtab() ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (m_symtab_ap.get() == NULL) { m_symtab_ap.reset(new Symtab(this)); - Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); + std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex()); ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock()); if (delegate_sp) delegate_sp->PopulateSymtab(this, *m_symtab_ap); @@ -200,7 +200,7 @@ ObjectFileJIT::Dump (Stream *s) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); s->Printf("%p: ", static_cast<void*>(this)); s->Indent(); s->PutCString("ObjectFileJIT"); diff --git a/source/Plugins/ObjectFile/Mach-O/Makefile b/source/Plugins/ObjectFile/Mach-O/Makefile deleted file mode 100644 index 2fab0238e411d..0000000000000 --- a/source/Plugins/ObjectFile/Mach-O/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/ObjectFile/Mach-O/Makefile -----------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginObjectFileMachO -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 9c1e177825084..5f8242211b7f6 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -541,6 +541,7 @@ public: lldb::offset_t next_thread_state = offset + (count * 4); switch (flavor) { + case GPRAltRegSet: case GPRRegSet: for (uint32_t i=0; i<count; ++i) { @@ -1129,7 +1130,9 @@ ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(), - m_thread_context_offsets_valid(false) + m_thread_context_offsets_valid(false), + m_reexported_dylibs (), + m_allow_assembly_emulation_unwind_plans (true) { ::memset (&m_header, 0, sizeof(m_header)); ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); @@ -1144,7 +1147,9 @@ ObjectFileMachO::ObjectFileMachO (const lldb::ModuleSP &module_sp, m_mach_sections(), m_entry_point_address(), m_thread_context_offsets(), - m_thread_context_offsets_valid(false) + m_thread_context_offsets_valid(false), + m_reexported_dylibs (), + m_allow_assembly_emulation_unwind_plans (true) { ::memset (&m_header, 0, sizeof(m_header)); ::memset (&m_dysymtab, 0, sizeof(m_dysymtab)); @@ -1212,7 +1217,7 @@ ObjectFileMachO::ParseHeader () ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); bool can_parse = false; lldb::offset_t offset = 0; m_data.SetByteOrder (endian::InlHostByteOrder()); @@ -1387,6 +1392,7 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr) case eSectionTypeCompactUnwind: return eAddressClassRuntime; + case eSectionTypeAbsoluteAddress: case eSectionTypeELFSymbolTable: case eSectionTypeELFDynamicSymbols: case eSectionTypeELFRelocationEntries: @@ -1451,11 +1457,11 @@ ObjectFileMachO::GetSymtab() ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (m_symtab_ap.get() == NULL) { m_symtab_ap.reset(new Symtab(this)); - Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); + std::lock_guard<std::recursive_mutex> symtab_guard(m_symtab_ap->GetMutex()); ParseSymtab (); m_symtab_ap->Finalize (); } @@ -1619,6 +1625,10 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) } if (m_data.GetU32(&offset, &load_cmd.maxprot, 4)) { + const uint32_t segment_permissions = + ((load_cmd.initprot & VM_PROT_READ) ? ePermissionsReadable : 0) | + ((load_cmd.initprot & VM_PROT_WRITE) ? ePermissionsWritable : 0) | + ((load_cmd.initprot & VM_PROT_EXECUTE) ? ePermissionsExecutable : 0); const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0; @@ -1645,6 +1655,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) segment_sp->SetIsEncrypted (segment_is_encrypted); m_sections_ap->AddSection(segment_sp); + segment_sp->SetPermissions(segment_permissions); if (add_to_unified) unified_section_list.AddSection(segment_sp); } @@ -1776,7 +1787,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) sect64.align, load_cmd.flags)); // Flags for this section segment_sp->SetIsFake(true); - + segment_sp->SetPermissions(segment_permissions); m_sections_ap->AddSection(segment_sp); if (add_to_unified) unified_section_list.AddSection(segment_sp); @@ -1926,6 +1937,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list) section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL; section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted); + section_sp->SetPermissions(segment_permissions); segment_sp->GetChildren().AddSection(section_sp); if (segment_sp->IsFake()) @@ -2601,6 +2613,23 @@ ObjectFileMachO::ParseSymtab () const size_t function_starts_count = function_starts.GetSize(); + // For user process binaries (executables, dylibs, frameworks, bundles), if we don't have + // LC_FUNCTION_STARTS/eh_frame section in this binary, we're going to assume the binary + // has been stripped. Don't allow assembly language instruction emulation because we don't + // know proper function start boundaries. + // + // For all other types of binaries (kernels, stand-alone bare board binaries, kexts), they + // may not have LC_FUNCTION_STARTS / eh_frame sections - we should not make any assumptions + // about them based on that. + if (function_starts_count == 0 && CalculateStrata() == eStrataUser) + { + m_allow_assembly_emulation_unwind_plans = false; + Log *unwind_or_symbol_log (lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_SYMBOLS | LIBLLDB_LOG_UNWIND)); + + if (unwind_or_symbol_log) + module_sp->LogMessage(unwind_or_symbol_log, "no LC_FUNCTION_STARTS, will not allow assembly profiled unwinds"); + } + const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : static_cast<user_id_t>(NO_SECT); @@ -3078,7 +3107,7 @@ ObjectFileMachO::ParseSymtab () { // 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 - const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName().AsCString(); + const char *so_path = sym[sym_idx - 1].GetMangled().GetDemangledName(lldb::eLanguageTypeUnknown).AsCString(); if (so_path && so_path[0]) { std::string full_so_path (so_path); @@ -3465,7 +3494,7 @@ ObjectFileMachO::ParseSymtab () sym[sym_idx].GetMangled().SetValue(const_symbol_name, symbol_name_is_mangled); if (is_gsym && is_debug) { - const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString(); + const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString(); if (gsym_name) N_GSYM_name_to_sym_idx[gsym_name] = sym_idx; } @@ -3539,7 +3568,7 @@ ObjectFileMachO::ParseSymtab () bool found_it = false; for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) { - if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled)) + if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, 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 @@ -3578,7 +3607,7 @@ ObjectFileMachO::ParseSymtab () bool found_it = false; for (ValueToSymbolIndexMap::const_iterator pos = range.first; pos != range.second; ++pos) { - if (sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(Mangled::ePreferMangled)) + if (sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled) == sym[pos->second].GetMangled().GetName(lldb::eLanguageTypeUnknown, 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 @@ -3595,7 +3624,7 @@ ObjectFileMachO::ParseSymtab () } else { - const char *gsym_name = sym[sym_idx].GetMangled().GetName(Mangled::ePreferMangled).GetCString(); + const char *gsym_name = sym[sym_idx].GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled).GetCString(); if (gsym_name) { // Combine N_GSYM stab entries with the non stab symbol @@ -4089,7 +4118,7 @@ ObjectFileMachO::ParseSymtab () case N_ECOML: // end common (local name): 0,,n_sect,0,address symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value); - // Fall through + LLVM_FALLTHROUGH; case N_ECOMM: // end common: name,,n_sect,0,0 @@ -4145,7 +4174,8 @@ ObjectFileMachO::ParseSymtab () ConstString undefined_name(symbol_name + ((symbol_name[0] == '_') ? 1 : 0)); undefined_name_to_desc[undefined_name] = nlist.n_desc; } - // Fall through + LLVM_FALLTHROUGH; + case N_PBUD: type = eSymbolTypeUndefined; break; @@ -4516,7 +4546,6 @@ ObjectFileMachO::ParseSymtab () if (function_starts_count > 0) { - char synthetic_function_symbol[PATH_MAX]; uint32_t num_synthetic_function_symbols = 0; for (i=0; i<function_starts_count; ++i) { @@ -4531,7 +4560,6 @@ ObjectFileMachO::ParseSymtab () num_syms = sym_idx + num_synthetic_function_symbols; sym = symtab->Resize (num_syms); } - uint32_t synthetic_function_symbol_idx = 0; for (i=0; i<function_starts_count; ++i) { const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i); @@ -4566,13 +4594,8 @@ ObjectFileMachO::ParseSymtab () { symbol_byte_size = section_end_file_addr - symbol_file_addr; } - snprintf (synthetic_function_symbol, - sizeof(synthetic_function_symbol), - "___lldb_unnamed_function%u$$%s", - ++synthetic_function_symbol_idx, - module_sp->GetFileSpec().GetFilename().GetCString()); sym[sym_idx].SetID (synthetic_sym_id++); - sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol)); + sym[sym_idx].GetMangled().SetDemangledName(GetNextSyntheticSymbolName()); sym[sym_idx].SetType (eSymbolTypeCode); sym[sym_idx].SetIsSynthetic (true); sym[sym_idx].GetAddressRef() = symbol_addr; @@ -4743,7 +4766,7 @@ ObjectFileMachO::Dump (Stream *s) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); s->Printf("%p: ", static_cast<void*>(this)); s->Indent(); if (m_header.magic == MH_MAGIC_64 || m_header.magic == MH_CIGAM_64) @@ -4827,9 +4850,22 @@ ObjectFileMachO::GetArchitecture (const llvm::MachO::mach_header &header, if (header.filetype == MH_PRELOAD) { - // Set vendor to an unspecified unknown or a "*" so it can match any vendor - triple.setVendor(llvm::Triple::UnknownVendor); - triple.setVendorName(llvm::StringRef()); + if (header.cputype == CPU_TYPE_ARM) + { + // If this is a 32-bit arm binary, and it's a standalone binary, + // force the Vendor to Apple so we don't accidentally pick up + // the generic armv7 ABI at runtime. Apple's armv7 ABI always uses + // r7 for the frame pointer register; most other armv7 ABIs use a + // combination of r7 and r11. + triple.setVendor(llvm::Triple::Apple); + } + else + { + // Set vendor to an unspecified unknown or a "*" so it can match any vendor + // This is required for correct behavior of EFI debugging on x86_64 + triple.setVendor(llvm::Triple::UnknownVendor); + triple.setVendorName(llvm::StringRef()); + } return true; } else @@ -4886,7 +4922,7 @@ ObjectFileMachO::GetUUID (lldb_private::UUID* uuid) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); return GetUUID (m_header, m_data, offset, *uuid); } @@ -4900,7 +4936,7 @@ ObjectFileMachO::GetDependentModules (FileSpecList& files) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); struct load_command load_cmd; lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); std::vector<std::string> rpath_paths; @@ -5028,7 +5064,7 @@ ObjectFileMachO::GetEntryPointAddress () ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); struct load_command load_cmd; lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); uint32_t i; @@ -5059,7 +5095,7 @@ ObjectFileMachO::GetEntryPointAddress () switch (m_header.cputype) { case llvm::MachO::CPU_TYPE_ARM: - if (flavor == 1) // ARM_THREAD_STATE from mach/arm/thread_status.h + if (flavor == 1 || flavor == 9) // ARM_THREAD_STATE/ARM_THREAD_STATE32 from mach/arm/thread_status.h { offset += 60; // This is the offset of pc in the GPR thread state data structure. start_address = m_data.GetU32(&offset); @@ -5111,6 +5147,7 @@ ObjectFileMachO::GetEntryPointAddress () start_address = text_segment_sp->GetFileAddress() + entryoffset; } } + break; default: break; @@ -5177,7 +5214,7 @@ ObjectFileMachO::GetNumThreadContexts () ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (!m_thread_context_offsets_valid) { m_thread_context_offsets_valid = true; @@ -5211,7 +5248,7 @@ ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &th ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (!m_thread_context_offsets_valid) GetNumThreadContexts (); @@ -5347,7 +5384,7 @@ ObjectFileMachO::GetVersion (uint32_t *versions, uint32_t num_versions) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); struct dylib_command load_cmd; lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic); uint32_t version_cmd = 0; @@ -5402,7 +5439,7 @@ ObjectFileMachO::GetArchitecture (ArchSpec &arch) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); return GetArchitecture (m_header, m_data, MachHeaderSizeFromMagic(m_header.magic), arch); } return false; @@ -5614,6 +5651,12 @@ ObjectFileMachO::GetIsDynamicLinkEditor() return m_header.filetype == llvm::MachO::MH_DYLINKER; } +bool +ObjectFileMachO::AllowAssemblyEmulationUnwindPlans () +{ + return m_allow_assembly_emulation_unwind_plans; +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 6b7ad531b83bf..251a0865e7823 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -19,7 +19,6 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Core/RangeMap.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" //---------------------------------------------------------------------- @@ -176,6 +175,9 @@ public: lldb::offset_t *data_offset_ptr, llvm::MachO::mach_header &header); + bool + AllowAssemblyEmulationUnwindPlans () override; + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -247,6 +249,7 @@ protected: FileRangeArray m_thread_context_offsets; bool m_thread_context_offsets_valid; lldb_private::FileSpecList m_reexported_dylibs; + bool m_allow_assembly_emulation_unwind_plans; }; #endif // liblldb_ObjectFileMachO_h_ diff --git a/source/Plugins/ObjectFile/PECOFF/Makefile b/source/Plugins/ObjectFile/PECOFF/Makefile deleted file mode 100644 index 1b5abc461e826..0000000000000 --- a/source/Plugins/ObjectFile/PECOFF/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/ObjectFile/PECOFF/Makefile --------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginObjectFilePECOFF -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index ccd4400995c74..5f5a0ab07ad69 100644 --- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -192,7 +192,8 @@ ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp, m_dos_header (), m_coff_header (), m_coff_header_opt (), - m_sect_headers () + m_sect_headers (), + m_entry_point_address () { ::memset (&m_dos_header, 0, sizeof(m_dos_header)); ::memset (&m_coff_header, 0, sizeof(m_coff_header)); @@ -211,7 +212,7 @@ ObjectFilePECOFF::ParseHeader () ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); m_sect_headers.clear(); m_data.SetByteOrder (eByteOrderLittle); lldb::offset_t offset = 0; @@ -533,13 +534,13 @@ ObjectFilePECOFF::GetSymtab() ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (m_symtab_ap.get() == NULL) { SectionList *sect_list = GetSectionList(); m_symtab_ap.reset(new Symtab(this)); - Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); - + std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex()); + const uint32_t num_syms = m_coff_header.nsyms; if (num_syms > 0 && m_coff_header.symoff > 0) @@ -662,6 +663,7 @@ ObjectFilePECOFF::GetSymtab() symbols[i].SetDebug(true); } } + m_symtab_ap->CalculateSymbolSizes(); } } return m_symtab_ap.get(); @@ -687,7 +689,7 @@ ObjectFilePECOFF::CreateSections (SectionList &unified_section_list) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); const uint32_t nsects = m_sect_headers.size(); ModuleSP module_sp (GetModule()); for (uint32_t idx = 0; idx<nsects; ++idx) @@ -813,6 +815,25 @@ ObjectFilePECOFF::GetDependentModules (FileSpecList& files) return 0; } +lldb_private::Address +ObjectFilePECOFF::GetEntryPointAddress () +{ + if (m_entry_point_address.IsValid()) + return m_entry_point_address; + + if (!ParseHeader() || !IsExecutable()) + return m_entry_point_address; + + SectionList *section_list = GetSectionList(); + addr_t offset = m_coff_header_opt.entry; + + if (!section_list) + m_entry_point_address.SetOffset(offset); + else + m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); + return m_entry_point_address; +} + //---------------------------------------------------------------------- // Dump @@ -826,7 +847,7 @@ ObjectFilePECOFF::Dump(Stream *s) ModuleSP module_sp(GetModule()); if (module_sp) { - lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); s->Printf("%p: ", static_cast<void*>(this)); s->Indent(); s->PutCString("ObjectFilePECOFF"); diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h index 44e5ee1b044b6..6c1cdbf56c6b8 100644 --- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -144,8 +144,8 @@ public: uint32_t GetDependentModules(lldb_private::FileSpecList& files) override; -// virtual lldb_private::Address -// GetEntryPointAddress (); + virtual lldb_private::Address + GetEntryPointAddress () override; ObjectFile::Type CalculateType() override; @@ -301,6 +301,7 @@ private: coff_opt_header_t m_coff_header_opt; SectionHeaderColl m_sect_headers; lldb::addr_t m_image_base; + lldb_private::Address m_entry_point_address; }; #endif // liblldb_ObjectFilePECOFF_h_ |