forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[llvm-objcopy] Add --compress-sections
--compress-sections is similar to --compress-debug-sections but applies to arbitrary sections. * `--compress-sections <section>=none`: decompress sections * `--compress-sections <section>=[zlib|zstd]`: compress sections with zlib/zstd Like `--remove-section`, the pattern is by default a glob, but a regex when --regex is specified. For `--remove-section` like options, `!` prevents matches and is not dependent on ordering (see `ELF/wildcard-syntax.test`). Since `--compress-sections a=zlib --compress-sections a=none` naturally allows overriding, having an order-independent `!` would be confusing. Therefore, `!` is disallowed. Sections within a segment are effectively immutable. Report an error for an attempt to (de)compress them. `SHF_ALLOC` sections in a relocatable file can be compressed, but linkers usually reject them. Note: Before this patch, a compressed relocation section is recognized as a `RelocationSectionBase` as well and `removeSections` `!ToRemove(*ToRelSec)` may incorrectly interpret a `CompressedSections` as `RelocationSectionBase`, leading to ubsan failure for the new test. Fix this by setting `OriginalFlags` in CompressedSection::CompressedSection. Link: https://discourse.llvm.org/t/rfc-compress-arbitrary-sections-with-ld-lld-compress-sections/71674 Pull Request: llvm#85036
- Loading branch information
Showing
10 changed files
with
283 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
llvm/test/tools/llvm-objcopy/ELF/compress-sections-within-segment.s
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
## Disallow (de)compression for sections within a segment as they are | ||
## effectively immutable. | ||
# RUN: rm -rf %t && mkdir %t && cd %t | ||
# RUN: yaml2obj %s -o a | ||
# RUN: not llvm-objcopy a /dev/null --compress-sections .text=zlib 2>&1 | FileCheck %s --implicit-check-not=error: | ||
|
||
# CHECK: error: 'a': section '.text' within a segment cannot be (de)compressed | ||
|
||
# RUN: not llvm-objcopy a /dev/null --compress-sections foo=none 2>&1 | FileCheck %s --check-prefix=CHECK2 --implicit-check-not=error: | ||
|
||
# CHECK2: error: 'a': section 'foo' within a segment cannot be (de)compressed | ||
|
||
## There is an error even if 'foo' is already compressed with zlib. | ||
# RUN: not llvm-objcopy a /dev/null --compress-sections foo=zlib 2>&1 | FileCheck %s --check-prefix=CHECK3 --implicit-check-not=error: | ||
|
||
# CHECK3: error: 'a': section 'foo' within a segment cannot be (de)compressed | ||
|
||
--- !ELF | ||
FileHeader: | ||
Class: ELFCLASS64 | ||
Data: ELFDATA2LSB | ||
Type: ET_EXEC | ||
Machine: EM_X86_64 | ||
ProgramHeaders: | ||
- Type: PT_LOAD | ||
FirstSec: .text | ||
LastSec: foo | ||
Align: 0x1000 | ||
Offset: 0x1000 | ||
Sections: | ||
- Name: .text | ||
Type: SHT_PROGBITS | ||
Offset: 0x1000 | ||
Content: C3 | ||
- Name: foo | ||
Type: SHT_PROGBITS | ||
Flags: [ SHF_COMPRESSED ] | ||
Content: 010000000000000040000000000000000100000000000000789cd36280002d3269002f800151 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# REQUIRES: x86-registered-target, zlib, zstd | ||
|
||
# RUN: rm -rf %t && mkdir %t && cd %t | ||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o a.o | ||
## '*0=none' wins because it is the last. '*0' sections are decompressed (if originally compressed) or kept unchanged (if uncompressed). | ||
## No section is named 'nomatch'. The third option is a no-op. | ||
# RUN: llvm-objcopy a.o out --compress-sections='*0=zlib' --compress-sections '*0=none' --compress-sections 'nomatch=none' 2>&1 | count 0 | ||
# RUN: llvm-readelf -S out | FileCheck %s --check-prefix=CHECK1 | ||
|
||
# CHECK1: Name Type Address Off Size ES Flg Lk Inf Al | ||
# CHECK1: .text PROGBITS [[#%x,TEXT:]] [[#%x,]] [[#%x,]] 00 AX 0 0 4 | ||
# CHECK1: foo0 PROGBITS [[#%x,FOO0:]] [[#%x,]] [[#%x,]] 00 A 0 0 8 | ||
# CHECK1-NEXT: .relafoo0 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 I 11 3 8 | ||
# CHECK1-NEXT: foo1 PROGBITS [[#%x,FOO1:]] [[#%x,]] [[#%x,]] 00 A 0 0 8 | ||
# CHECK1-NEXT: .relafoo1 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 I 11 5 8 | ||
# CHECK1: nonalloc0 PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 0 0 8 | ||
# CHECK1-NEXT: .relanonalloc0 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 I 11 7 8 | ||
# CHECK1-NEXT: nonalloc1 PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 0 0 8 | ||
# CHECK1-NEXT: .debug_str PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 01 MS 0 0 1 | ||
|
||
## Mixing zlib and zstd. | ||
# RUN: llvm-objcopy a.o out2 --compress-sections '*c0=zlib' --compress-sections .debug_str=zstd | ||
# RUN: llvm-readelf -Sr -x nonalloc0 -x .debug_str out2 2>&1 | FileCheck %s --check-prefix=CHECK2 | ||
# RUN: llvm-readelf -z -x nonalloc0 -x .debug_str out2 | FileCheck %s --check-prefix=CHECK2DE | ||
|
||
# CHECK2: Name Type Address Off Size ES Flg Lk Inf Al | ||
# CHECK2: .text PROGBITS [[#%x,TEXT:]] [[#%x,]] [[#%x,]] 00 AX 0 0 4 | ||
# CHECK2: foo0 PROGBITS [[#%x,FOO0:]] [[#%x,]] [[#%x,]] 00 A 0 0 8 | ||
# CHECK2-NEXT: .relafoo0 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 I 11 3 8 | ||
# CHECK2-NEXT: foo1 PROGBITS [[#%x,FOO1:]] [[#%x,]] [[#%x,]] 00 A 0 0 8 | ||
# CHECK2-NEXT: .relafoo1 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 I 11 5 8 | ||
# CHECK2: nonalloc0 PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 C 0 0 8 | ||
# CHECK2-NEXT: .relanonalloc0 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 IC 11 7 8 | ||
# CHECK2-NEXT: nonalloc1 PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 0 0 8 | ||
# CHECK2-NEXT: .debug_str PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 01 MSC 0 0 8 | ||
|
||
## llvm-readelf -r doesn't support SHF_COMPRESSED SHT_RELA. | ||
# CHECK2: warning: {{.*}}: unable to read relocations from SHT_RELA section with index 8: section [index 8] has an invalid sh_size ([[#]]) which is not a multiple of its sh_entsize (24) | ||
|
||
# CHECK2: Hex dump of section 'nonalloc0': | ||
## zlib with ch_size=0x10 | ||
# CHECK2-NEXT: 01000000 00000000 10000000 00000000 | ||
# CHECK2-NEXT: 08000000 00000000 {{.*}} | ||
# CHECK2: Hex dump of section '.debug_str': | ||
## zstd with ch_size=0x38 | ||
# CHECK2-NEXT: 02000000 00000000 38000000 00000000 | ||
# CHECK2-NEXT: 01000000 00000000 {{.*}} | ||
|
||
# CHECK2DE: Hex dump of section 'nonalloc0': | ||
# CHECK2DE-NEXT: 0x00000000 00000000 00000000 00000000 00000000 ................ | ||
# CHECK2DE-EMPTY: | ||
# CHECK2DE-NEXT: Hex dump of section '.debug_str': | ||
# CHECK2DE-NEXT: 0x00000000 41414141 41414141 41414141 41414141 AAAAAAAAAAAAAAAA | ||
|
||
## --decompress-debug-sections takes precedence, even if it is before --compress-sections. | ||
# RUN: llvm-objcopy a.o out3 --decompress-debug-sections --compress-sections .debug_str=zstd | ||
# RUN: llvm-readelf -S out3 | FileCheck %s --check-prefix=CHECK3 | ||
|
||
# CHECK3: .debug_str PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 01 MS 0 0 1 | ||
|
||
# RUN: llvm-objcopy a.o out4 --compress-sections '*0=zlib' | ||
# RUN: llvm-readelf -S out4 | FileCheck %s --check-prefix=CHECK4 | ||
|
||
# CHECK4: Name Type Address Off Size ES Flg Lk Inf Al | ||
# CHECK4: .text PROGBITS [[#%x,TEXT:]] [[#%x,]] [[#%x,]] 00 AX 0 0 4 | ||
# CHECK4: foo0 PROGBITS [[#%x,FOO0:]] [[#%x,]] [[#%x,]] 00 AC 0 0 8 | ||
# CHECK4-NEXT: .relafoo0 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 IC 11 3 8 | ||
# CHECK4-NEXT: foo1 PROGBITS [[#%x,FOO1:]] [[#%x,]] [[#%x,]] 00 A 0 0 8 | ||
# CHECK4-NEXT: .relafoo1 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 I 11 5 8 | ||
# CHECK4: nonalloc0 PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 C 0 0 8 | ||
# CHECK4-NEXT: .relanonalloc0 RELA [[#%x,]] [[#%x,]] [[#%x,]] 18 IC 11 7 8 | ||
# CHECK4-NEXT: nonalloc1 PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 00 0 0 8 | ||
# CHECK4-NEXT: .debug_str PROGBITS 0000000000000000 [[#%x,]] [[#%x,]] 01 MS 0 0 1 | ||
|
||
## If a section is already compressed, compression request for another format is ignored. | ||
# RUN: llvm-objcopy a.o out5 --compress-sections 'nonalloc0=zlib' | ||
# RUN: llvm-readelf -x nonalloc0 out5 | FileCheck %s --check-prefix=CHECK5 | ||
# RUN: llvm-objcopy out5 out5a --compress-sections 'nonalloc0=zstd' | ||
# RUN: cmp out5 out5a | ||
|
||
# CHECK5: Hex dump of section 'nonalloc0': | ||
## zlib with ch_size=0x10 | ||
# CHECK5-NEXT: 01000000 00000000 10000000 00000000 | ||
# CHECK5-NEXT: 08000000 00000000 {{.*}} | ||
|
||
# RUN: not llvm-objcopy --compress-sections=foo a.o out 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=ERR1 --implicit-check-not=error: | ||
# ERR1: error: --compress-sections: parse error, not 'section-glob=[none|zlib|zstd]' | ||
|
||
# RUN: llvm-objcopy --compress-sections 'a[=zlib' a.o out 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=ERR2 --implicit-check-not=error: | ||
# ERR2: warning: invalid glob pattern, unmatched '[' | ||
|
||
# RUN: not llvm-objcopy a.o out --compress-sections='.debug*=zlib-gabi' --compress-sections='.debug*=' 2>&1 | \ | ||
# RUN: FileCheck -check-prefix=ERR3 %s | ||
# ERR3: error: invalid or unsupported --compress-sections format: .debug*=zlib-gabi | ||
|
||
# RUN: not llvm-objcopy a.o out --compress-sections='!.debug*=zlib' 2>&1 | \ | ||
# RUN: FileCheck -check-prefix=ERR4 %s | ||
# ERR4: error: --compress-sections: negative pattern is unsupported | ||
|
||
.globl _start | ||
_start: | ||
ret | ||
|
||
.section foo0,"a" | ||
.balign 8 | ||
.quad .text-. | ||
.quad .text-. | ||
.section foo1,"a" | ||
.balign 8 | ||
.quad .text-. | ||
.quad .text-. | ||
.section nonalloc0,"" | ||
.balign 8 | ||
.quad .text+1 | ||
.quad .text+2 | ||
sym0: | ||
.section nonalloc1,"" | ||
.balign 8 | ||
.quad 42 | ||
sym1: | ||
|
||
.section .debug_str,"MS",@progbits,1 | ||
.Linfo_string0: | ||
.asciz "AAAAAAAAAAAAAAAAAAAAAAAAAAA" | ||
.Linfo_string1: | ||
.asciz "BBBBBBBBBBBBBBBBBBBBBBBBBBB" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters