]> git.pld-linux.org Git - packages/elfutils.git/blob - elfutils-strip-copy-symtab.patch
35cc6b87ef884e97678d973ee0d2399e144e03c2
[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,6 +827,37 @@ 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 @@ -835,6 +867,7 @@ handle_elf (int fd, Elf *elf, const char
56                    elf_errmsg (-1));
57  
58           bool discard_section = (shdr_info[cnt].idx > 0
59 +                                 && shdr_info[cnt].debug_data == NULL
60                                   && shdr_info[cnt].shdr.sh_type != SHT_NOTE
61                                   && cnt != ehdr->e_shstrndx);
62  
63 @@ -865,6 +898,13 @@ handle_elf (int fd, Elf *elf, const char
64           *debugdata = *shdr_info[cnt].data;
65           if (discard_section)
66             debugdata->d_buf = NULL;
67 +         else if (shdr_info[cnt].debug_data != NULL)
68 +           {
69 +             shdr_info[cnt].debug_data = xmalloc (debugdata->d_size);
70 +             memcpy (shdr_info[cnt].debug_data, debugdata->d_buf,
71 +                     debugdata->d_size);
72 +             debugdata->d_buf = shdr_info[cnt].debug_data;
73 +           }
74         }
75  
76        /* Finish the ELF header.  Fill in the fields not handled by
77 @@ -1056,7 +1096,7 @@ handle_elf (int fd, Elf *elf, const char
78             shdr_info[shdr_info[cnt].shdr.sh_info].idx;
79  
80         /* Get the data from the old file if necessary.  We already
81 -           created the data for the section header string table.  */
82 +          created the data for the section header string table.  */
83         if (cnt < shnum)
84           {
85             if (shdr_info[cnt].data == NULL)
86 @@ -1283,6 +1323,13 @@ handle_elf (int fd, Elf *elf, const char
87               if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
88                 continue;
89  
90 +             /* If the symbol table is not discarded, but additionally
91 +                duplicated in separate debug file and this section
92 +                is discarded, don't adjust anything.  */
93 +             if (shdr_info[cnt].idx == 0
94 +                 && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
95 +               continue;
96 +
97               Elf32_Word *newsymidx
98                 = shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
99               Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
100 @@ -1341,6 +1388,13 @@ handle_elf (int fd, Elf *elf, const char
101               if (shdr_info[symtabidx].newsymidx == NULL)
102                 continue;
103  
104 +             /* If the symbol table is not discarded, but additionally
105 +                duplicated in separate debug file and this section
106 +                is discarded, don't adjust anything.  */
107 +             if (shdr_info[cnt].idx == 0
108 +                 && shdr_info[symtabidx].debug_data != NULL)
109 +               continue;
110 +
111               assert (shdr_info[cnt].idx > 0);
112  
113               /* The hash section in the new file.  */
114 @@ -1460,7 +1514,7 @@ handle_elf (int fd, Elf *elf, const char
115                           chain[hidx] = inner;
116                         }
117                     }
118 -               }
119 +               }
120             }
121           else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
122             {
123 @@ -1473,6 +1527,13 @@ handle_elf (int fd, Elf *elf, const char
124               if (shdr_info[symtabidx].newsymidx == NULL)
125                 continue;
126  
127 +             /* If the symbol table is not discarded, but additionally
128 +                duplicated in separate debug file and this section
129 +                is discarded, don't adjust anything.  */
130 +             if (shdr_info[cnt].idx == 0
131 +                 && shdr_info[symtabidx].debug_data != NULL)
132 +               continue;
133 +
134               assert (shdr_info[cnt].idx > 0);
135  
136               /* The symbol version section in the new file.  */
137 @@ -1515,20 +1576,27 @@ handle_elf (int fd, Elf *elf, const char
138           else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
139             {
140               /* Check whether the associated symbol table changed.  */
141 -             if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
142 -               {
143 -                 /* Yes the symbol table changed.  Update the section
144 -                    header of the section group.  */
145 -                 scn = elf_getscn (newelf, shdr_info[cnt].idx);
146 -                 GElf_Shdr shdr_mem;
147 -                 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
148 -                 assert (shdr != NULL);
149 +             if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
150 +               continue;
151  
152 -                 size_t stabidx = shdr_info[cnt].old_sh_link;
153 -                 shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
154 +             /* If the symbol table is not discarded, but additionally
155 +                duplicated in separate debug file and this section
156 +                is discarded, don't adjust anything.  */
157 +             if (shdr_info[cnt].idx == 0
158 +                 && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
159 +               continue;
160  
161 -                 (void) gelf_update_shdr (scn, shdr);
162 -               }
163 +             /* Yes the symbol table changed.  Update the section
164 +                header of the section group.  */
165 +             scn = elf_getscn (newelf, shdr_info[cnt].idx);
166 +             GElf_Shdr shdr_mem;
167 +             GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
168 +             assert (shdr != NULL);
169 +
170 +             size_t stabidx = shdr_info[cnt].old_sh_link;
171 +             shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
172 +
173 +             (void) gelf_update_shdr (scn, shdr);
174             }
175         }
176      }
177 @@ -1658,7 +1726,10 @@ handle_elf (int fd, Elf *elf, const char
178          table indices.  */
179        if (any_symtab_changes)
180         for (cnt = 1; cnt <= shdridx; ++cnt)
181 -         free (shdr_info[cnt].newsymidx);
182 +         {
183 +           free (shdr_info[cnt].newsymidx);
184 +           free (shdr_info[cnt].debug_data);
185 +         }
186  
187        /* Free the memory.  */
188        if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
189 --- elfutils/tests/run-strip-test5.sh.~1~
190 +++ elfutils/tests/run-strip-test5.sh
191 @@ -1,5 +1,5 @@
192  original=testfile8
193 -stripped=testfile16
194 -debugfile=testfile16.debug
195 +stripped=testfile16.symtab
196 +debugfile=testfile16.symtab.debug
197  
198  . $srcdir/run-strip-test.sh
199
This page took 0.05621 seconds and 2 git commands to generate.