From 19a2418bece082126f710ed5dec45e52fac03ffd Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 16 Jul 2025 23:09:42 -0700 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6-beta.1 --- llvm/docs/Extensions.rst | 20 ++++++++++++++++++++ llvm/include/llvm/BinaryFormat/ELF.h | 1 + llvm/lib/MC/MCParser/ELFAsmParser.cpp | 4 +++- llvm/lib/Object/ELF.cpp | 1 + llvm/test/MC/AsmParser/llvm_section_types.s | 5 +++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst index bad72c6ca8295..d8fb87b6998ad 100644 --- a/llvm/docs/Extensions.rst +++ b/llvm/docs/Extensions.rst @@ -581,6 +581,26 @@ This section stores pairs of (jump table address, number of entries). This information is useful for tools that need to statically reconstruct the control flow of executables. +``SHT_LLVM_CFI_JUMP_TABLE`` Section (CFI jump table) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This section contains the instructions that make up a `CFI jump table`_. +It is expected to be ``SHF_ALLOC`` and may be laid out like a normal +section. The ``SHT_LLVM_CFI_JUMP_TABLE`` section type gives the linker +permission to modify the section in ways that would not normally be +permitted, in order to optimize calls via the jump table. + +Each ``sh_entsize`` sized slice of a section of this type containing +exactly one relocation may be considered to be a jump table entry +that branches to the target of the relocation. This allows the linker +to replace the jump table entry with the function body if it is small +enough, or if the function is the last function in the jump table. + +A section of this type does not have to be placed according to its +name. The linker may place the section in whichever output section it +sees fit (generally the section that would provide the best locality). + +.. _CFI jump table: https://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#forward-edge-cfi-for-indirect-function-calls + CodeView-Dependent ------------------ diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index ebb257ab33821..b9e38801d880f 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1159,6 +1159,7 @@ enum : unsigned { SHT_LLVM_OFFLOADING = 0x6fff4c0b, // LLVM device offloading data. SHT_LLVM_LTO = 0x6fff4c0c, // .llvm.lto for fat LTO. SHT_LLVM_JT_SIZES = 0x6fff4c0d, // LLVM jump tables sizes. + SHT_LLVM_CFI_JUMP_TABLE = 0x6fff4c0e, // LLVM CFI jump table. // Android's experimental support for SHT_RELR sections. // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512 SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets. diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index ec8b40261a6ca..c7c3df330fc94 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -571,7 +571,7 @@ bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) { return TokError("expected end of directive"); } - if (Mergeable) + if (Mergeable || TypeName == "llvm_cfi_jump_table") if (parseMergeSize(Size)) return true; if (Flags & ELF::SHF_LINK_ORDER) @@ -637,6 +637,8 @@ bool ELFAsmParser::parseSectionArguments(bool IsPush, SMLoc loc) { Type = ELF::SHT_LLVM_LTO; else if (TypeName == "llvm_jt_sizes") Type = ELF::SHT_LLVM_JT_SIZES; + else if (TypeName == "llvm_cfi_jump_table") + Type = ELF::SHT_LLVM_CFI_JUMP_TABLE; else if (TypeName.getAsInteger(0, Type)) return TokError("unknown section type"); } diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index ff99dc25abe07..28a7040ea8d56 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -321,6 +321,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_JT_SIZES) + STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CFI_JUMP_TABLE) STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); diff --git a/llvm/test/MC/AsmParser/llvm_section_types.s b/llvm/test/MC/AsmParser/llvm_section_types.s index 147b1499d2b88..1e644ced853b3 100644 --- a/llvm/test/MC/AsmParser/llvm_section_types.s +++ b/llvm/test/MC/AsmParser/llvm_section_types.s @@ -17,6 +17,8 @@ .byte 1 .section .section8,"",@llvm_lto .byte 1 +.section .section9,"",@llvm_cfi_jump_table,1 +.byte 1 # CHECK: Name: .section1 # CHECK-NEXT: Type: SHT_LLVM_BB_ADDR_MAP @@ -34,3 +36,6 @@ # CHECK-NEXT: Type: SHT_LLVM_OFFLOADING # CHECK: Name: .section8 # CHECK-NEXT: Type: SHT_LLVM_LTO +# CHECK: Name: .section9 +# CHECK-NEXT: Type: SHT_LLVM_CFI_JUMP_TABLE +# CHECK: EntrySize: 1 From 1d1abdde5f652a1d29f4820a8e7b25de87b7eb2d Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 17 Jul 2025 21:27:48 -0700 Subject: [PATCH 2/2] Fix parser and add parser test Created using spr 1.3.6-beta.1 --- llvm/lib/MC/MCSectionELF.cpp | 4 +++- llvm/test/MC/AsmParser/llvm_section_types.s | 12 +++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp index cc7cdf2fe4d1a..299fe40706e3a 100644 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -176,11 +176,13 @@ void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, OS << "llvm_lto"; else if (Type == ELF::SHT_LLVM_JT_SIZES) OS << "llvm_jt_sizes"; + else if (Type == ELF::SHT_LLVM_CFI_JUMP_TABLE) + OS << "llvm_cfi_jump_table"; else OS << "0x" << Twine::utohexstr(Type); if (EntrySize) { - assert(Flags & ELF::SHF_MERGE); + assert((Flags & ELF::SHF_MERGE) || Type == ELF::SHT_LLVM_CFI_JUMP_TABLE); OS << "," << EntrySize; } diff --git a/llvm/test/MC/AsmParser/llvm_section_types.s b/llvm/test/MC/AsmParser/llvm_section_types.s index 1e644ced853b3..83e5db0256647 100644 --- a/llvm/test/MC/AsmParser/llvm_section_types.s +++ b/llvm/test/MC/AsmParser/llvm_section_types.s @@ -1,22 +1,32 @@ -## Verify that LLVM-specific section types are correctly inferred from assembly input. +## Verify that LLVM-specific section types are correctly inferred from assembly input and printed. +# RUN: llvm-mc -triple i386-pc-linux %s | FileCheck --check-prefix=ASM %s # RUN: llvm-mc -triple i386-pc-linux -filetype=obj -o %t %s # RUN: llvm-readobj -S %t | FileCheck %s +# ASM: .section .section1,"",@llvm_bb_addr_map .section .section1,"",@llvm_bb_addr_map .byte 1 +# ASM: .section .section2,"",@llvm_call_graph_profile .section .section2,"",@llvm_call_graph_profile .byte 1 +# ASM: .section .section3,"",@llvm_odrtab .section .section3,"",@llvm_odrtab .byte 1 +# ASM: .section .section4,"",@llvm_linker_options .section .section4,"",@llvm_linker_options .byte 1 +# ASM: .section .section5,"",@llvm_sympart .section .section5,"",@llvm_sympart .byte 1 +# ASM: .section .section6,"",@llvm_dependent_libraries .section .section6,"",@llvm_dependent_libraries .byte 1 +# ASM: .section .section7,"",@llvm_offloading .section .section7,"",@llvm_offloading .byte 1 +# ASM: .section .section8,"",@llvm_lto .section .section8,"",@llvm_lto .byte 1 +# ASM: .section .section9,"",@llvm_cfi_jump_table,1 .section .section9,"",@llvm_cfi_jump_table,1 .byte 1