[Lldb-commits] [lldb] [LLDB] Fix debuginfo ELF files overwriting Unified Section List (PR #166635)
Jacob Lalonde via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 5 12:47:44 PST 2025
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/166635
>From d0ca47b7bde844f1ab8543da4f832ad875ff643e Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Fri, 31 Oct 2025 15:55:02 -0700
Subject: [PATCH 1/5] Add static function to SectionList to support merging,
and implementing merging logic in objectfileELF
---
lldb/include/lldb/Core/Section.h | 11 ++++++++
lldb/source/Core/Section.cpp | 26 +++++++++++++++++
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 28 ++++++++++++++++---
3 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h
index f0f5a0b3499c0..3bde0f3adc12f 100644
--- a/lldb/include/lldb/Core/Section.h
+++ b/lldb/include/lldb/Core/Section.h
@@ -96,6 +96,17 @@ class SectionList {
/// information.
uint64_t GetDebugInfoSize() const;
+ // Callback to decide of two matching sections should be used in the merged
+ // output.
+ using MergeCallback =
+ std::function<lldb::SectionSP(lldb::SectionSP, lldb::SectionSP)>;
+
+ // Function that merges two different sections into a new output list. All
+ // unique sections will be checked for conflict and resolved using the
+ // supplied merging callback.
+ static std::shared_ptr<SectionList> Merge(SectionList &lhs, SectionList &rhs,
+ MergeCallback filter);
+
protected:
collection m_sections;
};
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 02d9d86fe5374..42f220395f7e2 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -683,6 +683,32 @@ uint64_t SectionList::GetDebugInfoSize() const {
return debug_info_size;
}
+std::shared_ptr<SectionList> SectionList::Merge(SectionList &lhs, SectionList &rhs, MergeCallback filter) {
+ std::shared_ptr<SectionList> output_sp = std::make_shared<SectionList>();
+
+ // Iterate through all the sections in lhs and see if we have matches in
+ // the rhs list.
+ for (const auto &lhs_section : lhs) {
+ auto rhs_section = rhs.FindSectionByType(lhs_section->GetType(), true);
+ if (rhs_section)
+ output_sp->AddSection(filter(lhs_section, rhs_section));
+ else
+ output_sp->AddSection(lhs_section);
+ }
+
+ // Now that we've visited all possible duplicates, we can iterate over
+ // the rhs and take any values not in lhs.
+ for (const auto &rhs_section : rhs) {
+ auto lhs_section = lhs.FindSectionByType(rhs_section->GetType(), true);
+ // Because we already visited everything overlapping between rhs
+ // and lhs, any section not in lhs is unique and can be output.
+ if (!lhs_section)
+ output_sp->AddSection(rhs_section);
+ }
+
+ return output_sp;
+}
+
namespace llvm {
namespace json {
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 097c91b623e8f..53e1b3dbc1286 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -130,6 +130,27 @@ class ELFRelocation {
RelocUnion reloc;
};
+
+lldb::SectionSP MergeSections(lldb::SectionSP lhs, lldb::SectionSP rhs) {
+ assert(lhs && rhs);
+
+ // We only take the RHS is the LHS is SHT_NOBITS, which would be
+ // represented as a size of 0. Where we can take the rhs.
+ if (lhs->GetByteSize() == 0)
+ return rhs;
+
+ auto *log = GetLog(LLDBLog::Object);
+ // Now that we're taking the lhs, we should do some sanity checks to warn the user
+ // if this debuginfo/dwp looks invalid.
+ if (lhs->GetByteSize() != rhs->GetByteSize())
+ LLDB_LOGF(log, "WARNING: Mistamched sizes for section %s, expected: %" PRIx64" actual: %" PRIx64, lhs->GetTypeAsCString(), lhs->GetByteSize(), rhs->GetByteSize());
+
+ if (lhs->GetFileAddress() != rhs->GetFileAddress())
+ LLDB_LOGF(log, "WARNING: Mismatch addresses for section %s, expected: %" PRIx64" actual: %" PRIx64, lhs->GetTypeAsCString(), lhs->GetFileAddress(), rhs->GetFileAddress());
+
+ return lhs;
+}
+
} // end anonymous namespace
ELFRelocation::ELFRelocation(unsigned type) {
@@ -1967,10 +1988,9 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
- // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
- // unified section list.
- if (GetType() != eTypeDebugInfo)
- unified_section_list = *m_sections_up;
+ // Merge the two, keeping any unique sections
+ std::shared_ptr<SectionList> merged_section_list = SectionList::Merge(unified_section_list, *m_sections_up, MergeSections);
+ unified_section_list = *merged_section_list;
// If there's a .gnu_debugdata section, we'll try to read the .symtab that's
// embedded in there and replace the one in the original object file (if any).
>From 257b149b43c782413bddf4285c6d16b13f7a9ce7 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 3 Nov 2025 10:23:13 -0800
Subject: [PATCH 2/5] Refactor to call module's warning function
---
lldb/source/Core/Section.cpp | 9 +-
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 176 +++++++-----------
2 files changed, 77 insertions(+), 108 deletions(-)
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 42f220395f7e2..763f1b60896d6 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -683,13 +683,14 @@ uint64_t SectionList::GetDebugInfoSize() const {
return debug_info_size;
}
-std::shared_ptr<SectionList> SectionList::Merge(SectionList &lhs, SectionList &rhs, MergeCallback filter) {
+std::shared_ptr<SectionList>
+SectionList::Merge(SectionList &lhs, SectionList &rhs, MergeCallback filter) {
std::shared_ptr<SectionList> output_sp = std::make_shared<SectionList>();
// Iterate through all the sections in lhs and see if we have matches in
// the rhs list.
for (const auto &lhs_section : lhs) {
- auto rhs_section = rhs.FindSectionByType(lhs_section->GetType(), true);
+ auto rhs_section = rhs.FindSectionByID(lhs_section->GetID());
if (rhs_section)
output_sp->AddSection(filter(lhs_section, rhs_section));
else
@@ -697,9 +698,9 @@ std::shared_ptr<SectionList> SectionList::Merge(SectionList &lhs, SectionList &r
}
// Now that we've visited all possible duplicates, we can iterate over
- // the rhs and take any values not in lhs.
+ // the rhs and take any values not in lhs.
for (const auto &rhs_section : rhs) {
- auto lhs_section = lhs.FindSectionByType(rhs_section->GetType(), true);
+ auto lhs_section = lhs.FindSectionByID(rhs_section->GetID());
// Because we already visited everything overlapping between rhs
// and lhs, any section not in lhs is unique and can be output.
if (!lhs_section)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 53e1b3dbc1286..5b47fdc4c2863 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -139,14 +139,29 @@ lldb::SectionSP MergeSections(lldb::SectionSP lhs, lldb::SectionSP rhs) {
if (lhs->GetByteSize() == 0)
return rhs;
- auto *log = GetLog(LLDBLog::Object);
- // Now that we're taking the lhs, we should do some sanity checks to warn the user
- // if this debuginfo/dwp looks invalid.
- if (lhs->GetByteSize() != rhs->GetByteSize())
- LLDB_LOGF(log, "WARNING: Mistamched sizes for section %s, expected: %" PRIx64" actual: %" PRIx64, lhs->GetTypeAsCString(), lhs->GetByteSize(), rhs->GetByteSize());
+ lldb::ModuleSP lhs_module_parent = lhs->GetModule();
+ lldb::ModuleSP rhs_module_parent = rhs->GetModule();
+ assert(lhs_module_parent && rhs_module_parent);
+ // Now that we're taking the lhs, we should do some sanity checks to warn the
+ // user if this debuginfo/dwp looks invalid. However if RHS is SHT_NO_BITS
+ // we want to ignore the size comparison.
+ if (rhs->GetByteSize() > 0 && lhs->GetByteSize() != rhs->GetByteSize())
+ lhs_module_parent->ReportWarning(
+ "Mismatched size for section {0} when merging with {1}, expected: "
+ "{2:x}, "
+ "actual: {3:x}",
+ lhs->GetTypeAsCString(),
+ rhs_module_parent->GetFileSpec().GetPathAsConstString().GetCString(),
+ lhs->GetByteSize(), rhs->GetByteSize());
if (lhs->GetFileAddress() != rhs->GetFileAddress())
- LLDB_LOGF(log, "WARNING: Mismatch addresses for section %s, expected: %" PRIx64" actual: %" PRIx64, lhs->GetTypeAsCString(), lhs->GetFileAddress(), rhs->GetFileAddress());
+ lhs_module_parent->ReportWarning(
+ "Mismatch addresses for section {0} when "
+ "merging with {1}, expected: {2:x}, "
+ "actual: {3:x}",
+ lhs->GetTypeAsCString(),
+ rhs_module_parent->GetFileSpec().GetPathAsConstString().GetCString(),
+ lhs->GetByteSize(), rhs->GetByteSize());
return lhs;
}
@@ -228,16 +243,14 @@ elf_sxword ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
return llvm::cast<ELFRela *>(rel.reloc)->r_addend;
}
-elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
+elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
if (llvm::isa<ELFRel *>(rel.reloc))
return 0;
else
return llvm::cast<ELFRela *>(rel.reloc)->r_addend;
}
-static user_id_t SegmentID(size_t PHdrIndex) {
- return ~user_id_t(PHdrIndex);
-}
+static user_id_t SegmentID(size_t PHdrIndex) { return ~user_id_t(PHdrIndex); }
bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
// Read all fields.
@@ -270,7 +283,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
return true;
}
-static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
+static uint32_t mipsVariantFromElfFlags(const elf::ELFHeader &header) {
const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
uint32_t endian = header.e_ident[EI_DATA];
uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
@@ -278,7 +291,8 @@ static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
// If there aren't any elf flags available (e.g core elf file) then return
// default
- // 32 or 64 bit arch (without any architecture revision) based on object file's class.
+ // 32 or 64 bit arch (without any architecture revision) based on object
+ // file's class.
if (header.e_type == ET_CORE) {
switch (fileclass) {
case llvm::ELF::ELFCLASS32:
@@ -847,24 +861,6 @@ bool ObjectFileELF::ParseHeader() {
}
UUID ObjectFileELF::GetUUID() {
- if (m_uuid)
- return m_uuid;
-
- // Try loading note info from any PT_NOTE program headers. This is more
- // friendly to ELF files that have no section headers, like ELF files that
- // are loaded from memory.
- for (const ELFProgramHeader &H : ProgramHeaders()) {
- if (H.p_type == llvm::ELF::PT_NOTE) {
- DataExtractor note_data = GetSegmentData(H);
- if (note_data.GetByteSize()) {
- lldb_private::ArchSpec arch_spec;
- RefineModuleDetailsFromNote(note_data, arch_spec, m_uuid);
- if (m_uuid)
- return m_uuid;
- }
- }
- }
-
// Need to parse the section list to get the UUIDs, so make sure that's been
// done.
if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
@@ -1239,7 +1235,8 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// Set the elf OS version to NetBSD. Also clear the vendor.
arch_spec.GetTriple().setOSName(
llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor,
- version_patch).str());
+ version_patch)
+ .str());
arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
}
// Process NetBSD ELF core(5) notes
@@ -1269,17 +1266,23 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// count = 0x000000000000000a (10)
// page_size = 0x0000000000001000 (4096)
// Index start end file_ofs path
- // ===== ------------------ ------------------ ------------------ -------------------------------------
- // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out
- // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
- // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
- // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
- // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
+ // ===== ------------------ ------------------ ------------------
+ // ------------------------------------- [ 0] 0x0000000000401000
+ // 0x0000000000000000 /tmp/a.out [ 1]
+ // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [
+ // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
+ // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
+ // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000
+ // 0x00007fa79cda7000 0x00000000000001bb
+ // /lib/x86_64-linux-gnu/libc-2.19.so [ 5] 0x00007fa79cda7000
+ // 0x00007fa79cdab000 0x00000000000001ba
+ // /lib/x86_64-linux-gnu/libc-2.19.so [ 6] 0x00007fa79cdab000
+ // 0x00007fa79cdad000 0x00000000000001be
+ // /lib/x86_64-linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000
+ // 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022
+ // /lib/x86_64-linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000
+ // 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
//
// In the 32 bit ELFs the count, page_size, start, end, file_ofs are
// uint32_t.
@@ -1302,7 +1305,8 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
return error;
}
llvm::StringRef path(cstr);
- if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
+ if (path.contains("/lib/x86_64-linux-gnu") ||
+ path.contains("/lib/i386-linux-gnu")) {
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
break;
}
@@ -1606,7 +1610,8 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
DataExtractor data;
if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
- data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
+ data.SetData(object_data, sheader.sh_offset, section_size) ==
+ section_size)
ParseARMAttributes(data, section_size, arch_spec);
}
@@ -1781,7 +1786,7 @@ struct SectionAddressInfo {
// different sections to not overlap. This class handles that logic.
class VMAddressProvider {
using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4,
- llvm::IntervalMapHalfOpenInfo<addr_t>>;
+ llvm::IntervalMapHalfOpenInfo<addr_t>>;
ObjectFile::Type ObjectType;
addr_t NextVMAddress = 0;
@@ -1873,7 +1878,7 @@ class VMAddressProvider {
std::move(Sect));
}
};
-}
+} // namespace
// We have to do this because ELF doesn't have section IDs, and also
// doesn't require section names to be unique. (We use the section index
@@ -1988,8 +1993,10 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
- // Merge the two, keeping any unique sections
- std::shared_ptr<SectionList> merged_section_list = SectionList::Merge(unified_section_list, *m_sections_up, MergeSections);
+ // Merge the two adding any new sections, and overwriting any existing
+ // sections that are SHT_NOBITS
+ std::shared_ptr<SectionList> merged_section_list =
+ SectionList::Merge(unified_section_list, *m_sections_up, MergeSections);
unified_section_list = *merged_section_list;
// If there's a .gnu_debugdata section, we'll try to read the .symtab that's
@@ -2075,22 +2082,9 @@ static char FindArmAarch64MappingSymbol(const char *symbol_name) {
return '\0';
}
-static char FindRISCVMappingSymbol(const char *symbol_name) {
- if (!symbol_name)
- return '\0';
-
- if (strcmp(symbol_name, "$d") == 0) {
- return 'd';
- }
- if (strcmp(symbol_name, "$x") == 0) {
- return 'x';
- }
- return '\0';
-}
-
#define STO_MIPS_ISA (3 << 6)
#define STO_MICROMIPS (2 << 6)
-#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
+#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER) & STO_MIPS_ISA) == STO_MICROMIPS)
// private
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
@@ -2153,12 +2147,6 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (!symbol_name)
symbol_name = "";
- // Skip local symbols starting with ".L" because these are compiler
- // generated local labels used for internal purposes (e.g. debugging,
- // optimization) and are not relevant for symbol resolution or external
- // linkage.
- if (llvm::StringRef(symbol_name).starts_with(".L"))
- continue;
// No need to add non-section symbols that have no names
if (symbol.getType() != STT_SECTION &&
(symbol_name == nullptr || symbol_name[0] == '\0'))
@@ -2247,6 +2235,7 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
int64_t symbol_value_offset = 0;
uint32_t additional_flags = 0;
+
if (arch.IsValid()) {
if (arch.GetMachine() == llvm::Triple::arm) {
if (symbol.getBinding() == STB_LOCAL) {
@@ -2291,27 +2280,6 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (mapping_symbol)
continue;
}
- } else if (arch.GetTriple().isRISCV()) {
- if (symbol.getBinding() == STB_LOCAL) {
- char mapping_symbol = FindRISCVMappingSymbol(symbol_name);
- if (symbol_type == eSymbolTypeCode) {
- // Only handle $d and $x mapping symbols.
- // Other mapping symbols are ignored as they don't affect address
- // classification.
- switch (mapping_symbol) {
- case 'x':
- // $x - marks a RISCV instruction sequence
- address_class_map[symbol.st_value] = AddressClass::eCode;
- break;
- case 'd':
- // $d - marks a RISCV data item sequence
- address_class_map[symbol.st_value] = AddressClass::eData;
- break;
- }
- }
- if (mapping_symbol)
- continue;
- }
}
if (arch.GetMachine() == llvm::Triple::arm) {
@@ -2345,7 +2313,7 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
* flag to check whether the symbol is microMIPS and then set the address
* class
* accordingly.
- */
+ */
if (arch.IsMIPS()) {
if (IS_MICROMIPS(symbol.st_other))
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
@@ -2877,8 +2845,8 @@ unsigned ObjectFileELF::ApplyRelocations(
case R_386_32:
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
if (symbol) {
- addr_t f_offset =
- rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel);
+ addr_t f_offset = rel_section->GetFileOffset() +
+ ELFRelocation::RelocOffset32(rel);
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
WritableDataBuffer *data_buffer =
@@ -2895,8 +2863,8 @@ unsigned ObjectFileELF::ApplyRelocations(
*dst = value;
} else {
GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}",
- rel_section->GetName().AsCString(), i,
- reloc_symbol(rel));
+ rel_section->GetName().AsCString(), i,
+ reloc_symbol(rel));
}
break;
case R_386_NONE:
@@ -2912,7 +2880,8 @@ unsigned ObjectFileELF::ApplyRelocations(
}
break;
default:
- GetModule()->ReportError("unsupported 32-bit ELF machine arch: {0}", hdr->e_machine);
+ GetModule()->ReportError("unsupported 32-bit ELF machine arch: {0}",
+ hdr->e_machine);
break;
}
} else {
@@ -2959,7 +2928,8 @@ unsigned ObjectFileELF::ApplyRelocations(
}
break;
default:
- GetModule()->ReportError("unsupported 64-bit ELF machine arch: {0}", hdr->e_machine);
+ GetModule()->ReportError("unsupported 64-bit ELF machine arch: {0}",
+ hdr->e_machine);
break;
}
}
@@ -3124,8 +3094,8 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
bool is_valid_entry_point =
entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
- if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
- entry_point_file_addr)) {
+ if (is_valid_entry_point &&
+ !lldb_symtab.FindSymbolContainingFileAddress(entry_point_file_addr)) {
uint64_t symbol_id = lldb_symtab.GetNumSymbols();
// Don't set the name for any synthetic symbols, the Symbol
// object will generate one if needed when the name is accessed
@@ -3162,8 +3132,7 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
}
}
-void ObjectFileELF::RelocateSection(lldb_private::Section *section)
-{
+void ObjectFileELF::RelocateSection(lldb_private::Section *section) {
static const char *debug_prefix = ".debug";
// Set relocated bit so we stop getting called, regardless of whether we
@@ -3669,8 +3638,7 @@ ArchSpec ObjectFileELF::GetArchitecture() {
ParseSectionHeaders();
}
- if (CalculateType() == eTypeCoreFile &&
- !m_arch_spec.TripleOSWasSpecified()) {
+ if (CalculateType() == eTypeCoreFile && !m_arch_spec.TripleOSWasSpecified()) {
// Core files don't have section headers yet they have PT_NOTE program
// headers that might shed more light on the architecture
for (const elf::ELFProgramHeader &H : ProgramHeaders()) {
@@ -3770,8 +3738,8 @@ ObjectFile::Strata ObjectFileELF::CalculateStrata() {
}
size_t ObjectFileELF::ReadSectionData(Section *section,
- lldb::offset_t section_offset, void *dst,
- size_t dst_len) {
+ lldb::offset_t section_offset, void *dst,
+ size_t dst_len) {
// If some other objectfile owns this data, pass this to them.
if (section->GetObjectFile() != this)
return section->GetObjectFile()->ReadSectionData(section, section_offset,
>From cb40c995763af49754f34904e0d311ad22b1c11e Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Wed, 5 Nov 2025 11:36:14 -0800
Subject: [PATCH 3/5] Add new test and fix bug with IDs
---
lldb/source/Core/Section.cpp | 9 ++--
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 1 +
.../API/python_api/module_section/Makefile | 4 +-
.../python_api/unified_section_list/Makefile | 5 ++
.../TestModuleUnifiedSectionList.py | 50 +++++++++++++++++++
.../python_api/unified_section_list/main.cpp | 5 ++
6 files changed, 69 insertions(+), 5 deletions(-)
create mode 100644 lldb/test/API/python_api/unified_section_list/Makefile
create mode 100644 lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py
create mode 100644 lldb/test/API/python_api/unified_section_list/main.cpp
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 763f1b60896d6..244cdf934c0ec 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -690,17 +690,18 @@ SectionList::Merge(SectionList &lhs, SectionList &rhs, MergeCallback filter) {
// Iterate through all the sections in lhs and see if we have matches in
// the rhs list.
for (const auto &lhs_section : lhs) {
- auto rhs_section = rhs.FindSectionByID(lhs_section->GetID());
- if (rhs_section)
+ auto rhs_section = rhs.FindSectionByName(lhs_section->GetName());
+ if (rhs_section) {
+ assert(lhs_section->GetName() == rhs_section->GetName());
output_sp->AddSection(filter(lhs_section, rhs_section));
- else
+ } else
output_sp->AddSection(lhs_section);
}
// Now that we've visited all possible duplicates, we can iterate over
// the rhs and take any values not in lhs.
for (const auto &rhs_section : rhs) {
- auto lhs_section = lhs.FindSectionByID(rhs_section->GetID());
+ auto lhs_section = lhs.FindSectionByName(rhs_section->GetName());
// Because we already visited everything overlapping between rhs
// and lhs, any section not in lhs is unique and can be output.
if (!lhs_section)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 5b47fdc4c2863..6018fe37c0ad4 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -142,6 +142,7 @@ lldb::SectionSP MergeSections(lldb::SectionSP lhs, lldb::SectionSP rhs) {
lldb::ModuleSP lhs_module_parent = lhs->GetModule();
lldb::ModuleSP rhs_module_parent = rhs->GetModule();
assert(lhs_module_parent && rhs_module_parent);
+
// Now that we're taking the lhs, we should do some sanity checks to warn the
// user if this debuginfo/dwp looks invalid. However if RHS is SHT_NO_BITS
// we want to ignore the size comparison.
diff --git a/lldb/test/API/python_api/module_section/Makefile b/lldb/test/API/python_api/module_section/Makefile
index 79209db9696aa..07910f74e232b 100644
--- a/lldb/test/API/python_api/module_section/Makefile
+++ b/lldb/test/API/python_api/module_section/Makefile
@@ -1,6 +1,8 @@
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
ENABLE_THREADS := YES
-CXX_SOURCES := main.cpp b.cpp c.cpp
+CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
+
+
include Makefile.rules
diff --git a/lldb/test/API/python_api/unified_section_list/Makefile b/lldb/test/API/python_api/unified_section_list/Makefile
new file mode 100644
index 0000000000000..431e716ab8f69
--- /dev/null
+++ b/lldb/test/API/python_api/unified_section_list/Makefile
@@ -0,0 +1,5 @@
+CXX_SOURCES := main.cpp
+
+SPLIT_DEBUG_SYMBOLS := YES
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py b/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py
new file mode 100644
index 0000000000000..dfec5f630bfb0
--- /dev/null
+++ b/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py
@@ -0,0 +1,50 @@
+"""
+Test Unified Section List merging.
+"""
+
+import os
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from lldbsuite.test.lldbutil import symbol_type_to_str
+
+
+class ModuleUnifiedSectionList(TestBase):
+ def test_unified_section_list(self):
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+ debug_info = self.getBuildArtifact("a.out.debug")
+ new_dir = os.path.join(os.path.dirname(debug_info), "new_dir")
+ os.mkdir(new_dir)
+ renamed_debug_info = os.path.join(new_dir, "renamed.debug")
+ os.rename(debug_info, renamed_debug_info)
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ self.assertGreater(target.GetNumModules(), 0)
+
+ main_exe_module = target.GetModuleAtIndex(0)
+ eh_frame = main_exe_module.FindSection(".eh_frame")
+ self.assertTrue(eh_frame.IsValid())
+ self.assertGreater(eh_frame.size, 0)
+
+ # Should be stripped in main executable.
+ debug_info_section = main_exe_module.FindSection(".debug_info")
+ self.assertFalse(debug_info_section.IsValid())
+
+ ci = self.dbg.GetCommandInterpreter()
+ res = lldb.SBCommandReturnObject()
+ ci.HandleCommand(f"target symbols add {renamed_debug_info}", res)
+ self.assertTrue(res.Succeeded())
+
+ # Should be stripped in .debuginfo but be present in main executable.
+ main_exe_module = target.GetModuleAtIndex(0)
+ eh_frame = main_exe_module.FindSection(".eh_frame")
+ self.assertTrue(eh_frame.IsValid())
+ self.assertGreater(eh_frame.size, 0)
+
+ # Should be unified and both sections should have contents.
+ debug_info_section = main_exe_module.FindSection(".debug_info")
+ self.assertTrue(debug_info_section.IsValid())
+ self.assertGreater(debug_info_section.file_size, 0)
diff --git a/lldb/test/API/python_api/unified_section_list/main.cpp b/lldb/test/API/python_api/unified_section_list/main.cpp
new file mode 100644
index 0000000000000..943123b4059db
--- /dev/null
+++ b/lldb/test/API/python_api/unified_section_list/main.cpp
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main() {
+ printf("Hello World\n");
+}
>From f7763af2e6603d48e51ffd05cb084378a6b5bfb6 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Wed, 5 Nov 2025 11:41:18 -0800
Subject: [PATCH 4/5] Fix accidental formatting
---
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 144 ++++++++++++------
.../API/python_api/module_section/Makefile | 4 +-
2 files changed, 97 insertions(+), 51 deletions(-)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 6018fe37c0ad4..06815b03d47c5 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -166,7 +166,6 @@ lldb::SectionSP MergeSections(lldb::SectionSP lhs, lldb::SectionSP rhs) {
return lhs;
}
-
} // end anonymous namespace
ELFRelocation::ELFRelocation(unsigned type) {
@@ -244,14 +243,16 @@ elf_sxword ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
return llvm::cast<ELFRela *>(rel.reloc)->r_addend;
}
-elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
+elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
if (llvm::isa<ELFRel *>(rel.reloc))
return 0;
else
return llvm::cast<ELFRela *>(rel.reloc)->r_addend;
}
-static user_id_t SegmentID(size_t PHdrIndex) { return ~user_id_t(PHdrIndex); }
+static user_id_t SegmentID(size_t PHdrIndex) {
+ return ~user_id_t(PHdrIndex);
+}
bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
// Read all fields.
@@ -284,7 +285,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
return true;
}
-static uint32_t mipsVariantFromElfFlags(const elf::ELFHeader &header) {
+static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
uint32_t endian = header.e_ident[EI_DATA];
uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
@@ -292,8 +293,7 @@ static uint32_t mipsVariantFromElfFlags(const elf::ELFHeader &header) {
// If there aren't any elf flags available (e.g core elf file) then return
// default
- // 32 or 64 bit arch (without any architecture revision) based on object
- // file's class.
+ // 32 or 64 bit arch (without any architecture revision) based on object file's class.
if (header.e_type == ET_CORE) {
switch (fileclass) {
case llvm::ELF::ELFCLASS32:
@@ -862,6 +862,24 @@ bool ObjectFileELF::ParseHeader() {
}
UUID ObjectFileELF::GetUUID() {
+ if (m_uuid)
+ return m_uuid;
+
+ // Try loading note info from any PT_NOTE program headers. This is more
+ // friendly to ELF files that have no section headers, like ELF files that
+ // are loaded from memory.
+ for (const ELFProgramHeader &H : ProgramHeaders()) {
+ if (H.p_type == llvm::ELF::PT_NOTE) {
+ DataExtractor note_data = GetSegmentData(H);
+ if (note_data.GetByteSize()) {
+ lldb_private::ArchSpec arch_spec;
+ RefineModuleDetailsFromNote(note_data, arch_spec, m_uuid);
+ if (m_uuid)
+ return m_uuid;
+ }
+ }
+ }
+
// Need to parse the section list to get the UUIDs, so make sure that's been
// done.
if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
@@ -1236,8 +1254,7 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// Set the elf OS version to NetBSD. Also clear the vendor.
arch_spec.GetTriple().setOSName(
llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor,
- version_patch)
- .str());
+ version_patch).str());
arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
}
// Process NetBSD ELF core(5) notes
@@ -1267,23 +1284,17 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
// count = 0x000000000000000a (10)
// page_size = 0x0000000000001000 (4096)
// Index start end file_ofs path
- // ===== ------------------ ------------------ ------------------
- // ------------------------------------- [ 0] 0x0000000000401000
- // 0x0000000000000000 /tmp/a.out [ 1]
- // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [
- // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
- // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
- // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000
- // 0x00007fa79cda7000 0x00000000000001bb
- // /lib/x86_64-linux-gnu/libc-2.19.so [ 5] 0x00007fa79cda7000
- // 0x00007fa79cdab000 0x00000000000001ba
- // /lib/x86_64-linux-gnu/libc-2.19.so [ 6] 0x00007fa79cdab000
- // 0x00007fa79cdad000 0x00000000000001be
- // /lib/x86_64-linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000
- // 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
- // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022
- // /lib/x86_64-linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000
- // 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
+ // ===== ------------------ ------------------ ------------------ -------------------------------------
+ // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out
+ // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
+ // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
+ // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
+ // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
+ // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
//
// In the 32 bit ELFs the count, page_size, start, end, file_ofs are
// uint32_t.
@@ -1306,8 +1317,7 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
return error;
}
llvm::StringRef path(cstr);
- if (path.contains("/lib/x86_64-linux-gnu") ||
- path.contains("/lib/i386-linux-gnu")) {
+ if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
break;
}
@@ -1611,8 +1621,7 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
DataExtractor data;
if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
- data.SetData(object_data, sheader.sh_offset, section_size) ==
- section_size)
+ data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
ParseARMAttributes(data, section_size, arch_spec);
}
@@ -1787,7 +1796,7 @@ struct SectionAddressInfo {
// different sections to not overlap. This class handles that logic.
class VMAddressProvider {
using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4,
- llvm::IntervalMapHalfOpenInfo<addr_t>>;
+ llvm::IntervalMapHalfOpenInfo<addr_t>>;
ObjectFile::Type ObjectType;
addr_t NextVMAddress = 0;
@@ -1879,7 +1888,7 @@ class VMAddressProvider {
std::move(Sect));
}
};
-} // namespace
+}
// We have to do this because ELF doesn't have section IDs, and also
// doesn't require section names to be unique. (We use the section index
@@ -2083,9 +2092,22 @@ static char FindArmAarch64MappingSymbol(const char *symbol_name) {
return '\0';
}
+static char FindRISCVMappingSymbol(const char *symbol_name) {
+ if (!symbol_name)
+ return '\0';
+
+ if (strcmp(symbol_name, "$d") == 0) {
+ return 'd';
+ }
+ if (strcmp(symbol_name, "$x") == 0) {
+ return 'x';
+ }
+ return '\0';
+}
+
#define STO_MIPS_ISA (3 << 6)
#define STO_MICROMIPS (2 << 6)
-#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER) & STO_MIPS_ISA) == STO_MICROMIPS)
+#define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
// private
std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
@@ -2148,6 +2170,12 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (!symbol_name)
symbol_name = "";
+ // Skip local symbols starting with ".L" because these are compiler
+ // generated local labels used for internal purposes (e.g. debugging,
+ // optimization) and are not relevant for symbol resolution or external
+ // linkage.
+ if (llvm::StringRef(symbol_name).starts_with(".L"))
+ continue;
// No need to add non-section symbols that have no names
if (symbol.getType() != STT_SECTION &&
(symbol_name == nullptr || symbol_name[0] == '\0'))
@@ -2236,7 +2264,6 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
int64_t symbol_value_offset = 0;
uint32_t additional_flags = 0;
-
if (arch.IsValid()) {
if (arch.GetMachine() == llvm::Triple::arm) {
if (symbol.getBinding() == STB_LOCAL) {
@@ -2281,6 +2308,27 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (mapping_symbol)
continue;
}
+ } else if (arch.GetTriple().isRISCV()) {
+ if (symbol.getBinding() == STB_LOCAL) {
+ char mapping_symbol = FindRISCVMappingSymbol(symbol_name);
+ if (symbol_type == eSymbolTypeCode) {
+ // Only handle $d and $x mapping symbols.
+ // Other mapping symbols are ignored as they don't affect address
+ // classification.
+ switch (mapping_symbol) {
+ case 'x':
+ // $x - marks a RISCV instruction sequence
+ address_class_map[symbol.st_value] = AddressClass::eCode;
+ break;
+ case 'd':
+ // $d - marks a RISCV data item sequence
+ address_class_map[symbol.st_value] = AddressClass::eData;
+ break;
+ }
+ }
+ if (mapping_symbol)
+ continue;
+ }
}
if (arch.GetMachine() == llvm::Triple::arm) {
@@ -2314,7 +2362,7 @@ ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
* flag to check whether the symbol is microMIPS and then set the address
* class
* accordingly.
- */
+ */
if (arch.IsMIPS()) {
if (IS_MICROMIPS(symbol.st_other))
address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
@@ -2846,8 +2894,8 @@ unsigned ObjectFileELF::ApplyRelocations(
case R_386_32:
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
if (symbol) {
- addr_t f_offset = rel_section->GetFileOffset() +
- ELFRelocation::RelocOffset32(rel);
+ addr_t f_offset =
+ rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel);
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
WritableDataBuffer *data_buffer =
@@ -2864,8 +2912,8 @@ unsigned ObjectFileELF::ApplyRelocations(
*dst = value;
} else {
GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}",
- rel_section->GetName().AsCString(), i,
- reloc_symbol(rel));
+ rel_section->GetName().AsCString(), i,
+ reloc_symbol(rel));
}
break;
case R_386_NONE:
@@ -2881,8 +2929,7 @@ unsigned ObjectFileELF::ApplyRelocations(
}
break;
default:
- GetModule()->ReportError("unsupported 32-bit ELF machine arch: {0}",
- hdr->e_machine);
+ GetModule()->ReportError("unsupported 32-bit ELF machine arch: {0}", hdr->e_machine);
break;
}
} else {
@@ -2929,8 +2976,7 @@ unsigned ObjectFileELF::ApplyRelocations(
}
break;
default:
- GetModule()->ReportError("unsupported 64-bit ELF machine arch: {0}",
- hdr->e_machine);
+ GetModule()->ReportError("unsupported 64-bit ELF machine arch: {0}", hdr->e_machine);
break;
}
}
@@ -3095,8 +3141,8 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
bool is_valid_entry_point =
entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
- if (is_valid_entry_point &&
- !lldb_symtab.FindSymbolContainingFileAddress(entry_point_file_addr)) {
+ if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
+ entry_point_file_addr)) {
uint64_t symbol_id = lldb_symtab.GetNumSymbols();
// Don't set the name for any synthetic symbols, the Symbol
// object will generate one if needed when the name is accessed
@@ -3133,7 +3179,8 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
}
}
-void ObjectFileELF::RelocateSection(lldb_private::Section *section) {
+void ObjectFileELF::RelocateSection(lldb_private::Section *section)
+{
static const char *debug_prefix = ".debug";
// Set relocated bit so we stop getting called, regardless of whether we
@@ -3639,7 +3686,8 @@ ArchSpec ObjectFileELF::GetArchitecture() {
ParseSectionHeaders();
}
- if (CalculateType() == eTypeCoreFile && !m_arch_spec.TripleOSWasSpecified()) {
+ if (CalculateType() == eTypeCoreFile &&
+ !m_arch_spec.TripleOSWasSpecified()) {
// Core files don't have section headers yet they have PT_NOTE program
// headers that might shed more light on the architecture
for (const elf::ELFProgramHeader &H : ProgramHeaders()) {
@@ -3739,8 +3787,8 @@ ObjectFile::Strata ObjectFileELF::CalculateStrata() {
}
size_t ObjectFileELF::ReadSectionData(Section *section,
- lldb::offset_t section_offset, void *dst,
- size_t dst_len) {
+ lldb::offset_t section_offset, void *dst,
+ size_t dst_len) {
// If some other objectfile owns this data, pass this to them.
if (section->GetObjectFile() != this)
return section->GetObjectFile()->ReadSectionData(section, section_offset,
diff --git a/lldb/test/API/python_api/module_section/Makefile b/lldb/test/API/python_api/module_section/Makefile
index 07910f74e232b..79209db9696aa 100644
--- a/lldb/test/API/python_api/module_section/Makefile
+++ b/lldb/test/API/python_api/module_section/Makefile
@@ -1,8 +1,6 @@
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
ENABLE_THREADS := YES
-CXX_SOURCES := main.cpp
+CXX_SOURCES := main.cpp b.cpp c.cpp
MAKE_DSYM :=NO
-
-
include Makefile.rules
>From 19c54b9b7777def06dac970e3337db342c528d27 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Wed, 5 Nov 2025 12:47:27 -0800
Subject: [PATCH 5/5] only test Nix hosts and run formatters again
---
.../unified_section_list/TestModuleUnifiedSectionList.py | 2 ++
lldb/test/API/python_api/unified_section_list/main.cpp | 4 +---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py b/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py
index dfec5f630bfb0..11a7aea8612f1 100644
--- a/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py
+++ b/lldb/test/API/python_api/unified_section_list/TestModuleUnifiedSectionList.py
@@ -12,6 +12,8 @@
class ModuleUnifiedSectionList(TestBase):
+
+ @skipUnlessPlatform(["linux", "freebsd", "netbsd"])
def test_unified_section_list(self):
self.build()
exe = self.getBuildArtifact("a.out")
diff --git a/lldb/test/API/python_api/unified_section_list/main.cpp b/lldb/test/API/python_api/unified_section_list/main.cpp
index 943123b4059db..45fd52eeeb303 100644
--- a/lldb/test/API/python_api/unified_section_list/main.cpp
+++ b/lldb/test/API/python_api/unified_section_list/main.cpp
@@ -1,5 +1,3 @@
#include <stdio.h>
-int main() {
- printf("Hello World\n");
-}
+int main() { printf("Hello World\n"); }
More information about the lldb-commits
mailing list