This is an archive of the discontinued LLVM Phabricator instance.

Arm: Don't define a label twice with two setjmps in a function.
ClosedPublic

Authored by MatzeB on Apr 27 2015, 5:54 PM.

Diff Detail

Repository
rL LLVM

Event Timeline

MatzeB updated this revision to Diff 24522.Apr 27 2015, 5:54 PM
MatzeB retitled this revision from to Arm: Don't define a label twice with two setjmps in a function..
MatzeB updated this object.
MatzeB edited the test plan for this revision. (Show Details)
MatzeB added a reviewer: grosbach.
MatzeB set the repository for this revision to rL LLVM.
MatzeB added a subscriber: Unknown Object (MLST).

Simply do what the comment in ARMAsmPrinter says and use directional labels.

Which comment would that be? I had a look in both ARMAsmPrinter.h and ARMAsmPrinter.cpp and could find no mention of directional labels.

I'm a bit lost, too.

The review description is seriously lacking, and the change seems odd.

I'm no expert in SJLJ, so I'd rather someone with more knowledge in it to review, but for that, we'd need a better description and maybe some comments on why your substitution is valid, what it fixes, etc.

cheers,
--renato

First to avoid confusion this is not about SJLJ exception handling but just about the implementation of setjmp (which is part of SJLJ exception handling but can also be used independently with __builtin_setjmp() for example).

The code in question implements setjmp, to do it has to: Store the current program counter into the provided jump buffer. The tricky part here is that controlflow can either start at the beginning of the sequence, or we can come from a longjmp call which executed a jump to the stored program counter. Now depending on whether we executed the setjmp first or came from a longjmp invocation we want to return different values. This is why the code is generated in a way that first sets r0 to 0 and then jumps over an instruction that sets r0 to 1, while the PC that is stored earlier is adjust in a way that the PC of the 1-setting instruction is stored. So far for what the code there is supposed to be doing[1]. The comment in the code I referenced explains how the generated instructions should look like:

// Two incoming args: GPR:$src, GPR:$val
 // mov $val, pc
 // adds $val, #7
 // str $val, [$src, #4]
 // movs r0, #0
 // b 1f
 // movs r0, #1
 // 1:

The problem here is that the label for the jump is created by this:

raw_svector_ostream(Name) << DL->getPrivateGlobalPrefix() << "SJLJEH"

which is unique per function, but as soon as someone uses __builtin_setjmp() twice in a function we will have a duplicate label. My patch simply fixes that by using local/directional lables. Local labels are documented here:
https://sourceware.org/binutils/docs-2.25/as/Symbol-Names.html#Symbol-Names
The comment already used the syntax for local labels so that seemed like a natural fix.

[1] Now that I explained that in detail I realize that the existing code is even more broken in that it returns 1 in the longjmp case but should be returning the value loaded from the jmpbuf by the longjmp instruction (the longjmp instruction always loads that value into r7) if longjmp would simply load the value into r0 we could also implement all of this easily without a jump... But my intention here was to fix a simply bug that makes the assembler abort. Fixing the whole setjmp implementation properly is for another patch.

Hi Matthias,

Sorry, this fell out of my radar. Now it's a lot clearer what do you mean by "the comment" and why are you using the directional labels. It looks ok to me, but I'm adding some EH and Darwin folks, as this affects them more than anything.

I just have one question: can you create your temporary labels with some prefix? Like "SJLJEH".1 .2 .3 etc? That'd help when reading the resulting assembly.

cheers,
--renato

rengolin accepted this revision.Jul 3 2015, 10:27 AM
rengolin added a reviewer: rengolin.

Hi Matthias,

I guess people don't feel strongly about this one. I think it's good.

Can you tag the labels with some "SJLJ" text? Just so we know what are they?

Otherwise, LGTM. Thanks!

This revision is now accepted and ready to land.Jul 3 2015, 10:27 AM
This revision was automatically updated to reflect the committed changes.