On Tue, Feb 25, 2014 at 5:41 PM, Eric Christopher <echristo at gmail.com>wrote:> On Mon, Feb 24, 2014 at 4:33 PM, Tom Roeder <tmroeder at google.com> wrote: > > > > I'm definitely interested in removing the inline asm bits. I'm not > > sure what you mean by a pseudo-plt, though; do you mean hooking into > > the code that generates the Procedure Linkage Table? I really don't > > know much about the LLVM back end, so I'd have to learn how that all > > works in LLVM first. > > Either that or using similar functionality. It's definitely more > complicated on the start than using the inline assembly. > > -eric >I've been digging around in the back end for a bit now, trying to figure out the best way to implement the jump-instruction tables; there's already support for jump tables there, but it's a different kind of jump table than the one I want. One direction that looks promising to me is to add an intrinsic, something like: declare void @llvm.jump.instr.table.entry(i8*, i8*) The first argument would be the original function (the one that gets jumped to in the table), and the second argument is the _JT function declared but not defined by the pass. Then I can add a custom lowering in each supported architecture that would turn this into a labeled jump instruction something like .globl func_JT func_JT: jmp func at PLT The CFI pass would add a special function that would consist only of these intrinsics, one for each jump statement needed by the table, and padded to a power of two using another special intrinsic (something like llvm.undefined.instr) that would lower to an undefined instruction (like ud2 in x86). I'd appreciate feedback anyone might have about this proposal. Thanks, Tom -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140317/efb5749f/attachment.html>
On Mon, Mar 17, 2014 at 10:28:52AM -0700, Tom Roeder wrote:> On Tue, Feb 25, 2014 at 5:41 PM, Eric Christopher <echristo at gmail.com>wrote: > > > On Mon, Feb 24, 2014 at 4:33 PM, Tom Roeder <tmroeder at google.com> wrote: > > > > > > I'm definitely interested in removing the inline asm bits. I'm not > > > sure what you mean by a pseudo-plt, though; do you mean hooking into > > > the code that generates the Procedure Linkage Table? I really don't > > > know much about the LLVM back end, so I'd have to learn how that all > > > works in LLVM first. > > > > Either that or using similar functionality. It's definitely more > > complicated on the start than using the inline assembly. > > > > -eric > > > > I've been digging around in the back end for a bit now, trying to figure > out the best way to implement the jump-instruction tables; there's already > support for jump tables there, but it's a different kind of jump table than > the one I want. > > One direction that looks promising to me is to add an intrinsic, something > like: > > declare void @llvm.jump.instr.table.entry(i8*, i8*) > > The first argument would be the original function (the one that gets jumped > to in the table), and the second argument is the _JT function declared but > not defined by the pass. > > Then I can add a custom lowering in each supported architecture that would > turn this into a labeled jump instruction something like > > .globl func_JT > func_JT: > jmp func at PLT > > > The CFI pass would add a special function that would consist only of these > intrinsics, one for each jump statement needed by the table, and padded to > a power of two using another special intrinsic (something like > llvm.undefined.instr) that would lower to an undefined instruction (like > ud2 in x86). > > I'd appreciate feedback anyone might have about this proposal.Creating these intrinsic calls could potentially introduce pessimizations, as the midend would consider the functions to be used. Though maybe this doesn't matter if the CFI pass is run late. It also seems sort of distasteful to have a function whose sole purpose is to hold metadata about other functions. An alternative proposal: introduce a new function attribute named, say, 'jumptable', which would cause the backend to emit a jump table entry and redirect function references other than calls through the jump table. (Direct function calls could call the original function directly, as an optimization.) The CFI pass could then consist of marking every address-taken function with 'jumptable' and introducing the pointer safety checks at call sites. Thanks, -- Peter
On Thu, Mar 20, 2014 at 3:29 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:> > On Mon, Mar 17, 2014 at 10:28:52AM -0700, Tom Roeder wrote: > > On Tue, Feb 25, 2014 at 5:41 PM, Eric Christopher <echristo at gmail.com>wrote: > > > > > On Mon, Feb 24, 2014 at 4:33 PM, Tom Roeder <tmroeder at google.com> wrote: > > > > > > > > I'm definitely interested in removing the inline asm bits. I'm not > > > > sure what you mean by a pseudo-plt, though; do you mean hooking into > > > > the code that generates the Procedure Linkage Table? I really don't > > > > know much about the LLVM back end, so I'd have to learn how that all > > > > works in LLVM first. > > > > > > Either that or using similar functionality. It's definitely more > > > complicated on the start than using the inline assembly. > > > > > > -eric > > > > > > > I've been digging around in the back end for a bit now, trying to figure > > out the best way to implement the jump-instruction tables; there's already > > support for jump tables there, but it's a different kind of jump table than > > the one I want. > > > > One direction that looks promising to me is to add an intrinsic, something > > like: > > > > declare void @llvm.jump.instr.table.entry(i8*, i8*) > > > > The first argument would be the original function (the one that gets jumped > > to in the table), and the second argument is the _JT function declared but > > not defined by the pass. > > > > Then I can add a custom lowering in each supported architecture that would > > turn this into a labeled jump instruction something like > > > > .globl func_JT > > func_JT: > > jmp func at PLT > > > > > > The CFI pass would add a special function that would consist only of these > > intrinsics, one for each jump statement needed by the table, and padded to > > a power of two using another special intrinsic (something like > > llvm.undefined.instr) that would lower to an undefined instruction (like > > ud2 in x86). > > > > I'd appreciate feedback anyone might have about this proposal. > > Creating these intrinsic calls could potentially introduce pessimizations, > as the midend would consider the functions to be used. Though maybe this > doesn't matter if the CFI pass is run late. > > It also seems sort of distasteful to have a function whose sole purpose is > to hold metadata about other functions.The way I've implemented it (see the patch I sent to llvm-commits yesterday), it's not just metadata: the intrinsic lowers to the jumptable entry code given above. The CFI pass then generates a function for each jump table; the function consists solely of these intrinsic calls.> > > An alternative proposal: introduce a new function attribute named, say, > 'jumptable', which would cause the backend to emit a jump table entry and > redirect function references other than calls through the jump table. (Direct > function calls could call the original function directly, as an optimization.) > > The CFI pass could then consist of marking every address-taken function with > 'jumptable' and introducing the pointer safety checks at call sites.That's an interesting suggestion. I'll look into it.