This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch x86/darwin] fix PR51784 'PIC register not correctly preserved...'


Hi,

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.

[For the Darwin case, it is always necessary to preserve and restore the PIC base, since a different base is used in each function].

The remainder of the patch is darwin-specific, to provide restoration of the pic register at non-local-goto-recievers.

==

I have verified that the patch works as expected on x86_64-linux (@m32), i686-darwin9 and x86_64-darwin12 (@m32) - and that, otherwise, there are no test changes (Ada and Java tested on Darwin, but not on Linux).

(Other Darwin folks {thanks!} have tested this across a wider range of Darwin versions)

==

OK for trunk?

OK open branches? (since this is a wrong code bug)

thanks,
Iain

gcc/

	PR target/51784
	* config/i386/i386.c (output_set_got, DARWIN): Adjust to emit a second label for nonlocal
	goto receivers. Don't output pic base labels unless we're producing PIC; mark that action
	unreachable().
	(ix86_save_reg): If the function contains a nonlocal label, save the PIC base reg.
	* config/darwin-protos.h (machopic_should_output_picbase_label): New.
	* gcc/config/darwin.c (emitted_pic_label_num): New GTY. 
	(update_pic_label_number_if_needed): New.
	(machopic_output_function_base_name): Adjust for nonlocal receiver case.
	(machopic_should_output_picbase_label): New.
	* config/i386/i386.md (enum unspecv): UNSPECV_NLGR: New.
	(nonlocal_goto_receiver): New insn and split.

Attachment: PR51784-diff.txt
Description: Text document


	
	


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]