aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-wrapper.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2018-08-30 17:50:39 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2018-08-30 15:50:39 +0000
commit4e6a938029976924c3be5300e2d0caaae9d05c5d (patch)
treef482b9338950b03acf1d43ad637a602bd05f03ea /gcc/lto-wrapper.c
parent24c35f687a2d1e95c45086f5a13a3624cf21f32a (diff)
downloadgcc-4e6a938029976924c3be5300e2d0caaae9d05c5d.zip
gcc-4e6a938029976924c3be5300e2d0caaae9d05c5d.tar.gz
gcc-4e6a938029976924c3be5300e2d0caaae9d05c5d.tar.bz2
re PR lto/86517 (relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object with LTO)
PR lto/86517 * lto-opts.c (lto_write_options): Always stream PIC/PIE mode. * lto-wrapper.c (merge_and_complain): Fix merging of PIC/PIE. From-SVN: r263988
Diffstat (limited to 'gcc/lto-wrapper.c')
-rw-r--r--gcc/lto-wrapper.c83
1 files changed, 73 insertions, 10 deletions
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 9cfdfae..2b9d47e 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -409,6 +409,11 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
It is a common mistake to mix few -fPIC compiled objects into otherwise
non-PIC code. We do not want to build everything with PIC then.
+ Similarly we merge PIE options, however in addition we keep
+ -fPIC + -fPIE = -fPIE
+ -fpic + -fPIE = -fpie
+ -fPIC/-fpic + -fpie = -fpie
+
It would be good to warn on mismatches, but it is bit hard to do as
we do not know what nothing translates to. */
@@ -416,11 +421,38 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
if ((*decoded_options)[j].opt_index == OPT_fPIC
|| (*decoded_options)[j].opt_index == OPT_fpic)
{
- if (!pic_option
- || (pic_option->value > 0) != ((*decoded_options)[j].value > 0))
- remove_option (decoded_options, j, decoded_options_count);
- else if (pic_option->opt_index == OPT_fPIC
- && (*decoded_options)[j].opt_index == OPT_fpic)
+ /* -fno-pic in one unit implies -fno-pic everywhere. */
+ if ((*decoded_options)[j].value == 0)
+ j++;
+ /* If we have no pic option or merge in -fno-pic, we still may turn
+ existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present. */
+ else if ((pic_option && pic_option->value == 0)
+ || !pic_option)
+ {
+ if (pie_option)
+ {
+ bool big = (*decoded_options)[j].opt_index == OPT_fPIC
+ && pie_option->opt_index == OPT_fPIE;
+ (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
+ if (pie_option->value)
+ (*decoded_options)[j].canonical_option[0] = big ? "-fPIE" : "-fpie";
+ else
+ (*decoded_options)[j].canonical_option[0] = big ? "-fno-pie" : "-fno-pie";
+ (*decoded_options)[j].value = pie_option->value;
+ j++;
+ }
+ else if (pic_option)
+ {
+ (*decoded_options)[j] = *pic_option;
+ j++;
+ }
+ /* We do not know if target defaults to pic or not, so just remove
+ option if it is missing in one unit but enabled in other. */
+ else
+ remove_option (decoded_options, j, decoded_options_count);
+ }
+ else if (pic_option->opt_index == OPT_fpic
+ && (*decoded_options)[j].opt_index == OPT_fPIC)
{
(*decoded_options)[j] = *pic_option;
j++;
@@ -431,11 +463,42 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
else if ((*decoded_options)[j].opt_index == OPT_fPIE
|| (*decoded_options)[j].opt_index == OPT_fpie)
{
- if (!pie_option
- || pie_option->value != (*decoded_options)[j].value)
- remove_option (decoded_options, j, decoded_options_count);
- else if (pie_option->opt_index == OPT_fPIE
- && (*decoded_options)[j].opt_index == OPT_fpie)
+ /* -fno-pie in one unit implies -fno-pie everywhere. */
+ if ((*decoded_options)[j].value == 0)
+ j++;
+ /* If we have no pie option or merge in -fno-pie, we still preserve
+ PIE/pie if pic/PIC is present. */
+ else if ((pie_option && pie_option->value == 0)
+ || !pie_option)
+ {
+ /* If -fPIC/-fpic is given, merge it with -fPIE/-fpie. */
+ if (pic_option)
+ {
+ if (pic_option->opt_index == OPT_fpic
+ && (*decoded_options)[j].opt_index == OPT_fPIE)
+ {
+ (*decoded_options)[j].opt_index = OPT_fpie;
+ (*decoded_options)[j].canonical_option[0]
+ = pic_option->value ? "-fpie" : "-fno-pie";
+ }
+ else if (!pic_option->value)
+ (*decoded_options)[j].canonical_option[0] = "-fno-pie";
+ (*decoded_options)[j].value = pic_option->value;
+ j++;
+ }
+ else if (pie_option)
+ {
+ (*decoded_options)[j] = *pie_option;
+ j++;
+ }
+ /* Because we always append pic/PIE options this code path should
+ not happen unless the LTO object was built by old lto1 which
+ did not contain that logic yet. */
+ else
+ remove_option (decoded_options, j, decoded_options_count);
+ }
+ else if (pie_option->opt_index == OPT_fpie
+ && (*decoded_options)[j].opt_index == OPT_fPIE)
{
(*decoded_options)[j] = *pie_option;
j++;