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.