Index: include/lldb/Core/Section.h =================================================================== --- include/lldb/Core/Section.h +++ include/lldb/Core/Section.h @@ -119,6 +119,7 @@ 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 @@ -132,6 +133,7 @@ lldb::addr_t vm_size, lldb::offset_t file_offset, lldb::offset_t file_size, + uint32_t log2align, uint32_t flags); ~Section (); @@ -284,6 +286,17 @@ return m_obj_file; } + uint32_t GetLog2Align() + { + return m_log2align; + } + + void + SetLog2Align(uint32_t align) + { + m_log2align = align; + } + protected: @@ -296,6 +309,7 @@ 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 Index: lib/Makefile =================================================================== --- lib/Makefile +++ lib/Makefile @@ -101,7 +101,9 @@ lldbPluginSymbolVendorMacOSX.a \ lldbPluginProcessDarwin.a \ lldbPluginProcessMachCore.a \ - lldbPluginSystemRuntimeMacOSX.a + lldbPluginSystemRuntimeMacOSX.a \ + lldbPluginProcessElfCore.a \ + lldbPluginJITLoaderGDB.a endif ifeq ($(HOST_OS),Linux) Index: source/Core/Section.cpp =================================================================== --- source/Core/Section.cpp +++ source/Core/Section.cpp @@ -27,6 +27,7 @@ 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), @@ -39,6 +40,7 @@ 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), @@ -58,6 +60,7 @@ 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), @@ -70,6 +73,7 @@ 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), @@ -142,7 +146,7 @@ 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
(this)->shared_from_this()); } Index: source/Expression/IRExecutionUnit.cpp =================================================================== --- source/Expression/IRExecutionUnit.cpp +++ source/Expression/IRExecutionUnit.cpp @@ -917,6 +917,7 @@ 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); } Index: source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp =================================================================== --- source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -144,6 +144,29 @@ return instance->ReadJITDescriptor(false); } +static void updateSectionLoadAddress(const SectionList §ion_list, Target &target, uint64_t symbolfile_addr, uint64_t symbolfile_size, uint64_t &vmaddrheuristic) +{ + const uint32_t num_sections = section_list.GetSize(); + for (uint32_t i = 0; iIsFake()) { + updateSectionLoadAddress(section_sp->GetChildren(), target, symbolfile_addr, symbolfile_size, vmaddrheuristic); + } + else if (section_sp->GetFileAddress() > vmaddrheuristic) + target.SetSectionLoadAddress(section_sp, section_sp->GetFileAddress(), true); + else { + section_sp->SetFileAddress(symbolfile_addr+section_sp->GetFileOffset()); + target.SetSectionLoadAddress(section_sp, symbolfile_addr+section_sp->GetFileOffset(), true); + } + // This is an upper bound, but a good enough heuristic + vmaddrheuristic += section_sp->GetByteSize() + (2<GetLog2Align()); + } + } +} + bool JITLoaderGDB::ReadJITDescriptor(bool all_entries) { @@ -212,7 +235,23 @@ m_jit_objects.insert( std::pair( symbolfile_addr, module_sp)); - module_sp->SetLoadAddress(target, 0, true, changed); + 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; + updateSectionLoadAddress(*section_list, target, symbolfile_addr, symbolfile_size, vmaddrheuristic); + } + } + } + else + { + module_sp->SetLoadAddress(target, 0, true, changed); + } // load the symbol table right away module_sp->GetObjectFile()->GetSymtab(); @@ -295,9 +334,7 @@ JITLoaderGDB::CreateInstance(Process *process, bool force) { JITLoaderSP jit_loader_sp; - ArchSpec arch (process->GetTarget().GetArchitecture()); - if (arch.GetTriple().getVendor() != llvm::Triple::Apple) - jit_loader_sp.reset(new JITLoaderGDB(process)); + jit_loader_sp.reset(new JITLoaderGDB(process)); return jit_loader_sp; } Index: source/Plugins/Makefile =================================================================== --- source/Plugins/Makefile +++ source/Plugins/Makefile @@ -33,6 +33,8 @@ #DIRS += Process/MacOSX-User DIRS += Process/mach-core DIRS += SystemRuntime/MacOSX +DIRS += Process/elf-core +DIRS += JITLoader/GDB endif ifeq ($(HOST_OS),Linux) Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1236,6 +1236,7 @@ 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) Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1220,6 +1220,7 @@ 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); @@ -1348,6 +1349,7 @@ 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); @@ -1480,6 +1482,7 @@ sect64.size, sect64.offset, sect64.offset == 0 ? 0 : sect64.size, + sect64.align, sect64.flags)); // Set the section to be encrypted to match the segment @@ -1890,7 +1893,7 @@ uint32_t memory_module_load_level = eMemoryModuleLoadLevelComplete; - if (process) + if (process && m_header.filetype != llvm::MachO::MH_OBJECT) { Target &target = process->GetTarget(); Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp =================================================================== --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -753,6 +753,7 @@ 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);