Skip to content

Commit b5e71d7

Browse files
authored
Add section type to support CFI jump table relaxation.
For context see main pull request: #147424. Reviewers: MaskRay Reviewed By: MaskRay Pull Request: #149259
1 parent 796d5a8 commit b5e71d7

File tree

6 files changed

+44
-3
lines changed

6 files changed

+44
-3
lines changed

llvm/docs/Extensions.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,26 @@ This section stores pairs of (jump table address, number of entries).
581581
This information is useful for tools that need to statically reconstruct
582582
the control flow of executables.
583583

584+
``SHT_LLVM_CFI_JUMP_TABLE`` Section (CFI jump table)
585+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
586+
This section contains the instructions that make up a `CFI jump table`_.
587+
It is expected to be ``SHF_ALLOC`` and may be laid out like a normal
588+
section. The ``SHT_LLVM_CFI_JUMP_TABLE`` section type gives the linker
589+
permission to modify the section in ways that would not normally be
590+
permitted, in order to optimize calls via the jump table.
591+
592+
Each ``sh_entsize`` sized slice of a section of this type containing
593+
exactly one relocation may be considered to be a jump table entry
594+
that branches to the target of the relocation. This allows the linker
595+
to replace the jump table entry with the function body if it is small
596+
enough, or if the function is the last function in the jump table.
597+
598+
A section of this type does not have to be placed according to its
599+
name. The linker may place the section in whichever output section it
600+
sees fit (generally the section that would provide the best locality).
601+
602+
.. _CFI jump table: https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#forward-edge-cfi-for-indirect-function-calls
603+
584604
CodeView-Dependent
585605
------------------
586606

llvm/include/llvm/BinaryFormat/ELF.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@ enum : unsigned {
11591159
SHT_LLVM_OFFLOADING = 0x6fff4c0b, // LLVM device offloading data.
11601160
SHT_LLVM_LTO = 0x6fff4c0c, // .llvm.lto for fat LTO.
11611161
SHT_LLVM_JT_SIZES = 0x6fff4c0d, // LLVM jump tables sizes.
1162+
SHT_LLVM_CFI_JUMP_TABLE = 0x6fff4c0e, // LLVM CFI jump table.
11621163
// Android's experimental support for SHT_RELR sections.
11631164
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
11641165
SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.

llvm/lib/MC/MCParser/ELFAsmParser.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) {
571571
return TokError("expected end of directive");
572572
}
573573

574-
if (Mergeable)
574+
if (Mergeable || TypeName == "llvm_cfi_jump_table")
575575
if (parseMergeSize(Size))
576576
return true;
577577
if (Flags & ELF::SHF_LINK_ORDER)
@@ -637,6 +637,8 @@ bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) {
637637
Type = ELF::SHT_LLVM_LTO;
638638
else if (TypeName == "llvm_jt_sizes")
639639
Type = ELF::SHT_LLVM_JT_SIZES;
640+
else if (TypeName == "llvm_cfi_jump_table")
641+
Type = ELF::SHT_LLVM_CFI_JUMP_TABLE;
640642
else if (TypeName.getAsInteger(0, Type))
641643
return TokError("unknown section type");
642644
}

llvm/lib/MC/MCSectionELF.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,13 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
176176
OS << "llvm_lto";
177177
else if (Type == ELF::SHT_LLVM_JT_SIZES)
178178
OS << "llvm_jt_sizes";
179+
else if (Type == ELF::SHT_LLVM_CFI_JUMP_TABLE)
180+
OS << "llvm_cfi_jump_table";
179181
else
180182
OS << "0x" << Twine::utohexstr(Type);
181183

182184
if (EntrySize) {
183-
assert(Flags & ELF::SHF_MERGE);
185+
assert((Flags & ELF::SHF_MERGE) || Type == ELF::SHT_LLVM_CFI_JUMP_TABLE);
184186
OS << "," << EntrySize;
185187
}
186188

llvm/lib/Object/ELF.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
321321
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING);
322322
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO);
323323
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_JT_SIZES)
324+
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CFI_JUMP_TABLE)
324325
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_SFRAME);
325326
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
326327
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);

llvm/test/MC/AsmParser/llvm_section_types.s

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,34 @@
1-
## Verify that LLVM-specific section types are correctly inferred from assembly input.
1+
## Verify that LLVM-specific section types are correctly inferred from assembly input and printed.
2+
# RUN: llvm-mc -triple i386-pc-linux %s | FileCheck --check-prefix=ASM %s
23
# RUN: llvm-mc -triple i386-pc-linux -filetype=obj -o %t %s
34
# RUN: llvm-readobj -S %t | FileCheck %s
5+
# ASM: .section .section1,"",@llvm_bb_addr_map
46
.section .section1,"",@llvm_bb_addr_map
57
.byte 1
8+
# ASM: .section .section2,"",@llvm_call_graph_profile
69
.section .section2,"",@llvm_call_graph_profile
710
.byte 1
11+
# ASM: .section .section3,"",@llvm_odrtab
812
.section .section3,"",@llvm_odrtab
913
.byte 1
14+
# ASM: .section .section4,"",@llvm_linker_options
1015
.section .section4,"",@llvm_linker_options
1116
.byte 1
17+
# ASM: .section .section5,"",@llvm_sympart
1218
.section .section5,"",@llvm_sympart
1319
.byte 1
20+
# ASM: .section .section6,"",@llvm_dependent_libraries
1421
.section .section6,"",@llvm_dependent_libraries
1522
.byte 1
23+
# ASM: .section .section7,"",@llvm_offloading
1624
.section .section7,"",@llvm_offloading
1725
.byte 1
26+
# ASM: .section .section8,"",@llvm_lto
1827
.section .section8,"",@llvm_lto
1928
.byte 1
29+
# ASM: .section .section9,"",@llvm_cfi_jump_table,1
30+
.section .section9,"",@llvm_cfi_jump_table,1
31+
.byte 1
2032

2133
# CHECK: Name: .section1
2234
# CHECK-NEXT: Type: SHT_LLVM_BB_ADDR_MAP
@@ -34,3 +46,6 @@
3446
# CHECK-NEXT: Type: SHT_LLVM_OFFLOADING
3547
# CHECK: Name: .section8
3648
# CHECK-NEXT: Type: SHT_LLVM_LTO
49+
# CHECK: Name: .section9
50+
# CHECK-NEXT: Type: SHT_LLVM_CFI_JUMP_TABLE
51+
# CHECK: EntrySize: 1

0 commit comments

Comments
 (0)