1 From c2aaac080c05369f6fb7009d85dcf9bb98a914e6 Mon Sep 17 00:00:00 2001
2 From: Alan Modra <amodra@gmail.com>
3 Date: Sat, 4 Oct 2014 15:53:58 +0930
4 Subject: [PATCH] Discard zero address range eh_frame FDEs
6 These are useless because they can't match any address. In fact,
7 worse than useless because the .eh_frame_hdr lookup table matching
8 addresses to FDEs does not contain information about the FDE range.
9 The table is sorted by address; Range is inferred by the address
10 delta from one entry to the next. So if a zero address range FDE is
11 followed by a normal non-zero range FDE for the same address,
12 everything is good. However, the qsort could just as easily sort the
13 FDEs in the other order, in which case the normal FDE would
14 effectively be seen to have a zero range.
18 * elf-bfd.h (struct eh_cie_fde): Comment re NULL u.fde.cie_inf.
19 * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Mark zero address
20 range FDEs for discarding.
21 (vma_compare): Sort on range after address.
22 (_bfd_elf_gc_mark_fdes): Test for NULL u.fde.cie_inf.
23 (_bfd_elf_discard_section_eh_frame): Likewise. Write "FDE" in
24 error message rather than "fde".
25 (_bfd_elf_write_section_eh_frame_hdr): Write "PC" and "FDE" in
28 * ld-elf/eh1.s: Don't create FDEs with zero address ranges.
29 * ld-elf/eh3.s: Likewise.
30 * ld-elf/eh1.d, * ld-elf/eh2.d, * ld-elf/eh3.d: Adjust.
31 * ld-mips-elf/eh-frame1-n32.d: Warning match update.
32 * ld-mips-elf/eh-frame1-n64.d: Likewise.
33 * ld-mips-elf/eh-frame2-n32.d: Likewise.
34 * ld-mips-elf/eh-frame2-n64.d: Likewise.
36 bfd/ChangeLog | 13 +++++++++++++
37 bfd/elf-bfd.h | 4 +++-
38 bfd/elf-eh-frame.c | 24 +++++++++++++++++++-----
39 ld/testsuite/ChangeLog | 12 +++++++++++-
40 ld/testsuite/ld-elf/eh1.d | 6 +++---
41 ld/testsuite/ld-elf/eh1.s | 3 +++
42 ld/testsuite/ld-elf/eh2.d | 6 +++---
43 ld/testsuite/ld-elf/eh3.d | 6 +++---
44 ld/testsuite/ld-elf/eh3.s | 3 +++
45 ld/testsuite/ld-mips-elf/eh-frame1-n32.d | 2 +-
46 ld/testsuite/ld-mips-elf/eh-frame1-n64.d | 2 +-
47 ld/testsuite/ld-mips-elf/eh-frame2-n32.d | 2 +-
48 ld/testsuite/ld-mips-elf/eh-frame2-n64.d | 2 +-
49 13 files changed, 65 insertions(+), 20 deletions(-)
51 diff --git a/bfd/ChangeLog b/bfd/ChangeLog
52 index e4445dc..dd59324 100644
56 +2014-10-04 Alan Modra <amodra@gmail.com>
59 + * elf-bfd.h (struct eh_cie_fde): Comment re NULL u.fde.cie_inf.
60 + * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Mark zero address
61 + range FDEs for discarding.
62 + (vma_compare): Sort on range after address.
63 + (_bfd_elf_gc_mark_fdes): Test for NULL u.fde.cie_inf.
64 + (_bfd_elf_discard_section_eh_frame): Likewise. Write "FDE" in
65 + error message rather than "fde".
66 + (_bfd_elf_write_section_eh_frame_hdr): Write "PC" and "FDE" in
69 2014-09-29 H.J. Lu <hongjiu.lu@intel.com>
72 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
73 index dc343ec..b2feee3 100644
76 @@ -280,7 +280,9 @@ struct eh_cie_fde
78 If REMOVED == 0, this is the CIE that we have chosen to use for
79 the output FDE. The CIE's REMOVED field is also 0, but the CIE
80 - might belong to a different .eh_frame input section from the FDE. */
81 + might belong to a different .eh_frame input section from the FDE.
83 + May be NULL to signify that the FDE should be discarded. */
84 struct eh_cie_fde *cie_inf;
85 struct eh_cie_fde *next_for_section;
87 diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
88 index b32add3..331570a 100644
89 --- a/bfd/elf-eh-frame.c
90 +++ b/bfd/elf-eh-frame.c
91 @@ -808,6 +808,16 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
92 length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
93 REQUIRE (skip_bytes (&buf, end, 2 * length));
95 + SKIP_RELOCS (buf - length);
96 + if (!GET_RELOC (buf - length)
97 + && read_value (abfd, buf - length, length, FALSE) == 0)
99 + (*info->callbacks->minfo)
100 + (_("discarding zero address range FDE in %B(%A).\n"),
102 + this_inf->u.fde.cie_inf = NULL;
105 /* Skip the augmentation size, if present. */
106 if (cie->augmentation[0] == 'z')
107 REQUIRE (read_uleb128 (&buf, end, &length));
108 @@ -959,7 +969,7 @@ _bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
109 /* At this stage, all cie_inf fields point to local CIEs, so we
110 can use the same cookie to refer to them. */
111 cie = fde->u.fde.cie_inf;
112 - if (!cie->u.cie.gc_mark)
113 + if (cie != NULL && !cie->u.cie.gc_mark)
115 cie->u.cie.gc_mark = 1;
116 if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie))
117 @@ -1137,7 +1147,7 @@ _bfd_elf_discard_section_eh_frame
118 /* There should only be one zero terminator, on the last input
119 file supplying .eh_frame (crtend.o). Remove any others. */
120 ent->removed = sec->map_head.s != NULL;
121 - else if (!ent->cie)
122 + else if (!ent->cie && ent->u.fde.cie_inf != NULL)
125 if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL)
126 @@ -1170,7 +1180,7 @@ _bfd_elf_discard_section_eh_frame
127 since it is affected by runtime relocations. */
128 hdr_info->table = FALSE;
129 (*info->callbacks->einfo)
130 - (_("%P: fde encoding in %B(%A) prevents .eh_frame_hdr"
131 + (_("%P: FDE encoding in %B(%A) prevents .eh_frame_hdr"
132 " table being created.\n"), abfd, sec);
135 @@ -1725,6 +1735,10 @@ vma_compare (const void *a, const void *b)
137 if (p->initial_loc < q->initial_loc)
139 + if (p->range > q->range)
141 + if (p->range < q->range)
146 @@ -1821,7 +1835,7 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
147 && (hdr_info->array[i].initial_loc
148 != sec->output_section->vma + val))
149 (*info->callbacks->einfo)
150 - (_("%X%P: .eh_frame_hdr table[%u] pc overflow.\n"), i);
151 + (_("%X%P: .eh_frame_hdr table[%u] PC overflow.\n"), i);
152 bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
154 val = hdr_info->array[i].fde - sec->output_section->vma;
155 @@ -1830,7 +1844,7 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
156 && (hdr_info->array[i].fde
157 != sec->output_section->vma + val))
158 (*info->callbacks->einfo)
159 - (_("%X%P: .eh_frame_hdr table[%u] fde overflow.\n"), i);
160 + (_("%X%P: .eh_frame_hdr table[%u] FDE overflow.\n"), i);
161 bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
164 diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
165 index a03dd71..fd0c8ba 100644
166 --- a/ld/testsuite/ChangeLog
167 +++ b/ld/testsuite/ChangeLog
169 +2014-10-04 Alan Modra <amodra@gmail.com>
171 + * ld-elf/eh1.s: Don't create FDEs with zero address ranges.
172 + * ld-elf/eh3.s: Likewise.
173 + * ld-elf/eh1.d, * ld-elf/eh2.d, * ld-elf/eh3.d: Adjust.
174 + * ld-mips-elf/eh-frame1-n32.d: Warning match update.
175 + * ld-mips-elf/eh-frame1-n64.d: Likewise.
176 + * ld-mips-elf/eh-frame2-n32.d: Likewise.
177 + * ld-mips-elf/eh-frame2-n64.d: Likewise.
179 2014-09-22 Alan Modra <amodra@gmail.com>
181 * ld-plugin/lto.exp: Use both --print-file-name and --print-prog-name
184 2014-06-09 Ryan Mansfield <rmansfield@qnx.com>
186 - * config/default.exp (GASP): Remove.
187 + * config/default.exp (GASP): Remove.
189 2014-06-03 Alan Modra <amodra@gmail.com>
191 diff --git a/ld/testsuite/ld-elf/eh1.d b/ld/testsuite/ld-elf/eh1.d
192 index bdf84cc..f6841dc 100644
193 --- a/ld/testsuite/ld-elf/eh1.d
194 +++ b/ld/testsuite/ld-elf/eh1.d
195 @@ -23,11 +23,11 @@ Contents of the .eh_frame section:
199 -0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078..0+400078
200 - DW_CFA_advance_loc: 0 to 0+400078
201 +0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
202 + DW_CFA_advance_loc: 8 to 0+400080
203 DW_CFA_def_cfa_offset: 16
204 DW_CFA_offset: r6 \(rbp\) at cfa-16
205 - DW_CFA_advance_loc: 0 to 0+400078
206 + DW_CFA_advance_loc: 8 to 0+400088
207 DW_CFA_def_cfa_register: r6 \(rbp\)
209 0+0038 ZERO terminator
210 diff --git a/ld/testsuite/ld-elf/eh1.s b/ld/testsuite/ld-elf/eh1.s
211 index a605209..73d715f 100644
212 --- a/ld/testsuite/ld-elf/eh1.s
213 +++ b/ld/testsuite/ld-elf/eh1.s
215 .type _start, %function
224 .size _start, .-_start
225 .section .eh_frame,"a",%progbits
226 diff --git a/ld/testsuite/ld-elf/eh2.d b/ld/testsuite/ld-elf/eh2.d
227 index 65ad448..cb75a2d 100644
228 --- a/ld/testsuite/ld-elf/eh2.d
229 +++ b/ld/testsuite/ld-elf/eh2.d
230 @@ -23,11 +23,11 @@ Contents of the .eh_frame section:
234 -0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078..0+400078
235 - DW_CFA_advance_loc: 0 to 0+400078
236 +0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
237 + DW_CFA_advance_loc: 8 to 0+400080
238 DW_CFA_def_cfa_offset: 16
239 DW_CFA_offset: r6 \(rbp\) at cfa-16
240 - DW_CFA_advance_loc: 0 to 0+400078
241 + DW_CFA_advance_loc: 8 to 0+400088
242 DW_CFA_def_cfa_register: r6 \(rbp\)
244 0+0038 ZERO terminator
245 diff --git a/ld/testsuite/ld-elf/eh3.d b/ld/testsuite/ld-elf/eh3.d
246 index 2d322dd..6ac584a 100644
247 --- a/ld/testsuite/ld-elf/eh3.d
248 +++ b/ld/testsuite/ld-elf/eh3.d
249 @@ -23,11 +23,11 @@ Contents of the .eh_frame section:
253 -0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078..0+400078
254 - DW_CFA_advance_loc: 0 to 0+400078
255 +0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
256 + DW_CFA_advance_loc: 8 to 0+400080
257 DW_CFA_def_cfa_offset: 16
258 DW_CFA_offset: r6 \(rbp\) at cfa-16
259 - DW_CFA_advance_loc: 0 to 0+400078
260 + DW_CFA_advance_loc: 8 to 0+400088
261 DW_CFA_def_cfa_register: r6 \(rbp\)
263 0+0038 ZERO terminator
264 diff --git a/ld/testsuite/ld-elf/eh3.s b/ld/testsuite/ld-elf/eh3.s
265 index 24bd90d..e293c38 100644
266 --- a/ld/testsuite/ld-elf/eh3.s
267 +++ b/ld/testsuite/ld-elf/eh3.s
269 .type _start, %function
278 .size _start, .-_start
279 .section .eh_frame,"a",%progbits
280 diff --git a/ld/testsuite/ld-mips-elf/eh-frame1-n32.d b/ld/testsuite/ld-mips-elf/eh-frame1-n32.d
281 index 0542ebd..eafd022 100644
282 --- a/ld/testsuite/ld-mips-elf/eh-frame1-n32.d
283 +++ b/ld/testsuite/ld-mips-elf/eh-frame1-n32.d
285 #as: -march=from-abi -EB -n32 --defsym alignment=2 --defsym fill=0x40
286 #readelf: --relocs -wf
287 #ld: -shared -melf32btsmipn32 -Teh-frame1.ld
288 -#warning: fde encoding in.*prevents \.eh_frame_hdr table being created.
289 +#warning: FDE encoding in.*prevents \.eh_frame_hdr table being created.
291 Relocation section '\.rel\.dyn' .*:
293 diff --git a/ld/testsuite/ld-mips-elf/eh-frame1-n64.d b/ld/testsuite/ld-mips-elf/eh-frame1-n64.d
294 index 2a7aa30..cdc43bc 100644
295 --- a/ld/testsuite/ld-mips-elf/eh-frame1-n64.d
296 +++ b/ld/testsuite/ld-mips-elf/eh-frame1-n64.d
298 #as: -march=from-abi -EB -64 --defsym alignment=3 --defsym fill=0x40
299 #readelf: --relocs -wf
300 #ld: -shared -melf64btsmip -Teh-frame1.ld
301 -#warning: fde encoding in.*prevents \.eh_frame_hdr table being created.
302 +#warning: FDE encoding in.*prevents \.eh_frame_hdr table being created.
304 Relocation section '\.rel\.dyn' .*:
306 diff --git a/ld/testsuite/ld-mips-elf/eh-frame2-n32.d b/ld/testsuite/ld-mips-elf/eh-frame2-n32.d
307 index cda4409..528be87 100644
308 --- a/ld/testsuite/ld-mips-elf/eh-frame2-n32.d
309 +++ b/ld/testsuite/ld-mips-elf/eh-frame2-n32.d
311 #as: -march=from-abi -EB -n32 --defsym alignment=2 --defsym fill=0
312 #readelf: --relocs -wf
313 #ld: -shared -melf32btsmipn32 -Teh-frame1.ld
314 -#warning: fde encoding in.*prevents \.eh_frame_hdr table being created.
315 +#warning: FDE encoding in.*prevents \.eh_frame_hdr table being created.
317 Relocation section '\.rel\.dyn' .*:
319 diff --git a/ld/testsuite/ld-mips-elf/eh-frame2-n64.d b/ld/testsuite/ld-mips-elf/eh-frame2-n64.d
320 index 05ba94f..add403e 100644
321 --- a/ld/testsuite/ld-mips-elf/eh-frame2-n64.d
322 +++ b/ld/testsuite/ld-mips-elf/eh-frame2-n64.d
324 #as: -march=from-abi -EB -64 --defsym alignment=3 --defsym fill=0
325 #readelf: --relocs -wf
326 #ld: -shared -melf64btsmip -Teh-frame1.ld
327 -#warning: fde encoding in.*prevents \.eh_frame_hdr table being created.
328 +#warning: FDE encoding in.*prevents \.eh_frame_hdr table being created.
330 Relocation section '\.rel\.dyn' .*: