Skip to content

Commit 122d368

Browse files
authored
[llvm-objcopy] --[de]compress-debug-sections: don't compress SHF_ALLOC sections, only decompress .debug sections
Simplify --[de]compress-debug-sections to make it easier to add custom section [de]compression. Change the following two behaviors to match GNU objcopy. * --compress-debug-sections compresses SHF_ALLOC sections while GNU doesn't. * --decompress-debug-sections decompresses non-debug sections while GNU doesn't. Pull Request: #84885
1 parent 79cd2c0 commit 122d368

File tree

6 files changed

+68
-40
lines changed

6 files changed

+68
-40
lines changed

llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -214,33 +214,32 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
214214
SecName.str().c_str());
215215
}
216216

217-
static bool isCompressable(const SectionBase &Sec) {
218-
return !(Sec.Flags & ELF::SHF_COMPRESSED) &&
219-
StringRef(Sec.Name).starts_with(".debug");
220-
}
221-
222-
static Error replaceDebugSections(
223-
Object &Obj, function_ref<bool(const SectionBase &)> ShouldReplace,
224-
function_ref<Expected<SectionBase *>(const SectionBase *)> AddSection) {
217+
Error Object::compressOrDecompressSections(const CommonConfig &Config) {
225218
// Build a list of the debug sections we are going to replace.
226219
// We can't call `AddSection` while iterating over sections,
227220
// because it would mutate the sections array.
228-
SmallVector<SectionBase *, 13> ToReplace;
229-
for (auto &Sec : Obj.sections())
230-
if (ShouldReplace(Sec))
231-
ToReplace.push_back(&Sec);
232-
233-
// Build a mapping from original section to a new one.
234-
DenseMap<SectionBase *, SectionBase *> FromTo;
235-
for (SectionBase *S : ToReplace) {
236-
Expected<SectionBase *> NewSection = AddSection(S);
237-
if (!NewSection)
238-
return NewSection.takeError();
239-
240-
FromTo[S] = *NewSection;
221+
SmallVector<std::pair<SectionBase *, std::function<SectionBase *()>>, 0>
222+
ToReplace;
223+
for (SectionBase &Sec : sections()) {
224+
if ((Sec.Flags & SHF_ALLOC) || !StringRef(Sec.Name).starts_with(".debug"))
225+
continue;
226+
if (auto *CS = dyn_cast<CompressedSection>(&Sec)) {
227+
if (Config.DecompressDebugSections) {
228+
ToReplace.emplace_back(
229+
&Sec, [=] { return &addSection<DecompressedSection>(*CS); });
230+
}
231+
} else if (Config.CompressionType != DebugCompressionType::None) {
232+
ToReplace.emplace_back(&Sec, [&, S = &Sec] {
233+
return &addSection<CompressedSection>(
234+
CompressedSection(*S, Config.CompressionType, Is64Bits));
235+
});
236+
}
241237
}
242238

243-
return Obj.replaceSections(FromTo);
239+
DenseMap<SectionBase *, SectionBase *> FromTo;
240+
for (auto [S, Func] : ToReplace)
241+
FromTo[S] = Func();
242+
return replaceSections(FromTo);
244243
}
245244

246245
static bool isAArch64MappingSymbol(const Symbol &Sym) {
@@ -534,24 +533,8 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
534533
if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred))
535534
return E;
536535

537-
if (Config.CompressionType != DebugCompressionType::None) {
538-
if (Error Err = replaceDebugSections(
539-
Obj, isCompressable,
540-
[&Config, &Obj](const SectionBase *S) -> Expected<SectionBase *> {
541-
return &Obj.addSection<CompressedSection>(
542-
CompressedSection(*S, Config.CompressionType, Obj.Is64Bits));
543-
}))
544-
return Err;
545-
} else if (Config.DecompressDebugSections) {
546-
if (Error Err = replaceDebugSections(
547-
Obj,
548-
[](const SectionBase &S) { return isa<CompressedSection>(&S); },
549-
[&Obj](const SectionBase *S) {
550-
const CompressedSection *CS = cast<CompressedSection>(S);
551-
return &Obj.addSection<DecompressedSection>(*CS);
552-
}))
553-
return Err;
554-
}
536+
if (Error E = Obj.compressOrDecompressSections(Config))
537+
return E;
555538

556539
return Error::success();
557540
}

