Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
Patch from Keno Fischer to enable JITLoaderGDB with mach-o file support.
Browse files Browse the repository at this point in the history
The patch is as is with the functionality left disabled for apple vendors because of performance regressions. If this is enabled it ends up searching for symbols in all shared libraries that are loadeded.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@211638 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Greg Clayton committed Jun 24, 2014
1 parent 21538d8 commit a900ab6
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 11 deletions.
14 changes: 14 additions & 0 deletions include/lldb/Core/Section.h
Expand Up @@ -119,6 +119,7 @@ class Section :
lldb::addr_t vm_size,
lldb::offset_t file_offset,
lldb::offset_t file_size,
uint32_t log2align,
uint32_t flags);

// Create a section that is a child of parent_section_sp
Expand All @@ -132,6 +133,7 @@ class Section :
lldb::addr_t vm_size,
lldb::offset_t file_offset,
lldb::offset_t file_size,
uint32_t log2align,
uint32_t flags);

~Section ();
Expand Down Expand Up @@ -284,6 +286,17 @@ class Section :
return m_obj_file;
}

uint32_t GetLog2Align()
{
return m_log2align;
}

void
SetLog2Align(uint32_t align)
{
m_log2align = align;
}


protected:

Expand All @@ -296,6 +309,7 @@ class Section :
lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in memory at runtime
lldb::offset_t m_file_offset; // Object file offset (if any)
lldb::offset_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...)
uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be aligned to 2^m_log2align)
SectionList m_children; // Child sections
bool m_fake:1, // If true, then this section only can contain the address if one of its
// children contains an address. This allows for gaps between the children
Expand Down
4 changes: 3 additions & 1 deletion lib/Makefile
Expand Up @@ -101,7 +101,9 @@ ifeq ($(HOST_OS),Darwin)
lldbPluginSymbolVendorMacOSX.a \
lldbPluginProcessDarwin.a \
lldbPluginProcessMachCore.a \
lldbPluginSystemRuntimeMacOSX.a
lldbPluginSystemRuntimeMacOSX.a \
lldbPluginProcessElfCore.a \
lldbPluginJITLoaderGDB.a
endif

ifeq ($(HOST_OS),Linux)
Expand Down
6 changes: 5 additions & 1 deletion source/Core/Section.cpp
Expand Up @@ -27,6 +27,7 @@ Section::Section (const ModuleSP &module_sp,
addr_t byte_size,
lldb::offset_t file_offset,
lldb::offset_t file_size,
uint32_t log2align,
uint32_t flags) :
ModuleChild (module_sp),
UserID (sect_id),
Expand All @@ -39,6 +40,7 @@ Section::Section (const ModuleSP &module_sp,
m_byte_size (byte_size),
m_file_offset (file_offset),
m_file_size (file_size),
m_log2align (log2align),
m_children (),
m_fake (false),
m_encrypted (false),
Expand All @@ -58,6 +60,7 @@ Section::Section (const lldb::SectionSP &parent_section_sp,
addr_t byte_size,
lldb::offset_t file_offset,
lldb::offset_t file_size,
uint32_t log2align,
uint32_t flags) :
ModuleChild (module_sp),
UserID (sect_id),
Expand All @@ -70,6 +73,7 @@ Section::Section (const lldb::SectionSP &parent_section_sp,
m_byte_size (byte_size),
m_file_offset (file_offset),
m_file_size (file_size),
m_log2align (log2align),
m_children (),
m_fake (false),
m_encrypted (false),
Expand Down Expand Up @@ -142,7 +146,7 @@ Section::GetLoadBaseAddress (Target *target) const
if (load_base_addr != LLDB_INVALID_ADDRESS)
load_base_addr += GetOffset();
}
else
if (load_base_addr == LLDB_INVALID_ADDRESS)
{
load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
}
Expand Down
1 change: 1 addition & 0 deletions source/Expression/IRExecutionUnit.cpp
Expand Up @@ -917,6 +917,7 @@ IRExecutionUnit::PopulateSectionList (lldb_private::ObjectFile *obj_file,
record.m_size,
record.m_host_address, // file_offset (which is the host address for the data)
record.m_size, // file_size
0,
record.m_permissions)); // flags
section_list.AddSection (section_sp);
}
Expand Down
84 changes: 76 additions & 8 deletions source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
Expand Up @@ -102,13 +102,15 @@ JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list)
log->Printf("JITLoaderGDB::%s looking for JIT register hook",
__FUNCTION__);

addr_t jit_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
addr_t jit_addr = GetSymbolAddress(module_list,
ConstString("__jit_debug_register_code"),
eSymbolTypeAny);
if (jit_addr == LLDB_INVALID_ADDRESS)
return;

