Print this page
3265 link-editor builds bogus .eh_frame_hdr on ia32
        
*** 193,203 ****
   *      sh_base - Base address of ELF section containing desired datum
   *      sh_offset - Offset relative to sh_base of desired datum.
   */
  uint64_t
  dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
!     unsigned char *eident, uint64_t sh_base, uint64_t sh_offset)
  {
          uint64_t    dot = *dotp;
          uint_t      lsb;
          uint_t      wordsize;
          uint_t      fsize;
--- 193,204 ----
   *      sh_base - Base address of ELF section containing desired datum
   *      sh_offset - Offset relative to sh_base of desired datum.
   */
  uint64_t
  dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
!     unsigned char *eident, boolean_t frame_hdr, uint64_t sh_base,
!     uint64_t sh_offset, uint64_t dbase)
  {
          uint64_t    dot = *dotp;
          uint_t      lsb;
          uint_t      wordsize;
          uint_t      fsize;
*** 279,297 ****
          }
  
          /*
           * If value is relative to a base address, adjust it
           */
-         if (result) {
                  switch (ehe_flags & 0xf0) {
                  case DW_EH_PE_pcrel:
                          result += sh_base + sh_offset;
                          break;
  
                  case DW_EH_PE_datarel:
                          result += sh_base;
                          break;
                  }
!         }
          *dotp = dot;
          return (result);
  }
--- 280,308 ----
          }
  
          /*
           * If value is relative to a base address, adjust it
           */
          switch (ehe_flags & 0xf0) {
          case DW_EH_PE_pcrel:
                  result += sh_base + sh_offset;
                  break;
  
+         /*
+          * datarel is relative to .eh_frame_hdr if within .eh_frame,
+          * but GOT if not.
+          */
          case DW_EH_PE_datarel:
+                 if (frame_hdr)
                          result += sh_base;
+                 else
+                         result += dbase;
                  break;
          }
! 
!         /* Truncate the result to its specified size */
!         result = (result << ((sizeof (uint64_t) - fsize) * 8)) >>
!             ((sizeof (uint64_t) - fsize) * 8);
! 
          *dotp = dot;
          return (result);
  }