Skip to content

Commit

Permalink
[DWARF] Don't process .debug_info relocations for DWO Context
Browse files Browse the repository at this point in the history
When we build with split dwarf in single mode the .o files that contain both "normal" debug sections and dwo sections, along with relocaiton sections for "normal" debug sections.
When we create DWARF context in DWARFObjInMemory we process relocations and store them in the map for .debug_info, etc section.
For DWO Context we also do it for non dwo dwarf sections. Which I believe is not necessary. This leads to a lot of memory being wasted. We observed 70GB extra memory being used.

I went with context sensitive approach, flag is passed in. I am not sure if it's always safe not to process relocations for regular debug sections if Obj contains .dwo sections.
If it is alternatvie might be just to scan, in constructor, sections and if there are .dwo sections not to process regular debug ones.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D106624
  • Loading branch information
ayermolo committed Aug 2, 2021
1 parent ce1c59d commit 5a865b0
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 27 deletions.
7 changes: 5 additions & 2 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Expand Up @@ -387,9 +387,12 @@ class DWARFContext : public DIContext {

function_ref<void(Error)> getWarningHandler() { return WarningHandler; }

enum class ProcessDebugRelocations { Process, Ignore };

static std::unique_ptr<DWARFContext>
create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
std::string DWPName = "",
create(const object::ObjectFile &Obj,
ProcessDebugRelocations RelocAction = ProcessDebugRelocations::Process,
const LoadedObjectInfo *L = nullptr, std::string DWPName = "",
std::function<void(Error)> RecoverableErrorHandler =
WithColor::defaultErrorHandler,
std::function<void(Error)> WarningHandler =
Expand Down
31 changes: 16 additions & 15 deletions llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Expand Up @@ -1411,7 +1411,8 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) {

auto S = std::make_shared<DWOFile>();
S->File = std::move(Obj.get());
S->Context = DWARFContext::create(*S->File.getBinary());
S->Context = DWARFContext::create(*S->File.getBinary(),
ProcessDebugRelocations::Ignore);
*Entry = S;
auto *Ctxt = S->Context.get();
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
Expand Down Expand Up @@ -1652,7 +1653,9 @@ class DWARFObjInMemory final : public DWARFObject {
}
}
DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
function_ref<void(Error)> HandleError, function_ref<void(Error)> HandleWarning )
function_ref<void(Error)> HandleError,
function_ref<void(Error)> HandleWarning,
DWARFContext::ProcessDebugRelocations RelocAction)
: IsLittleEndian(Obj.isLittleEndian()),
AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
Obj(&Obj) {
Expand Down Expand Up @@ -1735,7 +1738,12 @@ class DWARFObjInMemory final : public DWARFObject {
S.Data = Data;
}

if (RelocatedSection == Obj.section_end())
if (RelocatedSection != Obj.section_end() && Name.contains(".dwo"))
HandleWarning(
createError("Unexpected relocations for dwo section " + Name));

if (RelocatedSection == Obj.section_end() ||
(RelocAction == DWARFContext::ProcessDebugRelocations::Ignore))
continue;

StringRef RelSecName;
Expand Down Expand Up @@ -1772,18 +1780,10 @@ class DWARFObjInMemory final : public DWARFObject {
if (RelSecName == "debug_info")
Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
.Relocs;
else if (RelSecName == "debug_info.dwo")
Map = &static_cast<DWARFSectionMap &>(
InfoDWOSections[*RelocatedSection])
.Relocs;
else if (RelSecName == "debug_types")
Map =
&static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
.Relocs;
else if (RelSecName == "debug_types.dwo")
Map = &static_cast<DWARFSectionMap &>(
TypesDWOSections[*RelocatedSection])
.Relocs;
else
continue;
}
Expand Down Expand Up @@ -1966,12 +1966,13 @@ class DWARFObjInMemory final : public DWARFObject {
} // namespace

std::unique_ptr<DWARFContext>
DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
std::string DWPName,
DWARFContext::create(const object::ObjectFile &Obj,
ProcessDebugRelocations RelocAction,
const LoadedObjectInfo *L, std::string DWPName,
std::function<void(Error)> RecoverableErrorHandler,
std::function<void(Error)> WarningHandler) {
auto DObj =
std::make_unique<DWARFObjInMemory>(Obj, L, RecoverableErrorHandler, WarningHandler);
auto DObj = std::make_unique<DWARFObjInMemory>(
Obj, L, RecoverableErrorHandler, WarningHandler, RelocAction);
return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
RecoverableErrorHandler,
WarningHandler);
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
Expand Up @@ -600,7 +600,9 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
}
}
if (!Context)
Context = DWARFContext::create(*Objects.second, nullptr, Opts.DWPName);
Context = DWARFContext::create(
*Objects.second, DWARFContext::ProcessDebugRelocations::Process,
nullptr, Opts.DWPName);
return createModuleInfo(Objects.first, std::move(Context), ModuleName);
}

