From b73c87bc4ffaecbc9c0f54d4ff95659fc13d2d65 Mon Sep 17 00:00:00 2001 From: Maksim Panchenko Date: Mon, 6 Dec 2021 23:32:40 -0800 Subject: [PATCH] [BOLT][DWARF] Force allocation of debug_line in RuntimeDyld Summary: Currently, RuntimeDyld will not allocate a section without relocations even if such a section is marked allocatable and defines symbols. When we emit .debug_line for compile units with unchanged code, we output original (input) data, without relocations. If all units are emitted in this way, we will have no relocations in the emitted .debug_line. RuntimeDyld will not allocate the section and as a result we will write an empty .debug_line section. To workaround the issue, always emit a relocation of RELOC_NONE type when emitting raw contents to debug_line. (cherry picked from FBD32909869) --- bolt/include/bolt/Core/DebugData.h | 2 +- bolt/lib/Core/DebugData.cpp | 13 +++++++++++-- bolt/test/Inputs/hello.c | 7 +++++++ bolt/test/non-empty-debug-line.test | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 bolt/test/Inputs/hello.c create mode 100644 bolt/test/non-empty-debug-line.test diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h index 2e3dc36d181d..35b7cd014978 100644 --- a/bolt/include/bolt/Core/DebugData.h +++ b/bolt/include/bolt/Core/DebugData.h @@ -600,7 +600,7 @@ public: /// Emit the Dwarf file and the line tables for a given CU. void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, - Optional &LineStr) const; + Optional &LineStr, BinaryContext &BC) const; Expected tryGetFile(StringRef &Directory, StringRef &FileName, Optional Checksum, diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp index 90f2cf8d342e..ec74ef3bbbf0 100644 --- a/bolt/lib/Core/DebugData.cpp +++ b/bolt/lib/Core/DebugData.cpp @@ -782,7 +782,8 @@ static inline void emitDwarfLineTable( } void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, - Optional &LineStr) const { + Optional &LineStr, + BinaryContext &BC) const { if (!RawData.empty()) { assert(MCLineSections.getMCLineEntries().empty() && InputSequences.empty() && @@ -790,6 +791,14 @@ void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, MCOS->emitLabel(getLabel()); MCOS->emitBytes(RawData); + // Emit fake relocation for RuntimeDyld to always allocate the section. + // + // FIXME: remove this once RuntimeDyld stops skipping allocatable sections + // without relocations. + MCOS->emitRelocDirective( + *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", + MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); + return; } @@ -830,7 +839,7 @@ void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { // Handle the rest of the Compile Units. for (auto &CUIDTablePair : LineTables) { - CUIDTablePair.second.emitCU(&Streamer, Params, LineStr); + CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); } } diff --git a/bolt/test/Inputs/hello.c b/bolt/test/Inputs/hello.c new file mode 100644 index 000000000000..150656567ad3 --- /dev/null +++ b/bolt/test/Inputs/hello.c @@ -0,0 +1,7 @@ +#include + +int main() { + printf("Hello, world!\n"); + + return 0; +} diff --git a/bolt/test/non-empty-debug-line.test b/bolt/test/non-empty-debug-line.test new file mode 100644 index 000000000000..0922adede523 --- /dev/null +++ b/bolt/test/non-empty-debug-line.test @@ -0,0 +1,19 @@ +# Verifies that BOLT emits DWARF line table with the same size if +# no functions with debug info were modified. + +RUN: %clang %S/Inputs/hello.c -g -o %t +RUN: llvm-bolt %t -o %t1 -update-debug-sections -funcs=_start +RUN: llvm-readobj -S %t > %t2 +RUN: llvm-readobj -S %t1 >> %t2 +RUN: FileCheck %s --input-file %t2 + +# Check the input and grab .debug_line size. +CHECK: File: +CHECK: Name: .debug_line +CHECK: Size: [[SIZE:[0-9]+]] + +# Verify .debug_line size is the same after BOLT. +CHECK: File: +CHECK: Name: .debug_line +CHECK: Size: +CHECK-SAME: [[SIZE]]