summaryrefslogtreecommitdiff
path: root/source/Plugins/ObjectFile
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/ObjectFile')
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.cpp3
-rw-r--r--source/Plugins/ObjectFile/ELF/Makefile14
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp458
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h26
-rw-r--r--source/Plugins/ObjectFile/JIT/Makefile14
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp6
-rw-r--r--source/Plugins/ObjectFile/Mach-O/Makefile14
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp109
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h5
-rw-r--r--source/Plugins/ObjectFile/PECOFF/Makefile14
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp35
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h5
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 &section_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 &section_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 &section_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 &section_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 &section_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 &section_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 &sect_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 &sect_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 &section_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_