]> git.pld-linux.org Git - packages/elfutils.git/blob - elfutils-strip-copy-symtab.patch
- updated from FC
[packages/elfutils.git] / elfutils-strip-copy-symtab.patch
1 2006-09-19  Jakub Jelinek  <jakub@redhat.com>
2
3         * strip.c (handle_elf): Formatting.  If any relocation sections
4         stripped into separate debug info reference symtab that is kept,
5         emit symtab/strtab also into the separate debug info file.
6
7 --- elfutils/src/strip.c
8 +++ elfutils/src/strip.c
9 @@ -399,6 +399,7 @@ handle_elf (int fd, Elf *elf, const char
10      Elf_Scn *newscn;
11      struct Ebl_Strent *se;
12      Elf32_Word *newsymidx;
13 +    void *debug_data;
14    } *shdr_info = NULL;
15    Elf_Scn *scn;
16    size_t cnt;
17 @@ -826,8 +827,39 @@ handle_elf (int fd, Elf *elf, const char
18       The ones that are not removed in the stripped file are SHT_NOBITS.  */
19    if (debug_fname != NULL)
20      {
21 +      /* libbfd and apps using it don't cope with separate debuginfo objects
22 +        with relocation sections against SHT_NOBITS .symtab/.strtab
23 +        - libbfd isn't able to look up the .symtab/.strtab in the stripped
24 +        object instead.  As a workaround, emit .symtab/.strtab in both
25 +        places.  */
26        for (cnt = 1; cnt < shnum; ++cnt)
27         {
28 +         if (shdr_info[cnt].idx == 0
29 +             && (shdr_info[cnt].shdr.sh_type == SHT_REL
30 +                 || shdr_info[cnt].shdr.sh_type == SHT_RELA)
31 +             && (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
32 +           {
33 +             Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
34 +             struct shdr_info *si = &shdr_info[symtabidx];
35 +             si->debug_data = "";
36 +             shdr_info[si->old_sh_link].debug_data = "";
37 +             if (si->symtab_idx)
38 +               shdr_info[si->symtab_idx].debug_data = "";
39 +
40 +             if (si->shdr.sh_type != SHT_SYMTAB
41 +                 || (si->shdr.sh_flags & SHF_ALLOC)
42 +                 || shdr_info[si->old_sh_link].shdr.sh_type != SHT_STRTAB
43 +                 || (shdr_info[si->old_sh_link].shdr.sh_flags & SHF_ALLOC)
44 +                 || (si->symtab_idx
45 +                     && (shdr_info[si->symtab_idx].shdr.sh_flags
46 +                         & SHF_ALLOC)))
47 +               error (EXIT_FAILURE, 0,
48 +                      gettext ("invalid symtab/strtab referenced by nonallocated section"));
49 +           }
50 +       }
51 +
52 +      for (cnt = 1; cnt < shnum; ++cnt)
53 +       {
54           scn = elf_newscn (debugelf);
55           if (scn == NULL)
56             error (EXIT_FAILURE, 0,
57 @@ -835,7 +867,8 @@ handle_elf (int fd, Elf *elf, const char
58                    elf_errmsg (-1));
59  
60           bool discard_section = (shdr_info[cnt].idx > 0
61 -                                 && cnt != ehdr->e_shstrndx);
62 +                                 && cnt != ehdr->e_shstrndx
63 +                                 && shdr_info[cnt].debug_data == NULL);
64  
65           /* Set the section header in the new file.  */
66           GElf_Shdr debugshdr = shdr_info[cnt].shdr;
67 @@ -864,6 +897,13 @@ handle_elf (int fd, Elf *elf, const char
68           *debugdata = *shdr_info[cnt].data;
69           if (discard_section)
70             debugdata->d_buf = NULL;
71 +         else if (shdr_info[cnt].debug_data != NULL)
72 +           {
73 +             shdr_info[cnt].debug_data = xmalloc (debugdata->d_size);
74 +             memcpy (shdr_info[cnt].debug_data, debugdata->d_buf,
75 +                     debugdata->d_size);
76 +             debugdata->d_buf = shdr_info[cnt].debug_data;
77 +           }
78         }
79  
80        /* Finish the ELF header.  Fill in the fields not handled by
81 @@ -1055,7 +1095,7 @@ handle_elf (int fd, Elf *elf, const char
82             shdr_info[shdr_info[cnt].shdr.sh_info].idx;
83  
84         /* Get the data from the old file if necessary.  We already
85 -           created the data for the section header string table.  */
86 +          created the data for the section header string table.  */
87         if (cnt < shnum)
88           {
89             if (shdr_info[cnt].data == NULL)
90 @@ -1264,6 +1304,13 @@ handle_elf (int fd, Elf *elf, const char
91               if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
92                 continue;
93  
94 +             /* If the symbol table is not discarded, but additionally
95 +                duplicated in separate debug file and this section
96 +                is discarded, don't adjust anything.  */
97 +             if (shdr_info[cnt].idx == 0
98 +                 && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
99 +               continue;
100 +
101               Elf32_Word *newsymidx
102                 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
103               Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
104 @@ -1322,6 +1369,13 @@ handle_elf (int fd, Elf *elf, const char
105               if (shdr_info[symtabidx].newsymidx == NULL)
106                 continue;
107  
108 +             /* If the symbol table is not discarded, but additionally
109 +                duplicated in separate debug file and this section
110 +                is discarded, don't adjust anything.  */
111 +             if (shdr_info[cnt].idx == 0
112 +                 && shdr_info[symtabidx].debug_data != NULL)
113 +               continue;
114 +
115               assert (shdr_info[cnt].idx > 0);
116  
117               /* The hash section in the new file.  */
118 @@ -1447,7 +1501,7 @@ handle_elf (int fd, Elf *elf, const char
119                           chain[hidx] = inner;
120                         }
121                     }
122 -               }
123 +               }
124             }
125           else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
126             {
127 @@ -1460,6 +1514,13 @@ handle_elf (int fd, Elf *elf, const char
128               if (shdr_info[symtabidx].newsymidx == NULL)
129                 continue;
130  
131 +             /* If the symbol table is not discarded, but additionally
132 +                duplicated in separate debug file and this section
133 +                is discarded, don't adjust anything.  */
134 +             if (shdr_info[cnt].idx == 0
135 +                 && shdr_info[symtabidx].debug_data != NULL)
136 +               continue;
137 +
138               assert (shdr_info[cnt].idx > 0);
139  
140               /* The symbol version section in the new file.  */
141 @@ -1504,20 +1565,27 @@ handle_elf (int fd, Elf *elf, const char
142           else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
143             {
144               /* Check whether the associated symbol table changed.  */
145 -             if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
146 -               {
147 -                 /* Yes the symbol table changed.  Update the section
148 -                    header of the section group.  */
149 -                 scn = elf_getscn (newelf, shdr_info[cnt].idx);
150 -                 GElf_Shdr shdr_mem;
151 -                 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
152 -                 assert (shdr != NULL);
153 +             if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
154 +               continue;
155  
156 -                 size_t stabidx = shdr_info[cnt].old_sh_link;
157 -                 shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
158 +             /* If the symbol table is not discarded, but additionally
159 +                duplicated in separate debug file and this section
160 +                is discarded, don't adjust anything.  */
161 +             if (shdr_info[cnt].idx == 0
162 +                 && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
163 +               continue;
164  
165 -                 (void) gelf_update_shdr (scn, shdr);
166 -               }
167 +             /* Yes the symbol table changed.  Update the section
168 +                header of the section group.  */
169 +             scn = elf_getscn (newelf, shdr_info[cnt].idx);
170 +             GElf_Shdr shdr_mem;
171 +             GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
172 +             assert (shdr != NULL);
173 +
174 +             size_t stabidx = shdr_info[cnt].old_sh_link;
175 +             shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
176 +
177 +             (void) gelf_update_shdr (scn, shdr);
178             }
179         }
180      }
181 @@ -1647,7 +1715,10 @@ handle_elf (int fd, Elf *elf, const char
182          table indices.  */
183        if (any_symtab_changes)
184         for (cnt = 1; cnt <= shdridx; ++cnt)
185 -         free (shdr_info[cnt].newsymidx);
186 +         {
187 +           free (shdr_info[cnt].newsymidx);
188 +           free (shdr_info[cnt].debug_data);
189 +         }
190  
191        /* Free the memory.  */
192        if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
193
This page took 0.050799 seconds and 3 git commands to generate.