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

@@ -530,11 +530,11 @@
  *      osabi - OSABI to use in displaying information
  *      file - Name of file
  *      flags - Command line option flags
  */
 static void
-unwind_eh_frame(Cache *cache, Word shndx, Phdr *uphdr, Ehdr *ehdr,
+unwind_eh_frame(Cache *cache, Word shndx, Word shnum, Phdr *uphdr, Ehdr *ehdr,
     gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
 {
 #if     defined(_ELF64)
 #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_64
 #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_64

@@ -549,11 +549,20 @@
         size_t                  datasize = _cache->c_data->d_size;
         Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
         uint64_t                ndx, frame_ptr, fde_cnt, tabndx;
         uint_t                  vers, frame_ptr_enc, fde_cnt_enc, table_enc;
         uint64_t                initloc, initloc0;
+        uint64_t                gotaddr = 0;
+        int                     cnt;
 
+        for (cnt = 1; cnt < shnum; cnt++) {
+                if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
+                    MSG_ELF_GOT_SIZE) == 0) {
+                        gotaddr = cache[cnt].c_shdr->sh_addr;
+                        break;
+                }
+        }
 
         /*
          * Is this a .eh_frame_hdr?
          */
         if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||

@@ -576,22 +585,22 @@
                 table_enc = data[ndx++];
 
                 dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
 
                 frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
-                    ehdr->e_ident, shdr->sh_addr, ndx);
+                    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
                 if (eh_state->hdr_cnt == 1) {
                         eh_state->hdr_ndx = shndx;
                         eh_state->frame_ptr = frame_ptr;
                 }
 
                 dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
                     conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
                     EC_XWORD(frame_ptr));
 
                 fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
-                    ehdr->e_ident, shdr->sh_addr, ndx);
+                    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
 
                 dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
                     conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
                     EC_XWORD(fde_cnt));
                 dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),

@@ -599,21 +608,21 @@
                 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
                 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
 
                 for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
                         initloc = dwarf_ehe_extract(data, &ndx, table_enc,
-                            ehdr->e_ident, shdr->sh_addr, ndx);
+                            ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
                         /*LINTED:E_VAR_USED_BEFORE_SET*/
                         if ((tabndx != 0) && (initloc0 > initloc))
                                 (void) fprintf(stderr,
                                     MSG_INTL(MSG_ERR_BADSORT), file,
                                     _cache->c_name, EC_WORD(tabndx));
                         dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
                             EC_XWORD(initloc),
                             EC_XWORD(dwarf_ehe_extract(data, &ndx,
-                            table_enc, ehdr->e_ident, shdr->sh_addr,
-                            ndx)));
+                            table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
+                            ndx, gotaddr)));
                         initloc0 = initloc;
                 }
         } else {                /* Display the .eh_frame section */
                 eh_state->frame_cnt++;
                 if (eh_state->frame_cnt == 1) {

@@ -626,11 +635,11 @@
                         (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
                             file, EC_WORD(shndx), _cache->c_name,
                             conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
                 }
                 dump_eh_frame(data, datasize, shdr->sh_addr,
-                    ehdr->e_machine, ehdr->e_ident);
+                    ehdr->e_machine, ehdr->e_ident, gotaddr);
         }
 
         /*
          * If we've seen the .eh_frame_hdr and the first .eh_frame section,
          * compare the header frame_ptr to the address of the actual frame

@@ -873,12 +882,12 @@
 
                 if (is_exrange)
                         unwind_exception_ranges(_cache, file,
                             _elf_sys_encoding() != ehdr->e_ident[EI_DATA]);
                 else
-                        unwind_eh_frame(cache, cnt, uphdr, ehdr, &eh_state,
-                            osabi, file, flags);
+                        unwind_eh_frame(cache, cnt, shnum, uphdr, ehdr,
+                            &eh_state, osabi, file, flags);
         }
 }
 
 /*
  * Initialize a symbol table state structure