Skip to content

Commit a5fe401

Browse files
author
Yonghong Song
committed
Add EmitUniqueJumpTableSection option to enable unique jmptable sections
Currently llvm has an option EmitJumpTableSizesSection which enables unique jmptable size sections. This patch added an option EmitUniqueJumpTableSection which enables unique jmptable sections. This patch will have EmitUniqueJumpTableSection on by default for BPF programs. Without this, the jmptable will be in '.rodata' sections which may include a lot of other stuffs e.g. const strings. With EmitUniqueJumpTableSection, the llvm will generate unique jump table section per function based on llvm internal conventions and it will support ELF, XCOFF and COFF. The following is an example with bpf selftest user_ringbuf_success.bpf.c (also in description in llvm#133856): $ llvm-readelf -S user_ringbuf_success.bpf.o ... [ 6] .rodata.read_protocol_msg PROGBITS 0000000000000000 000740 000020 00 A 0 0 8 [ 7] .rel.rodata.read_protocol_msg REL 0000000000000000 0038e8 000040 10 I 42 6 8 [ 8] .llvm_jump_table_sizes LLVM_JT_SIZES 0000000000000000 000760 000010 00 0 0 1 [ 9] .rel.llvm_jump_table_sizes REL 0000000000000000 003928 000010 10 I 42 8 8 ... [14] .rodata.publish_next_kern_msg PROGBITS 0000000000000000 0008a0 000020 00 A 0 0 8 [15] .rel.rodata.publish_next_kern_msg REL 0000000000000000 0039b8 000040 10 I 42 14 8 [16] .llvm_jump_table_sizes LLVM_JT_SIZES 0000000000000000 0008c0 000010 00 0 0 1 [17] .rel.llvm_jump_table_sizes REL 0000000000000000 0039f8 000010 10 I 42 16 8 ... $ llvm-readelf -r user_ringbuf_success.bpf.o ... Relocation section '.rel.rodata.read_protocol_msg' at offset 0x38e8 contains 4 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000008 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000010 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000018 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text Relocation section '.rel.llvm_jump_table_sizes' at offset 0x3928 contains 1 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000000a00000002 R_BPF_64_ABS64 0000000000000000 .rodata.read_protocol_msg ... Relocation section '.rel.rodata.publish_next_kern_msg' at offset 0x39b8 contains 4 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000008 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000010 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000018 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text Relocation section '.rel.llvm_jump_table_sizes' at offset 0x39f8 contains 1 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000001200000002 R_BPF_64_ABS64 0000000000000000 .rodata.publish_next_kern_msg ... $ llvm-readelf -x '.rodata.read_protocol_msg' user_ringbuf_success.bpf.o Hex dump of section '.rodata.read_protocol_msg': 0x00000000 a8000000 00000000 10010000 00000000 ................ 0x00000010 b8000000 00000000 c8000000 00000000 ................ $ llvm-readelf -x '.rodata.publish_next_kern_msg' user_ringbuf_success.bpf.o Hex dump of section '.rodata.publish_next_kern_msg': 0x00000000 28040000 00000000 00050000 00000000 (............... 0x00000010 70040000 00000000 b8040000 00000000 p............... $ llvm-objdump -Sr user_ringbuf_success.bpf.o ... 0000000000000000 <read_protocol_msg>: ... ; switch (msg->msg_op) { 13: 61 03 00 00 00 00 00 00 w3 = *(u32 *)(r0 + 0x0) 14: 26 03 1c 00 03 00 00 00 if w3 > 0x3 goto +0x1c <read_protocol_msg+0x158> 15: 67 03 00 00 03 00 00 00 r3 <<= 0x3 16: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0x0 ll 0000000000000080: R_BPF_64_64 .rodata.read_protocol_msg 18: 0f 31 00 00 00 00 00 00 r1 += r3 19: 79 11 00 00 00 00 00 00 r1 = *(u64 *)(r1 + 0x0) 20: 0d 01 00 00 00 00 00 00 gotox r1 ... What if a single function has two switch statements? The following is an example: $ cat test.c struct simple_ctx { int x; int y; int z; }; int ret_user, ret_user2; void bar(void); int foo(struct simple_ctx *ctx, struct simple_ctx *ctx2) { switch (ctx->x) { case 1: ret_user = 8; break; case 6: ret_user = 3; break; case 2: ret_user = 4; break; case 31: ret_user = 5; break; default: ret_user = 19; break; } bar(); switch (ctx2->x) { case 0: ret_user2 = 8; break; case 7: ret_user2 = 3; break; case 9: ret_user2 = 4; break; case 31: ret_user2 = 5; break; default: ret_user2 = 29; break; } return 0; } $ clang --target=bpf -O2 -c test.c $ llvm-readelf -S test.o ... [ 4] .rodata.foo PROGBITS 0000000000000000 0001b8 0001f8 00 A 0 0 8 [ 5] .rel.rodata.foo REL 0000000000000000 0004e0 0003f0 10 I 10 4 8 [ 6] .llvm_jump_table_sizes LLVM_JT_SIZES 0000000000000000 0003b0 000020 00 0 0 1 [ 7] .rel.llvm_jump_table_sizes REL 0000000000000000 0008d0 000020 10 I 10 6 8 ... Note that the same '.llvm_jump-table_sizes' has information for two switch tables since they are in the same function. $ llvm-readelf -x '.llvm_jump_table_sizes' test.o Hex dump of section '.llvm_jump_table_sizes': 0x00000000 00000000 00000000 1f000000 00000000 ................ 0x00000010 f8000000 00000000 20000000 00000000 ........ ....... From the above, the total entries for two switch tables has 0x3f entries: $ llvm-readelf -x '.rodata.foo' test.o Hex dump of section '.rodata.foo': 0x00000000 58000000 00000000 78000000 00000000 X.......x....... 0x00000010 98000000 00000000 98000000 00000000 ................ 0x00000020 98000000 00000000 68000000 00000000 ........h....... 0x00000030 98000000 00000000 98000000 00000000 ................ 0x00000040 98000000 00000000 98000000 00000000 ................ 0x00000050 98000000 00000000 98000000 00000000 ................ 0x00000060 98000000 00000000 98000000 00000000 ................ 0x00000070 98000000 00000000 98000000 00000000 ................ 0x00000080 98000000 00000000 98000000 00000000 ................ 0x00000090 98000000 00000000 98000000 00000000 ................ 0x000000a0 98000000 00000000 98000000 00000000 ................ 0x000000b0 98000000 00000000 98000000 00000000 ................ 0x000000c0 98000000 00000000 98000000 00000000 ................ 0x000000d0 98000000 00000000 98000000 00000000 ................ 0x000000e0 98000000 00000000 98000000 00000000 ................ 0x000000f0 88000000 00000000 08010000 00000000 ................ 0x00000100 48010000 00000000 48010000 00000000 H.......H....... 0x00000110 48010000 00000000 48010000 00000000 H.......H....... 0x00000120 48010000 00000000 48010000 00000000 H.......H....... 0x00000130 28010000 00000000 48010000 00000000 (.......H....... 0x00000140 18010000 00000000 48010000 00000000 ........H....... 0x00000150 48010000 00000000 48010000 00000000 H.......H....... 0x00000160 48010000 00000000 48010000 00000000 H.......H....... 0x00000170 48010000 00000000 48010000 00000000 H.......H....... 0x00000180 48010000 00000000 48010000 00000000 H.......H....... 0x00000190 48010000 00000000 48010000 00000000 H.......H....... 0x000001a0 48010000 00000000 48010000 00000000 H.......H....... 0x000001b0 48010000 00000000 48010000 00000000 H.......H....... 0x000001c0 48010000 00000000 48010000 00000000 H.......H....... 0x000001d0 48010000 00000000 48010000 00000000 H.......H....... 0x000001e0 48010000 00000000 48010000 00000000 H.......H....... 0x000001f0 38010000 00000000 Related relocations: $ llvm-readelf -r test.o ... Relocation section '.rel.rodata.foo' at offset 0x4e0 contains 63 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 0000000000000008 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text ... Relocation section '.rel.llvm_jump_table_sizes' at offset 0x8d0 contains 2 entries: Offset Info Type Symbol's Value Symbol's Name 0000000000000000 0000000300000002 R_BPF_64_ABS64 0000000000000000 .rodata.foo 0000000000000010 0000000300000002 R_BPF_64_ABS64 0000000000000000 .rodata.foo
1 parent 134470a commit a5fe401

File tree

7 files changed

+44
-22
lines changed

7 files changed

+44
-22
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
namespace llvm {
3838
extern cl::opt<bool> EmitJumpTableSizesSection;
39+
extern cl::opt<bool> EmitUniqueJumpTableSection;
3940

4041
class AddrLabelMap;
4142
class AsmPrinterHandler;

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
7878
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
7979
const TargetMachine &TM) const override;
8080

81-
MCSection *getSectionForJumpTable(const Function &F,
82-
const TargetMachine &TM) const override;
8381
MCSection *
8482
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
85-
const MachineJumpTableEntry *JTE) const override;
83+
bool EmitUniqueSection = false) const override;
84+
MCSection *
85+
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
86+
const MachineJumpTableEntry *JTE,
87+
bool EmitUniqueSection = false) const override;
8688
MCSection *getSectionForLSDA(const Function &F, const MCSymbol &FnSym,
8789
const TargetMachine &TM) const override;
8890

