elf-eh-frame.c revision 1.7 1 1.1 christos /* .eh_frame section optimization.
2 1.7 christos Copyright (C) 2001-2020 Free Software Foundation, Inc.
3 1.1 christos Written by Jakub Jelinek <jakub (at) redhat.com>.
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the Free Software
19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 christos MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos #include "sysdep.h"
23 1.1 christos #include "bfd.h"
24 1.1 christos #include "libbfd.h"
25 1.1 christos #include "elf-bfd.h"
26 1.1 christos #include "dwarf2.h"
27 1.1 christos
28 1.1 christos #define EH_FRAME_HDR_SIZE 8
29 1.1 christos
30 1.1 christos struct cie
31 1.1 christos {
32 1.1 christos unsigned int length;
33 1.1 christos unsigned int hash;
34 1.1 christos unsigned char version;
35 1.1 christos unsigned char local_personality;
36 1.1 christos char augmentation[20];
37 1.1 christos bfd_vma code_align;
38 1.1 christos bfd_signed_vma data_align;
39 1.1 christos bfd_vma ra_column;
40 1.1 christos bfd_vma augmentation_size;
41 1.1 christos union {
42 1.1 christos struct elf_link_hash_entry *h;
43 1.3 christos struct {
44 1.3 christos unsigned int bfd_id;
45 1.3 christos unsigned int index;
46 1.3 christos } sym;
47 1.1 christos unsigned int reloc_index;
48 1.1 christos } personality;
49 1.1 christos struct eh_cie_fde *cie_inf;
50 1.1 christos unsigned char per_encoding;
51 1.1 christos unsigned char lsda_encoding;
52 1.1 christos unsigned char fde_encoding;
53 1.1 christos unsigned char initial_insn_length;
54 1.1 christos unsigned char can_make_lsda_relative;
55 1.1 christos unsigned char initial_instructions[50];
56 1.1 christos };
57 1.1 christos
58 1.1 christos
59 1.1 christos
60 1.1 christos /* If *ITER hasn't reached END yet, read the next byte into *RESULT and
61 1.1 christos move onto the next byte. Return true on success. */
62 1.1 christos
63 1.1 christos static inline bfd_boolean
64 1.1 christos read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result)
65 1.1 christos {
66 1.1 christos if (*iter >= end)
67 1.1 christos return FALSE;
68 1.1 christos *result = *((*iter)++);
69 1.1 christos return TRUE;
70 1.1 christos }
71 1.1 christos
72 1.1 christos /* Move *ITER over LENGTH bytes, or up to END, whichever is closer.
73 1.1 christos Return true it was possible to move LENGTH bytes. */
74 1.1 christos
75 1.1 christos static inline bfd_boolean
76 1.1 christos skip_bytes (bfd_byte **iter, bfd_byte *end, bfd_size_type length)
77 1.1 christos {
78 1.1 christos if ((bfd_size_type) (end - *iter) < length)
79 1.1 christos {
80 1.1 christos *iter = end;
81 1.1 christos return FALSE;
82 1.1 christos }
83 1.1 christos *iter += length;
84 1.1 christos return TRUE;
85 1.1 christos }
86 1.1 christos
87 1.1 christos /* Move *ITER over an leb128, stopping at END. Return true if the end
88 1.1 christos of the leb128 was found. */
89 1.1 christos
90 1.1 christos static bfd_boolean
91 1.1 christos skip_leb128 (bfd_byte **iter, bfd_byte *end)
92 1.1 christos {
93 1.1 christos unsigned char byte;
94 1.1 christos do
95 1.1 christos if (!read_byte (iter, end, &byte))
96 1.1 christos return FALSE;
97 1.1 christos while (byte & 0x80);
98 1.1 christos return TRUE;
99 1.1 christos }
100 1.1 christos
101 1.1 christos /* Like skip_leb128, but treat the leb128 as an unsigned value and
102 1.1 christos store it in *VALUE. */
103 1.1 christos
104 1.1 christos static bfd_boolean
105 1.1 christos read_uleb128 (bfd_byte **iter, bfd_byte *end, bfd_vma *value)
106 1.1 christos {
107 1.1 christos bfd_byte *start, *p;
108 1.1 christos
109 1.1 christos start = *iter;
110 1.1 christos if (!skip_leb128 (iter, end))
111 1.1 christos return FALSE;
112 1.1 christos
113 1.1 christos p = *iter;
114 1.1 christos *value = *--p;
115 1.1 christos while (p > start)
116 1.1 christos *value = (*value << 7) | (*--p & 0x7f);
117 1.1 christos
118 1.1 christos return TRUE;
119 1.1 christos }
120 1.1 christos
121 1.1 christos /* Like read_uleb128, but for signed values. */
122 1.1 christos
123 1.1 christos static bfd_boolean
124 1.1 christos read_sleb128 (bfd_byte **iter, bfd_byte *end, bfd_signed_vma *value)
125 1.1 christos {
126 1.1 christos bfd_byte *start, *p;
127 1.1 christos
128 1.1 christos start = *iter;
129 1.1 christos if (!skip_leb128 (iter, end))
130 1.1 christos return FALSE;
131 1.1 christos
132 1.1 christos p = *iter;
133 1.1 christos *value = ((*--p & 0x7f) ^ 0x40) - 0x40;
134 1.1 christos while (p > start)
135 1.1 christos *value = (*value << 7) | (*--p & 0x7f);
136 1.1 christos
137 1.1 christos return TRUE;
138 1.1 christos }
139 1.1 christos
140 1.1 christos /* Return 0 if either encoding is variable width, or not yet known to bfd. */
141 1.1 christos
142 1.1 christos static
143 1.1 christos int get_DW_EH_PE_width (int encoding, int ptr_size)
144 1.1 christos {
145 1.1 christos /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
146 1.1 christos was added to bfd. */
147 1.1 christos if ((encoding & 0x60) == 0x60)
148 1.1 christos return 0;
149 1.1 christos
150 1.1 christos switch (encoding & 7)
151 1.1 christos {
152 1.1 christos case DW_EH_PE_udata2: return 2;
153 1.1 christos case DW_EH_PE_udata4: return 4;
154 1.1 christos case DW_EH_PE_udata8: return 8;
155 1.1 christos case DW_EH_PE_absptr: return ptr_size;
156 1.1 christos default:
157 1.1 christos break;
158 1.1 christos }
159 1.1 christos
160 1.1 christos return 0;
161 1.1 christos }
162 1.1 christos
163 1.1 christos #define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
164 1.1 christos
165 1.1 christos /* Read a width sized value from memory. */
166 1.1 christos
167 1.1 christos static bfd_vma
168 1.1 christos read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed)
169 1.1 christos {
170 1.1 christos bfd_vma value;
171 1.1 christos
172 1.1 christos switch (width)
173 1.1 christos {
174 1.1 christos case 2:
175 1.1 christos if (is_signed)
176 1.1 christos value = bfd_get_signed_16 (abfd, buf);
177 1.1 christos else
178 1.1 christos value = bfd_get_16 (abfd, buf);
179 1.1 christos break;
180 1.1 christos case 4:
181 1.1 christos if (is_signed)
182 1.1 christos value = bfd_get_signed_32 (abfd, buf);
183 1.1 christos else
184 1.1 christos value = bfd_get_32 (abfd, buf);
185 1.1 christos break;
186 1.1 christos case 8:
187 1.1 christos if (is_signed)
188 1.1 christos value = bfd_get_signed_64 (abfd, buf);
189 1.1 christos else
190 1.1 christos value = bfd_get_64 (abfd, buf);
191 1.1 christos break;
192 1.1 christos default:
193 1.1 christos BFD_FAIL ();
194 1.1 christos return 0;
195 1.1 christos }
196 1.1 christos
197 1.1 christos return value;
198 1.1 christos }
199 1.1 christos
200 1.1 christos /* Store a width sized value to memory. */
201 1.1 christos
202 1.1 christos static void
203 1.1 christos write_value (bfd *abfd, bfd_byte *buf, bfd_vma value, int width)
204 1.1 christos {
205 1.1 christos switch (width)
206 1.1 christos {
207 1.1 christos case 2: bfd_put_16 (abfd, value, buf); break;
208 1.1 christos case 4: bfd_put_32 (abfd, value, buf); break;
209 1.1 christos case 8: bfd_put_64 (abfd, value, buf); break;
210 1.1 christos default: BFD_FAIL ();
211 1.1 christos }
212 1.1 christos }
213 1.1 christos
214 1.1 christos /* Return one if C1 and C2 CIEs can be merged. */
215 1.1 christos
216 1.1 christos static int
217 1.1 christos cie_eq (const void *e1, const void *e2)
218 1.1 christos {
219 1.1 christos const struct cie *c1 = (const struct cie *) e1;
220 1.1 christos const struct cie *c2 = (const struct cie *) e2;
221 1.1 christos
222 1.1 christos if (c1->hash == c2->hash
223 1.1 christos && c1->length == c2->length
224 1.1 christos && c1->version == c2->version
225 1.1 christos && c1->local_personality == c2->local_personality
226 1.1 christos && strcmp (c1->augmentation, c2->augmentation) == 0
227 1.1 christos && strcmp (c1->augmentation, "eh") != 0
228 1.1 christos && c1->code_align == c2->code_align
229 1.1 christos && c1->data_align == c2->data_align
230 1.1 christos && c1->ra_column == c2->ra_column
231 1.1 christos && c1->augmentation_size == c2->augmentation_size
232 1.1 christos && memcmp (&c1->personality, &c2->personality,
233 1.1 christos sizeof (c1->personality)) == 0
234 1.3 christos && (c1->cie_inf->u.cie.u.sec->output_section
235 1.3 christos == c2->cie_inf->u.cie.u.sec->output_section)
236 1.1 christos && c1->per_encoding == c2->per_encoding
237 1.1 christos && c1->lsda_encoding == c2->lsda_encoding
238 1.1 christos && c1->fde_encoding == c2->fde_encoding
239 1.1 christos && c1->initial_insn_length == c2->initial_insn_length
240 1.3 christos && c1->initial_insn_length <= sizeof (c1->initial_instructions)
241 1.1 christos && memcmp (c1->initial_instructions,
242 1.1 christos c2->initial_instructions,
243 1.1 christos c1->initial_insn_length) == 0)
244 1.1 christos return 1;
245 1.1 christos
246 1.1 christos return 0;
247 1.1 christos }
248 1.1 christos
249 1.1 christos static hashval_t
250 1.1 christos cie_hash (const void *e)
251 1.1 christos {
252 1.1 christos const struct cie *c = (const struct cie *) e;
253 1.1 christos return c->hash;
254 1.1 christos }
255 1.1 christos
256 1.1 christos static hashval_t
257 1.1 christos cie_compute_hash (struct cie *c)
258 1.1 christos {
259 1.1 christos hashval_t h = 0;
260 1.3 christos size_t len;
261 1.1 christos h = iterative_hash_object (c->length, h);
262 1.1 christos h = iterative_hash_object (c->version, h);
263 1.1 christos h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
264 1.1 christos h = iterative_hash_object (c->code_align, h);
265 1.1 christos h = iterative_hash_object (c->data_align, h);
266 1.1 christos h = iterative_hash_object (c->ra_column, h);
267 1.1 christos h = iterative_hash_object (c->augmentation_size, h);
268 1.1 christos h = iterative_hash_object (c->personality, h);
269 1.3 christos h = iterative_hash_object (c->cie_inf->u.cie.u.sec->output_section, h);
270 1.1 christos h = iterative_hash_object (c->per_encoding, h);
271 1.1 christos h = iterative_hash_object (c->lsda_encoding, h);
272 1.1 christos h = iterative_hash_object (c->fde_encoding, h);
273 1.1 christos h = iterative_hash_object (c->initial_insn_length, h);
274 1.3 christos len = c->initial_insn_length;
275 1.3 christos if (len > sizeof (c->initial_instructions))
276 1.3 christos len = sizeof (c->initial_instructions);
277 1.3 christos h = iterative_hash (c->initial_instructions, len, h);
278 1.1 christos c->hash = h;
279 1.1 christos return h;
280 1.1 christos }
281 1.1 christos
282 1.1 christos /* Return the number of extra bytes that we'll be inserting into
283 1.1 christos ENTRY's augmentation string. */
284 1.1 christos
285 1.1 christos static INLINE unsigned int
286 1.1 christos extra_augmentation_string_bytes (struct eh_cie_fde *entry)
287 1.1 christos {
288 1.1 christos unsigned int size = 0;
289 1.1 christos if (entry->cie)
290 1.1 christos {
291 1.1 christos if (entry->add_augmentation_size)
292 1.1 christos size++;
293 1.1 christos if (entry->u.cie.add_fde_encoding)
294 1.1 christos size++;
295 1.1 christos }
296 1.1 christos return size;
297 1.1 christos }
298 1.1 christos
299 1.1 christos /* Likewise ENTRY's augmentation data. */
300 1.1 christos
301 1.1 christos static INLINE unsigned int
302 1.1 christos extra_augmentation_data_bytes (struct eh_cie_fde *entry)
303 1.1 christos {
304 1.1 christos unsigned int size = 0;
305 1.1 christos if (entry->add_augmentation_size)
306 1.1 christos size++;
307 1.1 christos if (entry->cie && entry->u.cie.add_fde_encoding)
308 1.1 christos size++;
309 1.1 christos return size;
310 1.1 christos }
311 1.1 christos
312 1.6 christos /* Return the size that ENTRY will have in the output. */
313 1.1 christos
314 1.1 christos static unsigned int
315 1.6 christos size_of_output_cie_fde (struct eh_cie_fde *entry)
316 1.1 christos {
317 1.1 christos if (entry->removed)
318 1.1 christos return 0;
319 1.1 christos if (entry->size == 4)
320 1.1 christos return 4;
321 1.1 christos return (entry->size
322 1.1 christos + extra_augmentation_string_bytes (entry)
323 1.6 christos + extra_augmentation_data_bytes (entry));
324 1.6 christos }
325 1.6 christos
326 1.6 christos /* Return the offset of the FDE or CIE after ENT. */
327 1.6 christos
328 1.6 christos static unsigned int
329 1.6 christos next_cie_fde_offset (const struct eh_cie_fde *ent,
330 1.6 christos const struct eh_cie_fde *last,
331 1.6 christos const asection *sec)
332 1.6 christos {
333 1.6 christos while (++ent < last)
334 1.6 christos {
335 1.6 christos if (!ent->removed)
336 1.6 christos return ent->new_offset;
337 1.6 christos }
338 1.6 christos return sec->size;
339 1.1 christos }
340 1.1 christos
341 1.1 christos /* Assume that the bytes between *ITER and END are CFA instructions.
342 1.1 christos Try to move *ITER past the first instruction and return true on
343 1.1 christos success. ENCODED_PTR_WIDTH gives the width of pointer entries. */
344 1.1 christos
345 1.1 christos static bfd_boolean
346 1.1 christos skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
347 1.1 christos {
348 1.1 christos bfd_byte op;
349 1.1 christos bfd_vma length;
350 1.1 christos
351 1.1 christos if (!read_byte (iter, end, &op))
352 1.1 christos return FALSE;
353 1.1 christos
354 1.1 christos switch (op & 0xc0 ? op & 0xc0 : op)
355 1.1 christos {
356 1.1 christos case DW_CFA_nop:
357 1.1 christos case DW_CFA_advance_loc:
358 1.1 christos case DW_CFA_restore:
359 1.1 christos case DW_CFA_remember_state:
360 1.1 christos case DW_CFA_restore_state:
361 1.1 christos case DW_CFA_GNU_window_save:
362 1.1 christos /* No arguments. */
363 1.1 christos return TRUE;
364 1.1 christos
365 1.1 christos case DW_CFA_offset:
366 1.1 christos case DW_CFA_restore_extended:
367 1.1 christos case DW_CFA_undefined:
368 1.1 christos case DW_CFA_same_value:
369 1.1 christos case DW_CFA_def_cfa_register:
370 1.1 christos case DW_CFA_def_cfa_offset:
371 1.1 christos case DW_CFA_def_cfa_offset_sf:
372 1.1 christos case DW_CFA_GNU_args_size:
373 1.1 christos /* One leb128 argument. */
374 1.1 christos return skip_leb128 (iter, end);
375 1.1 christos
376 1.1 christos case DW_CFA_val_offset:
377 1.1 christos case DW_CFA_val_offset_sf:
378 1.1 christos case DW_CFA_offset_extended:
379 1.1 christos case DW_CFA_register:
380 1.1 christos case DW_CFA_def_cfa:
381 1.1 christos case DW_CFA_offset_extended_sf:
382 1.1 christos case DW_CFA_GNU_negative_offset_extended:
383 1.1 christos case DW_CFA_def_cfa_sf:
384 1.1 christos /* Two leb128 arguments. */
385 1.1 christos return (skip_leb128 (iter, end)
386 1.1 christos && skip_leb128 (iter, end));
387 1.1 christos
388 1.1 christos case DW_CFA_def_cfa_expression:
389 1.1 christos /* A variable-length argument. */
390 1.1 christos return (read_uleb128 (iter, end, &length)
391 1.1 christos && skip_bytes (iter, end, length));
392 1.1 christos
393 1.1 christos case DW_CFA_expression:
394 1.1 christos case DW_CFA_val_expression:
395 1.1 christos /* A leb128 followed by a variable-length argument. */
396 1.1 christos return (skip_leb128 (iter, end)
397 1.1 christos && read_uleb128 (iter, end, &length)
398 1.1 christos && skip_bytes (iter, end, length));
399 1.1 christos
400 1.1 christos case DW_CFA_set_loc:
401 1.1 christos return skip_bytes (iter, end, encoded_ptr_width);
402 1.1 christos
403 1.1 christos case DW_CFA_advance_loc1:
404 1.1 christos return skip_bytes (iter, end, 1);
405 1.1 christos
406 1.1 christos case DW_CFA_advance_loc2:
407 1.1 christos return skip_bytes (iter, end, 2);
408 1.1 christos
409 1.1 christos case DW_CFA_advance_loc4:
410 1.1 christos return skip_bytes (iter, end, 4);
411 1.1 christos
412 1.1 christos case DW_CFA_MIPS_advance_loc8:
413 1.1 christos return skip_bytes (iter, end, 8);
414 1.1 christos
415 1.1 christos default:
416 1.1 christos return FALSE;
417 1.1 christos }
418 1.1 christos }
419 1.1 christos
420 1.1 christos /* Try to interpret the bytes between BUF and END as CFA instructions.
421 1.1 christos If every byte makes sense, return a pointer to the first DW_CFA_nop
422 1.1 christos padding byte, or END if there is no padding. Return null otherwise.
423 1.1 christos ENCODED_PTR_WIDTH is as for skip_cfa_op. */
424 1.1 christos
425 1.1 christos static bfd_byte *
426 1.1 christos skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width,
427 1.1 christos unsigned int *set_loc_count)
428 1.1 christos {
429 1.1 christos bfd_byte *last;
430 1.1 christos
431 1.1 christos last = buf;
432 1.1 christos while (buf < end)
433 1.1 christos if (*buf == DW_CFA_nop)
434 1.1 christos buf++;
435 1.1 christos else
436 1.1 christos {
437 1.1 christos if (*buf == DW_CFA_set_loc)
438 1.1 christos ++*set_loc_count;
439 1.1 christos if (!skip_cfa_op (&buf, end, encoded_ptr_width))
440 1.1 christos return 0;
441 1.1 christos last = buf;
442 1.1 christos }
443 1.1 christos return last;
444 1.1 christos }
445 1.1 christos
446 1.1 christos /* Convert absolute encoding ENCODING into PC-relative form.
447 1.1 christos SIZE is the size of a pointer. */
448 1.1 christos
449 1.1 christos static unsigned char
450 1.1 christos make_pc_relative (unsigned char encoding, unsigned int ptr_size)
451 1.1 christos {
452 1.1 christos if ((encoding & 0x7f) == DW_EH_PE_absptr)
453 1.1 christos switch (ptr_size)
454 1.1 christos {
455 1.1 christos case 2:
456 1.1 christos encoding |= DW_EH_PE_sdata2;
457 1.1 christos break;
458 1.1 christos case 4:
459 1.1 christos encoding |= DW_EH_PE_sdata4;
460 1.1 christos break;
461 1.1 christos case 8:
462 1.1 christos encoding |= DW_EH_PE_sdata8;
463 1.1 christos break;
464 1.1 christos }
465 1.1 christos return encoding | DW_EH_PE_pcrel;
466 1.1 christos }
467 1.1 christos
468 1.3 christos /* Examine each .eh_frame_entry section and discard those
469 1.3 christos those that are marked SEC_EXCLUDE. */
470 1.1 christos
471 1.3 christos static void
472 1.3 christos bfd_elf_discard_eh_frame_entry (struct eh_frame_hdr_info *hdr_info)
473 1.3 christos {
474 1.3 christos unsigned int i;
475 1.3 christos for (i = 0; i < hdr_info->array_count; i++)
476 1.3 christos {
477 1.3 christos if (hdr_info->u.compact.entries[i]->flags & SEC_EXCLUDE)
478 1.3 christos {
479 1.3 christos unsigned int j;
480 1.3 christos for (j = i + 1; j < hdr_info->array_count; j++)
481 1.3 christos hdr_info->u.compact.entries[j-1] = hdr_info->u.compact.entries[j];
482 1.3 christos
483 1.3 christos hdr_info->array_count--;
484 1.3 christos hdr_info->u.compact.entries[hdr_info->array_count] = NULL;
485 1.3 christos i--;
486 1.6 christos }
487 1.3 christos }
488 1.3 christos }
489 1.3 christos
490 1.3 christos /* Add a .eh_frame_entry section. */
491 1.3 christos
492 1.3 christos static void
493 1.3 christos bfd_elf_record_eh_frame_entry (struct eh_frame_hdr_info *hdr_info,
494 1.3 christos asection *sec)
495 1.3 christos {
496 1.3 christos if (hdr_info->array_count == hdr_info->u.compact.allocated_entries)
497 1.3 christos {
498 1.3 christos if (hdr_info->u.compact.allocated_entries == 0)
499 1.3 christos {
500 1.3 christos hdr_info->frame_hdr_is_compact = TRUE;
501 1.3 christos hdr_info->u.compact.allocated_entries = 2;
502 1.3 christos hdr_info->u.compact.entries =
503 1.3 christos bfd_malloc (hdr_info->u.compact.allocated_entries
504 1.3 christos * sizeof (hdr_info->u.compact.entries[0]));
505 1.3 christos }
506 1.3 christos else
507 1.3 christos {
508 1.3 christos hdr_info->u.compact.allocated_entries *= 2;
509 1.3 christos hdr_info->u.compact.entries =
510 1.3 christos bfd_realloc (hdr_info->u.compact.entries,
511 1.3 christos hdr_info->u.compact.allocated_entries
512 1.3 christos * sizeof (hdr_info->u.compact.entries[0]));
513 1.3 christos }
514 1.3 christos
515 1.3 christos BFD_ASSERT (hdr_info->u.compact.entries);
516 1.3 christos }
517 1.3 christos
518 1.3 christos hdr_info->u.compact.entries[hdr_info->array_count++] = sec;
519 1.3 christos }
520 1.3 christos
521 1.3 christos /* Parse a .eh_frame_entry section. Figure out which text section it
522 1.3 christos references. */
523 1.3 christos
524 1.3 christos bfd_boolean
525 1.3 christos _bfd_elf_parse_eh_frame_entry (struct bfd_link_info *info,
526 1.3 christos asection *sec, struct elf_reloc_cookie *cookie)
527 1.1 christos {
528 1.3 christos struct elf_link_hash_table *htab;
529 1.1 christos struct eh_frame_hdr_info *hdr_info;
530 1.3 christos unsigned long r_symndx;
531 1.3 christos asection *text_sec;
532 1.3 christos
533 1.3 christos htab = elf_hash_table (info);
534 1.3 christos hdr_info = &htab->eh_info;
535 1.3 christos
536 1.3 christos if (sec->size == 0
537 1.3 christos || sec->sec_info_type != SEC_INFO_TYPE_NONE)
538 1.3 christos {
539 1.3 christos return TRUE;
540 1.3 christos }
541 1.3 christos
542 1.3 christos if (sec->output_section && bfd_is_abs_section (sec->output_section))
543 1.3 christos {
544 1.3 christos /* At least one of the sections is being discarded from the
545 1.3 christos link, so we should just ignore them. */
546 1.3 christos return TRUE;
547 1.3 christos }
548 1.1 christos
549 1.3 christos if (cookie->rel == cookie->relend)
550 1.3 christos return FALSE;
551 1.3 christos
552 1.3 christos /* The first relocation is the function start. */
553 1.3 christos r_symndx = cookie->rel->r_info >> cookie->r_sym_shift;
554 1.3 christos if (r_symndx == STN_UNDEF)
555 1.3 christos return FALSE;
556 1.3 christos
557 1.3 christos text_sec = _bfd_elf_section_for_symbol (cookie, r_symndx, FALSE);
558 1.3 christos
559 1.3 christos if (text_sec == NULL)
560 1.3 christos return FALSE;
561 1.3 christos
562 1.3 christos elf_section_eh_frame_entry (text_sec) = sec;
563 1.3 christos if (text_sec->output_section
564 1.3 christos && bfd_is_abs_section (text_sec->output_section))
565 1.3 christos sec->flags |= SEC_EXCLUDE;
566 1.3 christos
567 1.3 christos sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME_ENTRY;
568 1.3 christos elf_section_data (sec)->sec_info = text_sec;
569 1.3 christos bfd_elf_record_eh_frame_entry (hdr_info, sec);
570 1.3 christos return TRUE;
571 1.1 christos }
572 1.1 christos
573 1.1 christos /* Try to parse .eh_frame section SEC, which belongs to ABFD. Store the
574 1.1 christos information in the section's sec_info field on success. COOKIE
575 1.1 christos describes the relocations in SEC. */
576 1.1 christos
577 1.1 christos void
578 1.1 christos _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
579 1.1 christos asection *sec, struct elf_reloc_cookie *cookie)
580 1.1 christos {
581 1.1 christos #define REQUIRE(COND) \
582 1.1 christos do \
583 1.1 christos if (!(COND)) \
584 1.1 christos goto free_no_table; \
585 1.1 christos while (0)
586 1.1 christos
587 1.1 christos bfd_byte *ehbuf = NULL, *buf, *end;
588 1.1 christos bfd_byte *last_fde;
589 1.1 christos struct eh_cie_fde *this_inf;
590 1.1 christos unsigned int hdr_length, hdr_id;
591 1.1 christos unsigned int cie_count;
592 1.1 christos struct cie *cie, *local_cies = NULL;
593 1.1 christos struct elf_link_hash_table *htab;
594 1.1 christos struct eh_frame_hdr_info *hdr_info;
595 1.1 christos struct eh_frame_sec_info *sec_info = NULL;
596 1.1 christos unsigned int ptr_size;
597 1.1 christos unsigned int num_cies;
598 1.1 christos unsigned int num_entries;
599 1.1 christos elf_gc_mark_hook_fn gc_mark_hook;
600 1.1 christos
601 1.1 christos htab = elf_hash_table (info);
602 1.1 christos hdr_info = &htab->eh_info;
603 1.1 christos
604 1.1 christos if (sec->size == 0
605 1.1 christos || sec->sec_info_type != SEC_INFO_TYPE_NONE)
606 1.1 christos {
607 1.1 christos /* This file does not contain .eh_frame information. */
608 1.1 christos return;
609 1.1 christos }
610 1.1 christos
611 1.1 christos if (bfd_is_abs_section (sec->output_section))
612 1.1 christos {
613 1.1 christos /* At least one of the sections is being discarded from the
614 1.1 christos link, so we should just ignore them. */
615 1.1 christos return;
616 1.1 christos }
617 1.1 christos
618 1.1 christos /* Read the frame unwind information from abfd. */
619 1.1 christos
620 1.1 christos REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
621 1.1 christos
622 1.1 christos /* If .eh_frame section size doesn't fit into int, we cannot handle
623 1.1 christos it (it would need to use 64-bit .eh_frame format anyway). */
624 1.1 christos REQUIRE (sec->size == (unsigned int) sec->size);
625 1.1 christos
626 1.1 christos ptr_size = (get_elf_backend_data (abfd)
627 1.1 christos ->elf_backend_eh_frame_address_size (abfd, sec));
628 1.1 christos REQUIRE (ptr_size != 0);
629 1.1 christos
630 1.1 christos /* Go through the section contents and work out how many FDEs and
631 1.1 christos CIEs there are. */
632 1.1 christos buf = ehbuf;
633 1.1 christos end = ehbuf + sec->size;
634 1.1 christos num_cies = 0;
635 1.1 christos num_entries = 0;
636 1.1 christos while (buf != end)
637 1.1 christos {
638 1.1 christos num_entries++;
639 1.1 christos
640 1.1 christos /* Read the length of the entry. */
641 1.1 christos REQUIRE (skip_bytes (&buf, end, 4));
642 1.1 christos hdr_length = bfd_get_32 (abfd, buf - 4);
643 1.1 christos
644 1.1 christos /* 64-bit .eh_frame is not supported. */
645 1.1 christos REQUIRE (hdr_length != 0xffffffff);
646 1.1 christos if (hdr_length == 0)
647 1.1 christos break;
648 1.1 christos
649 1.1 christos REQUIRE (skip_bytes (&buf, end, 4));
650 1.1 christos hdr_id = bfd_get_32 (abfd, buf - 4);
651 1.1 christos if (hdr_id == 0)
652 1.1 christos num_cies++;
653 1.1 christos
654 1.1 christos REQUIRE (skip_bytes (&buf, end, hdr_length - 4));
655 1.1 christos }
656 1.1 christos
657 1.1 christos sec_info = (struct eh_frame_sec_info *)
658 1.1 christos bfd_zmalloc (sizeof (struct eh_frame_sec_info)
659 1.6 christos + (num_entries - 1) * sizeof (struct eh_cie_fde));
660 1.1 christos REQUIRE (sec_info);
661 1.1 christos
662 1.1 christos /* We need to have a "struct cie" for each CIE in this section. */
663 1.6 christos if (num_cies)
664 1.6 christos {
665 1.6 christos local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
666 1.6 christos REQUIRE (local_cies);
667 1.6 christos }
668 1.1 christos
669 1.1 christos /* FIXME: octets_per_byte. */
670 1.1 christos #define ENSURE_NO_RELOCS(buf) \
671 1.3 christos while (cookie->rel < cookie->relend \
672 1.3 christos && (cookie->rel->r_offset \
673 1.3 christos < (bfd_size_type) ((buf) - ehbuf))) \
674 1.3 christos { \
675 1.3 christos REQUIRE (cookie->rel->r_info == 0); \
676 1.3 christos cookie->rel++; \
677 1.3 christos }
678 1.1 christos
679 1.1 christos /* FIXME: octets_per_byte. */
680 1.1 christos #define SKIP_RELOCS(buf) \
681 1.1 christos while (cookie->rel < cookie->relend \
682 1.1 christos && (cookie->rel->r_offset \
683 1.1 christos < (bfd_size_type) ((buf) - ehbuf))) \
684 1.1 christos cookie->rel++
685 1.1 christos
686 1.1 christos /* FIXME: octets_per_byte. */
687 1.1 christos #define GET_RELOC(buf) \
688 1.1 christos ((cookie->rel < cookie->relend \
689 1.1 christos && (cookie->rel->r_offset \
690 1.1 christos == (bfd_size_type) ((buf) - ehbuf))) \
691 1.1 christos ? cookie->rel : NULL)
692 1.1 christos
693 1.1 christos buf = ehbuf;
694 1.1 christos cie_count = 0;
695 1.1 christos gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
696 1.1 christos while ((bfd_size_type) (buf - ehbuf) != sec->size)
697 1.1 christos {
698 1.1 christos char *aug;
699 1.1 christos bfd_byte *start, *insns, *insns_end;
700 1.1 christos bfd_size_type length;
701 1.1 christos unsigned int set_loc_count;
702 1.1 christos
703 1.1 christos this_inf = sec_info->entry + sec_info->count;
704 1.1 christos last_fde = buf;
705 1.1 christos
706 1.1 christos /* Read the length of the entry. */
707 1.1 christos REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4));
708 1.1 christos hdr_length = bfd_get_32 (abfd, buf - 4);
709 1.1 christos
710 1.1 christos /* The CIE/FDE must be fully contained in this input section. */
711 1.1 christos REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size);
712 1.1 christos end = buf + hdr_length;
713 1.1 christos
714 1.1 christos this_inf->offset = last_fde - ehbuf;
715 1.1 christos this_inf->size = 4 + hdr_length;
716 1.1 christos this_inf->reloc_index = cookie->rel - cookie->rels;
717 1.1 christos
718 1.1 christos if (hdr_length == 0)
719 1.1 christos {
720 1.1 christos /* A zero-length CIE should only be found at the end of
721 1.6 christos the section, but allow multiple terminators. */
722 1.6 christos while (skip_bytes (&buf, ehbuf + sec->size, 4))
723 1.6 christos REQUIRE (bfd_get_32 (abfd, buf - 4) == 0);
724 1.1 christos REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
725 1.1 christos ENSURE_NO_RELOCS (buf);
726 1.1 christos sec_info->count++;
727 1.1 christos break;
728 1.1 christos }
729 1.1 christos
730 1.1 christos REQUIRE (skip_bytes (&buf, end, 4));
731 1.1 christos hdr_id = bfd_get_32 (abfd, buf - 4);
732 1.1 christos
733 1.1 christos if (hdr_id == 0)
734 1.1 christos {
735 1.1 christos unsigned int initial_insn_length;
736 1.1 christos
737 1.1 christos /* CIE */
738 1.1 christos this_inf->cie = 1;
739 1.1 christos
740 1.1 christos /* Point CIE to one of the section-local cie structures. */
741 1.1 christos cie = local_cies + cie_count++;
742 1.1 christos
743 1.1 christos cie->cie_inf = this_inf;
744 1.1 christos cie->length = hdr_length;
745 1.1 christos start = buf;
746 1.1 christos REQUIRE (read_byte (&buf, end, &cie->version));
747 1.1 christos
748 1.1 christos /* Cannot handle unknown versions. */
749 1.1 christos REQUIRE (cie->version == 1
750 1.1 christos || cie->version == 3
751 1.1 christos || cie->version == 4);
752 1.1 christos REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
753 1.1 christos
754 1.1 christos strcpy (cie->augmentation, (char *) buf);
755 1.1 christos buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
756 1.6 christos this_inf->u.cie.aug_str_len = buf - start - 1;
757 1.1 christos ENSURE_NO_RELOCS (buf);
758 1.1 christos if (buf[0] == 'e' && buf[1] == 'h')
759 1.1 christos {
760 1.1 christos /* GCC < 3.0 .eh_frame CIE */
761 1.1 christos /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
762 1.1 christos is private to each CIE, so we don't need it for anything.
763 1.1 christos Just skip it. */
764 1.1 christos REQUIRE (skip_bytes (&buf, end, ptr_size));
765 1.1 christos SKIP_RELOCS (buf);
766 1.1 christos }
767 1.1 christos if (cie->version >= 4)
768 1.1 christos {
769 1.1 christos REQUIRE (buf + 1 < end);
770 1.1 christos REQUIRE (buf[0] == ptr_size);
771 1.1 christos REQUIRE (buf[1] == 0);
772 1.1 christos buf += 2;
773 1.1 christos }
774 1.1 christos REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
775 1.1 christos REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
776 1.1 christos if (cie->version == 1)
777 1.1 christos {
778 1.1 christos REQUIRE (buf < end);
779 1.1 christos cie->ra_column = *buf++;
780 1.1 christos }
781 1.1 christos else
782 1.1 christos REQUIRE (read_uleb128 (&buf, end, &cie->ra_column));
783 1.1 christos ENSURE_NO_RELOCS (buf);
784 1.1 christos cie->lsda_encoding = DW_EH_PE_omit;
785 1.1 christos cie->fde_encoding = DW_EH_PE_omit;
786 1.1 christos cie->per_encoding = DW_EH_PE_omit;
787 1.1 christos aug = cie->augmentation;
788 1.1 christos if (aug[0] != 'e' || aug[1] != 'h')
789 1.1 christos {
790 1.1 christos if (*aug == 'z')
791 1.1 christos {
792 1.1 christos aug++;
793 1.1 christos REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size));
794 1.6 christos ENSURE_NO_RELOCS (buf);
795 1.1 christos }
796 1.1 christos
797 1.1 christos while (*aug != '\0')
798 1.1 christos switch (*aug++)
799 1.1 christos {
800 1.7 christos case 'B':
801 1.7 christos break;
802 1.1 christos case 'L':
803 1.1 christos REQUIRE (read_byte (&buf, end, &cie->lsda_encoding));
804 1.1 christos ENSURE_NO_RELOCS (buf);
805 1.1 christos REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size));
806 1.1 christos break;
807 1.1 christos case 'R':
808 1.1 christos REQUIRE (read_byte (&buf, end, &cie->fde_encoding));
809 1.1 christos ENSURE_NO_RELOCS (buf);
810 1.1 christos REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size));
811 1.1 christos break;
812 1.1 christos case 'S':
813 1.1 christos break;
814 1.1 christos case 'P':
815 1.1 christos {
816 1.1 christos int per_width;
817 1.1 christos
818 1.1 christos REQUIRE (read_byte (&buf, end, &cie->per_encoding));
819 1.1 christos per_width = get_DW_EH_PE_width (cie->per_encoding,
820 1.1 christos ptr_size);
821 1.1 christos REQUIRE (per_width);
822 1.1 christos if ((cie->per_encoding & 0x70) == DW_EH_PE_aligned)
823 1.1 christos {
824 1.1 christos length = -(buf - ehbuf) & (per_width - 1);
825 1.1 christos REQUIRE (skip_bytes (&buf, end, length));
826 1.6 christos if (per_width == 8)
827 1.6 christos this_inf->u.cie.per_encoding_aligned8 = 1;
828 1.1 christos }
829 1.1 christos this_inf->u.cie.personality_offset = buf - start;
830 1.1 christos ENSURE_NO_RELOCS (buf);
831 1.1 christos /* Ensure we have a reloc here. */
832 1.1 christos REQUIRE (GET_RELOC (buf));
833 1.1 christos cie->personality.reloc_index
834 1.1 christos = cookie->rel - cookie->rels;
835 1.1 christos /* Cope with MIPS-style composite relocations. */
836 1.1 christos do
837 1.1 christos cookie->rel++;
838 1.1 christos while (GET_RELOC (buf) != NULL);
839 1.1 christos REQUIRE (skip_bytes (&buf, end, per_width));
840 1.1 christos }
841 1.1 christos break;
842 1.1 christos default:
843 1.1 christos /* Unrecognized augmentation. Better bail out. */
844 1.1 christos goto free_no_table;
845 1.1 christos }
846 1.1 christos }
847 1.6 christos this_inf->u.cie.aug_data_len
848 1.6 christos = buf - start - 1 - this_inf->u.cie.aug_str_len;
849 1.1 christos
850 1.1 christos /* For shared libraries, try to get rid of as many RELATIVE relocs
851 1.1 christos as possible. */
852 1.3 christos if (bfd_link_pic (info)
853 1.1 christos && (get_elf_backend_data (abfd)
854 1.1 christos ->elf_backend_can_make_relative_eh_frame
855 1.1 christos (abfd, info, sec)))
856 1.1 christos {
857 1.1 christos if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr)
858 1.1 christos this_inf->make_relative = 1;
859 1.1 christos /* If the CIE doesn't already have an 'R' entry, it's fairly
860 1.1 christos easy to add one, provided that there's no aligned data
861 1.1 christos after the augmentation string. */
862 1.1 christos else if (cie->fde_encoding == DW_EH_PE_omit
863 1.1 christos && (cie->per_encoding & 0x70) != DW_EH_PE_aligned)
864 1.1 christos {
865 1.1 christos if (*cie->augmentation == 0)
866 1.1 christos this_inf->add_augmentation_size = 1;
867 1.1 christos this_inf->u.cie.add_fde_encoding = 1;
868 1.1 christos this_inf->make_relative = 1;
869 1.1 christos }
870 1.1 christos
871 1.1 christos if ((cie->lsda_encoding & 0x70) == DW_EH_PE_absptr)
872 1.1 christos cie->can_make_lsda_relative = 1;
873 1.1 christos }
874 1.1 christos
875 1.1 christos /* If FDE encoding was not specified, it defaults to
876 1.1 christos DW_EH_absptr. */
877 1.1 christos if (cie->fde_encoding == DW_EH_PE_omit)
878 1.1 christos cie->fde_encoding = DW_EH_PE_absptr;
879 1.1 christos
880 1.1 christos initial_insn_length = end - buf;
881 1.3 christos cie->initial_insn_length = initial_insn_length;
882 1.3 christos memcpy (cie->initial_instructions, buf,
883 1.3 christos initial_insn_length <= sizeof (cie->initial_instructions)
884 1.3 christos ? initial_insn_length : sizeof (cie->initial_instructions));
885 1.1 christos insns = buf;
886 1.1 christos buf += initial_insn_length;
887 1.1 christos ENSURE_NO_RELOCS (buf);
888 1.1 christos
889 1.3 christos if (!bfd_link_relocatable (info))
890 1.3 christos {
891 1.3 christos /* Keep info for merging cies. */
892 1.3 christos this_inf->u.cie.u.full_cie = cie;
893 1.3 christos this_inf->u.cie.per_encoding_relative
894 1.3 christos = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
895 1.3 christos }
896 1.1 christos }
897 1.1 christos else
898 1.1 christos {
899 1.1 christos /* Find the corresponding CIE. */
900 1.1 christos unsigned int cie_offset = this_inf->offset + 4 - hdr_id;
901 1.1 christos for (cie = local_cies; cie < local_cies + cie_count; cie++)
902 1.1 christos if (cie_offset == cie->cie_inf->offset)
903 1.1 christos break;
904 1.1 christos
905 1.1 christos /* Ensure this FDE references one of the CIEs in this input
906 1.1 christos section. */
907 1.1 christos REQUIRE (cie != local_cies + cie_count);
908 1.1 christos this_inf->u.fde.cie_inf = cie->cie_inf;
909 1.1 christos this_inf->make_relative = cie->cie_inf->make_relative;
910 1.1 christos this_inf->add_augmentation_size
911 1.1 christos = cie->cie_inf->add_augmentation_size;
912 1.1 christos
913 1.1 christos ENSURE_NO_RELOCS (buf);
914 1.1 christos if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
915 1.1 christos {
916 1.1 christos asection *rsec;
917 1.1 christos
918 1.1 christos REQUIRE (GET_RELOC (buf));
919 1.1 christos
920 1.1 christos /* Chain together the FDEs for each section. */
921 1.3 christos rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook,
922 1.3 christos cookie, NULL);
923 1.1 christos /* RSEC will be NULL if FDE was cleared out as it was belonging to
924 1.1 christos a discarded SHT_GROUP. */
925 1.1 christos if (rsec)
926 1.1 christos {
927 1.1 christos REQUIRE (rsec->owner == abfd);
928 1.1 christos this_inf->u.fde.next_for_section = elf_fde_list (rsec);
929 1.1 christos elf_fde_list (rsec) = this_inf;
930 1.1 christos }
931 1.1 christos }
932 1.1 christos
933 1.1 christos /* Skip the initial location and address range. */
934 1.1 christos start = buf;
935 1.1 christos length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
936 1.1 christos REQUIRE (skip_bytes (&buf, end, 2 * length));
937 1.1 christos
938 1.3 christos SKIP_RELOCS (buf - length);
939 1.3 christos if (!GET_RELOC (buf - length)
940 1.3 christos && read_value (abfd, buf - length, length, FALSE) == 0)
941 1.3 christos {
942 1.3 christos (*info->callbacks->minfo)
943 1.6 christos /* xgettext:c-format */
944 1.6 christos (_("discarding zero address range FDE in %pB(%pA).\n"),
945 1.3 christos abfd, sec);
946 1.3 christos this_inf->u.fde.cie_inf = NULL;
947 1.3 christos }
948 1.3 christos
949 1.1 christos /* Skip the augmentation size, if present. */
950 1.1 christos if (cie->augmentation[0] == 'z')
951 1.1 christos REQUIRE (read_uleb128 (&buf, end, &length));
952 1.1 christos else
953 1.1 christos length = 0;
954 1.1 christos
955 1.1 christos /* Of the supported augmentation characters above, only 'L'
956 1.1 christos adds augmentation data to the FDE. This code would need to
957 1.1 christos be adjusted if any future augmentations do the same thing. */
958 1.1 christos if (cie->lsda_encoding != DW_EH_PE_omit)
959 1.1 christos {
960 1.1 christos SKIP_RELOCS (buf);
961 1.1 christos if (cie->can_make_lsda_relative && GET_RELOC (buf))
962 1.1 christos cie->cie_inf->u.cie.make_lsda_relative = 1;
963 1.1 christos this_inf->lsda_offset = buf - start;
964 1.1 christos /* If there's no 'z' augmentation, we don't know where the
965 1.1 christos CFA insns begin. Assume no padding. */
966 1.1 christos if (cie->augmentation[0] != 'z')
967 1.1 christos length = end - buf;
968 1.1 christos }
969 1.1 christos
970 1.1 christos /* Skip over the augmentation data. */
971 1.1 christos REQUIRE (skip_bytes (&buf, end, length));
972 1.1 christos insns = buf;
973 1.1 christos
974 1.1 christos buf = last_fde + 4 + hdr_length;
975 1.1 christos
976 1.1 christos /* For NULL RSEC (cleared FDE belonging to a discarded section)
977 1.1 christos the relocations are commonly cleared. We do not sanity check if
978 1.1 christos all these relocations are cleared as (1) relocations to
979 1.1 christos .gcc_except_table will remain uncleared (they will get dropped
980 1.1 christos with the drop of this unused FDE) and (2) BFD already safely drops
981 1.1 christos relocations of any type to .eh_frame by
982 1.1 christos elf_section_ignore_discarded_relocs.
983 1.1 christos TODO: The .gcc_except_table entries should be also filtered as
984 1.1 christos .eh_frame entries; or GCC could rather use COMDAT for them. */
985 1.1 christos SKIP_RELOCS (buf);
986 1.1 christos }
987 1.1 christos
988 1.1 christos /* Try to interpret the CFA instructions and find the first
989 1.1 christos padding nop. Shrink this_inf's size so that it doesn't
990 1.1 christos include the padding. */
991 1.1 christos length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
992 1.1 christos set_loc_count = 0;
993 1.1 christos insns_end = skip_non_nops (insns, end, length, &set_loc_count);
994 1.1 christos /* If we don't understand the CFA instructions, we can't know
995 1.1 christos what needs to be adjusted there. */
996 1.1 christos if (insns_end == NULL
997 1.1 christos /* For the time being we don't support DW_CFA_set_loc in
998 1.1 christos CIE instructions. */
999 1.1 christos || (set_loc_count && this_inf->cie))
1000 1.1 christos goto free_no_table;
1001 1.1 christos this_inf->size -= end - insns_end;
1002 1.1 christos if (insns_end != end && this_inf->cie)
1003 1.1 christos {
1004 1.1 christos cie->initial_insn_length -= end - insns_end;
1005 1.1 christos cie->length -= end - insns_end;
1006 1.1 christos }
1007 1.1 christos if (set_loc_count
1008 1.1 christos && ((cie->fde_encoding & 0x70) == DW_EH_PE_pcrel
1009 1.1 christos || this_inf->make_relative))
1010 1.1 christos {
1011 1.1 christos unsigned int cnt;
1012 1.1 christos bfd_byte *p;
1013 1.1 christos
1014 1.1 christos this_inf->set_loc = (unsigned int *)
1015 1.6 christos bfd_malloc ((set_loc_count + 1) * sizeof (unsigned int));
1016 1.1 christos REQUIRE (this_inf->set_loc);
1017 1.1 christos this_inf->set_loc[0] = set_loc_count;
1018 1.1 christos p = insns;
1019 1.1 christos cnt = 0;
1020 1.1 christos while (p < end)
1021 1.1 christos {
1022 1.1 christos if (*p == DW_CFA_set_loc)
1023 1.1 christos this_inf->set_loc[++cnt] = p + 1 - start;
1024 1.1 christos REQUIRE (skip_cfa_op (&p, end, length));
1025 1.1 christos }
1026 1.1 christos }
1027 1.1 christos
1028 1.1 christos this_inf->removed = 1;
1029 1.1 christos this_inf->fde_encoding = cie->fde_encoding;
1030 1.1 christos this_inf->lsda_encoding = cie->lsda_encoding;
1031 1.1 christos sec_info->count++;
1032 1.1 christos }
1033 1.1 christos BFD_ASSERT (sec_info->count == num_entries);
1034 1.1 christos BFD_ASSERT (cie_count == num_cies);
1035 1.1 christos
1036 1.1 christos elf_section_data (sec)->sec_info = sec_info;
1037 1.1 christos sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME;
1038 1.3 christos if (!bfd_link_relocatable (info))
1039 1.1 christos {
1040 1.3 christos /* Keep info for merging cies. */
1041 1.1 christos sec_info->cies = local_cies;
1042 1.1 christos local_cies = NULL;
1043 1.1 christos }
1044 1.1 christos goto success;
1045 1.1 christos
1046 1.1 christos free_no_table:
1047 1.6 christos _bfd_error_handler
1048 1.6 christos /* xgettext:c-format */
1049 1.6 christos (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
1050 1.1 christos abfd, sec);
1051 1.3 christos hdr_info->u.dwarf.table = FALSE;
1052 1.1 christos if (sec_info)
1053 1.1 christos free (sec_info);
1054 1.1 christos success:
1055 1.1 christos if (ehbuf)
1056 1.1 christos free (ehbuf);
1057 1.1 christos if (local_cies)
1058 1.1 christos free (local_cies);
1059 1.1 christos #undef REQUIRE
1060 1.1 christos }
1061 1.1 christos
1062 1.3 christos /* Order eh_frame_hdr entries by the VMA of their text section. */
1063 1.3 christos
1064 1.3 christos static int
1065 1.3 christos cmp_eh_frame_hdr (const void *a, const void *b)
1066 1.3 christos {
1067 1.3 christos bfd_vma text_a;
1068 1.3 christos bfd_vma text_b;
1069 1.3 christos asection *sec;
1070 1.3 christos
1071 1.3 christos sec = *(asection *const *)a;
1072 1.3 christos sec = (asection *) elf_section_data (sec)->sec_info;
1073 1.3 christos text_a = sec->output_section->vma + sec->output_offset;
1074 1.3 christos sec = *(asection *const *)b;
1075 1.3 christos sec = (asection *) elf_section_data (sec)->sec_info;
1076 1.3 christos text_b = sec->output_section->vma + sec->output_offset;
1077 1.3 christos
1078 1.3 christos if (text_a < text_b)
1079 1.3 christos return -1;
1080 1.3 christos return text_a > text_b;
1081 1.3 christos
1082 1.3 christos }
1083 1.3 christos
1084 1.3 christos /* Add space for a CANTUNWIND terminator to SEC if the text sections
1085 1.3 christos referenced by it and NEXT are not contiguous, or NEXT is NULL. */
1086 1.3 christos
1087 1.3 christos static void
1088 1.3 christos add_eh_frame_hdr_terminator (asection *sec,
1089 1.3 christos asection *next)
1090 1.3 christos {
1091 1.3 christos bfd_vma end;
1092 1.3 christos bfd_vma next_start;
1093 1.3 christos asection *text_sec;
1094 1.3 christos
1095 1.3 christos if (next)
1096 1.3 christos {
1097 1.3 christos /* See if there is a gap (presumably a text section without unwind info)
1098 1.3 christos between these two entries. */
1099 1.3 christos text_sec = (asection *) elf_section_data (sec)->sec_info;
1100 1.3 christos end = text_sec->output_section->vma + text_sec->output_offset
1101 1.3 christos + text_sec->size;
1102 1.3 christos text_sec = (asection *) elf_section_data (next)->sec_info;
1103 1.3 christos next_start = text_sec->output_section->vma + text_sec->output_offset;
1104 1.3 christos if (end == next_start)
1105 1.3 christos return;
1106 1.3 christos }
1107 1.3 christos
1108 1.3 christos /* Add space for a CANTUNWIND terminator. */
1109 1.3 christos if (!sec->rawsize)
1110 1.3 christos sec->rawsize = sec->size;
1111 1.3 christos
1112 1.7 christos bfd_set_section_size (sec, sec->size + 8);
1113 1.3 christos }
1114 1.3 christos
1115 1.3 christos /* Finish a pass over all .eh_frame_entry sections. */
1116 1.1 christos
1117 1.3 christos bfd_boolean
1118 1.1 christos _bfd_elf_end_eh_frame_parsing (struct bfd_link_info *info)
1119 1.1 christos {
1120 1.1 christos struct eh_frame_hdr_info *hdr_info;
1121 1.3 christos unsigned int i;
1122 1.1 christos
1123 1.1 christos hdr_info = &elf_hash_table (info)->eh_info;
1124 1.3 christos
1125 1.3 christos if (info->eh_frame_hdr_type != COMPACT_EH_HDR
1126 1.3 christos || hdr_info->array_count == 0)
1127 1.3 christos return FALSE;
1128 1.3 christos
1129 1.3 christos bfd_elf_discard_eh_frame_entry (hdr_info);
1130 1.3 christos
1131 1.3 christos qsort (hdr_info->u.compact.entries, hdr_info->array_count,
1132 1.3 christos sizeof (asection *), cmp_eh_frame_hdr);
1133 1.3 christos
1134 1.3 christos for (i = 0; i < hdr_info->array_count - 1; i++)
1135 1.3 christos {
1136 1.3 christos add_eh_frame_hdr_terminator (hdr_info->u.compact.entries[i],
1137 1.3 christos hdr_info->u.compact.entries[i + 1]);
1138 1.3 christos }
1139 1.3 christos
1140 1.3 christos /* Add a CANTUNWIND terminator after the last entry. */
1141 1.3 christos add_eh_frame_hdr_terminator (hdr_info->u.compact.entries[i], NULL);
1142 1.3 christos return TRUE;
1143 1.1 christos }
1144 1.1 christos
1145 1.1 christos /* Mark all relocations against CIE or FDE ENT, which occurs in
1146 1.1 christos .eh_frame section SEC. COOKIE describes the relocations in SEC;
1147 1.1 christos its "rel" field can be changed freely. */
1148 1.1 christos
1149 1.1 christos static bfd_boolean
1150 1.1 christos mark_entry (struct bfd_link_info *info, asection *sec,
1151 1.1 christos struct eh_cie_fde *ent, elf_gc_mark_hook_fn gc_mark_hook,
1152 1.1 christos struct elf_reloc_cookie *cookie)
1153 1.1 christos {
1154 1.1 christos /* FIXME: octets_per_byte. */
1155 1.1 christos for (cookie->rel = cookie->rels + ent->reloc_index;
1156 1.1 christos cookie->rel < cookie->relend
1157 1.1 christos && cookie->rel->r_offset < ent->offset + ent->size;
1158 1.1 christos cookie->rel++)
1159 1.1 christos if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie))
1160 1.1 christos return FALSE;
1161 1.1 christos
1162 1.1 christos return TRUE;
1163 1.1 christos }
1164 1.1 christos
1165 1.1 christos /* Mark all the relocations against FDEs that relate to code in input
1166 1.1 christos section SEC. The FDEs belong to .eh_frame section EH_FRAME, whose
1167 1.1 christos relocations are described by COOKIE. */
1168 1.1 christos
1169 1.1 christos bfd_boolean
1170 1.1 christos _bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
1171 1.1 christos asection *eh_frame, elf_gc_mark_hook_fn gc_mark_hook,
1172 1.1 christos struct elf_reloc_cookie *cookie)
1173 1.1 christos {
1174 1.1 christos struct eh_cie_fde *fde, *cie;
1175 1.1 christos
1176 1.1 christos for (fde = elf_fde_list (sec); fde; fde = fde->u.fde.next_for_section)
1177 1.1 christos {
1178 1.1 christos if (!mark_entry (info, eh_frame, fde, gc_mark_hook, cookie))
1179 1.1 christos return FALSE;
1180 1.1 christos
1181 1.1 christos /* At this stage, all cie_inf fields point to local CIEs, so we
1182 1.1 christos can use the same cookie to refer to them. */
1183 1.1 christos cie = fde->u.fde.cie_inf;
1184 1.3 christos if (cie != NULL && !cie->u.cie.gc_mark)
1185 1.1 christos {
1186 1.1 christos cie->u.cie.gc_mark = 1;
1187 1.1 christos if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie))
1188 1.1 christos return FALSE;
1189 1.1 christos }
1190 1.1 christos }
1191 1.1 christos return TRUE;
1192 1.1 christos }
1193 1.1 christos
1194 1.1 christos /* Input section SEC of ABFD is an .eh_frame section that contains the
1195 1.1 christos CIE described by CIE_INF. Return a version of CIE_INF that is going
1196 1.1 christos to be kept in the output, adding CIE_INF to the output if necessary.
1197 1.1 christos
1198 1.1 christos HDR_INFO is the .eh_frame_hdr information and COOKIE describes the
1199 1.1 christos relocations in REL. */
1200 1.1 christos
1201 1.1 christos static struct eh_cie_fde *
1202 1.1 christos find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
1203 1.1 christos struct eh_frame_hdr_info *hdr_info,
1204 1.1 christos struct elf_reloc_cookie *cookie,
1205 1.1 christos struct eh_cie_fde *cie_inf)
1206 1.1 christos {
1207 1.1 christos unsigned long r_symndx;
1208 1.1 christos struct cie *cie, *new_cie;
1209 1.1 christos Elf_Internal_Rela *rel;
1210 1.1 christos void **loc;
1211 1.1 christos
1212 1.1 christos /* Use CIE_INF if we have already decided to keep it. */
1213 1.1 christos if (!cie_inf->removed)
1214 1.1 christos return cie_inf;
1215 1.1 christos
1216 1.1 christos /* If we have merged CIE_INF with another CIE, use that CIE instead. */
1217 1.1 christos if (cie_inf->u.cie.merged)
1218 1.1 christos return cie_inf->u.cie.u.merged_with;
1219 1.1 christos
1220 1.1 christos cie = cie_inf->u.cie.u.full_cie;
1221 1.1 christos
1222 1.1 christos /* Assume we will need to keep CIE_INF. */
1223 1.1 christos cie_inf->removed = 0;
1224 1.1 christos cie_inf->u.cie.u.sec = sec;
1225 1.1 christos
1226 1.1 christos /* If we are not merging CIEs, use CIE_INF. */
1227 1.1 christos if (cie == NULL)
1228 1.1 christos return cie_inf;
1229 1.1 christos
1230 1.1 christos if (cie->per_encoding != DW_EH_PE_omit)
1231 1.1 christos {
1232 1.1 christos bfd_boolean per_binds_local;
1233 1.1 christos
1234 1.3 christos /* Work out the address of personality routine, or at least
1235 1.3 christos enough info that we could calculate the address had we made a
1236 1.3 christos final section layout. The symbol on the reloc is enough,
1237 1.3 christos either the hash for a global, or (bfd id, index) pair for a
1238 1.3 christos local. The assumption here is that no one uses addends on
1239 1.3 christos the reloc. */
1240 1.1 christos rel = cookie->rels + cie->personality.reloc_index;
1241 1.1 christos memset (&cie->personality, 0, sizeof (cie->personality));
1242 1.1 christos #ifdef BFD64
1243 1.1 christos if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
1244 1.1 christos r_symndx = ELF64_R_SYM (rel->r_info);
1245 1.1 christos else
1246 1.1 christos #endif
1247 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
1248 1.1 christos if (r_symndx >= cookie->locsymcount
1249 1.1 christos || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
1250 1.1 christos {
1251 1.1 christos struct elf_link_hash_entry *h;
1252 1.1 christos
1253 1.1 christos r_symndx -= cookie->extsymoff;
1254 1.1 christos h = cookie->sym_hashes[r_symndx];
1255 1.1 christos
1256 1.1 christos while (h->root.type == bfd_link_hash_indirect
1257 1.1 christos || h->root.type == bfd_link_hash_warning)
1258 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link;
1259 1.1 christos
1260 1.1 christos cie->personality.h = h;
1261 1.1 christos per_binds_local = SYMBOL_REFERENCES_LOCAL (info, h);
1262 1.1 christos }
1263 1.1 christos else
1264 1.1 christos {
1265 1.1 christos Elf_Internal_Sym *sym;
1266 1.1 christos asection *sym_sec;
1267 1.1 christos
1268 1.1 christos sym = &cookie->locsyms[r_symndx];
1269 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, sym->st_shndx);
1270 1.1 christos if (sym_sec == NULL)
1271 1.1 christos return cie_inf;
1272 1.1 christos
1273 1.1 christos if (sym_sec->kept_section != NULL)
1274 1.1 christos sym_sec = sym_sec->kept_section;
1275 1.1 christos if (sym_sec->output_section == NULL)
1276 1.1 christos return cie_inf;
1277 1.1 christos
1278 1.1 christos cie->local_personality = 1;
1279 1.3 christos cie->personality.sym.bfd_id = abfd->id;
1280 1.3 christos cie->personality.sym.index = r_symndx;
1281 1.1 christos per_binds_local = TRUE;
1282 1.1 christos }
1283 1.1 christos
1284 1.1 christos if (per_binds_local
1285 1.3 christos && bfd_link_pic (info)
1286 1.1 christos && (cie->per_encoding & 0x70) == DW_EH_PE_absptr
1287 1.1 christos && (get_elf_backend_data (abfd)
1288 1.1 christos ->elf_backend_can_make_relative_eh_frame (abfd, info, sec)))
1289 1.1 christos {
1290 1.1 christos cie_inf->u.cie.make_per_encoding_relative = 1;
1291 1.1 christos cie_inf->u.cie.per_encoding_relative = 1;
1292 1.1 christos }
1293 1.1 christos }
1294 1.1 christos
1295 1.1 christos /* See if we can merge this CIE with an earlier one. */
1296 1.1 christos cie_compute_hash (cie);
1297 1.3 christos if (hdr_info->u.dwarf.cies == NULL)
1298 1.1 christos {
1299 1.3 christos hdr_info->u.dwarf.cies = htab_try_create (1, cie_hash, cie_eq, free);
1300 1.3 christos if (hdr_info->u.dwarf.cies == NULL)
1301 1.1 christos return cie_inf;
1302 1.1 christos }
1303 1.3 christos loc = htab_find_slot_with_hash (hdr_info->u.dwarf.cies, cie,
1304 1.3 christos cie->hash, INSERT);
1305 1.1 christos if (loc == NULL)
1306 1.1 christos return cie_inf;
1307 1.1 christos
1308 1.1 christos new_cie = (struct cie *) *loc;
1309 1.1 christos if (new_cie == NULL)
1310 1.1 christos {
1311 1.1 christos /* Keep CIE_INF and record it in the hash table. */
1312 1.1 christos new_cie = (struct cie *) malloc (sizeof (struct cie));
1313 1.1 christos if (new_cie == NULL)
1314 1.1 christos return cie_inf;
1315 1.1 christos
1316 1.1 christos memcpy (new_cie, cie, sizeof (struct cie));
1317 1.1 christos *loc = new_cie;
1318 1.1 christos }
1319 1.1 christos else
1320 1.1 christos {
1321 1.1 christos /* Merge CIE_INF with NEW_CIE->CIE_INF. */
1322 1.1 christos cie_inf->removed = 1;
1323 1.1 christos cie_inf->u.cie.merged = 1;
1324 1.1 christos cie_inf->u.cie.u.merged_with = new_cie->cie_inf;
1325 1.1 christos if (cie_inf->u.cie.make_lsda_relative)
1326 1.1 christos new_cie->cie_inf->u.cie.make_lsda_relative = 1;
1327 1.1 christos }
1328 1.1 christos return new_cie->cie_inf;
1329 1.1 christos }
1330 1.1 christos
1331 1.6 christos /* For a given OFFSET in SEC, return the delta to the new location
1332 1.6 christos after .eh_frame editing. */
1333 1.6 christos
1334 1.6 christos static bfd_signed_vma
1335 1.6 christos offset_adjust (bfd_vma offset, const asection *sec)
1336 1.6 christos {
1337 1.6 christos struct eh_frame_sec_info *sec_info
1338 1.6 christos = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1339 1.6 christos unsigned int lo, hi, mid;
1340 1.6 christos struct eh_cie_fde *ent = NULL;
1341 1.6 christos bfd_signed_vma delta;
1342 1.6 christos
1343 1.6 christos lo = 0;
1344 1.6 christos hi = sec_info->count;
1345 1.6 christos if (hi == 0)
1346 1.6 christos return 0;
1347 1.6 christos
1348 1.6 christos while (lo < hi)
1349 1.6 christos {
1350 1.6 christos mid = (lo + hi) / 2;
1351 1.6 christos ent = &sec_info->entry[mid];
1352 1.6 christos if (offset < ent->offset)
1353 1.6 christos hi = mid;
1354 1.6 christos else if (mid + 1 >= hi)
1355 1.6 christos break;
1356 1.6 christos else if (offset >= ent[1].offset)
1357 1.6 christos lo = mid + 1;
1358 1.6 christos else
1359 1.6 christos break;
1360 1.6 christos }
1361 1.6 christos
1362 1.6 christos if (!ent->removed)
1363 1.6 christos delta = (bfd_vma) ent->new_offset - (bfd_vma) ent->offset;
1364 1.6 christos else if (ent->cie && ent->u.cie.merged)
1365 1.6 christos {
1366 1.6 christos struct eh_cie_fde *cie = ent->u.cie.u.merged_with;
1367 1.6 christos delta = ((bfd_vma) cie->new_offset + cie->u.cie.u.sec->output_offset
1368 1.6 christos - (bfd_vma) ent->offset - sec->output_offset);
1369 1.6 christos }
1370 1.6 christos else
1371 1.6 christos {
1372 1.6 christos /* Is putting the symbol on the next entry best for a deleted
1373 1.6 christos CIE/FDE? */
1374 1.6 christos struct eh_cie_fde *last = sec_info->entry + sec_info->count;
1375 1.6 christos delta = ((bfd_vma) next_cie_fde_offset (ent, last, sec)
1376 1.6 christos - (bfd_vma) ent->offset);
1377 1.6 christos return delta;
1378 1.6 christos }
1379 1.6 christos
1380 1.6 christos /* Account for editing within this CIE/FDE. */
1381 1.6 christos offset -= ent->offset;
1382 1.6 christos if (ent->cie)
1383 1.6 christos {
1384 1.6 christos unsigned int extra
1385 1.6 christos = ent->add_augmentation_size + ent->u.cie.add_fde_encoding;
1386 1.6 christos if (extra == 0
1387 1.6 christos || offset <= 9u + ent->u.cie.aug_str_len)
1388 1.6 christos return delta;
1389 1.6 christos delta += extra;
1390 1.6 christos if (offset <= 9u + ent->u.cie.aug_str_len + ent->u.cie.aug_data_len)
1391 1.6 christos return delta;
1392 1.6 christos delta += extra;
1393 1.6 christos }
1394 1.6 christos else
1395 1.6 christos {
1396 1.6 christos unsigned int ptr_size, width, extra = ent->add_augmentation_size;
1397 1.6 christos if (offset <= 12 || extra == 0)
1398 1.6 christos return delta;
1399 1.6 christos ptr_size = (get_elf_backend_data (sec->owner)
1400 1.6 christos ->elf_backend_eh_frame_address_size (sec->owner, sec));
1401 1.6 christos width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1402 1.6 christos if (offset <= 8 + 2 * width)
1403 1.6 christos return delta;
1404 1.6 christos delta += extra;
1405 1.6 christos }
1406 1.6 christos
1407 1.6 christos return delta;
1408 1.6 christos }
1409 1.6 christos
1410 1.6 christos /* Adjust a global symbol defined in .eh_frame, so that it stays
1411 1.6 christos relative to its original CIE/FDE. It is assumed that a symbol
1412 1.6 christos defined at the beginning of a CIE/FDE belongs to that CIE/FDE
1413 1.6 christos rather than marking the end of the previous CIE/FDE. This matters
1414 1.6 christos when a CIE is merged with a previous CIE, since the symbol is
1415 1.6 christos moved to the merged CIE. */
1416 1.6 christos
1417 1.6 christos bfd_boolean
1418 1.6 christos _bfd_elf_adjust_eh_frame_global_symbol (struct elf_link_hash_entry *h,
1419 1.6 christos void *arg ATTRIBUTE_UNUSED)
1420 1.6 christos {
1421 1.6 christos asection *sym_sec;
1422 1.6 christos bfd_signed_vma delta;
1423 1.6 christos
1424 1.6 christos if (h->root.type != bfd_link_hash_defined
1425 1.6 christos && h->root.type != bfd_link_hash_defweak)
1426 1.6 christos return TRUE;
1427 1.6 christos
1428 1.6 christos sym_sec = h->root.u.def.section;
1429 1.6 christos if (sym_sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME
1430 1.6 christos || elf_section_data (sym_sec)->sec_info == NULL)
1431 1.6 christos return TRUE;
1432 1.6 christos
1433 1.6 christos delta = offset_adjust (h->root.u.def.value, sym_sec);
1434 1.6 christos h->root.u.def.value += delta;
1435 1.6 christos
1436 1.6 christos return TRUE;
1437 1.6 christos }
1438 1.6 christos
1439 1.6 christos /* The same for all local symbols defined in .eh_frame. Returns true
1440 1.6 christos if any symbol was changed. */
1441 1.6 christos
1442 1.6 christos static int
1443 1.6 christos adjust_eh_frame_local_symbols (const asection *sec,
1444 1.6 christos struct elf_reloc_cookie *cookie)
1445 1.6 christos {
1446 1.6 christos unsigned int shndx;
1447 1.6 christos Elf_Internal_Sym *sym;
1448 1.6 christos Elf_Internal_Sym *end_sym;
1449 1.6 christos int adjusted = 0;
1450 1.6 christos
1451 1.6 christos shndx = elf_section_data (sec)->this_idx;
1452 1.6 christos end_sym = cookie->locsyms + cookie->locsymcount;
1453 1.6 christos for (sym = cookie->locsyms + 1; sym < end_sym; ++sym)
1454 1.6 christos if (sym->st_info <= ELF_ST_INFO (STB_LOCAL, STT_OBJECT)
1455 1.6 christos && sym->st_shndx == shndx)
1456 1.6 christos {
1457 1.6 christos bfd_signed_vma delta = offset_adjust (sym->st_value, sec);
1458 1.6 christos
1459 1.6 christos if (delta != 0)
1460 1.6 christos {
1461 1.6 christos adjusted = 1;
1462 1.6 christos sym->st_value += delta;
1463 1.6 christos }
1464 1.6 christos }
1465 1.6 christos return adjusted;
1466 1.6 christos }
1467 1.6 christos
1468 1.1 christos /* This function is called for each input file before the .eh_frame
1469 1.1 christos section is relocated. It discards duplicate CIEs and FDEs for discarded
1470 1.1 christos functions. The function returns TRUE iff any entries have been
1471 1.1 christos deleted. */
1472 1.1 christos
1473 1.1 christos bfd_boolean
1474 1.1 christos _bfd_elf_discard_section_eh_frame
1475 1.1 christos (bfd *abfd, struct bfd_link_info *info, asection *sec,
1476 1.1 christos bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
1477 1.1 christos struct elf_reloc_cookie *cookie)
1478 1.1 christos {
1479 1.1 christos struct eh_cie_fde *ent;
1480 1.1 christos struct eh_frame_sec_info *sec_info;
1481 1.1 christos struct eh_frame_hdr_info *hdr_info;
1482 1.6 christos unsigned int ptr_size, offset, eh_alignment;
1483 1.6 christos int changed;
1484 1.1 christos
1485 1.1 christos if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
1486 1.1 christos return FALSE;
1487 1.1 christos
1488 1.1 christos sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1489 1.1 christos if (sec_info == NULL)
1490 1.1 christos return FALSE;
1491 1.1 christos
1492 1.1 christos ptr_size = (get_elf_backend_data (sec->owner)
1493 1.1 christos ->elf_backend_eh_frame_address_size (sec->owner, sec));
1494 1.1 christos
1495 1.1 christos hdr_info = &elf_hash_table (info)->eh_info;
1496 1.1 christos for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1497 1.1 christos if (ent->size == 4)
1498 1.1 christos /* There should only be one zero terminator, on the last input
1499 1.1 christos file supplying .eh_frame (crtend.o). Remove any others. */
1500 1.1 christos ent->removed = sec->map_head.s != NULL;
1501 1.3 christos else if (!ent->cie && ent->u.fde.cie_inf != NULL)
1502 1.1 christos {
1503 1.1 christos bfd_boolean keep;
1504 1.1 christos if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL)
1505 1.1 christos {
1506 1.1 christos unsigned int width
1507 1.1 christos = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1508 1.1 christos bfd_vma value
1509 1.1 christos = read_value (abfd, sec->contents + ent->offset + 8 + width,
1510 1.1 christos width, get_DW_EH_PE_signed (ent->fde_encoding));
1511 1.1 christos keep = value != 0;
1512 1.1 christos }
1513 1.1 christos else
1514 1.1 christos {
1515 1.1 christos cookie->rel = cookie->rels + ent->reloc_index;
1516 1.1 christos /* FIXME: octets_per_byte. */
1517 1.1 christos BFD_ASSERT (cookie->rel < cookie->relend
1518 1.1 christos && cookie->rel->r_offset == ent->offset + 8);
1519 1.1 christos keep = !(*reloc_symbol_deleted_p) (ent->offset + 8, cookie);
1520 1.1 christos }
1521 1.1 christos if (keep)
1522 1.1 christos {
1523 1.3 christos if (bfd_link_pic (info)
1524 1.1 christos && (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr
1525 1.1 christos && ent->make_relative == 0)
1526 1.1 christos || (ent->fde_encoding & 0x70) == DW_EH_PE_aligned))
1527 1.1 christos {
1528 1.5 christos static int num_warnings_issued = 0;
1529 1.5 christos
1530 1.1 christos /* If a shared library uses absolute pointers
1531 1.1 christos which we cannot turn into PC relative,
1532 1.1 christos don't create the binary search table,
1533 1.1 christos since it is affected by runtime relocations. */
1534 1.3 christos hdr_info->u.dwarf.table = FALSE;
1535 1.7 christos /* Only warn if --eh-frame-hdr was specified. */
1536 1.7 christos if (info->eh_frame_hdr_type != 0)
1537 1.5 christos {
1538 1.7 christos if (num_warnings_issued < 10)
1539 1.7 christos {
1540 1.7 christos _bfd_error_handler
1541 1.7 christos /* xgettext:c-format */
1542 1.7 christos (_("FDE encoding in %pB(%pA) prevents .eh_frame_hdr"
1543 1.7 christos " table being created"), abfd, sec);
1544 1.7 christos num_warnings_issued ++;
1545 1.7 christos }
1546 1.7 christos else if (num_warnings_issued == 10)
1547 1.7 christos {
1548 1.7 christos _bfd_error_handler
1549 1.7 christos (_("further warnings about FDE encoding preventing .eh_frame_hdr generation dropped"));
1550 1.7 christos num_warnings_issued ++;
1551 1.7 christos }
1552 1.5 christos }
1553 1.1 christos }
1554 1.1 christos ent->removed = 0;
1555 1.3 christos hdr_info->u.dwarf.fde_count++;
1556 1.1 christos ent->u.fde.cie_inf = find_merged_cie (abfd, info, sec, hdr_info,
1557 1.1 christos cookie, ent->u.fde.cie_inf);
1558 1.1 christos }
1559 1.1 christos }
1560 1.1 christos
1561 1.1 christos if (sec_info->cies)
1562 1.1 christos {
1563 1.1 christos free (sec_info->cies);
1564 1.1 christos sec_info->cies = NULL;
1565 1.1 christos }
1566 1.1 christos
1567 1.6 christos /* It may be that some .eh_frame input section has greater alignment
1568 1.6 christos than other .eh_frame sections. In that case we run the risk of
1569 1.6 christos padding with zeros before that section, which would be seen as a
1570 1.6 christos zero terminator. Alignment padding must be added *inside* the
1571 1.6 christos last FDE instead. For other FDEs we align according to their
1572 1.6 christos encoding, in order to align FDE address range entries naturally. */
1573 1.1 christos offset = 0;
1574 1.6 christos changed = 0;
1575 1.1 christos for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1576 1.1 christos if (!ent->removed)
1577 1.1 christos {
1578 1.6 christos eh_alignment = 4;
1579 1.6 christos if (ent->size == 4)
1580 1.6 christos ;
1581 1.6 christos else if (ent->cie)
1582 1.6 christos {
1583 1.6 christos if (ent->u.cie.per_encoding_aligned8)
1584 1.6 christos eh_alignment = 8;
1585 1.6 christos }
1586 1.6 christos else
1587 1.6 christos {
1588 1.6 christos eh_alignment = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1589 1.6 christos if (eh_alignment < 4)
1590 1.6 christos eh_alignment = 4;
1591 1.6 christos }
1592 1.6 christos offset = (offset + eh_alignment - 1) & -eh_alignment;
1593 1.1 christos ent->new_offset = offset;
1594 1.6 christos if (ent->new_offset != ent->offset)
1595 1.6 christos changed = 1;
1596 1.6 christos offset += size_of_output_cie_fde (ent);
1597 1.1 christos }
1598 1.1 christos
1599 1.6 christos eh_alignment = 4;
1600 1.6 christos offset = (offset + eh_alignment - 1) & -eh_alignment;
1601 1.1 christos sec->rawsize = sec->size;
1602 1.1 christos sec->size = offset;
1603 1.6 christos if (sec->size != sec->rawsize)
1604 1.6 christos changed = 1;
1605 1.6 christos
1606 1.6 christos if (changed && adjust_eh_frame_local_symbols (sec, cookie))
1607 1.6 christos {
1608 1.6 christos Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1609 1.6 christos symtab_hdr->contents = (unsigned char *) cookie->locsyms;
1610 1.6 christos }
1611 1.6 christos return changed;
1612 1.1 christos }
1613 1.1 christos
1614 1.1 christos /* This function is called for .eh_frame_hdr section after
1615 1.1 christos _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
1616 1.1 christos input sections. It finalizes the size of .eh_frame_hdr section. */
1617 1.1 christos
1618 1.1 christos bfd_boolean
1619 1.1 christos _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
1620 1.1 christos {
1621 1.1 christos struct elf_link_hash_table *htab;
1622 1.1 christos struct eh_frame_hdr_info *hdr_info;
1623 1.1 christos asection *sec;
1624 1.1 christos
1625 1.1 christos htab = elf_hash_table (info);
1626 1.1 christos hdr_info = &htab->eh_info;
1627 1.1 christos
1628 1.3 christos if (!hdr_info->frame_hdr_is_compact && hdr_info->u.dwarf.cies != NULL)
1629 1.1 christos {
1630 1.3 christos htab_delete (hdr_info->u.dwarf.cies);
1631 1.3 christos hdr_info->u.dwarf.cies = NULL;
1632 1.1 christos }
1633 1.1 christos
1634 1.1 christos sec = hdr_info->hdr_sec;
1635 1.1 christos if (sec == NULL)
1636 1.1 christos return FALSE;
1637 1.1 christos
1638 1.3 christos if (info->eh_frame_hdr_type == COMPACT_EH_HDR)
1639 1.3 christos {
1640 1.3 christos /* For compact frames we only add the header. The actual table comes
1641 1.6 christos from the .eh_frame_entry sections. */
1642 1.3 christos sec->size = 8;
1643 1.3 christos }
1644 1.3 christos else
1645 1.3 christos {
1646 1.3 christos sec->size = EH_FRAME_HDR_SIZE;
1647 1.3 christos if (hdr_info->u.dwarf.table)
1648 1.3 christos sec->size += 4 + hdr_info->u.dwarf.fde_count * 8;
1649 1.3 christos }
1650 1.1 christos
1651 1.3 christos elf_eh_frame_hdr (abfd) = sec;
1652 1.1 christos return TRUE;
1653 1.1 christos }
1654 1.1 christos
1655 1.1 christos /* Return true if there is at least one non-empty .eh_frame section in
1656 1.1 christos input files. Can only be called after ld has mapped input to
1657 1.1 christos output sections, and before sections are stripped. */
1658 1.3 christos
1659 1.1 christos bfd_boolean
1660 1.1 christos _bfd_elf_eh_frame_present (struct bfd_link_info *info)
1661 1.1 christos {
1662 1.1 christos asection *eh = bfd_get_section_by_name (info->output_bfd, ".eh_frame");
1663 1.1 christos
1664 1.1 christos if (eh == NULL)
1665 1.1 christos return FALSE;
1666 1.1 christos
1667 1.1 christos /* Count only sections which have at least a single CIE or FDE.
1668 1.1 christos There cannot be any CIE or FDE <= 8 bytes. */
1669 1.1 christos for (eh = eh->map_head.s; eh != NULL; eh = eh->map_head.s)
1670 1.1 christos if (eh->size > 8)
1671 1.1 christos return TRUE;
1672 1.1 christos
1673 1.1 christos return FALSE;
1674 1.1 christos }
1675 1.1 christos
1676 1.3 christos /* Return true if there is at least one .eh_frame_entry section in
1677 1.3 christos input files. */
1678 1.3 christos
1679 1.3 christos bfd_boolean
1680 1.3 christos _bfd_elf_eh_frame_entry_present (struct bfd_link_info *info)
1681 1.3 christos {
1682 1.3 christos asection *o;
1683 1.3 christos bfd *abfd;
1684 1.3 christos
1685 1.3 christos for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
1686 1.3 christos {
1687 1.3 christos for (o = abfd->sections; o; o = o->next)
1688 1.3 christos {
1689 1.7 christos const char *name = bfd_section_name (o);
1690 1.3 christos
1691 1.3 christos if (strcmp (name, ".eh_frame_entry")
1692 1.3 christos && !bfd_is_abs_section (o->output_section))
1693 1.3 christos return TRUE;
1694 1.3 christos }
1695 1.3 christos }
1696 1.3 christos return FALSE;
1697 1.3 christos }
1698 1.3 christos
1699 1.1 christos /* This function is called from size_dynamic_sections.
1700 1.1 christos It needs to decide whether .eh_frame_hdr should be output or not,
1701 1.1 christos because when the dynamic symbol table has been sized it is too late
1702 1.1 christos to strip sections. */
1703 1.1 christos
1704 1.1 christos bfd_boolean
1705 1.1 christos _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
1706 1.1 christos {
1707 1.1 christos struct elf_link_hash_table *htab;
1708 1.1 christos struct eh_frame_hdr_info *hdr_info;
1709 1.3 christos struct bfd_link_hash_entry *bh = NULL;
1710 1.3 christos struct elf_link_hash_entry *h;
1711 1.1 christos
1712 1.1 christos htab = elf_hash_table (info);
1713 1.1 christos hdr_info = &htab->eh_info;
1714 1.1 christos if (hdr_info->hdr_sec == NULL)
1715 1.1 christos return TRUE;
1716 1.1 christos
1717 1.1 christos if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)
1718 1.3 christos || info->eh_frame_hdr_type == 0
1719 1.3 christos || (info->eh_frame_hdr_type == DWARF2_EH_HDR
1720 1.3 christos && !_bfd_elf_eh_frame_present (info))
1721 1.3 christos || (info->eh_frame_hdr_type == COMPACT_EH_HDR
1722 1.3 christos && !_bfd_elf_eh_frame_entry_present (info)))
1723 1.1 christos {
1724 1.1 christos hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
1725 1.1 christos hdr_info->hdr_sec = NULL;
1726 1.1 christos return TRUE;
1727 1.1 christos }
1728 1.1 christos
1729 1.3 christos /* Add a hidden symbol so that systems without access to PHDRs can
1730 1.3 christos find the table. */
1731 1.3 christos if (! (_bfd_generic_link_add_one_symbol
1732 1.3 christos (info, info->output_bfd, "__GNU_EH_FRAME_HDR", BSF_LOCAL,
1733 1.3 christos hdr_info->hdr_sec, 0, NULL, FALSE, FALSE, &bh)))
1734 1.3 christos return FALSE;
1735 1.3 christos
1736 1.3 christos h = (struct elf_link_hash_entry *) bh;
1737 1.3 christos h->def_regular = 1;
1738 1.3 christos h->other = STV_HIDDEN;
1739 1.3 christos get_elf_backend_data
1740 1.3 christos (info->output_bfd)->elf_backend_hide_symbol (info, h, TRUE);
1741 1.3 christos
1742 1.3 christos if (!hdr_info->frame_hdr_is_compact)
1743 1.3 christos hdr_info->u.dwarf.table = TRUE;
1744 1.1 christos return TRUE;
1745 1.1 christos }
1746 1.1 christos
1747 1.1 christos /* Adjust an address in the .eh_frame section. Given OFFSET within
1748 1.1 christos SEC, this returns the new offset in the adjusted .eh_frame section,
1749 1.1 christos or -1 if the address refers to a CIE/FDE which has been removed
1750 1.1 christos or to offset with dynamic relocation which is no longer needed. */
1751 1.1 christos
1752 1.1 christos bfd_vma
1753 1.1 christos _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
1754 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
1755 1.1 christos asection *sec,
1756 1.1 christos bfd_vma offset)
1757 1.1 christos {
1758 1.1 christos struct eh_frame_sec_info *sec_info;
1759 1.1 christos unsigned int lo, hi, mid;
1760 1.1 christos
1761 1.1 christos if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
1762 1.1 christos return offset;
1763 1.1 christos sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1764 1.1 christos
1765 1.1 christos if (offset >= sec->rawsize)
1766 1.1 christos return offset - sec->rawsize + sec->size;
1767 1.1 christos
1768 1.1 christos lo = 0;
1769 1.1 christos hi = sec_info->count;
1770 1.1 christos mid = 0;
1771 1.1 christos while (lo < hi)
1772 1.1 christos {
1773 1.1 christos mid = (lo + hi) / 2;
1774 1.1 christos if (offset < sec_info->entry[mid].offset)
1775 1.1 christos hi = mid;
1776 1.1 christos else if (offset
1777 1.1 christos >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
1778 1.1 christos lo = mid + 1;
1779 1.1 christos else
1780 1.1 christos break;
1781 1.1 christos }
1782 1.1 christos
1783 1.1 christos BFD_ASSERT (lo < hi);
1784 1.1 christos
1785 1.1 christos /* FDE or CIE was removed. */
1786 1.1 christos if (sec_info->entry[mid].removed)
1787 1.1 christos return (bfd_vma) -1;
1788 1.1 christos
1789 1.1 christos /* If converting personality pointers to DW_EH_PE_pcrel, there will be
1790 1.1 christos no need for run-time relocation against the personality field. */
1791 1.1 christos if (sec_info->entry[mid].cie
1792 1.1 christos && sec_info->entry[mid].u.cie.make_per_encoding_relative
1793 1.1 christos && offset == (sec_info->entry[mid].offset + 8
1794 1.1 christos + sec_info->entry[mid].u.cie.personality_offset))
1795 1.1 christos return (bfd_vma) -2;
1796 1.1 christos
1797 1.1 christos /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
1798 1.1 christos relocation against FDE's initial_location field. */
1799 1.1 christos if (!sec_info->entry[mid].cie
1800 1.1 christos && sec_info->entry[mid].make_relative
1801 1.1 christos && offset == sec_info->entry[mid].offset + 8)
1802 1.1 christos return (bfd_vma) -2;
1803 1.1 christos
1804 1.1 christos /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
1805 1.1 christos for run-time relocation against LSDA field. */
1806 1.1 christos if (!sec_info->entry[mid].cie
1807 1.1 christos && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
1808 1.1 christos && offset == (sec_info->entry[mid].offset + 8
1809 1.1 christos + sec_info->entry[mid].lsda_offset))
1810 1.1 christos return (bfd_vma) -2;
1811 1.1 christos
1812 1.1 christos /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
1813 1.1 christos relocation against DW_CFA_set_loc's arguments. */
1814 1.1 christos if (sec_info->entry[mid].set_loc
1815 1.1 christos && sec_info->entry[mid].make_relative
1816 1.1 christos && (offset >= sec_info->entry[mid].offset + 8
1817 1.1 christos + sec_info->entry[mid].set_loc[1]))
1818 1.1 christos {
1819 1.1 christos unsigned int cnt;
1820 1.1 christos
1821 1.1 christos for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++)
1822 1.1 christos if (offset == sec_info->entry[mid].offset + 8
1823 1.1 christos + sec_info->entry[mid].set_loc[cnt])
1824 1.1 christos return (bfd_vma) -2;
1825 1.1 christos }
1826 1.1 christos
1827 1.1 christos /* Any new augmentation bytes go before the first relocation. */
1828 1.1 christos return (offset + sec_info->entry[mid].new_offset
1829 1.1 christos - sec_info->entry[mid].offset
1830 1.1 christos + extra_augmentation_string_bytes (sec_info->entry + mid)
1831 1.1 christos + extra_augmentation_data_bytes (sec_info->entry + mid));
1832 1.1 christos }
1833 1.1 christos
1834 1.3 christos /* Write out .eh_frame_entry section. Add CANTUNWIND terminator if needed.
1835 1.3 christos Also check that the contents look sane. */
1836 1.3 christos
1837 1.3 christos bfd_boolean
1838 1.3 christos _bfd_elf_write_section_eh_frame_entry (bfd *abfd, struct bfd_link_info *info,
1839 1.3 christos asection *sec, bfd_byte *contents)
1840 1.3 christos {
1841 1.3 christos const struct elf_backend_data *bed;
1842 1.3 christos bfd_byte cantunwind[8];
1843 1.3 christos bfd_vma addr;
1844 1.3 christos bfd_vma last_addr;
1845 1.3 christos bfd_vma offset;
1846 1.3 christos asection *text_sec = (asection *) elf_section_data (sec)->sec_info;
1847 1.3 christos
1848 1.3 christos if (!sec->rawsize)
1849 1.3 christos sec->rawsize = sec->size;
1850 1.3 christos
1851 1.3 christos BFD_ASSERT (sec->sec_info_type == SEC_INFO_TYPE_EH_FRAME_ENTRY);
1852 1.3 christos
1853 1.3 christos /* Check to make sure that the text section corresponding to this eh_frame_entry
1854 1.3 christos section has not been excluded. In particular, mips16 stub entries will be
1855 1.3 christos excluded outside of the normal process. */
1856 1.3 christos if (sec->flags & SEC_EXCLUDE
1857 1.3 christos || text_sec->flags & SEC_EXCLUDE)
1858 1.3 christos return TRUE;
1859 1.3 christos
1860 1.3 christos if (!bfd_set_section_contents (abfd, sec->output_section, contents,
1861 1.3 christos sec->output_offset, sec->rawsize))
1862 1.3 christos return FALSE;
1863 1.3 christos
1864 1.3 christos last_addr = bfd_get_signed_32 (abfd, contents);
1865 1.3 christos /* Check that all the entries are in order. */
1866 1.3 christos for (offset = 8; offset < sec->rawsize; offset += 8)
1867 1.3 christos {
1868 1.3 christos addr = bfd_get_signed_32 (abfd, contents + offset) + offset;
1869 1.3 christos if (addr <= last_addr)
1870 1.3 christos {
1871 1.6 christos /* xgettext:c-format */
1872 1.6 christos _bfd_error_handler (_("%pB: %pA not in order"), sec->owner, sec);
1873 1.3 christos return FALSE;
1874 1.3 christos }
1875 1.3 christos
1876 1.3 christos last_addr = addr;
1877 1.3 christos }
1878 1.3 christos
1879 1.3 christos addr = text_sec->output_section->vma + text_sec->output_offset
1880 1.3 christos + text_sec->size;
1881 1.3 christos addr &= ~1;
1882 1.3 christos addr -= (sec->output_section->vma + sec->output_offset + sec->rawsize);
1883 1.3 christos if (addr & 1)
1884 1.3 christos {
1885 1.6 christos /* xgettext:c-format */
1886 1.6 christos _bfd_error_handler (_("%pB: %pA invalid input section size"),
1887 1.6 christos sec->owner, sec);
1888 1.3 christos bfd_set_error (bfd_error_bad_value);
1889 1.3 christos return FALSE;
1890 1.3 christos }
1891 1.3 christos if (last_addr >= addr + sec->rawsize)
1892 1.3 christos {
1893 1.6 christos /* xgettext:c-format */
1894 1.6 christos _bfd_error_handler (_("%pB: %pA points past end of text section"),
1895 1.6 christos sec->owner, sec);
1896 1.3 christos bfd_set_error (bfd_error_bad_value);
1897 1.3 christos return FALSE;
1898 1.3 christos }
1899 1.3 christos
1900 1.3 christos if (sec->size == sec->rawsize)
1901 1.3 christos return TRUE;
1902 1.3 christos
1903 1.3 christos bed = get_elf_backend_data (abfd);
1904 1.3 christos BFD_ASSERT (sec->size == sec->rawsize + 8);
1905 1.3 christos BFD_ASSERT ((addr & 1) == 0);
1906 1.3 christos BFD_ASSERT (bed->cant_unwind_opcode);
1907 1.3 christos
1908 1.3 christos bfd_put_32 (abfd, addr, cantunwind);
1909 1.3 christos bfd_put_32 (abfd, (*bed->cant_unwind_opcode) (info), cantunwind + 4);
1910 1.3 christos return bfd_set_section_contents (abfd, sec->output_section, cantunwind,
1911 1.3 christos sec->output_offset + sec->rawsize, 8);
1912 1.3 christos }
1913 1.3 christos
1914 1.1 christos /* Write out .eh_frame section. This is called with the relocated
1915 1.1 christos contents. */
1916 1.1 christos
1917 1.1 christos bfd_boolean
1918 1.1 christos _bfd_elf_write_section_eh_frame (bfd *abfd,
1919 1.1 christos struct bfd_link_info *info,
1920 1.1 christos asection *sec,
1921 1.1 christos bfd_byte *contents)
1922 1.1 christos {
1923 1.1 christos struct eh_frame_sec_info *sec_info;
1924 1.1 christos struct elf_link_hash_table *htab;
1925 1.1 christos struct eh_frame_hdr_info *hdr_info;
1926 1.1 christos unsigned int ptr_size;
1927 1.6 christos struct eh_cie_fde *ent, *last_ent;
1928 1.1 christos
1929 1.1 christos if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
1930 1.1 christos /* FIXME: octets_per_byte. */
1931 1.1 christos return bfd_set_section_contents (abfd, sec->output_section, contents,
1932 1.1 christos sec->output_offset, sec->size);
1933 1.1 christos
1934 1.1 christos ptr_size = (get_elf_backend_data (abfd)
1935 1.1 christos ->elf_backend_eh_frame_address_size (abfd, sec));
1936 1.1 christos BFD_ASSERT (ptr_size != 0);
1937 1.1 christos
1938 1.1 christos sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1939 1.1 christos htab = elf_hash_table (info);
1940 1.1 christos hdr_info = &htab->eh_info;
1941 1.1 christos
1942 1.3 christos if (hdr_info->u.dwarf.table && hdr_info->u.dwarf.array == NULL)
1943 1.3 christos {
1944 1.3 christos hdr_info->frame_hdr_is_compact = FALSE;
1945 1.3 christos hdr_info->u.dwarf.array = (struct eh_frame_array_ent *)
1946 1.6 christos bfd_malloc (hdr_info->u.dwarf.fde_count
1947 1.3 christos * sizeof (*hdr_info->u.dwarf.array));
1948 1.3 christos }
1949 1.3 christos if (hdr_info->u.dwarf.array == NULL)
1950 1.1 christos hdr_info = NULL;
1951 1.1 christos
1952 1.1 christos /* The new offsets can be bigger or smaller than the original offsets.
1953 1.1 christos We therefore need to make two passes over the section: one backward
1954 1.1 christos pass to move entries up and one forward pass to move entries down.
1955 1.1 christos The two passes won't interfere with each other because entries are
1956 1.1 christos not reordered */
1957 1.1 christos for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
1958 1.1 christos if (!ent->removed && ent->new_offset > ent->offset)
1959 1.1 christos memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
1960 1.1 christos
1961 1.1 christos for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1962 1.1 christos if (!ent->removed && ent->new_offset < ent->offset)
1963 1.1 christos memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
1964 1.1 christos
1965 1.6 christos last_ent = sec_info->entry + sec_info->count;
1966 1.6 christos for (ent = sec_info->entry; ent < last_ent; ++ent)
1967 1.1 christos {
1968 1.1 christos unsigned char *buf, *end;
1969 1.1 christos unsigned int new_size;
1970 1.1 christos
1971 1.1 christos if (ent->removed)
1972 1.1 christos continue;
1973 1.1 christos
1974 1.1 christos if (ent->size == 4)
1975 1.1 christos {
1976 1.1 christos /* Any terminating FDE must be at the end of the section. */
1977 1.6 christos BFD_ASSERT (ent == last_ent - 1);
1978 1.1 christos continue;
1979 1.1 christos }
1980 1.1 christos
1981 1.1 christos buf = contents + ent->new_offset;
1982 1.1 christos end = buf + ent->size;
1983 1.6 christos new_size = next_cie_fde_offset (ent, last_ent, sec) - ent->new_offset;
1984 1.1 christos
1985 1.1 christos /* Update the size. It may be shrinked. */
1986 1.1 christos bfd_put_32 (abfd, new_size - 4, buf);
1987 1.1 christos
1988 1.1 christos /* Filling the extra bytes with DW_CFA_nops. */
1989 1.1 christos if (new_size != ent->size)
1990 1.1 christos memset (end, 0, new_size - ent->size);
1991 1.1 christos
1992 1.1 christos if (ent->cie)
1993 1.1 christos {
1994 1.1 christos /* CIE */
1995 1.1 christos if (ent->make_relative
1996 1.1 christos || ent->u.cie.make_lsda_relative
1997 1.1 christos || ent->u.cie.per_encoding_relative)
1998 1.1 christos {
1999 1.1 christos char *aug;
2000 1.7 christos unsigned int version, action, extra_string, extra_data;
2001 1.1 christos unsigned int per_width, per_encoding;
2002 1.1 christos
2003 1.1 christos /* Need to find 'R' or 'L' augmentation's argument and modify
2004 1.1 christos DW_EH_PE_* value. */
2005 1.1 christos action = ((ent->make_relative ? 1 : 0)
2006 1.1 christos | (ent->u.cie.make_lsda_relative ? 2 : 0)
2007 1.1 christos | (ent->u.cie.per_encoding_relative ? 4 : 0));
2008 1.1 christos extra_string = extra_augmentation_string_bytes (ent);
2009 1.1 christos extra_data = extra_augmentation_data_bytes (ent);
2010 1.1 christos
2011 1.7 christos /* Skip length, id. */
2012 1.7 christos buf += 8;
2013 1.7 christos version = *buf++;
2014 1.1 christos aug = (char *) buf;
2015 1.1 christos buf += strlen (aug) + 1;
2016 1.1 christos skip_leb128 (&buf, end);
2017 1.1 christos skip_leb128 (&buf, end);
2018 1.7 christos if (version == 1)
2019 1.7 christos skip_bytes (&buf, end, 1);
2020 1.7 christos else
2021 1.7 christos skip_leb128 (&buf, end);
2022 1.1 christos if (*aug == 'z')
2023 1.1 christos {
2024 1.1 christos /* The uleb128 will always be a single byte for the kind
2025 1.1 christos of augmentation strings that we're prepared to handle. */
2026 1.1 christos *buf++ += extra_data;
2027 1.1 christos aug++;
2028 1.1 christos }
2029 1.1 christos
2030 1.1 christos /* Make room for the new augmentation string and data bytes. */
2031 1.1 christos memmove (buf + extra_string + extra_data, buf, end - buf);
2032 1.1 christos memmove (aug + extra_string, aug, buf - (bfd_byte *) aug);
2033 1.1 christos buf += extra_string;
2034 1.1 christos end += extra_string + extra_data;
2035 1.1 christos
2036 1.1 christos if (ent->add_augmentation_size)
2037 1.1 christos {
2038 1.1 christos *aug++ = 'z';
2039 1.1 christos *buf++ = extra_data - 1;
2040 1.1 christos }
2041 1.1 christos if (ent->u.cie.add_fde_encoding)
2042 1.1 christos {
2043 1.1 christos BFD_ASSERT (action & 1);
2044 1.1 christos *aug++ = 'R';
2045 1.1 christos *buf++ = make_pc_relative (DW_EH_PE_absptr, ptr_size);
2046 1.1 christos action &= ~1;
2047 1.1 christos }
2048 1.1 christos
2049 1.1 christos while (action)
2050 1.1 christos switch (*aug++)
2051 1.1 christos {
2052 1.1 christos case 'L':
2053 1.1 christos if (action & 2)
2054 1.1 christos {
2055 1.1 christos BFD_ASSERT (*buf == ent->lsda_encoding);
2056 1.1 christos *buf = make_pc_relative (*buf, ptr_size);
2057 1.1 christos action &= ~2;
2058 1.1 christos }
2059 1.1 christos buf++;
2060 1.1 christos break;
2061 1.1 christos case 'P':
2062 1.1 christos if (ent->u.cie.make_per_encoding_relative)
2063 1.1 christos *buf = make_pc_relative (*buf, ptr_size);
2064 1.1 christos per_encoding = *buf++;
2065 1.1 christos per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
2066 1.1 christos BFD_ASSERT (per_width != 0);
2067 1.1 christos BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
2068 1.1 christos == ent->u.cie.per_encoding_relative);
2069 1.1 christos if ((per_encoding & 0x70) == DW_EH_PE_aligned)
2070 1.1 christos buf = (contents
2071 1.1 christos + ((buf - contents + per_width - 1)
2072 1.1 christos & ~((bfd_size_type) per_width - 1)));
2073 1.1 christos if (action & 4)
2074 1.1 christos {
2075 1.1 christos bfd_vma val;
2076 1.1 christos
2077 1.1 christos val = read_value (abfd, buf, per_width,
2078 1.1 christos get_DW_EH_PE_signed (per_encoding));
2079 1.1 christos if (ent->u.cie.make_per_encoding_relative)
2080 1.1 christos val -= (sec->output_section->vma
2081 1.1 christos + sec->output_offset
2082 1.1 christos + (buf - contents));
2083 1.1 christos else
2084 1.1 christos {
2085 1.1 christos val += (bfd_vma) ent->offset - ent->new_offset;
2086 1.1 christos val -= extra_string + extra_data;
2087 1.1 christos }
2088 1.1 christos write_value (abfd, buf, val, per_width);
2089 1.1 christos action &= ~4;
2090 1.1 christos }
2091 1.1 christos buf += per_width;
2092 1.1 christos break;
2093 1.1 christos case 'R':
2094 1.1 christos if (action & 1)
2095 1.1 christos {
2096 1.1 christos BFD_ASSERT (*buf == ent->fde_encoding);
2097 1.1 christos *buf = make_pc_relative (*buf, ptr_size);
2098 1.1 christos action &= ~1;
2099 1.1 christos }
2100 1.1 christos buf++;
2101 1.1 christos break;
2102 1.1 christos case 'S':
2103 1.1 christos break;
2104 1.1 christos default:
2105 1.1 christos BFD_FAIL ();
2106 1.1 christos }
2107 1.1 christos }
2108 1.1 christos }
2109 1.1 christos else
2110 1.1 christos {
2111 1.1 christos /* FDE */
2112 1.1 christos bfd_vma value, address;
2113 1.1 christos unsigned int width;
2114 1.1 christos bfd_byte *start;
2115 1.1 christos struct eh_cie_fde *cie;
2116 1.1 christos
2117 1.1 christos /* Skip length. */
2118 1.1 christos cie = ent->u.fde.cie_inf;
2119 1.1 christos buf += 4;
2120 1.1 christos value = ((ent->new_offset + sec->output_offset + 4)
2121 1.1 christos - (cie->new_offset + cie->u.cie.u.sec->output_offset));
2122 1.1 christos bfd_put_32 (abfd, value, buf);
2123 1.3 christos if (bfd_link_relocatable (info))
2124 1.3 christos continue;
2125 1.1 christos buf += 4;
2126 1.1 christos width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
2127 1.1 christos value = read_value (abfd, buf, width,
2128 1.1 christos get_DW_EH_PE_signed (ent->fde_encoding));
2129 1.1 christos address = value;
2130 1.1 christos if (value)
2131 1.1 christos {
2132 1.1 christos switch (ent->fde_encoding & 0x70)
2133 1.1 christos {
2134 1.1 christos case DW_EH_PE_textrel:
2135 1.1 christos BFD_ASSERT (hdr_info == NULL);
2136 1.1 christos break;
2137 1.1 christos case DW_EH_PE_datarel:
2138 1.1 christos {
2139 1.1 christos switch (abfd->arch_info->arch)
2140 1.1 christos {
2141 1.1 christos case bfd_arch_ia64:
2142 1.1 christos BFD_ASSERT (elf_gp (abfd) != 0);
2143 1.1 christos address += elf_gp (abfd);
2144 1.1 christos break;
2145 1.1 christos default:
2146 1.6 christos _bfd_error_handler
2147 1.6 christos (_("DW_EH_PE_datarel unspecified"
2148 1.6 christos " for this architecture"));
2149 1.1 christos /* Fall thru */
2150 1.1 christos case bfd_arch_frv:
2151 1.1 christos case bfd_arch_i386:
2152 1.1 christos BFD_ASSERT (htab->hgot != NULL
2153 1.1 christos && ((htab->hgot->root.type
2154 1.1 christos == bfd_link_hash_defined)
2155 1.1 christos || (htab->hgot->root.type
2156 1.1 christos == bfd_link_hash_defweak)));
2157 1.1 christos address
2158 1.1 christos += (htab->hgot->root.u.def.value
2159 1.1 christos + htab->hgot->root.u.def.section->output_offset
2160 1.1 christos + (htab->hgot->root.u.def.section->output_section
2161 1.1 christos ->vma));
2162 1.1 christos break;
2163 1.1 christos }
2164 1.1 christos }
2165 1.1 christos break;
2166 1.1 christos case DW_EH_PE_pcrel:
2167 1.1 christos value += (bfd_vma) ent->offset - ent->new_offset;
2168 1.1 christos address += (sec->output_section->vma
2169 1.1 christos + sec->output_offset
2170 1.1 christos + ent->offset + 8);
2171 1.1 christos break;
2172 1.1 christos }
2173 1.1 christos if (ent->make_relative)
2174 1.1 christos value -= (sec->output_section->vma
2175 1.1 christos + sec->output_offset
2176 1.1 christos + ent->new_offset + 8);
2177 1.1 christos write_value (abfd, buf, value, width);
2178 1.1 christos }
2179 1.1 christos
2180 1.1 christos start = buf;
2181 1.1 christos
2182 1.1 christos if (hdr_info)
2183 1.1 christos {
2184 1.1 christos /* The address calculation may overflow, giving us a
2185 1.1 christos value greater than 4G on a 32-bit target when
2186 1.1 christos dwarf_vma is 64-bit. */
2187 1.1 christos if (sizeof (address) > 4 && ptr_size == 4)
2188 1.1 christos address &= 0xffffffff;
2189 1.3 christos hdr_info->u.dwarf.array[hdr_info->array_count].initial_loc
2190 1.3 christos = address;
2191 1.3 christos hdr_info->u.dwarf.array[hdr_info->array_count].range
2192 1.3 christos = read_value (abfd, buf + width, width, FALSE);
2193 1.3 christos hdr_info->u.dwarf.array[hdr_info->array_count++].fde
2194 1.1 christos = (sec->output_section->vma
2195 1.1 christos + sec->output_offset
2196 1.1 christos + ent->new_offset);
2197 1.1 christos }
2198 1.1 christos
2199 1.1 christos if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel
2200 1.1 christos || cie->u.cie.make_lsda_relative)
2201 1.1 christos {
2202 1.1 christos buf += ent->lsda_offset;
2203 1.1 christos width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
2204 1.1 christos value = read_value (abfd, buf, width,
2205 1.1 christos get_DW_EH_PE_signed (ent->lsda_encoding));
2206 1.1 christos if (value)
2207 1.1 christos {
2208 1.1 christos if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
2209 1.1 christos value += (bfd_vma) ent->offset - ent->new_offset;
2210 1.1 christos else if (cie->u.cie.make_lsda_relative)
2211 1.1 christos value -= (sec->output_section->vma
2212 1.1 christos + sec->output_offset
2213 1.1 christos + ent->new_offset + 8 + ent->lsda_offset);
2214 1.1 christos write_value (abfd, buf, value, width);
2215 1.1 christos }
2216 1.1 christos }
2217 1.1 christos else if (ent->add_augmentation_size)
2218 1.1 christos {
2219 1.1 christos /* Skip the PC and length and insert a zero byte for the
2220 1.1 christos augmentation size. */
2221 1.1 christos buf += width * 2;
2222 1.1 christos memmove (buf + 1, buf, end - buf);
2223 1.1 christos *buf = 0;
2224 1.1 christos }
2225 1.1 christos
2226 1.1 christos if (ent->set_loc)
2227 1.1 christos {
2228 1.1 christos /* Adjust DW_CFA_set_loc. */
2229 1.1 christos unsigned int cnt;
2230 1.1 christos bfd_vma new_offset;
2231 1.1 christos
2232 1.1 christos width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
2233 1.1 christos new_offset = ent->new_offset + 8
2234 1.1 christos + extra_augmentation_string_bytes (ent)
2235 1.1 christos + extra_augmentation_data_bytes (ent);
2236 1.1 christos
2237 1.1 christos for (cnt = 1; cnt <= ent->set_loc[0]; cnt++)
2238 1.1 christos {
2239 1.1 christos buf = start + ent->set_loc[cnt];
2240 1.1 christos
2241 1.1 christos value = read_value (abfd, buf, width,
2242 1.1 christos get_DW_EH_PE_signed (ent->fde_encoding));
2243 1.1 christos if (!value)
2244 1.1 christos continue;
2245 1.1 christos
2246 1.1 christos if ((ent->fde_encoding & 0x70) == DW_EH_PE_pcrel)
2247 1.1 christos value += (bfd_vma) ent->offset + 8 - new_offset;
2248 1.1 christos if (ent->make_relative)
2249 1.1 christos value -= (sec->output_section->vma
2250 1.1 christos + sec->output_offset
2251 1.1 christos + new_offset + ent->set_loc[cnt]);
2252 1.1 christos write_value (abfd, buf, value, width);
2253 1.1 christos }
2254 1.1 christos }
2255 1.1 christos }
2256 1.1 christos }
2257 1.1 christos
2258 1.1 christos /* FIXME: octets_per_byte. */
2259 1.1 christos return bfd_set_section_contents (abfd, sec->output_section,
2260 1.1 christos contents, (file_ptr) sec->output_offset,
2261 1.1 christos sec->size);
2262 1.1 christos }
2263 1.1 christos
2264 1.1 christos /* Helper function used to sort .eh_frame_hdr search table by increasing
2265 1.1 christos VMA of FDE initial location. */
2266 1.1 christos
2267 1.1 christos static int
2268 1.1 christos vma_compare (const void *a, const void *b)
2269 1.1 christos {
2270 1.1 christos const struct eh_frame_array_ent *p = (const struct eh_frame_array_ent *) a;
2271 1.1 christos const struct eh_frame_array_ent *q = (const struct eh_frame_array_ent *) b;
2272 1.1 christos if (p->initial_loc > q->initial_loc)
2273 1.1 christos return 1;
2274 1.1 christos if (p->initial_loc < q->initial_loc)
2275 1.1 christos return -1;
2276 1.3 christos if (p->range > q->range)
2277 1.3 christos return 1;
2278 1.3 christos if (p->range < q->range)
2279 1.3 christos return -1;
2280 1.1 christos return 0;
2281 1.1 christos }
2282 1.1 christos
2283 1.3 christos /* Reorder .eh_frame_entry sections to match the associated text sections.
2284 1.3 christos This routine is called during the final linking step, just before writing
2285 1.3 christos the contents. At this stage, sections in the eh_frame_hdr_info are already
2286 1.3 christos sorted in order of increasing text section address and so we simply need
2287 1.3 christos to make the .eh_frame_entrys follow that same order. Note that it is
2288 1.3 christos invalid for a linker script to try to force a particular order of
2289 1.3 christos .eh_frame_entry sections. */
2290 1.3 christos
2291 1.3 christos bfd_boolean
2292 1.3 christos _bfd_elf_fixup_eh_frame_hdr (struct bfd_link_info *info)
2293 1.3 christos {
2294 1.3 christos asection *sec = NULL;
2295 1.3 christos asection *osec;
2296 1.3 christos struct eh_frame_hdr_info *hdr_info;
2297 1.3 christos unsigned int i;
2298 1.3 christos bfd_vma offset;
2299 1.3 christos struct bfd_link_order *p;
2300 1.3 christos
2301 1.3 christos hdr_info = &elf_hash_table (info)->eh_info;
2302 1.3 christos
2303 1.3 christos if (hdr_info->hdr_sec == NULL
2304 1.3 christos || info->eh_frame_hdr_type != COMPACT_EH_HDR
2305 1.3 christos || hdr_info->array_count == 0)
2306 1.3 christos return TRUE;
2307 1.3 christos
2308 1.3 christos /* Change section output offsets to be in text section order. */
2309 1.3 christos offset = 8;
2310 1.3 christos osec = hdr_info->u.compact.entries[0]->output_section;
2311 1.3 christos for (i = 0; i < hdr_info->array_count; i++)
2312 1.3 christos {
2313 1.3 christos sec = hdr_info->u.compact.entries[i];
2314 1.3 christos if (sec->output_section != osec)
2315 1.3 christos {
2316 1.6 christos _bfd_error_handler
2317 1.6 christos (_("invalid output section for .eh_frame_entry: %pA"),
2318 1.6 christos sec->output_section);
2319 1.3 christos return FALSE;
2320 1.3 christos }
2321 1.3 christos sec->output_offset = offset;
2322 1.3 christos offset += sec->size;
2323 1.3 christos }
2324 1.3 christos
2325 1.3 christos
2326 1.3 christos /* Fix the link_order to match. */
2327 1.3 christos for (p = sec->output_section->map_head.link_order; p != NULL; p = p->next)
2328 1.3 christos {
2329 1.3 christos if (p->type != bfd_indirect_link_order)
2330 1.3 christos abort();
2331 1.3 christos
2332 1.3 christos p->offset = p->u.indirect.section->output_offset;
2333 1.3 christos if (p->next != NULL)
2334 1.6 christos i--;
2335 1.3 christos }
2336 1.3 christos
2337 1.3 christos if (i != 0)
2338 1.3 christos {
2339 1.6 christos _bfd_error_handler
2340 1.6 christos (_("invalid contents in %pA section"), osec);
2341 1.3 christos return FALSE;
2342 1.3 christos }
2343 1.3 christos
2344 1.3 christos return TRUE;
2345 1.3 christos }
2346 1.3 christos
2347 1.3 christos /* The .eh_frame_hdr format for Compact EH frames:
2348 1.3 christos ubyte version (2)
2349 1.3 christos ubyte eh_ref_enc (DW_EH_PE_* encoding of typinfo references)
2350 1.3 christos uint32_t count (Number of entries in table)
2351 1.3 christos [array from .eh_frame_entry sections] */
2352 1.3 christos
2353 1.3 christos static bfd_boolean
2354 1.3 christos write_compact_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
2355 1.3 christos {
2356 1.3 christos struct elf_link_hash_table *htab;
2357 1.3 christos struct eh_frame_hdr_info *hdr_info;
2358 1.3 christos asection *sec;
2359 1.3 christos const struct elf_backend_data *bed;
2360 1.3 christos bfd_vma count;
2361 1.3 christos bfd_byte contents[8];
2362 1.3 christos unsigned int i;
2363 1.3 christos
2364 1.3 christos htab = elf_hash_table (info);
2365 1.3 christos hdr_info = &htab->eh_info;
2366 1.3 christos sec = hdr_info->hdr_sec;
2367 1.3 christos
2368 1.3 christos if (sec->size != 8)
2369 1.3 christos abort();
2370 1.3 christos
2371 1.3 christos for (i = 0; i < sizeof (contents); i++)
2372 1.3 christos contents[i] = 0;
2373 1.3 christos
2374 1.3 christos contents[0] = COMPACT_EH_HDR;
2375 1.3 christos bed = get_elf_backend_data (abfd);
2376 1.3 christos
2377 1.3 christos BFD_ASSERT (bed->compact_eh_encoding);
2378 1.3 christos contents[1] = (*bed->compact_eh_encoding) (info);
2379 1.3 christos
2380 1.3 christos count = (sec->output_section->size - 8) / 8;
2381 1.3 christos bfd_put_32 (abfd, count, contents + 4);
2382 1.3 christos return bfd_set_section_contents (abfd, sec->output_section, contents,
2383 1.3 christos (file_ptr) sec->output_offset, sec->size);
2384 1.3 christos }
2385 1.3 christos
2386 1.3 christos /* The .eh_frame_hdr format for DWARF frames:
2387 1.3 christos
2388 1.1 christos ubyte version (currently 1)
2389 1.6 christos ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
2390 1.1 christos .eh_frame section)
2391 1.1 christos ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
2392 1.1 christos number (or DW_EH_PE_omit if there is no
2393 1.1 christos binary search table computed))
2394 1.1 christos ubyte table_enc (DW_EH_PE_* encoding of binary search table,
2395 1.1 christos or DW_EH_PE_omit if not present.
2396 1.1 christos DW_EH_PE_datarel is using address of
2397 1.1 christos .eh_frame_hdr section start as base)
2398 1.1 christos [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
2399 1.1 christos optionally followed by:
2400 1.1 christos [encoded] fde_count (total number of FDEs in .eh_frame section)
2401 1.1 christos fde_count x [encoded] initial_loc, fde
2402 1.1 christos (array of encoded pairs containing
2403 1.1 christos FDE initial_location field and FDE address,
2404 1.1 christos sorted by increasing initial_loc). */
2405 1.1 christos
2406 1.3 christos static bfd_boolean
2407 1.3 christos write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
2408 1.1 christos {
2409 1.1 christos struct elf_link_hash_table *htab;
2410 1.1 christos struct eh_frame_hdr_info *hdr_info;
2411 1.1 christos asection *sec;
2412 1.3 christos bfd_boolean retval = TRUE;
2413 1.3 christos
2414 1.3 christos htab = elf_hash_table (info);
2415 1.3 christos hdr_info = &htab->eh_info;
2416 1.3 christos sec = hdr_info->hdr_sec;
2417 1.1 christos bfd_byte *contents;
2418 1.1 christos asection *eh_frame_sec;
2419 1.1 christos bfd_size_type size;
2420 1.1 christos bfd_vma encoded_eh_frame;
2421 1.1 christos
2422 1.1 christos size = EH_FRAME_HDR_SIZE;
2423 1.3 christos if (hdr_info->u.dwarf.array
2424 1.3 christos && hdr_info->array_count == hdr_info->u.dwarf.fde_count)
2425 1.3 christos size += 4 + hdr_info->u.dwarf.fde_count * 8;
2426 1.1 christos contents = (bfd_byte *) bfd_malloc (size);
2427 1.1 christos if (contents == NULL)
2428 1.1 christos return FALSE;
2429 1.1 christos
2430 1.1 christos eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
2431 1.1 christos if (eh_frame_sec == NULL)
2432 1.1 christos {
2433 1.1 christos free (contents);
2434 1.1 christos return FALSE;
2435 1.1 christos }
2436 1.1 christos
2437 1.1 christos memset (contents, 0, EH_FRAME_HDR_SIZE);
2438 1.3 christos /* Version. */
2439 1.3 christos contents[0] = 1;
2440 1.3 christos /* .eh_frame offset. */
2441 1.1 christos contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
2442 1.3 christos (abfd, info, eh_frame_sec, 0, sec, 4, &encoded_eh_frame);
2443 1.1 christos
2444 1.3 christos if (hdr_info->u.dwarf.array
2445 1.3 christos && hdr_info->array_count == hdr_info->u.dwarf.fde_count)
2446 1.1 christos {
2447 1.3 christos /* FDE count encoding. */
2448 1.3 christos contents[2] = DW_EH_PE_udata4;
2449 1.3 christos /* Search table encoding. */
2450 1.3 christos contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
2451 1.1 christos }
2452 1.1 christos else
2453 1.1 christos {
2454 1.1 christos contents[2] = DW_EH_PE_omit;
2455 1.1 christos contents[3] = DW_EH_PE_omit;
2456 1.1 christos }
2457 1.1 christos bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
2458 1.1 christos
2459 1.1 christos if (contents[2] != DW_EH_PE_omit)
2460 1.1 christos {
2461 1.1 christos unsigned int i;
2462 1.3 christos bfd_boolean overlap, overflow;
2463 1.1 christos
2464 1.3 christos bfd_put_32 (abfd, hdr_info->u.dwarf.fde_count,
2465 1.3 christos contents + EH_FRAME_HDR_SIZE);
2466 1.3 christos qsort (hdr_info->u.dwarf.array, hdr_info->u.dwarf.fde_count,
2467 1.3 christos sizeof (*hdr_info->u.dwarf.array), vma_compare);
2468 1.3 christos overlap = FALSE;
2469 1.3 christos overflow = FALSE;
2470 1.3 christos for (i = 0; i < hdr_info->u.dwarf.fde_count; i++)
2471 1.3 christos {
2472 1.3 christos bfd_vma val;
2473 1.3 christos
2474 1.3 christos val = hdr_info->u.dwarf.array[i].initial_loc
2475 1.3 christos - sec->output_section->vma;
2476 1.3 christos val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
2477 1.3 christos if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64
2478 1.3 christos && (hdr_info->u.dwarf.array[i].initial_loc
2479 1.3 christos != sec->output_section->vma + val))
2480 1.3 christos overflow = TRUE;
2481 1.3 christos bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
2482 1.3 christos val = hdr_info->u.dwarf.array[i].fde - sec->output_section->vma;
2483 1.3 christos val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
2484 1.3 christos if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64
2485 1.3 christos && (hdr_info->u.dwarf.array[i].fde
2486 1.3 christos != sec->output_section->vma + val))
2487 1.3 christos overflow = TRUE;
2488 1.3 christos bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
2489 1.3 christos if (i != 0
2490 1.3 christos && (hdr_info->u.dwarf.array[i].initial_loc
2491 1.3 christos < (hdr_info->u.dwarf.array[i - 1].initial_loc
2492 1.3 christos + hdr_info->u.dwarf.array[i - 1].range)))
2493 1.3 christos overlap = TRUE;
2494 1.3 christos }
2495 1.3 christos if (overflow)
2496 1.6 christos _bfd_error_handler (_(".eh_frame_hdr entry overflow"));
2497 1.3 christos if (overlap)
2498 1.6 christos _bfd_error_handler (_(".eh_frame_hdr refers to overlapping FDEs"));
2499 1.3 christos if (overflow || overlap)
2500 1.1 christos {
2501 1.3 christos bfd_set_error (bfd_error_bad_value);
2502 1.3 christos retval = FALSE;
2503 1.1 christos }
2504 1.1 christos }
2505 1.1 christos
2506 1.1 christos /* FIXME: octets_per_byte. */
2507 1.3 christos if (!bfd_set_section_contents (abfd, sec->output_section, contents,
2508 1.3 christos (file_ptr) sec->output_offset,
2509 1.3 christos sec->size))
2510 1.3 christos retval = FALSE;
2511 1.1 christos free (contents);
2512 1.3 christos
2513 1.3 christos if (hdr_info->u.dwarf.array != NULL)
2514 1.3 christos free (hdr_info->u.dwarf.array);
2515 1.1 christos return retval;
2516 1.1 christos }
2517 1.1 christos
2518 1.3 christos /* Write out .eh_frame_hdr section. This must be called after
2519 1.3 christos _bfd_elf_write_section_eh_frame has been called on all input
2520 1.3 christos .eh_frame sections. */
2521 1.3 christos
2522 1.3 christos bfd_boolean
2523 1.3 christos _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
2524 1.3 christos {
2525 1.3 christos struct elf_link_hash_table *htab;
2526 1.3 christos struct eh_frame_hdr_info *hdr_info;
2527 1.3 christos asection *sec;
2528 1.3 christos
2529 1.3 christos htab = elf_hash_table (info);
2530 1.3 christos hdr_info = &htab->eh_info;
2531 1.3 christos sec = hdr_info->hdr_sec;
2532 1.3 christos
2533 1.3 christos if (info->eh_frame_hdr_type == 0 || sec == NULL)
2534 1.3 christos return TRUE;
2535 1.3 christos
2536 1.3 christos if (info->eh_frame_hdr_type == COMPACT_EH_HDR)
2537 1.3 christos return write_compact_eh_frame_hdr (abfd, info);
2538 1.3 christos else
2539 1.3 christos return write_dwarf_eh_frame_hdr (abfd, info);
2540 1.3 christos }
2541 1.3 christos
2542 1.1 christos /* Return the width of FDE addresses. This is the default implementation. */
2543 1.1 christos
2544 1.1 christos unsigned int
2545 1.6 christos _bfd_elf_eh_frame_address_size (bfd *abfd, const asection *sec ATTRIBUTE_UNUSED)
2546 1.1 christos {
2547 1.1 christos return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
2548 1.1 christos }
2549 1.1 christos
2550 1.1 christos /* Decide whether we can use a PC-relative encoding within the given
2551 1.1 christos EH frame section. This is the default implementation. */
2552 1.1 christos
2553 1.1 christos bfd_boolean
2554 1.1 christos _bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
2555 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
2556 1.1 christos asection *eh_frame_section ATTRIBUTE_UNUSED)
2557 1.1 christos {
2558 1.1 christos return TRUE;
2559 1.1 christos }
2560 1.1 christos
2561 1.1 christos /* Select an encoding for the given address. Preference is given to
2562 1.1 christos PC-relative addressing modes. */
2563 1.1 christos
2564 1.1 christos bfd_byte
2565 1.1 christos _bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
2566 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
2567 1.1 christos asection *osec, bfd_vma offset,
2568 1.1 christos asection *loc_sec, bfd_vma loc_offset,
2569 1.1 christos bfd_vma *encoded)
2570 1.1 christos {
2571 1.1 christos *encoded = osec->vma + offset -
2572 1.1 christos (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
2573 1.1 christos return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
2574 1.1 christos }
2575