m_jit_descriptor_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
m_jit_descriptor_addr = GetSymbolAddress(module_list,
ConstString("__jit_debug_descriptor"),
eSymbolTypeData);
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
{
if (log)
Expand Down Expand Up @@ -144,6 +146,55 @@ JITLoaderGDB::JITDebugBreakpointHit(void *baton,
return instance->ReadJITDescriptor(false);
}

static void updateSectionLoadAddress(const SectionList &section_list,
Target &target,
uint64_t symbolfile_addr,
uint64_t symbolfile_size,
uint64_t &vmaddrheuristic,
uint64_t &min_addr,
uint64_t &max_addr)
{
const uint32_t num_sections = section_list.GetSize();
for (uint32_t i = 0; i<num_sections; ++i)
{
SectionSP section_sp(section_list.GetSectionAtIndex(i));
if (section_sp)
{
if(section_sp->IsFake()) {
uint64_t lower = (uint64_t)-1;
uint64_t upper = 0;
updateSectionLoadAddress(section_sp->GetChildren(), target, symbolfile_addr, symbolfile_size, vmaddrheuristic,
lower, upper);
if (lower < min_addr)
min_addr = lower;
if (upper > max_addr)
max_addr = upper;
const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress();
section_sp->Slide(slide_amount, false);
section_sp->GetChildren().Slide(-slide_amount, false);
section_sp->SetByteSize (upper - lower);
} else {
vmaddrheuristic += 2<<section_sp->GetLog2Align();
uint64_t lower;
if (section_sp->GetFileAddress() > vmaddrheuristic)
lower = section_sp->GetFileAddress();
else {
lower = symbolfile_addr+section_sp->GetFileOffset();
section_sp->SetFileAddress(symbolfile_addr+section_sp->GetFileOffset());
}
target.SetSectionLoadAddress(section_sp, lower, true);
uint64_t upper = lower + section_sp->GetByteSize();
if (lower < min_addr)
min_addr = lower;
if (upper > max_addr)
max_addr = upper;
// This is an upper bound, but a good enough heuristic
vmaddrheuristic += section_sp->GetByteSize();
}
}
}
}

bool
JITLoaderGDB::ReadJITDescriptor(bool all_entries)
{
Expand Down Expand Up @@ -209,10 +260,27 @@ JITLoaderGDB::ReadJITDescriptor(bool all_entries)
if (module_sp && module_sp->GetObjectFile())
{
bool changed;
m_jit_objects.insert(
std::pair<lldb::addr_t, const lldb::ModuleSP>(
symbolfile_addr, module_sp));
module_sp->SetLoadAddress(target, 0, true, changed);
m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o"))
{
ObjectFile *image_object_file = module_sp->GetObjectFile();
if (image_object_file)
{
const SectionList *section_list = image_object_file->GetSectionList ();
if (section_list)
{
uint64_t vmaddrheuristic = 0;
uint64_t lower = (uint64_t)-1;
uint64_t upper = 0;
updateSectionLoadAddress(*section_list, target, symbolfile_addr, symbolfile_size,
vmaddrheuristic, lower, upper);
}
}
}
else
{
module_sp->SetLoadAddress(target, 0, true, changed);
}

// load the symbol table right away
module_sp->GetObjectFile()->GetSymtab();
Expand Down
2 changes: 2 additions & 0 deletions source/Plugins/Makefile
Expand Up @@ -33,6 +33,8 @@ DIRS += SymbolVendor/MacOSX
#DIRS += Process/MacOSX-User
DIRS += Process/mach-core
DIRS += SystemRuntime/MacOSX
DIRS += Process/elf-core
DIRS += JITLoader/GDB
endif

ifeq ($(HOST_OS),Linux)
Expand Down
1 change: 1 addition & 0 deletions source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Expand Up @@ -1236,6 +1236,7 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)
vm_size, // VM size in bytes of this section.
header.sh_offset, // Offset of this section in the file.
file_size, // Size of the section as found in the file.
__builtin_ffs(header.sh_addralign), // Alignment of the section
header.sh_flags)); // Flags for this section.

if (is_thread_specific)
Expand Down
5 changes: 4 additions & 1 deletion source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Expand Up @@ -1346,6 +1346,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
load_cmd.vmsize, // VM size in bytes of this section
load_cmd.fileoff, // Offset to the data for this section in the file
load_cmd.filesize, // Size in bytes of this section as found in the the file
0, // Segments have no alignment information
load_cmd.flags)); // Flags for this section

segment_sp->SetIsEncrypted (segment_is_encrypted);
Expand Down Expand Up @@ -1474,6 +1475,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
sect64.size, // VM size in bytes of this section
sect64.offset, // Offset to the data for this section in the file
sect64.offset ? sect64.size : 0, // Size in bytes of this section as found in the the file
sect64.align,
load_cmd.flags)); // Flags for this section
segment_sp->SetIsFake(true);

Expand Down Expand Up @@ -1612,6 +1614,7 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
sect64.size,
sect64.offset,
sect64.offset == 0 ? 0 : sect64.size,
sect64.align,
sect64.flags));
// Set the section to be encrypted to match the segment

Expand Down Expand Up @@ -2022,7 +2025,7 @@ ObjectFileMachO::ParseSymtab ()

uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete;

if (process)
if (process && m_header.filetype != llvm::MachO::MH_OBJECT)
{
Target &target = process->GetTarget();

Expand Down
1 change: 1 addition & 0 deletions source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
Expand Up @@ -753,6 +753,7 @@ ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
m_sect_headers[idx].vmsize, // VM size in bytes of this section
m_sect_headers[idx].offset, // Offset to the data for this section in the file
m_sect_headers[idx].size, // Size in bytes of this section as found in the the file
m_coff_header_opt.sect_alignment, // Section alignment
m_sect_headers[idx].flags)); // Flags for this section

//section_sp->SetIsEncrypted (segment_is_encrypted);
Expand Down

0 comments on commit a900ab6

Please sign in to comment.