Skip to content

Commit f6260da

Browse files
authored
[SHT_LLVM_BB_ADDR_MAP] Support decompressing the SHT_LLVM_BB_ADDR_MAP section. (#142825)
Compression of SHT_LLVM_BB_ADDR_MAP with zstd can give 3X compression ratio, which is especially beneficial with PGO_analysis_map. To read the data back, we must decompress it. Though we can use llvm-objcopy to do this, it's much better to do this decompression internally in the library API.
1 parent 8ca220f commit f6260da

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

llvm/lib/Object/ELF.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/Object/ELF.h"
1010
#include "llvm/ADT/StringExtras.h"
1111
#include "llvm/BinaryFormat/ELF.h"
12+
#include "llvm/Object/Decompressor.h"
1213
#include "llvm/Support/Compiler.h"
1314
#include "llvm/Support/DataExtractor.h"
1415

@@ -782,6 +783,27 @@ decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
782783
if (!ContentsOrErr)
783784
return ContentsOrErr.takeError();
784785
ArrayRef<uint8_t> Content = *ContentsOrErr;
786+
787+
// Decompress the section if needed.
788+
std::unique_ptr<uint8_t[]> DecompressedContent;
789+
if (Sec.sh_flags & llvm::ELF::SHF_COMPRESSED) {
790+
Expected<StringRef> SectionNameOrErr = EF.getSectionName(Sec);
791+
if (!SectionNameOrErr)
792+
return SectionNameOrErr.takeError();
793+
auto DecompressorOrErr =
794+
Decompressor::create(*SectionNameOrErr, toStringRef(*ContentsOrErr),
795+
EF.isLE(), ELFT::Is64Bits);
796+
if (!DecompressorOrErr)
797+
return DecompressorOrErr.takeError();
798+
size_t DecompressedSize = DecompressorOrErr->getDecompressedSize();
799+
DecompressedContent = std::make_unique<uint8_t[]>(DecompressedSize);
800+
MutableArrayRef<uint8_t> DecompressedContentRef(DecompressedContent.get(),
801+
DecompressedSize);
802+
if (Error Err = DecompressorOrErr->decompress(DecompressedContentRef))
803+
return std::move(Err);
804+
Content = DecompressedContentRef;
805+
}
806+
785807
DataExtractor Data(Content, EF.isLE(), ELFT::Is64Bits ? 8 : 4);
786808
std::vector<BBAddrMap> FunctionEntries;
787809

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# REQUIRES: zstd
2+
## This test checks that we can read compressed SHT_LLVM_BB_ADDR_MAP sections.
3+
4+
## Check 64-bit:
5+
# RUN: yaml2obj --docnum=1 %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o
6+
# RUN: llvm-objcopy %t1.x64.o --compress-sections .llvm_bb_addr_map=zstd %t1.x64.compressed.o
7+
# RUN: llvm-readobj %t1.x64.compressed.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.compressed.o --check-prefix=CHECK
8+
9+
## Check 32-bit:
10+
# RUN: yaml2obj --docnum=1 %s -DBITS=32 -o %t1.x32.o
11+
# RUN: llvm-objcopy %t1.x32.o --compress-sections .llvm_bb_addr_map=zstd %t1.x32.compressed.o
12+
# RUN: llvm-readobj %t1.x32.compressed.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x11111 -DFILE=%t1.x32.compressed.o --check-prefix=CHECK
13+
14+
# CHECK: BBAddrMap [
15+
# CHECK-NEXT: Function {
16+
# CHECK-NEXT: At: [[ADDR]]
17+
# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3
18+
# CHECK-NEXT: Name: <?>
19+
# CHECK-NEXT: BB Ranges [
20+
# CHECK-NEXT: {
21+
# CHECK-NEXT: Base Address: [[ADDR]]
22+
# CHECK-NEXT: BB Entries [
23+
# CHECK-NEXT: {
24+
# CHECK-NEXT: ID: 0
25+
# CHECK-NEXT: Offset: 0x0
26+
# CHECK-NEXT: Size: 0x1
27+
# CHECK-NEXT: HasReturn: No
28+
# CHECK-NEXT: HasTailCall: Yes
29+
# CHECK-NEXT: IsEHPad: No
30+
# CHECK-NEXT: CanFallThrough: No
31+
# CHECK-NEXT: HasIndirectBranch: No
32+
# CHECK-NEXT: }
33+
# CHECK-NEXT: ]
34+
# CHECK-NEXT: }
35+
# CHECK-NEXT: {
36+
# CHECK-NEXT: Base Address: 0x44444
37+
# CHECK-NEXT: BB Entries [
38+
# CHECK-NEXT: {
39+
# CHECK-NEXT: ID: 2
40+
# CHECK-NEXT: Offset: 0x3
41+
# CHECK-NEXT: Size: 0x4
42+
# CHECK-NEXT: HasReturn: Yes
43+
# CHECK-NEXT: HasTailCall: No
44+
# CHECK-NEXT: IsEHPad: Yes
45+
# CHECK-NEXT: CanFallThrough: No
46+
# CHECK-NEXT: HasIndirectBranch: Yes
47+
# CHECK-NEXT: }
48+
# CHECK-NEXT: ]
49+
# CHECK-NEXT: }
50+
# CHECK-NEXT: ]
51+
# CHECK-NEXT: }
52+
# CHECK-NEXT: Function {
53+
# CHECK-NEXT: At: 0x22222
54+
# CHECK-NEXT: Name: foo
55+
# CHECK-NEXT: BB Ranges [
56+
# CHECK-NEXT: {
57+
# CHECK-NEXT: Base Address: 0x22222
58+
# CHECK-NEXT: BB Entries [
59+
# CHECK-NEXT: {
60+
# CHECK-NEXT: ID: 4
61+
# CHECK-NEXT: Offset: 0x6
62+
# CHECK-NEXT: Size: 0x7
63+
# CHECK-NEXT: HasReturn: No
64+
# CHECK-NEXT: HasTailCall: No
65+
# CHECK-NEXT: IsEHPad: No
66+
# CHECK-NEXT: CanFallThrough: Yes
67+
# CHECK-NEXT: HasIndirectBranch: No
68+
# CHECK-NEXT: }
69+
# CHECK-NEXT: ]
70+
# CHECK-NEXT: }
71+
# CHECK-NEXT: ]
72+
# CHECK-NEXT: }
73+
# CHECK-NEXT: ]
74+
75+
--- !ELF
76+
FileHeader:
77+
Class: ELFCLASS[[BITS]]
78+
Data: ELFDATA2LSB
79+
Type: ET_EXEC
80+
Sections:
81+
- Name: .text
82+
Type: SHT_PROGBITS
83+
Flags: [SHF_ALLOC]
84+
- Name: .text.bar
85+
Type: SHT_PROGBITS
86+
Flags: [SHF_ALLOC]
87+
- Name: .llvm_bb_addr_map
88+
Type: SHT_LLVM_BB_ADDR_MAP
89+
ShSize: [[SIZE=<none>]]
90+
Link: .text
91+
Entries:
92+
- Version: 2
93+
Feature: 0x8
94+
BBRanges:
95+
- BaseAddress: [[ADDR=0x11111]]
96+
BBEntries:
97+
- ID: 0
98+
AddressOffset: 0x0
99+
Size: 0x1
100+
Metadata: [[METADATA=0x2]]
101+
- BaseAddress: 0x44444
102+
BBEntries:
103+
- ID: 2
104+
AddressOffset: 0x3
105+
Size: 0x4
106+
Metadata: 0x15
107+
- Version: 2
108+
BBRanges:
109+
- BaseAddress: 0x22222
110+
BBEntries:
111+
- ID: 4
112+
AddressOffset: 0x6
113+
Size: 0x7
114+
Metadata: 0x8
115+
- Name: dummy_section
116+
Type: SHT_PROGBITS
117+
Size: 16
118+
- Name: '.llvm_bb_addr_map (1)'
119+
Type: SHT_LLVM_BB_ADDR_MAP
120+
Link: .text.bar
121+
Entries:
122+
- Version: 2
123+
BBRanges:
124+
- BaseAddress: 0x33333
125+
BBEntries:
126+
- ID: 6
127+
AddressOffset: 0x9
128+
Size: 0xa
129+
Metadata: 0x1b
130+
- ID: 7
131+
AddressOffset: 0xc
132+
Size: 0xd
133+
Metadata: 0xe
134+
Symbols:
135+
- Name: foo
136+
Section: .text
137+
Type: STT_FUNC
138+
Value: 0x22222
139+
- Name: bar
140+
Section: .text.bar
141+
Type: STT_FUNC
142+
Value: 0x33333

0 commit comments

Comments
 (0)