llvm/lib/ObjCopy/ELF/ELFObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,7 @@ class Object {
12101210

12111211
Error removeSections(bool AllowBrokenLinks,
12121212
std::function<bool(const SectionBase &)> ToRemove);
1213+
Error compressOrDecompressSections(const CommonConfig &Config);
12131214
Error replaceSections(const DenseMap<SectionBase *, SectionBase *> &FromTo);
12141215
Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
12151216
template <class T, class... Ts> T &addSection(Ts &&...Args) {

llvm/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ Sections:
4343
Type: SHT_PROGBITS
4444
Flags: [ SHF_GROUP ]
4545
Content: '00'
46+
- Name: .debug_alloc
47+
Type: SHT_PROGBITS
48+
Flags: [ SHF_ALLOC ]
49+
Content: 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
4650
Symbols:
4751
- Type: STT_SECTION
4852
Section: .debug_foo

llvm/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
1313
# COMPRESSED: .debug_foo PROGBITS 0000000000000000 000040 {{.*}} 00 C 0 0 8
1414
# COMPRESSED-NEXT: .notdebug_foo PROGBITS 0000000000000000 {{.*}} 000008 00 0 0 0
15+
# COMPRESSED: .debug_alloc PROGBITS 0000000000000000 {{.*}} 000040 00 A 0 0 0
1516
# UNCOMPRESSED: .debug_foo PROGBITS 0000000000000000 000040 000008 00 0 0 0
1617
# UNCOMPRESSED-NEXT: .notdebug_foo PROGBITS 0000000000000000 {{.*}} 000008 00 0 0 0
18+
# UNCOMPRESSED: .debug_alloc PROGBITS 0000000000000000 {{.*}} 000040 00 A 0 0 0
1719

1820
## Relocations do not change.
1921
# CHECK: Relocation section '.rela.debug_foo' at offset {{.*}} contains 2 entries:

llvm/test/tools/llvm-objcopy/ELF/compress-debug-sections-zstd.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
1313
# COMPRESSED: .debug_foo PROGBITS 0000000000000000 000040 {{.*}} 00 C 0 0 8
1414
# COMPRESSED-NEXT: .notdebug_foo PROGBITS 0000000000000000 {{.*}} 000008 00 0 0 0
15+
# COMPRESSED: .debug_alloc PROGBITS 0000000000000000 {{.*}} 000040 00 A 0 0 0
1516
# DECOMPRESSED: .debug_foo PROGBITS 0000000000000000 000040 000008 00 0 0 0
1617
# DECOMPRESSED-NEXT: .notdebug_foo PROGBITS 0000000000000000 {{.*}} 000008 00 0 0 0
18+
# DECOMPRESSED: .debug_alloc PROGBITS 0000000000000000 {{.*}} 000040 00 A 0 0 0
1719

1820
## Relocations do not change.
1921
# CHECK: Relocation section '.rela.debug_foo' at offset {{.*}} contains 2 entries:
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# REQUIRES: zlib
2+
## Test decompression for different sections.
3+
4+
# RUN: yaml2obj %s -o %t
5+
# RUN: llvm-objcopy --decompress-debug-sections %t %t.de
6+
# RUN: llvm-readelf -S %t.de | FileCheck %s
7+
8+
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al
9+
# CHECK: .debug_alloc PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 AC 0 0 0
10+
# CHECK-NEXT: .debug_nonalloc PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 0 0 1
11+
# CHECK-NEXT: .debugx PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 0 0 1
12+
# CHECK-NEXT: nodebug PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 C 0 0 0
13+
14+
--- !ELF
15+
FileHeader:
16+
Class: ELFCLASS64
17+
Data: ELFDATA2LSB
18+
Type: ET_REL
19+
Machine: EM_X86_64
20+
Sections:
21+
- Name: .debug_alloc
22+
Type: SHT_PROGBITS
23+
Flags: [ SHF_ALLOC, SHF_COMPRESSED ]
24+
Content: 010000000000000040000000000000000100000000000000789cd36280002d3269002f800151
25+
- Name: .debug_nonalloc
26+
Type: SHT_PROGBITS
27+
Flags: [ SHF_COMPRESSED ]
28+
Content: 010000000000000040000000000000000100000000000000789cd36280002d3269002f800151
29+
- Name: .debugx
30+
Type: SHT_PROGBITS
31+
Flags: [ SHF_COMPRESSED ]
32+
Content: 010000000000000040000000000000000100000000000000789cd36280002d3269002f800151
33+
- Name: nodebug
34+
Type: SHT_PROGBITS
35+
Flags: [ SHF_COMPRESSED ]
36+
Content: 010000000000000040000000000000000100000000000000789cd36280002d3269002f800151

0 commit comments

Comments
 (0)