@@ -197,8 +199,9 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
197199
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
198200
const TargetMachine &TM) const override;
199201

200-
MCSection *getSectionForJumpTable(const Function &F,
201-
const TargetMachine &TM) const override;
202+
MCSection *
203+
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
204+
bool EmitUniqueSection = false) const override;
202205

203206
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
204207
const Function &F) const override;
@@ -277,8 +280,9 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
277280
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
278281
const TargetMachine &TM) const override;
279282

280-
MCSection *getSectionForJumpTable(const Function &F,
281-
const TargetMachine &TM) const override;
283+
MCSection *
284+
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
285+
bool EmitUniqueSection = false) const override;
282286

283287
/// Given a constant with the SectionKind, return a section that it should be
284288
/// placed in.

llvm/include/llvm/Target/TargetLoweringObjectFile.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,13 @@ class LLVM_ABI TargetLoweringObjectFile : public MCObjectFileInfo {
142142
const GlobalValue *GV,
143143
const TargetMachine &TM) const;
144144

145-
virtual MCSection *getSectionForJumpTable(const Function &F,
146-
const TargetMachine &TM) const;
147145
virtual MCSection *
148146
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
149-
const MachineJumpTableEntry *JTE) const;
147+
bool EmitUniqueSection = false) const;
148+
virtual MCSection *
149+
getSectionForJumpTable(const Function &F, const TargetMachine &TM,
150+
const MachineJumpTableEntry *JTE,
151+
bool EmitUniqueSection = false) const;
150152

