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