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
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
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
|
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 * Copyright 2014 Nexenta Systems, Inc.
25 */
26
27 #include <string.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <sgs.h>
31 #include <debug.h>
32 #include <_libld.h>
33 #include <dwarf.h>
34 #include <stdlib.h>
35
36 /*
37 * A EH_FRAME_HDR consists of the following:
38 *
39 * Encoding Field
40 * --------------------------------
41 * unsigned byte version
42 * unsigned byte eh_frame_ptr_enc
43 * unsigned byte fde_count_enc
44 * unsigned byte table_enc
393 * indicates that this CIE is a terminator and
394 * that processing for unwind information is
395 * complete.
396 */
397 length = extract_uint(data + off, &ndx, bswap);
398 if (length == 0)
399 break;
400
401 /*
402 * Extract CIE id in lsb format.
403 */
404 id = extract_uint(data + off, &ndx, bswap);
405
406 /*
407 * A CIE record has a id of '0', otherwise
408 * this is a FDE entry and the 'id' is the
409 * CIE pointer.
410 */
411 if (id == 0) {
412 uint_t cieversion;
413 cieversion = data[off + ndx];
414 ndx += 1;
415 /* BEGIN CSTYLED */
416 if (cieversion != 1 && cieversion != 3) {
417 ld_eprintf(ofl, ERR_FATAL,
418 MSG_INTL(MSG_UNW_BADCIEVERS),
419 isp->is_file->ifl_name,
420 isp->is_name, off);
421 return (S_ERROR);
422 }
423 /* END CSTYLED */
424 } else {
425 fde_cnt++;
426 }
427 off += length + 4;
428 }
429 }
430 }
431
432 /*
433 * section size:
434 * byte version +1
435 * byte eh_frame_ptr_enc +1
436 * byte fde_count_enc +1
561 * indicates that this CIE is a terminator and that
562 * processing of unwind information is complete.
563 */
564 length = extract_uint(data + off, &ndx, bswap);
565 if (length == 0)
566 goto done;
567
568 /*
569 * Extract CIE id in lsb format.
570 */
571 id = extract_uint(data + off, &ndx, bswap);
572
573 /*
574 * A CIE record has a id of '0'; otherwise
575 * this is a FDE entry and the 'id' is the
576 * CIE pointer.
577 */
578 if (id == 0) {
579 char *cieaugstr;
580 uint_t cieaugndx;
581 uint_t cieversion;
582
583 ciePflag = 0;
584 cieRflag = 0;
585 /*
586 * We need to drill through the CIE
587 * to find the Rflag. It's the Rflag
588 * which describes how the FDE code-pointers
589 * are encoded.
590 */
591
592 cieversion = data[off + ndx];
593 ndx += 1;
594
595 /*
596 * augstr
597 */
598 cieaugstr = (char *)(&data[off + ndx]);
599 ndx += strlen(cieaugstr) + 1;
600
601 /*
602 * calign & dalign
603 */
604 (void) uleb_extract(&data[off], &ndx);
605 (void) sleb_extract(&data[off], &ndx);
606
607 /*
608 * retreg
609 */
610 if (cieversion == 1)
611 ndx++;
612 else
613 (void) uleb_extract(&data[off], &ndx);
614 /*
615 * we walk through the augmentation
616 * section now looking for the Rflag
617 */
618 for (cieaugndx = 0; cieaugstr[cieaugndx];
619 cieaugndx++) {
620 /* BEGIN CSTYLED */
621 switch (cieaugstr[cieaugndx]) {
622 case 'z':
623 /* size */
624 (void) uleb_extract(&data[off],
625 &ndx);
626 break;
627 case 'P':
628 /* personality */
629 ciePflag = data[off + ndx];
630 ndx++;
631 /*
632 * Just need to extract the
633 * value to move on to the next
|