Print this page
3265 link-editor builds bogus .eh_frame_hdr on ia32

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/tools/common/leb128.c
          +++ new/usr/src/cmd/sgs/tools/common/leb128.c
↓ open down ↓ 187 lines elided ↑ open up ↑
 188  188   *      data - Base of data buffer containing encoded bytes
 189  189   *      dotp - Address of variable containing index within data
 190  190   *              at which the desired datum starts.
 191  191   *      ehe_flags - DWARF encoding
 192  192   *      eident - ELF header e_ident[] array for object being processed
 193  193   *      sh_base - Base address of ELF section containing desired datum
 194  194   *      sh_offset - Offset relative to sh_base of desired datum.
 195  195   */
 196  196  uint64_t
 197  197  dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
 198      -    unsigned char *eident, uint64_t sh_base, uint64_t sh_offset)
      198 +    unsigned char *eident, boolean_t frame_hdr, uint64_t sh_base,
      199 +    uint64_t sh_offset, uint64_t dbase)
 199  200  {
 200  201          uint64_t    dot = *dotp;
 201  202          uint_t      lsb;
 202  203          uint_t      wordsize;
 203  204          uint_t      fsize;
 204  205          uint64_t    result;
 205  206  
 206  207          if (eident[EI_DATA] == ELFDATA2LSB)
 207  208                  lsb = 1;
 208  209          else
↓ open down ↓ 65 lines elided ↑ open up ↑
 274  275                  uint_t  bitshift;
 275  276                  sresult = result;
 276  277                  bitshift = (sizeof (uint64_t) - fsize) * 8;
 277  278                  sresult = (sresult << bitshift) >> bitshift;
 278  279                  result = sresult;
 279  280          }
 280  281  
 281  282          /*
 282  283           * If value is relative to a base address, adjust it
 283  284           */
 284      -        if (result) {
 285      -                switch (ehe_flags & 0xf0) {
 286      -                case DW_EH_PE_pcrel:
 287      -                        result += sh_base + sh_offset;
 288      -                        break;
      285 +        switch (ehe_flags & 0xf0) {
      286 +        case DW_EH_PE_pcrel:
      287 +                result += sh_base + sh_offset;
      288 +                break;
 289  289  
 290      -                case DW_EH_PE_datarel:
      290 +        /*
      291 +         * datarel is relative to .eh_frame_hdr if within .eh_frame,
      292 +         * but GOT if not.
      293 +         */
      294 +        case DW_EH_PE_datarel:
      295 +                if (frame_hdr)
 291  296                          result += sh_base;
 292      -                        break;
 293      -                }
      297 +                else
      298 +                        result += dbase;
      299 +                break;
 294  300          }
      301 +
      302 +        /* Truncate the result to its specified size */
      303 +        result = (result << ((sizeof (uint64_t) - fsize) * 8)) >>
      304 +            ((sizeof (uint64_t) - fsize) * 8);
      305 +
 295  306          *dotp = dot;
 296  307          return (result);
 297  308  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX