re PR lto/83452 (FAIL: gfortran.dg/save_6.f90 -O0 (test for excess errors))
authorRichard Biener <rguenther@suse.de>
Tue, 2 Jan 2018 08:45:05 +0000 (08:45 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 2 Jan 2018 08:45:05 +0000 (08:45 +0000)
2017-01-02  Richard Biener  <rguenther@suse.de>

PR lto/83452
* simple-object-elf.c (simple_object_elf_copy_lto_debug_section):
Do not use UNDEF locals for removed symbols but instead just
define them in the first prevailing section and with no name.
Use the same gnu_lto_v1 name for all removed globals we promote to
WEAK UNDEFs so hpux can use a stub to provide this symbol.  Clear
sh_info and sh_link in removed sections.

From-SVN: r256069

libiberty/ChangeLog
libiberty/simple-object-elf.c

index c8e1e137ab7c6d4afadd2868023e30fe9b830578..08abd3b12e378454258af6a131ee4f59ec84d040 100644 (file)
@@ -1,3 +1,13 @@
+2017-01-02  Richard Biener  <rguenther@suse.de>
+
+       PR lto/83452
+       * simple-object-elf.c (simple_object_elf_copy_lto_debug_section):
+       Do not use UNDEF locals for removed symbols but instead just
+       define them in the first prevailing section and with no name.
+       Use the same gnu_lto_v1 name for all removed globals we promote to
+       WEAK UNDEFs so hpux can use a stub to provide this symbol.  Clear
+       sh_info and sh_link in removed sections.
+
 2017-10-30  Richard Biener  <rguenther@suse.de>
 
        PR lto/82757
index 27431db98c7d7ba059b1fccaf92ecb3609788361..feef34126fa0c4de7231e3cbf36a0c572f7f2c2f 100644 (file)
@@ -1091,6 +1091,7 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
   int changed;
   int *pfnret;
   const char **pfnname;
+  unsigned first_shndx = 0;
 
   shdr_size = (ei_class == ELFCLASS32
               ? sizeof (Elf32_External_Shdr)
@@ -1158,6 +1159,9 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
       ret = (*pfn) (&name);
       pfnret[i - 1] = ret == 1 ? 0 : -1;
       pfnname[i - 1] = name;
+      if (first_shndx == 0
+         && pfnret[i - 1] == 0)
+       first_shndx = i;
     }
 
   /* Mark sections as preserved that are required by to be preserved
@@ -1327,6 +1331,15 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
                                           sobj->offset + stroff,
                                           (unsigned char *)strings,
                                           strsz, &errmsg, err);
+             /* Find gnu_lto_ in strings.  */
+             char *gnu_lto = strings;
+             while ((gnu_lto = memchr (gnu_lto, 'g',
+                                       strings + strsz - gnu_lto)))
+               if (strncmp (gnu_lto, "gnu_lto_v1",
+                            strings + strsz - gnu_lto) == 0)
+                 break;
+               else
+                 gnu_lto++;
              for (ent = buf; ent < buf + length; ent += entsize)
                {
                  unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
@@ -1366,31 +1379,27 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
                         in case it is local.  */
                      int bind = ELF_ST_BIND (*st_info);
                      int other = STV_DEFAULT;
-                     size_t st_name;
-
                      if (bind == STB_LOCAL)
-                       ELF_SET_FIELD (type_functions, ei_class, Sym,
-                                      ent, st_name, Elf_Word, 0);
+                       {
+                         /* Make discarded local symbols unnamed and
+                            defined in the first prevailing section.  */
+                         ELF_SET_FIELD (type_functions, ei_class, Sym,
+                                        ent, st_name, Elf_Word, 0);
+                         ELF_SET_FIELD (type_functions, ei_class, Sym,
+                                        ent, st_shndx, Elf_Half, first_shndx);
+                       }
                      else
                        {
+                         /* Make discarded global symbols hidden weak
+                            undefined and sharing the gnu_lto_ name.  */
                          bind = STB_WEAK;
-                         st_name = ELF_FETCH_FIELD (type_functions, ei_class,
-                                                    Sym, ent, st_name,
-                                                    Elf_Word);
-                         if (st_name < strsz)
-                           {
-                             char *p = strings + st_name;
-                             if (p[0] == '_'
-                                 && p[1] == '_'
-                                 && strncmp (p + (p[2] == '_'),
-                                             "__gnu_lto_", 10) == 0)
-                               {
-                                 other = STV_HIDDEN;
-                                 ELF_SET_FIELD (type_functions, ei_class, Sym,
-                                                ent, st_name, Elf_Word,
-                                                st_name + 2);
-                               }
-                           }
+                         other = STV_HIDDEN;
+                         if (gnu_lto)
+                           ELF_SET_FIELD (type_functions, ei_class, Sym,
+                                          ent, st_name, Elf_Word,
+                                          gnu_lto - strings);
+                         ELF_SET_FIELD (type_functions, ei_class, Sym,
+                                        ent, st_shndx, Elf_Half, SHN_UNDEF);
                        }
                      *st_other = other;
                      *st_info = ELF_ST_INFO (bind, STT_NOTYPE);
@@ -1398,8 +1407,6 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
                                     ent, st_value, Elf_Addr, 0);
                      ELF_SET_FIELD (type_functions, ei_class, Sym,
                                     ent, st_size, Elf_Word, 0);
-                     ELF_SET_FIELD (type_functions, ei_class, Sym,
-                                    ent, st_shndx, Elf_Half, SHN_UNDEF);
                    }
                }
              XDELETEVEC (strings);
@@ -1422,6 +1429,10 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
             link.  */
          ELF_SET_FIELD (type_functions, ei_class, Shdr,
                         shdr, sh_type, Elf_Word, SHT_NULL);
+         ELF_SET_FIELD (type_functions, ei_class, Shdr,
+                        shdr, sh_info, Elf_Word, 0);
+         ELF_SET_FIELD (type_functions, ei_class, Shdr,
+                        shdr, sh_link, Elf_Word, 0);
        }
 
       flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,