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