Print this page
3265 link-editor builds bogus .eh_frame_hdr on ia32
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/libld/common/unwind.c
+++ new/usr/src/cmd/sgs/libld/common/unwind.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 #include <string.h>
27 27 #include <stdio.h>
28 28 #include <sys/types.h>
29 29 #include <sgs.h>
30 30 #include <debug.h>
31 31 #include <_libld.h>
32 32 #include <dwarf.h>
33 33 #include <stdlib.h>
34 34
35 35 /*
36 36 * A EH_FRAME_HDR consists of the following:
37 37 *
38 38 * Encoding Field
39 39 * --------------------------------
40 40 * unsigned byte version
41 41 * unsigned byte eh_frame_ptr_enc
42 42 * unsigned byte fde_count_enc
43 43 * unsigned byte table_enc
44 44 * encoded eh_frame_ptr
45 45 * encoded fde_count
46 46 * [ binary search table ]
47 47 *
48 48 * The binary search table entries each consists of:
49 49 *
50 50 * encoded initial_func_loc
51 51 * encoded FDE_address
52 52 *
53 53 * The entries in the binary search table are sorted
54 54 * in a increasing order by the initial location.
55 55 *
56 56 *
57 57 * version
58 58 *
59 59 * Version of the .eh_frame_hdr format. This value shall be 1.
60 60 *
61 61 * eh_frame_ptr_enc
62 62 *
63 63 * The encoding format of the eh_frame_ptr field. For shared
64 64 * libraries the encoding must be
65 65 * DW_EH_PE_sdata4|DW_EH_PE_pcrel or
66 66 * DW_EH_PE_sdata4|DW_EH_PE_datarel.
67 67 *
68 68 *
69 69 * fde_count_enc
70 70 *
71 71 * The encoding format of the fde_count field. A value of
72 72 * DW_EH_PE_omit indicates the binary search table is not
73 73 * present.
74 74 *
75 75 * table_enc
76 76 *
77 77 * The encoding format of the entries in the binary search
78 78 * table. A value of DW_EH_PE_omit indicates the binary search
79 79 * table is not present. For shared libraries the encoding
80 80 * must be DW_EH_PE_sdata4|DW_EH_PE_pcrel or
81 81 * DW_EH_PE_sdata4|DW_EH_PE_datarel.
82 82 *
83 83 *
84 84 * eh_frame_ptr
85 85 *
86 86 * The encoded value of the pointer to the start of the
87 87 * .eh_frame section.
88 88 *
89 89 * fde_count
90 90 *
91 91 * The encoded value of the count of entries in the binary
92 92 * search table.
93 93 *
94 94 * binary search table
95 95 *
96 96 * A binary search table containing fde_count entries. Each
97 97 * entry of the table consist of two encoded values, the
98 98 * initial location of the function to which an FDE applies,
99 99 * and the address of the FDE. The entries are sorted in an
100 100 * increasing order by the initial location value.
101 101 *
102 102 */
103 103
104 104
105 105 /*
106 106 * EH_FRAME sections
107 107 * =================
108 108 *
109 109 * The call frame information needed for unwinding the stack is output in
110 110 * an ELF section(s) of type SHT_AMD64_UNWIND (amd64) or SHT_PROGBITS (other).
111 111 * In the simplest case there will be one such section per object file and it
112 112 * will be named ".eh_frame". An .eh_frame section consists of one or more
113 113 * subsections. Each subsection contains a CIE (Common Information Entry)
114 114 * followed by varying number of FDEs (Frame Descriptor Entry). A FDE
115 115 * corresponds to an explicit or compiler generated function in a
116 116 * compilation unit, all FDEs can access the CIE that begins their
117 117 * subsection for data.
118 118 *
119 119 * If an object file contains C++ template instantiations, there shall be
120 120 * a separate CIE immediately preceding each FDE corresponding to an
121 121 * instantiation.
122 122 *
123 123 * Using the preferred encoding specified below, the .eh_frame section can
124 124 * be entirely resolved at link time and thus can become part of the
125 125 * text segment.
126 126 *
127 127 * .eh_frame Section Layout
128 128 * ------------------------
129 129 *
130 130 * EH_PE encoding below refers to the pointer encoding as specified in the
131 131 * enhanced LSB Chapter 7 for Eh_Frame_Hdr.
132 132 *
133 133 * Common Information Entry (CIE)
134 134 * ------------------------------
135 135 * CIE has the following format:
136 136 *
137 137 * Length
138 138 * in
139 139 * Field Byte Description
140 140 * ----- ------ -----------
141 141 * 1. Length 4 Length of CIE (not including
142 142 * this 4-byte field).
143 143 *
144 144 * 2. CIE id 4 Value Zero (0) for .eh_frame
145 145 * (used to distinguish CIEs and
146 146 * FDEs when scanning the section)
147 147 *
148 148 * 3. Version 1 Value One (1)
149 149 *
150 150 * 4. CIE Augmentation string Null-terminated string with legal
151 151 * values being "" or 'z' optionally
152 152 * followed by single occurrences of
153 153 * 'P', 'L', or 'R' in any order.
154 154 * String The presence of character(s) in the
155 155 * string dictates the content of
156 156 * field 8, the Augmentation Section.
157 157 * Each character has one or two
158 158 * associated operands in the AS.
159 159 * Operand order depends on
160 160 * position in the string ('z' must
161 161 * be first).
162 162 *
163 163 * 5. Code Align Factor uleb128 To be multiplied with the
164 164 * "Advance Location" instructions in
165 165 * the Call Frame Instructions
166 166 *
167 167 * 6. Data Align Factor sleb128 To be multiplied with all offset
168 168 * in the Call Frame Instructions
169 169 *
170 170 * 7. Ret Address Reg 1 A "virtual" register representation
171 171 * of the return address. In Dwarf V2,
172 172 * this is a byte, otherwise it is
173 173 * uleb128. It is a byte in gcc 3.3.x
174 174 *
175 175 * 8. Optional CIE varying Present if Augmentation String in
176 176 * Augmentation Section field 4 is not 0.
177 177 *
178 178 * z:
179 179 * size uleb128 Length of the remainder of the
180 180 * Augmentation Section
181 181 *
182 182 * P:
183 183 * personality_enc 1 Encoding specifier - preferred
184 184 * value is a pc-relative, signed
185 185 * 4-byte
186 186 *
187 187 *
188 188 * personality routine (encoded) Encoded pointer to personality
189 189 * routine (actually to the PLT
190 190 * entry for the personality
191 191 * routine)
192 192 * R:
193 193 * code_enc 1 Non-default encoding for the
194 194 * code-pointers (FDE members
195 195 * "initial_location" and "address_range"
196 196 * and the operand for DW_CFA_set_loc)
197 197 * - preferred value is pc-relative,
198 198 * signed 4-byte.
199 199 * L:
200 200 * lsda_enc 1 FDE augmentation bodies may contain
201 201 * LSDA pointers. If so they are
202 202 * encoded as specified here -
203 203 * preferred value is pc-relative,
204 204 * signed 4-byte possibly indirect
205 205 * thru a GOT entry.
206 206 *
207 207 *
208 208 * 9. Optional Call Frame varying
209 209 * Instructions
210 210 *
211 211 * The size of the optional call frame instruction area must be computed
212 212 * based on the overall size and the offset reached while scanning the
213 213 * preceding fields of the CIE.
214 214 *
215 215 *
216 216 * Frame Descriptor Entry (FDE)
217 217 * ----------------------------
218 218 * FDE has the following format:
219 219 *
220 220 * Length
221 221 * in
222 222 * Field Byte Description
223 223 * ----- ------ -----------
224 224 * 1. Length 4 Length of remainder of this FDE
225 225 *
226 226 * 2. CIE Pointer 4 Distance from this field to the
227 227 * nearest preceding CIE
228 228 * (uthe value is subtracted from the
229 229 * current address). This value
230 230 * can never be zero and thus can
231 231 * be used to distinguish CIE's and
232 232 * FDE's when scanning the
233 233 * .eh_frame section
234 234 *
235 235 * 3. Initial Location varying Reference to the function code
236 236 * corresponding to this FDE.
237 237 * If 'R' is missing from the CIE
238 238 * Augmentation String, the field is an
239 239 * 8-byte absolute pointer. Otherwise,
240 240 * the corresponding EH_PE encoding in the
241 241 * CIE Augmentation Section is used to
242 242 * interpret the reference.
243 243 *
244 244 * 4. Address Range varying Size of the function code corresponding
245 245 * to this FDE.
246 246 * If 'R' is missing from the CIE
247 247 * Augmentation String, the field is an
248 248 * 8-byte unsigned number. Otherwise,
249 249 * the size is determined by the
250 250 * corresponding EH_PE encoding in the
251 251 * CIE Augmentation Section (the
252 252 * value is always absolute).
253 253 *
254 254 * 5. Optional FDE varying present if CIE augmentation
255 255 * Augmentation Section string is non-empty.
256 256 *
257 257 *
258 258 * 'z':
259 259 * length uleb128 length of the remainder of the
260 260 * FDE augmentation section
261 261 *
262 262 *
263 263 * 'L' (and length > 0):
264 264 * LSDA varying LSDA pointer, encoded in the
265 265 * format specified by the
266 266 * corresponding operand in the CIE's
267 267 * augmentation body.
268 268 *
269 269 * 6. Optional Call varying
270 270 * Frame Instructions
271 271 *
272 272 * The size of the optional call frame instruction area must be computed
273 273 * based on the overall size and the offset reached while scanning the
274 274 * preceding fields of the FDE.
275 275 *
276 276 * The overall size of a .eh_frame section is given in the ELF section
277 277 * header. The only way to determine the number of entries is to scan
278 278 * the section till the end and count.
279 279 *
280 280 */
281 281
282 282
283 283
284 284
285 285 static uint_t
286 286 extract_uint(const uchar_t *data, uint64_t *ndx, int do_swap)
287 287 {
288 288 uint_t r;
289 289 uchar_t *p = (uchar_t *)&r;
290 290
291 291 data += *ndx;
292 292 if (do_swap)
293 293 UL_ASSIGN_BSWAP_WORD(p, data);
294 294 else
295 295 UL_ASSIGN_WORD(p, data);
296 296
297 297 (*ndx) += 4;
298 298 return (r);
299 299 }
300 300
301 301 /*
302 302 * Create an unwind header (.eh_frame_hdr) output section.
303 303 * The section is created and space reserved, but the data
304 304 * is not copied into place. That is done by a later call
305 305 * to ld_unwind_populate(), after active relocations have been
306 306 * processed.
307 307 *
308 308 * When GNU linkonce processing is in effect, we can end up in a situation
309 309 * where the FDEs related to discarded sections remain in the eh_frame
310 310 * section. Ideally, we would remove these dead entries from eh_frame.
311 311 * However, that optimization has not yet been implemented. In the current
312 312 * implementation, the number of dead FDEs cannot be determined until
313 313 * active relocations are processed, and that processing follows the
314 314 * call to this function. This means that we are unable to detect dead FDEs
315 315 * here, and the section created by this routine is sized for maximum case
316 316 * where all FDEs are valid.
317 317 */
318 318 uintptr_t
319 319 ld_unwind_make_hdr(Ofl_desc *ofl)
320 320 {
321 321 int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0;
322 322 Shdr *shdr;
323 323 Elf_Data *elfdata;
324 324 Is_desc *isp;
325 325 size_t size;
326 326 Xword fde_cnt;
327 327 Aliste idx1;
328 328 Os_desc *osp;
329 329
330 330 /*
331 331 * we only build a unwind header if we have
332 332 * some unwind information in the file.
333 333 */
334 334 if (ofl->ofl_unwind == NULL)
335 335 return (1);
336 336
337 337 /*
338 338 * Allocate and initialize the Elf_Data structure.
339 339 */
340 340 if ((elfdata = libld_calloc(sizeof (Elf_Data), 1)) == NULL)
341 341 return (S_ERROR);
342 342 elfdata->d_type = ELF_T_BYTE;
343 343 elfdata->d_align = ld_targ.t_m.m_word_align;
344 344 elfdata->d_version = ofl->ofl_dehdr->e_version;
345 345
346 346 /*
347 347 * Allocate and initialize the Shdr structure.
348 348 */
349 349 if ((shdr = libld_calloc(sizeof (Shdr), 1)) == NULL)
350 350 return (S_ERROR);
351 351 shdr->sh_type = ld_targ.t_m.m_sht_unwind;
352 352 shdr->sh_flags = SHF_ALLOC;
353 353 shdr->sh_addralign = ld_targ.t_m.m_word_align;
354 354 shdr->sh_entsize = 0;
355 355
356 356 /*
357 357 * Allocate and initialize the Is_desc structure.
358 358 */
359 359 if ((isp = libld_calloc(1, sizeof (Is_desc))) == NULL)
360 360 return (S_ERROR);
361 361 isp->is_name = MSG_ORIG(MSG_SCN_UNWINDHDR);
362 362 isp->is_shdr = shdr;
363 363 isp->is_indata = elfdata;
364 364
365 365 if ((ofl->ofl_unwindhdr = ld_place_section(ofl, isp, NULL,
366 366 ld_targ.t_id.id_unwindhdr, NULL)) == (Os_desc *)S_ERROR)
367 367 return (S_ERROR);
368 368
369 369 /*
370 370 * Scan through all of the input Frame information, counting each FDE
371 371 * that requires an index. Each fde_entry gets a corresponding entry
372 372 * in the binary search table.
373 373 */
374 374 fde_cnt = 0;
375 375 for (APLIST_TRAVERSE(ofl->ofl_unwind, idx1, osp)) {
376 376 Aliste idx2;
377 377 int os_isdescs_idx;
378 378
379 379 OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx2, isp) {
380 380 uchar_t *data;
381 381 uint64_t off = 0;
382 382
383 383 data = isp->is_indata->d_buf;
384 384 size = isp->is_indata->d_size;
385 385
386 386 while (off < size) {
387 387 uint_t length, id;
388 388 uint64_t ndx = 0;
389 389
390 390 /*
391 391 * Extract length in lsb format. A zero length
392 392 * indicates that this CIE is a terminator and
393 393 * that processing for unwind information is
394 394 * complete.
395 395 */
396 396 length = extract_uint(data + off, &ndx, bswap);
397 397 if (length == 0)
398 398 break;
399 399
400 400 /*
401 401 * Extract CIE id in lsb format.
402 402 */
403 403 id = extract_uint(data + off, &ndx, bswap);
404 404
405 405 /*
406 406 * A CIE record has a id of '0', otherwise
407 407 * this is a FDE entry and the 'id' is the
408 408 * CIE pointer.
409 409 */
410 410 if (id == 0) {
411 411 uint_t cieversion;
412 412 /*
413 413 * The only CIE version supported
414 414 * is '1' - quick sanity check
415 415 * here.
416 416 */
417 417 cieversion = data[off + ndx];
418 418 ndx += 1;
419 419 /* BEGIN CSTYLED */
420 420 if (cieversion != 1) {
421 421 ld_eprintf(ofl, ERR_FATAL,
422 422 MSG_INTL(MSG_UNW_BADCIEVERS),
423 423 isp->is_file->ifl_name,
424 424 isp->is_name, off);
425 425 return (S_ERROR);
426 426 }
427 427 /* END CSTYLED */
428 428 } else {
429 429 fde_cnt++;
430 430 }
431 431 off += length + 4;
432 432 }
433 433 }
434 434 }
435 435
436 436 /*
437 437 * section size:
438 438 * byte version +1
439 439 * byte eh_frame_ptr_enc +1
440 440 * byte fde_count_enc +1
441 441 * byte table_enc +1
442 442 * 4 bytes eh_frame_ptr +4
443 443 * 4 bytes fde_count +4
444 444 * [4 bytes] [4bytes] * fde_count ...
445 445 */
446 446 size = 12 + (8 * fde_cnt);
447 447
448 448 if ((elfdata->d_buf = libld_calloc(size, 1)) == NULL)
449 449 return (S_ERROR);
450 450 elfdata->d_size = size;
451 451 shdr->sh_size = (Xword)size;
452 452
453 453 return (1);
454 454 }
455 455
456 456 /*
457 457 * the comparator function needs to calculate
458 458 * the actual 'initloc' of a bintab entry - to
459 459 * do this we initialize the following global to point
460 460 * to it.
461 461 */
462 462 static Addr framehdr_addr;
463 463
464 464 static int
465 465 bintabcompare(const void *p1, const void *p2)
466 466 {
467 467 uint_t *bintab1, *bintab2;
468 468 uint_t ent1, ent2;
469 469
470 470 bintab1 = (uint_t *)p1;
471 471 bintab2 = (uint_t *)p2;
472 472
473 473 assert(bintab1 != 0);
474 474 assert(bintab2 != 0);
475 475
476 476 ent1 = *bintab1 + framehdr_addr;
477 477 ent2 = *bintab2 + framehdr_addr;
478 478
479 479 if (ent1 > ent2)
480 480 return (1);
481 481 if (ent1 < ent2)
482 482 return (-1);
483 483 return (0);
484 484 }
485 485
486 486 uintptr_t
487 487 ld_unwind_populate_hdr(Ofl_desc *ofl)
488 488 {
489 489 uchar_t *hdrdata;
490 490 uint_t *binarytable;
491 491 uint_t hdroff;
492 492 Aliste idx;
493 493 Addr hdraddr;
494 494 Os_desc *hdrosp;
495 495 Os_desc *osp;
496 496 Os_desc *first_unwind;
497 497 uint_t fde_count;
498 498 uint_t *uint_ptr;
499 499 int bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0;
500 500
501 501 /*
502 502 * Are we building the unwind hdr?
503 503 */
504 504 if ((hdrosp = ofl->ofl_unwindhdr) == 0)
505 505 return (1);
506 506
507 507 hdrdata = hdrosp->os_outdata->d_buf;
508 508 hdraddr = hdrosp->os_shdr->sh_addr;
509 509 hdroff = 0;
510 510
511 511 /*
512 512 * version == 1
513 513 */
514 514 hdrdata[hdroff++] = 1;
515 515 /*
516 516 * The encodings are:
517 517 *
518 518 * eh_frameptr_enc sdata4 | pcrel
519 519 * fde_count_enc udata4
520 520 * table_enc sdata4 | datarel
521 521 */
522 522 hdrdata[hdroff++] = DW_EH_PE_sdata4 | DW_EH_PE_pcrel;
523 523 hdrdata[hdroff++] = DW_EH_PE_udata4;
524 524 hdrdata[hdroff++] = DW_EH_PE_sdata4 | DW_EH_PE_datarel;
525 525
526 526 /*
527 527 * Header Offsets
528 528 * -----------------------------------
529 529 * byte version +1
530 530 * byte eh_frame_ptr_enc +1
531 531 * byte fde_count_enc +1
532 532 * byte table_enc +1
533 533 * 4 bytes eh_frame_ptr +4
534 534 * 4 bytes fde_count +4
535 535 */
536 536 /* LINTED */
537 537 binarytable = (uint_t *)(hdrdata + 12);
538 538 first_unwind = 0;
539 539 fde_count = 0;
540 540
541 541 for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, osp)) {
542 542 uchar_t *data;
543 543 size_t size;
544 544 uint64_t off = 0;
545 545 uint_t cieRflag = 0, ciePflag = 0;
546 546 Shdr *shdr;
547 547
548 548 /*
549 549 * remember first UNWIND section to
550 550 * point to in the frame_ptr entry.
551 551 */
552 552 if (first_unwind == 0)
553 553 first_unwind = osp;
554 554
555 555 data = osp->os_outdata->d_buf;
556 556 shdr = osp->os_shdr;
557 557 size = shdr->sh_size;
558 558
559 559 while (off < size) {
560 560 uint_t length, id;
561 561 uint64_t ndx = 0;
562 562
563 563 /*
564 564 * Extract length in lsb format. A zero length
565 565 * indicates that this CIE is a terminator and that
566 566 * processing of unwind information is complete.
567 567 */
568 568 length = extract_uint(data + off, &ndx, bswap);
569 569 if (length == 0)
570 570 goto done;
571 571
572 572 /*
573 573 * Extract CIE id in lsb format.
574 574 */
575 575 id = extract_uint(data + off, &ndx, bswap);
576 576
577 577 /*
578 578 * A CIE record has a id of '0'; otherwise
579 579 * this is a FDE entry and the 'id' is the
580 580 * CIE pointer.
581 581 */
582 582 if (id == 0) {
583 583 char *cieaugstr;
584 584 uint_t cieaugndx;
585 585
586 586 ciePflag = 0;
587 587 cieRflag = 0;
588 588 /*
589 589 * We need to drill through the CIE
590 590 * to find the Rflag. It's the Rflag
591 591 * which describes how the FDE code-pointers
592 592 * are encoded.
593 593 */
594 594
595 595 /*
596 596 * burn through version
597 597 */
598 598 ndx++;
599 599
600 600 /*
601 601 * augstr
602 602 */
603 603 cieaugstr = (char *)(&data[off + ndx]);
604 604 ndx += strlen(cieaugstr) + 1;
605 605
606 606 /*
607 607 * calign & dalign
608 608 */
609 609 (void) uleb_extract(&data[off], &ndx);
610 610 (void) sleb_extract(&data[off], &ndx);
611 611
612 612 /*
613 613 * retreg
614 614 */
615 615 ndx++;
616 616
617 617 /*
618 618 * we walk through the augmentation
619 619 * section now looking for the Rflag
620 620 */
621 621 for (cieaugndx = 0; cieaugstr[cieaugndx];
622 622 cieaugndx++) {
623 623 /* BEGIN CSTYLED */
624 624 switch (cieaugstr[cieaugndx]) {
625 625 case 'z':
626 626 /* size */
627 627 (void) uleb_extract(&data[off],
628 628 &ndx);
629 629 break;
630 630 case 'P':
631 631 /* personality */
↓ open down ↓ |
631 lines elided |
↑ open up ↑ |
632 632 ciePflag = data[off + ndx];
633 633 ndx++;
634 634 /*
635 635 * Just need to extract the
636 636 * value to move on to the next
637 637 * field.
638 638 */
639 639 (void) dwarf_ehe_extract(
640 640 &data[off + ndx],
641 641 &ndx, ciePflag,
642 - ofl->ofl_dehdr->e_ident,
643 - shdr->sh_addr, off + ndx);
642 + ofl->ofl_dehdr->e_ident, B_FALSE,
643 + shdr->sh_addr, off + ndx, 0);
644 644 break;
645 645 case 'R':
646 646 /* code encoding */
647 647 cieRflag = data[off + ndx];
648 648 ndx++;
649 649 break;
650 650 case 'L':
651 651 /* lsda encoding */
652 652 ndx++;
653 653 break;
654 654 }
655 655 /* END CSTYLED */
656 656 }
657 657 } else {
658 658 uint_t bintabndx;
659 659 uint64_t initloc;
660 660 uint64_t fdeaddr;
661 + uint64_t gotaddr = 0;
662 +
663 + if (ofl->ofl_osgot != NULL)
664 + gotaddr =
665 + ofl->ofl_osgot->os_shdr->sh_addr;
661 666
662 667 initloc = dwarf_ehe_extract(&data[off],
663 668 &ndx, cieRflag, ofl->ofl_dehdr->e_ident,
664 - shdr->sh_addr, off + ndx);
669 + B_FALSE,
670 + shdr->sh_addr, off + ndx,
671 + gotaddr);
665 672
666 673 /*
667 674 * Ignore FDEs with initloc set to 0.
668 675 * initloc will not be 0 unless this FDE was
669 676 * abandoned due to GNU linkonce processing.
670 677 * The 0 value occurs because we don't resolve
671 678 * sloppy relocations for unwind header target
672 679 * sections.
673 680 */
674 681 if (initloc != 0) {
675 682 bintabndx = fde_count * 2;
676 683 fde_count++;
677 684
678 685 /*
679 686 * FDEaddr is adjusted
680 687 * to account for the length & id which
681 688 * have already been consumed.
682 689 */
683 690 fdeaddr = shdr->sh_addr + off;
684 691
685 692 binarytable[bintabndx] =
686 693 (uint_t)(initloc - hdraddr);
687 694 binarytable[bintabndx + 1] =
688 695 (uint_t)(fdeaddr - hdraddr);
689 696 }
690 697 }
691 698
692 699 /*
693 700 * the length does not include the length
694 701 * itself - so account for that too.
695 702 */
696 703 off += length + 4;
697 704 }
698 705 }
699 706
700 707 done:
701 708 /*
702 709 * Do a quicksort on the binary table. If this is a cross
703 710 * link from a system with the opposite byte order, xlate
704 711 * the resulting values into LSB order.
705 712 */
706 713 framehdr_addr = hdraddr;
707 714 qsort((void *)binarytable, (size_t)fde_count,
708 715 (size_t)(sizeof (uint_t) * 2), bintabcompare);
709 716 if (bswap) {
710 717 uint_t *btable = binarytable;
711 718 uint_t cnt;
712 719
713 720 for (cnt = fde_count * 2; cnt-- > 0; btable++)
714 721 *btable = ld_bswap_Word(*btable);
715 722 }
716 723
717 724 /*
718 725 * Fill in:
719 726 * first_frame_ptr
720 727 * fde_count
721 728 */
722 729 hdroff = 4;
723 730 /* LINTED */
724 731 uint_ptr = (uint_t *)(&hdrdata[hdroff]);
725 732 *uint_ptr = first_unwind->os_shdr->sh_addr -
726 733 (hdrosp->os_shdr->sh_addr + hdroff);
727 734 if (bswap)
728 735 *uint_ptr = ld_bswap_Word(*uint_ptr);
729 736
730 737 hdroff += 4;
731 738 /* LINTED */
732 739 uint_ptr = (uint_t *)&hdrdata[hdroff];
733 740 *uint_ptr = fde_count;
734 741 if (bswap)
735 742 *uint_ptr = ld_bswap_Word(*uint_ptr);
736 743
737 744 /*
738 745 * If relaxed relocations are active, then there is a chance
739 746 * that we didn't use all the space reserved for this section.
740 747 * For details, see the note at head of ld_unwind_make_hdr() above.
741 748 *
742 749 * Find the PT_SUNW_UNWIND program header, and change the size values
743 750 * to the size of the subset of the section that was actually used.
744 751 */
745 752 if (ofl->ofl_flags1 & FLG_OF1_RLXREL) {
746 753 Word phnum = ofl->ofl_nehdr->e_phnum;
747 754 Phdr *phdr = ofl->ofl_phdr;
748 755
749 756 for (; phnum-- > 0; phdr++) {
750 757 if (phdr->p_type == PT_SUNW_UNWIND) {
751 758 phdr->p_memsz = 12 + (8 * fde_count);
752 759 phdr->p_filesz = phdr->p_memsz;
753 760 break;
754 761 }
755 762 }
756 763 }
757 764
758 765 return (1);
759 766 }
760 767
761 768 /*
762 769 * Append an .eh_frame section to our output list if not already present.
763 770 *
764 771 * Usually, there is a single .eh_frame output section. However, there can
765 772 * be more if there are incompatible section flags on incoming sections.
766 773 * If this does happen, the frame_ptr field of the eh_frame_hdr section
767 774 * will point at the base of the first output section, and the other
768 775 * sections will not be accessible via frame_ptr. However, the .eh_frame_hdr
769 776 * will be able to access all the data in the different .eh_frame sections,
770 777 * because the entries in sorted table are all encoded as DW_EH_PE_datarel.
771 778 */
772 779 uintptr_t
773 780 ld_unwind_register(Os_desc *osp, Ofl_desc * ofl)
774 781 {
775 782 Aliste idx;
776 783 Os_desc *_osp;
777 784 /*
778 785 * Check to see if this output section is already
779 786 * on the list.
780 787 */
781 788 for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, _osp))
782 789 if (osp == _osp)
783 790 return (1);
784 791
785 792 /*
786 793 * Append output section to unwind list
787 794 */
788 795 if (aplist_append(&ofl->ofl_unwind, osp, AL_CNT_OFL_UNWIND) == NULL)
789 796 return (S_ERROR);
790 797
791 798 return (1);
792 799 }
↓ open down ↓ |
118 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX