[llvm-dev] Usage of the jumptable attribute

via llvm-dev llvm-dev at lists.llvm.org
Wed Sep 4 06:58:46 PDT 2019



> -----Original Message-----
> From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of
> Krzysztof Parzyszek via llvm-dev
> Sent: Wednesday, September 04, 2019 9:08 AM
> To: CompilerCrash; llvm-dev at lists.llvm.org
> Subject: Re: [llvm-dev] Usage of the jumptable attribute
> 
> 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).

In that case, shouldn't you update the LangRef to say so?
--paulr

> 
> --
> 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
> _______________________________________________
> 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