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


 178          */
 179         res = (res << (64 - shift)) >> (64 - shift);
 180 
 181         return (res);
 182 }
 183 
 184 /*
 185  * Extract a DWARF encoded datum
 186  *
 187  * entry:
 188  *      data - Base of data buffer containing encoded bytes
 189  *      dotp - Address of variable containing index within data
 190  *              at which the desired datum starts.
 191  *      ehe_flags - DWARF encoding
 192  *      eident - ELF header e_ident[] array for object being processed
 193  *      sh_base - Base address of ELF section containing desired datum
 194  *      sh_offset - Offset relative to sh_base of desired datum.
 195  */
 196 uint64_t
 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)

 199 {
 200         uint64_t    dot = *dotp;
 201         uint_t      lsb;
 202         uint_t      wordsize;
 203         uint_t      fsize;
 204         uint64_t    result;
 205 
 206         if (eident[EI_DATA] == ELFDATA2LSB)
 207                 lsb = 1;
 208         else
 209                 lsb = 0;
 210 
 211         if (eident[EI_CLASS] == ELFCLASS64)
 212                 wordsize = 8;
 213         else
 214                 wordsize = 4;
 215 
 216         switch (ehe_flags & 0x0f) {
 217         case DW_EH_PE_omit:
 218                 return (0);


 264                         val = data[dot];
 265                         result |= val << ((fsize - cnt - 1) * 8);
 266                 }
 267         }
 268         /*
 269          * perform sign extension
 270          */
 271         if ((ehe_flags & DW_EH_PE_signed) &&
 272             (fsize < sizeof (uint64_t))) {
 273                 int64_t sresult;
 274                 uint_t  bitshift;
 275                 sresult = result;
 276                 bitshift = (sizeof (uint64_t) - fsize) * 8;
 277                 sresult = (sresult << bitshift) >> bitshift;
 278                 result = sresult;
 279         }
 280 
 281         /*
 282          * If value is relative to a base address, adjust it
 283          */
 284         if (result) {
 285                 switch (ehe_flags & 0xf0) {
 286                 case DW_EH_PE_pcrel:
 287                         result += sh_base + sh_offset;
 288                         break;
 289 




 290                 case DW_EH_PE_datarel:

 291                         result += sh_base;


 292                         break;
 293                 }
 294         }




 295         *dotp = dot;
 296         return (result);
 297 }


 178          */
 179         res = (res << (64 - shift)) >> (64 - shift);
 180 
 181         return (res);
 182 }
 183 
 184 /*
 185  * Extract a DWARF encoded datum
 186  *
 187  * entry:
 188  *      data - Base of data buffer containing encoded bytes
 189  *      dotp - Address of variable containing index within data
 190  *              at which the desired datum starts.
 191  *      ehe_flags - DWARF encoding
 192  *      eident - ELF header e_ident[] array for object being processed
 193  *      sh_base - Base address of ELF section containing desired datum
 194  *      sh_offset - Offset relative to sh_base of desired datum.
 195  */
 196 uint64_t
 197 dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
 198     unsigned char *eident, boolean_t frame_hdr, uint64_t sh_base,
 199     uint64_t sh_offset, uint64_t dbase)
 200 {
 201         uint64_t    dot = *dotp;
 202         uint_t      lsb;
 203         uint_t      wordsize;
 204         uint_t      fsize;
 205         uint64_t    result;
 206 
 207         if (eident[EI_DATA] == ELFDATA2LSB)
 208                 lsb = 1;
 209         else
 210                 lsb = 0;
 211 
 212         if (eident[EI_CLASS] == ELFCLASS64)
 213                 wordsize = 8;
 214         else
 215                 wordsize = 4;
 216 
 217         switch (ehe_flags & 0x0f) {
 218         case DW_EH_PE_omit:
 219                 return (0);


 265                         val = data[dot];
 266                         result |= val << ((fsize - cnt - 1) * 8);
 267                 }
 268         }
 269         /*
 270          * perform sign extension
 271          */
 272         if ((ehe_flags & DW_EH_PE_signed) &&
 273             (fsize < sizeof (uint64_t))) {
 274                 int64_t sresult;
 275                 uint_t  bitshift;
 276                 sresult = result;
 277                 bitshift = (sizeof (uint64_t) - fsize) * 8;
 278                 sresult = (sresult << bitshift) >> bitshift;
 279                 result = sresult;
 280         }
 281 
 282         /*
 283          * If value is relative to a base address, adjust it
 284          */

 285         switch (ehe_flags & 0xf0) {
 286         case DW_EH_PE_pcrel:
 287                 result += sh_base + sh_offset;
 288                 break;
 289 
 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)
 296                         result += sh_base;
 297                 else
 298                         result += dbase;
 299                 break;
 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 
 306         *dotp = dot;
 307         return (result);
 308 }