The ShadowCallStack pass instruments functions marked with the
shadowcallstack attribute. The instrumented prolog saves the return
address to [gs:offset] where offset is stored and updated in [gs:0].
The instrumented epilog loads/updates the return address from [gs:0]
and checks that it matches the return address on the stack before
returning.
Details
Diff Detail
- Repository
- rL LLVM
- Build Status
Buildable 16594 Build 16594: arc lint + arc unit
Event Timeline
@craig.topper Just wanted to give you a heads up about this change as it's landing a pass in the X86 backend. The pass is specific to functions compiled with -fsanitize=shadow-call-stack so it shouldn't affect most users.
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
96 | AFAIK you can do it without a dummy instruction by using the iterator form of BuildMI and passing MBB->end() or MBB->begin() in case of the empty basic block. |
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
90 | I think this is possible if the function takes a nest parameter -- probably best to disable the protection in that case for now. |
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
65 | Do you need this functions like members. | |
91 | Why is there inconsistency reference vs pointer? | |
288 | LeafFuncOptimization looks redundunt: LeafFuncOptimization == ( LeafFuncRegister != X86::NoRegister) | |
294 | for (auto &MBB : Fn) MBB.addLiveIn(LeafFuncRegister); | |
325 | can getFallThrough return null? |
- Address Vitaly's comments
- Only add live-ins when a register was found
- Add a short leaf function test case
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
294 | The original loop actually skips the first basic bock: ++Fn.begin(), I'll add a comment to make that clearer. | |
325 | I don't think so, the check at 241 demonstrates there is at least one instruction in this function so if the first MBB is empty then there has to be another MBB following it. |
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
96 | I would imagine that you could save the result of MBB->begin() and use that to insert instructions forwards, as it should always refer to what used to be the first instruction. Does that not work? |
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
96 | Sorry, let me be more clear. BuildMI() has two forms: one to add to the end of an MBB and one to add before a given instruction in the MBB. That means that for an empty MBB we can't insert instructions in forwards order without inserting a fake instruction to insert behind or using two different forms to insert the same instructions (one inserting behind the first instruction and the other always using the add-to-the-end form.) |
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
96 | But there is another form that takes an iterator. http://llvm-cs.pcc.me.uk/include/llvm/CodeGen/MachineInstrBuilder.h#313 Can you pass the iterator that you previously got from MBB->begin() to it? |
lib/Target/X86/ShadowCallStack.cpp | ||
---|---|---|
96 | Huh, I didn't think this form would work because the iterator would be invalidated between MBB insertions but it looks like that's not the case for ilists so this form does work. |
Do you need this functions like members.
probably static non member should work as well