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