re PR lto/86517 (relocation R_X86_64_32 against `.rodata.str1.1' can not be used...
authorJan Hubicka <jh@suse.cz>
Thu, 30 Aug 2018 15:50:39 +0000 (17:50 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 30 Aug 2018 15:50:39 +0000 (15:50 +0000)
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

gcc/ChangeLog
gcc/lto-opts.c
gcc/lto-wrapper.c

index fe6dacb..cce66bc 100644 (file)
@@ -1,5 +1,11 @@
 2018-08-29  Jan Hubicka  <jh@suse.cz>
 
+       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.
+
+2018-08-29  Jan Hubicka  <jh@suse.cz>
+
        * lto-streamer-out.c (DFS::DFS_write_tree_body): Do not follow
        TYPE_STUB_DECL.
        (hash_tree): Do not visit TYPE_STUB_DECL.
index 09ec7c0..dbb41f6 100644 (file)
@@ -78,6 +78,21 @@ lto_write_options (void)
       && !global_options.x_flag_openacc)
     append_to_collect_gcc_options (&temporary_obstack, &first_p,
                                   "-fno-openacc");
+  /* Append PIC/PIE mode because its default depends on target and it is
+     subject of merging in lto-wrapper.  */
+  if (!global_options_set.x_flag_pic && !global_options_set.x_flag_pie)
+    {
+       append_to_collect_gcc_options (&temporary_obstack, &first_p,
+                                     global_options.x_flag_pic == 2
+                                     ? "-fPIC"
+                                     : global_options.x_flag_pic == 1
+                                     ? "-fpic"
+                                     : global_options.x_flag_pie == 2
+                                     ? "-fPIE"
+                                     : global_options.x_flag_pie == 1
+                                     ? "-fpie"
+                                     : "-fno-pie");
+    }
 
   /* Append options from target hook and store them to offload_lto section.  */
   if (lto_stream_offload_p)
index 9cfdfae..2b9d47e 100644 (file)
@@ -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++;