[PATCH] Arm: Don't define a label twice with two setjmps in a function.

Matthias Braun matze at braunis.de
Mon Jun 1 10:45:56 PDT 2015


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.


REPOSITORY
  rL LLVM

http://reviews.llvm.org/D9314

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the llvm-commits mailing list