Expand Down
57 changes: 57 additions & 0 deletions llvm/test/DebugInfo/X86/dwarfdump-rela-dwo.s
@@ -0,0 +1,57 @@
# Test objective to verify warning is printed if DWO secton has relocations.
#
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
# RUN: llvm-dwarfdump --debug-info %t.o | FileCheck %s
# RUN: llvm-dwarfdump --debug-info %t.o 2> %t.txt
# RUN: cat %t.txt | FileCheck %s --check-prefix=PART2

.section .debug_str.dwo,"MSe",@progbits,1
.dwo_producer:
.asciz "Handmade DWO producer"
.dwo_CU_5:
.asciz "V5_dwo_compile_unit"

.section .debug_str_offsets.dwo,"e",@progbits
.long Lstr_offsets_end-Lstr_offsets_start # Length of String Offsets Set
Lstr_offsets_start:
.short 5
.short 0
.long .dwo_producer-.debug_str.dwo
.long .dwo_CU_5-.debug_str.dwo
Lstr_offsets_end:

# And a .dwo copy for the .dwo sections.
.section .debug_abbrev.dwo,"e",@progbits
.byte 0x01 # Abbrev code
.byte 0x11 # DW_TAG_compile_unit
.byte 0x00 # DW_CHILDREN_no
.byte 0x25 # DW_AT_producer
.byte 0x0e # DW_FORM_strp
.byte 0x03 # DW_AT_name
.byte 0x25 # DW_FORM_strx1
.byte 0x00 # EOM(1)
.byte 0x00 # EOM(2)

.section .debug_info.dwo,"e",@progbits
# CHECK-LABEL: .debug_info.dwo

# DWARF v5 split CU header.
.long CU_split_5_end-CU_split_5_version # Length of Unit
CU_split_5_version:
.short 5 # DWARF version number
.byte 5 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long 0 # Offset Into Abbrev. Section
.quad 0x5a # DWO ID
# The split compile-unit DIE, with DW_AT_producer, DW_AT_name, DW_AT_stmt_list.
.byte 1
.long .dwo_producer
.byte 1
.byte 0 # NULL
CU_split_5_end:

# CHECK: 0x00000000: Compile Unit: length = 0x00000017, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = 0x000000000000005a (next unit at 0x0000001b)
# CHECK: 0x00000014: DW_TAG_compile_unit
# CHECK-NEXT: DW_AT_producer ("Handmade DWO producer")
# CHECK-NEXT: DW_AT_name ("V5_dwo_compile_unit")
# PART2: warning: Unexpected relocations for dwo section rela.debug_info.dwo
10 changes: 6 additions & 4 deletions llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
Expand Up @@ -536,8 +536,9 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
};
if (auto *Obj = dyn_cast<ObjectFile>(BinOrErr->get())) {
if (filterArch(*Obj)) {
std::unique_ptr<DWARFContext> DICtx =
DWARFContext::create(*Obj, nullptr, "", RecoverableErrorHandler);
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(
*Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
RecoverableErrorHandler);
if (!HandleObj(*Obj, *DICtx, Filename, OS))
Result = false;
}
Expand All @@ -548,8 +549,9 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
if (auto MachOOrErr = ObjForArch.getAsObjectFile()) {
auto &Obj = **MachOOrErr;
if (filterArch(Obj)) {
std::unique_ptr<DWARFContext> DICtx =
DWARFContext::create(Obj, nullptr, "", RecoverableErrorHandler);
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(
Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
RecoverableErrorHandler);
if (!HandleObj(Obj, *DICtx, ObjName, OS))
Result = false;
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
Expand Up @@ -185,7 +185,8 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
reportError(DataOrErr.takeError(), ObjF.getFileName());

// Construct DWARFDataExtractor to handle relocations ("PC Begin" fields).
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(ObjF, nullptr);
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(
ObjF, DWARFContext::ProcessDebugRelocations::Process, nullptr);
DWARFDataExtractor DE(DICtx->getDWARFObj(),
DICtx->getDWARFObj().getEHFrameSection(),
ELFT::TargetEndianness == support::endianness::little,
Expand Down
5 changes: 3 additions & 2 deletions llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
Expand Up @@ -413,8 +413,9 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
}
}

std::unique_ptr<DIContext> Context =
DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
std::unique_ptr<DIContext> Context = DWARFContext::create(
*SymbolObj, DWARFContext::ProcessDebugRelocations::Process,
LoadedObjInfo.get());

std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
object::computeSymbolSizes(*SymbolObj);
Expand Down
5 changes: 3 additions & 2 deletions llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
Expand Up @@ -2519,8 +2519,9 @@ TEST(DWARFDebugInfo, TestErrorReporting) {

// DWARFContext parses whole file and finds the two errors we expect.
int Errors = 0;
std::unique_ptr<DWARFContext> Ctx1 =
DWARFContext::create(**Obj, nullptr, "", [&](Error E) {
std::unique_ptr<DWARFContext> Ctx1 = DWARFContext::create(
**Obj, DWARFContext::ProcessDebugRelocations::Process, nullptr, "",
[&](Error E) {
++Errors;
consumeError(std::move(E));
});
Expand Down

0 comments on commit 5a865b0

Please sign in to comment.