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

@@ -193,11 +193,12 @@
  *      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)
+    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,19 +280,29 @@
         }
 
         /*
          * 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;
 
+        /*
+         * 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);
 }