151153
virtual MCSection *getSectionForLSDA(const Function &, const MCSymbol &,
152154
const TargetMachine &) const {

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ cl::opt<bool> llvm::EmitJumpTableSizesSection(
173173
cl::desc("Emit a section containing jump table addresses and sizes"),
174174
cl::Hidden, cl::init(false));
175175

176+
cl::opt<bool> llvm::EmitUniqueJumpTableSection(
177+
"emit-unique-jump-table-section",
178+
cl::desc("Emit a unique section containing jump table target addresses"),
179+
cl::Hidden, cl::init(false));
180+
181+
176182
// This isn't turned on by default, since several of the scheduling models are
177183
// not completely accurate, and we don't want to be misleading.
178184
static cl::opt<bool> PrintLatency(
@@ -2975,9 +2981,11 @@ void AsmPrinter::emitJumpTableImpl(const MachineJumpTableInfo &MJTI,
29752981
if (JTInDiffSection) {
29762982
if (TM.Options.EnableStaticDataPartitioning) {
29772983
JumpTableSection =
2978-
TLOF.getSectionForJumpTable(F, TM, &JT[JumpTableIndices.front()]);
2984+
TLOF.getSectionForJumpTable(F, TM, &JT[JumpTableIndices.front()],
2985+
EmitUniqueJumpTableSection);
29792986
} else {
2980-
JumpTableSection = TLOF.getSectionForJumpTable(F, TM);
2987+
JumpTableSection =
2988+
TLOF.getSectionForJumpTable(F, TM, EmitUniqueJumpTableSection);
29812989
}
29822990
OutStreamer->switchSection(JumpTableSection);
29832991
}

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -990,17 +990,19 @@ MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction(
990990
}
991991

992992
MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
993-
const Function &F, const TargetMachine &TM) const {
994-
return getSectionForJumpTable(F, TM, /*JTE=*/nullptr);
993+
const Function &F, const TargetMachine &TM,
994+
bool EmitUniqueSection) const {
995+
return getSectionForJumpTable(F, TM, /*JTE=*/nullptr, EmitUniqueSection);
995996
}
996997

997998
MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
998999
const Function &F, const TargetMachine &TM,
999-
const MachineJumpTableEntry *JTE) const {
1000+
const MachineJumpTableEntry *JTE, bool EmitUniqueSection) const {
10001001
// If the function can be removed, produce a unique section so that
10011002
// the table doesn't prevent the removal.
10021003
const Comdat *C = F.getComdat();
1003-
bool EmitUniqueSection = TM.getFunctionSections() || C;
1004+
if (!EmitUniqueSection)
1005+
EmitUniqueSection = TM.getFunctionSections() || C;
10041006
if (!EmitUniqueSection && !TM.getEnableStaticDataPartitioning())
10051007
return ReadOnlySection;
10061008

@@ -1878,11 +1880,13 @@ void TargetLoweringObjectFileCOFF::getNameWithPrefix(
18781880
}
18791881

18801882
MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
1881-
const Function &F, const TargetMachine &TM) const {
1883+
const Function &F, const TargetMachine &TM,
1884+
bool EmitUniqueSection) const {
18821885
// If the function can be removed, produce a unique section so that
18831886
// the table doesn't prevent the removal.
18841887
const Comdat *C = F.getComdat();
1885-
bool EmitUniqueSection = TM.getFunctionSections() || C;
1888+
if (!EmitUniqueSection)
1889+
EmitUniqueSection = TM.getFunctionSections() || C;
18861890
if (!EmitUniqueSection)
18871891
return ReadOnlySection;
18881892

@@ -2591,7 +2595,7 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
25912595
}
25922596

25932597
MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable(
2594-
const Function &F, const TargetMachine &TM) const {
2598+
const Function &F, const TargetMachine &TM, bool EmitUniqueSection) const {
25952599
assert (!F.getComdat() && "Comdat not supported on XCOFF.");
25962600

25972601
if (!TM.getFunctionSections())

llvm/lib/Target/BPF/BPFAsmPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class BPFAsmPrinter : public AsmPrinter {
5959

6060
bool BPFAsmPrinter::doInitialization(Module &M) {
6161
EmitJumpTableSizesSection = true;
62+
EmitUniqueJumpTableSection = true;
63+
6264
AsmPrinter::doInitialization(M);
6365

6466
// Only emit BTF when debuginfo available.

llvm/lib/Target/TargetLoweringObjectFile.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,14 @@ TargetLoweringObjectFile::SectionForGlobal(const GlobalObject *GO,
346346
}
347347

348348
MCSection *TargetLoweringObjectFile::getSectionForJumpTable(
349-
const Function &F, const TargetMachine &TM) const {
350-
return getSectionForJumpTable(F, TM, /*JTE=*/nullptr);
349+
const Function &F, const TargetMachine &TM,
350+
bool EmitUniqueSection) const {
351+
return getSectionForJumpTable(F, TM, /*JTE=*/nullptr, EmitUniqueSection);
351352
}
352353

353354
MCSection *TargetLoweringObjectFile::getSectionForJumpTable(
354355
const Function &F, const TargetMachine &TM,
355-
const MachineJumpTableEntry *JTE) const {
356+
const MachineJumpTableEntry *JTE, bool EmitUniqueSection) const {
356357
Align Alignment(1);
357358
return getSectionForConstant(F.getDataLayout(),
358359
SectionKind::getReadOnly(), /*C=*/nullptr,

0 commit comments

Comments
 (0)