[llvm-dev] Usage of the jumptable attribute
Krzysztof Parzyszek via llvm-dev
llvm-dev at lists.llvm.org
Wed Sep 4 06:08:09 PDT 2019
Hi Daniel,
This attribute doesn't do anything anymore. It was added a while back to implement control flow integrity, but that work was eventually removed. I believe it's still there for backwards compatibility (i.e. to read old bitcode).
--
Krzysztof Parzyszek kparzysz at quicinc.com AI tools development
> -----Original Message-----
> From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of CompilerCrash
> via llvm-dev
> Sent: Saturday, August 31, 2019 2:22 AM
> To: llvm-dev at lists.llvm.org
> Subject: [EXT] [llvm-dev] Usage of the jumptable attribute
>
> Hello everyone,
>
> I'm new to LLVM (which is a really great project by the way) and I hope this
> is the right place for my question.
>
> In the LLVM Language Reference Manual I found the "jumptable" function
> attribute, which seems to be exactly what I need for my project (where I want
> to add one level of indirection to every function call), but I have trouble
> figuring out, how to use it correctly.
>
> I wrote my own transformation pass (using LLVM 8.0.1) to add this attribute
> as well as unnamed_addr (I'm aware that this might break some programs, but
> jumptable requires it) to every function definition:
>
> // includes ...
>
> using namespace llvm;
>
> namespace {
> struct MyPass : public ModulePass {
> static char ID;
> MyPass() : ModulePass(ID) {}
>
> bool runOnModule(Module &M) override {
> for (Function &F : M.getFunctionList()) {
> if (!F.isDeclaration()) {
> F.setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
> F.addFnAttr(Attribute::JumpTable);
> }
> }
> return true;
> }
> };
> }
>
> char MyPass::ID = 0;
> static RegisterPass<MyPass> X("mypass", "My Pass");
>
> And I wrote a program test.c:
>
> #include <stdio.h>
>
> void foo() {
> puts("Hello World");
> }
>
> int main() {
> foo();
> }
>
> I compiled it to test.ll and ran it through opt:
>
> clang -O0 -emit-llvm -S -o test.ll test.c
> build/bin/opt -load build/lib/LLVMMyPass.so -mypass -S -o test.out.ll
> test.ll
>
> The output (test.out.ll) was identical to test.ll except for the 3
> occurrences of jumptable and the last 2 occurrences of unnamed_addr:
>
> ; ModuleID = 'test.ll'
> source_filename = "test.c"
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @.str = private unnamed_addr constant [12 x i8] c"Hello World\00", align
> 1
>
> ; Function Attrs: jumptable noinline nounwind optnone uwtable
> define dso_local void @foo() unnamed_addr #0 {
> %1 = call i32 @puts(i8* getelementptr inbounds ([12 x i8], [12 x
> i8]* @.str, i32 0, i32 0))
> ret void
> }
>
> declare dso_local i32 @puts(i8*) #1
>
> ; Function Attrs: jumptable noinline nounwind optnone uwtable
> define dso_local i32 @main() unnamed_addr #0 {
> call void @foo()
> ret i32 0
> }
>
> attributes #0 = { jumptable noinline nounwind optnone uwtable "no-jump-
> tables"="false"
> ; ... many more attributes ...
> }
> attributes #1 = {
> ; ... many more attributes ...
> }
>
> !llvm.module.flags = !{!0}
> !llvm.ident = !{!1}
>
> !0 = !{i32 1, !"wchar_size", i32 4}
> !1 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"}
>
> Finally, I executed:
>
> build/bin/llc -o test.out.s test.out.ll
> clang -o test.out.native test.out.s
> objdump --disassemble-all test.out.native
>
> I hoped to see some kind of jump table being used for the call to foo (maybe
> even the plt mechanism the dynamic library calls use), but it is just a
> "normal" jump to foo's address:
>
> 0000000000400500 <foo>:
> 400500: 55 push %rbp
> 400501: 48 89 e5 mov %rsp,%rbp
> 400504: 48 bf c0 05 40 00 00 movabs $0x4005c0,%rdi
> 40050b: 00 00 00
> 40050e: e8 cd fe ff ff callq 4003e0 <puts at plt>
> 400513: 5d pop %rbp
> 400514: c3 retq
> 400515: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
> 40051c: 00 00 00
> 40051f: 90 nop
>
> 0000000000400520 <main>:
> 400520: 55 push %rbp
> 400521: 48 89 e5 mov %rsp,%rbp
> 400524: e8 d7 ff ff ff callq 400500 <foo>
> 400529: 31 c0 xor %eax,%eax
> 40052b: 5d pop %rbp
> 40052c: c3 retq
> 40052d: 0f 1f 00 nopl (%rax)
>
> So, what am I doing wrong? The documentation indicates that the jump table is
> created at code-generation time. So I guess my pass works fine and I just
> need to get the code generator to process the jumptable attribute somehow? I
> found the createJumpInstrTablesPass in include/CodeGen/Passes.h, but it seems
> like it's never used.
>
> Thanks in advance
>
> Daniel
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
More information about the llvm-dev
mailing list