Print this page
5270 ld(1) cannot handle CIE version 3 in .eh_frame


   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