I try to implement a coarse-grained CFI in LLVM
(CFI = Contorl Flow Integrity)
I want to collect all address after call instructions
address after a call equals to a valid return site in coarse-grained CFI
I want to add a new section
and write all the possible return address in the new section
(and then, add the integrity check)
I have some quetions:
Which part of LLVM code should I implement my CFI ?
IR level or SelectionDAG/CodeGen?
LLVM MC can let me add a new section, right?
How can I get the real address of instruction in compile time?
Or should I modify linker/loader?
Hi -- can you describe a bit more what you mean by coarse-grained CFI?
We do some of what you're describing in the XRay implementation, where
we have a section for the instrumentation map and at runtime we're
able to tell which functions are instrumented.
The way we've had to do this is with attributes at LLVM IR for
functions, have a pass that will lower certain instructions (returns
and tail exits) into pseudo-instructions, and further lowering to
target/platform specific details (sections in ELF/MachO etc.).
Adding back llvm-dev
I trace the code of XRay
I found that "X86AsmPrinter::runOnMachineFunction" would call "emitXRayTable".
So, you use " void AsmPrinter::emitXRayTable() " to write something into a new section, right?
for (const auto &Sled : Sleds)
Sled.emit(WordSizeBytes, OutStreamer.get(), CurrentFnSym);
Sleds is array of XRayFunctionEntry .
In the AsmPrinter::XRayFunctionEntry::emit , there is a Out->EmitSymbolValue(CurrentFnSym, Bytes);
I wonder that whether the "CurrentFnSym" emitted to the new section will be a real adrress?
Will CurrentFnSym be fixed up by linker/loader or someone?
It must be fixed up by the linker.
Happy to help!