[BOLT] Error out on SHF_COMPRESSED debug sections (#185662)

Some binaries are built using `-gz=zstd`, but when using
`--update-debug-sections` on said binaries BOLT crashes.

This patch fixes this issue by recognising compressed debug sections in
binaries via their flag `SHF_COMPRESSED` and appropriately erroring out.

Legacy GNU-style compression is not handled.
This commit is contained in:
Amina Chabane 2026-03-10 17:18:12 +00:00 committed by GitHub
parent 3c5d257546
commit 498906f2df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 53 additions and 2 deletions

View File

@ -409,6 +409,9 @@ public:
/// Return true if the section holds debug information.
static bool isDebugSection(StringRef SectionName);
/// Return true if a debug section is compressed (by SHF_COMPRESSED flag).
static bool isCompressedDebugSection(const object::SectionRef &Section);
/// Adds Debug section to overwrite.
static void addToDebugSectionsToOverwrite(const char *Section) {
DebugSectionsToOverwrite.emplace_back(Section);

View File

@ -2196,6 +2196,19 @@ Error RewriteInstance::readSpecialSections() {
check_error(SectionNameOrErr.takeError(), "cannot get section name");
StringRef SectionName = *SectionNameOrErr;
// Detect a debug section and check if it's compressed.
// Compressed debug sections currently aren't supported.
if (isDebugSection(SectionName)) {
HasDebugInfo = true;
if (opts::UpdateDebugSections && isCompressedDebugSection(Section)) {
return createStringError(errc::not_supported,
Twine("compressed debug section '") +
SectionName +
"' detected. --update-debug-sections "
"requires uncompressed debug info");
}
}
if (Error E = Section.getContents().takeError())
return E;
BC->registerSection(Section);
@ -2204,8 +2217,6 @@ Error RewriteInstance::readSpecialSections() {
<< Twine::utohexstr(Section.getAddress()) << ":0x"
<< Twine::utohexstr(Section.getAddress() + Section.getSize())
<< "\n");
if (isDebugSection(SectionName))
HasDebugInfo = true;
}
// Set IsRelro section attribute based on PT_GNU_RELRO segment.
@ -6491,3 +6502,7 @@ bool RewriteInstance::isDebugSection(StringRef SectionName) {
return false;
}
bool RewriteInstance::isCompressedDebugSection(const SectionRef &Section) {
return (ELFSectionRef(Section).getFlags() & ELF::SHF_COMPRESSED) != 0;
}

View File

@ -0,0 +1,27 @@
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_AARCH64
Entry: 0x48000
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_X, PF_R ]
FirstSec: .text
LastSec: .text
VAddr: 0x48000
Align: 0x4000
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x48000
AddressAlign: 0x4
Content: 030F0B0700000000030F0B0700000000C0035FD6FFFFFF97000080D2A80B8052010000D4
- Name: .debug_info
Type: SHT_PROGBITS
Flags: [ SHF_COMPRESSED ]
AddressAlign: 0x1
Content: 0200000000000000DD33310000000000010000000000000028B52FFDA000001000CC6207
...

View File

@ -0,0 +1,6 @@
// Checks that BOLT correctly errors out on compressed debug sections.
//
// RUN: yaml2obj %p/Inputs/compressed-debug-sections.yaml -o %t.exe
// RUN: not llvm-bolt %t.exe -o %t.bolt --update-debug-sections 2>&1 | FileCheck %s
//
// CHECK: compressed debug section '.debug_info' detected. --update-debug-sections requires uncompressed debug info