Hello! > The PR is logged against Darwin, and (as Jakub points out in the PR > thread) indeed Darwin is missing a nonlocal_goto_receiver to restore > the PIC reg in code that uses it (most of the patch). > > However, there is a second issue, and (if I've understood things > correctly) this affects GOT targets too - thus there is a single > non-darwin-specific hunk for which I need approval for X86 as a whole. > > consider (x86 -fPIC -m32) > > == > > int g42 = 42; > > int foo (void) <=== doesn't use EBX, so doesn't save it. > { > __label__ x; > int z; > int bar (int *zz) <== does use EBX, and saves it > { > *zz = g42; > goto x; <== however, EBX is not restored here. > } > > bar(&z); > > x: > return z; > } > > == > > ... this all works OK when the caller of foo and foo are in one object > (and thus share the same GOT) > > .. however, suppose we build the code above as a shared lib and call > it from a pie executable (or another so). > > Now, when the caller (with a different GOT value from the lib) calls > foo() - EBX gets trashed (probably *boom*). > > The solution proposed here (for this aspect) is that, if a function > contains a nonlocal label, then the PICbase register should be > preserved. This is the only non-darwin-specific hunk in the patch.
I don't think this is the correct solution. Function bar() should restore %ebx before jumping to the label. The problem can be seen if you change "return z" to "return z + g42" at the end of your testcase. The test will be compiled to: bar.1372: pushl %ebp movl %esp, %ebp pushl %ebx call __x86.get_pc_thunk.bx addl $_GLOBAL_OFFSET_TABLE_, %ebx movl g42@GOT(%ebx), %edx movl (%edx), %edx movl %edx, (%eax) leal .L2@GOTOFF(%ebx), %eax movl (%ecx), %ebp movl 4(%ecx), %esp jmp *%eax and foo: pushl %ebp pushl %edi pushl %esi pushl %ebx call __x86.get_pc_thunk.bx addl $_GLOBAL_OFFSET_TABLE_, %ebx subl $16, %esp leal 16(%esp), %eax movl %eax, 4(%esp) leal 4(%esp), %ecx movl %esp, %eax movl %esp, 8(%esp) call bar.1372 .L2: movl g42@GOT(%ebx), %edx movl (%esp), %eax addl (%edx), %eax addl $16, %esp popl %ebx popl %esi popl %edi popl %ebp ret Under assumpiton that foo and bar doesn't share the same GOT, you will see that g42 after the label is accessed with "clobbered" %ebx. Uros.