Print this page
5688 ELF tools need to be more careful with dwarf data

@@ -549,11 +549,11 @@
         uchar_t                 *data = (uchar_t *)(_cache->c_data->d_buf);
         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                initloc, initloc0 = 0;
         uint64_t                gotaddr = 0;
         int                     cnt;
 
         for (cnt = 1; cnt < shnum; cnt++) {
                 if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),

@@ -561,10 +561,16 @@
                         gotaddr = cache[cnt].c_shdr->sh_addr;
                         break;
                 }
         }
 
+        if ((data == NULL) || (datasize == 0)) {
+                (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
+                    file, _cache ->c_name);
+                return;
+        }
+
         /*
          * Is this a .eh_frame_hdr?
          */
         if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
             (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),

@@ -585,45 +591,99 @@
                 fde_cnt_enc = data[ndx++];
                 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, B_TRUE, shdr->sh_addr, ndx, gotaddr);
+                switch (dwarf_ehe_extract(data, datasize, &ndx,
+                    &frame_ptr, frame_ptr_enc, ehdr->e_ident, B_TRUE,
+                    shdr->sh_addr, ndx, gotaddr)) {
+                case DW_OVERFLOW:
+                        (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWOVRFLW),
+                            file, _cache->c_name);
+                        return;
+                case DW_BAD_ENCODING:
+                        (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWBADENC),
+                            file, _cache->c_name, frame_ptr_enc);
+                        return;
+                case DW_SUCCESS:
+                        break;
+                }
                 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, B_TRUE, shdr->sh_addr, ndx, gotaddr);
+                switch (dwarf_ehe_extract(data, datasize, &ndx, &fde_cnt,
+                    fde_cnt_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx,
+                    gotaddr)) {
+                case DW_OVERFLOW:
+                        (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWOVRFLW),
+                            file, _cache->c_name);
+                        return;
+                case DW_BAD_ENCODING:
+                        (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWBADENC),
+                            file, _cache->c_name, fde_cnt_enc);
+                        return;
+                case DW_SUCCESS:
+                        break;
+                }
 
                 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),
                     conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
                 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, B_TRUE, shdr->sh_addr, ndx, gotaddr);
-                        /*LINTED:E_VAR_USED_BEFORE_SET*/
+                        uint64_t table;
+
+                        switch (dwarf_ehe_extract(data, datasize, &ndx,
+                            &initloc, table_enc, ehdr->e_ident, B_TRUE,
+                            shdr->sh_addr, ndx, gotaddr)) {
+                        case DW_OVERFLOW:
+                                (void) fprintf(stderr,
+                                    MSG_INTL(MSG_ERR_DWOVRFLW), file,
+                                    _cache->c_name);
+                                return;
+                        case DW_BAD_ENCODING:
+                                (void) fprintf(stderr,
+                                    MSG_INTL(MSG_ERR_DWBADENC), file,
+                                    _cache->c_name, table_enc);
+                                return;
+                        case DW_SUCCESS:
+                                break;
+                        }
                         if ((tabndx != 0) && (initloc0 > initloc))
                                 (void) fprintf(stderr,
                                     MSG_INTL(MSG_ERR_BADSORT), file,
                                     _cache->c_name, EC_WORD(tabndx));
+                        switch (dwarf_ehe_extract(data, datasize, &ndx, &table,
+                            table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
+                            ndx, gotaddr)) {
+                        case DW_OVERFLOW:
+                                (void) fprintf(stderr,
+                                    MSG_INTL(MSG_ERR_DWOVRFLW), file,
+                                    _cache->c_name);
+                                return;
+                        case DW_BAD_ENCODING:
+                                (void) fprintf(stderr,
+                                    MSG_INTL(MSG_ERR_DWBADENC), file,
+                                    _cache->c_name, table_enc);
+                                return;
+                        case DW_SUCCESS:
+                                break;
+                        }
+
                         dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
                             EC_XWORD(initloc),
-                            EC_XWORD(dwarf_ehe_extract(data, &ndx,
-                            table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
-                            ndx, gotaddr)));
+                            EC_XWORD(table));
                         initloc0 = initloc;
                 }
         } else {                /* Display the .eh_frame section */
                 eh_state->frame_cnt++;
                 if (eh_state->frame_cnt == 1) {

@@ -635,12 +695,12 @@
 
                         (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, gotaddr);
+                dump_eh_frame(file, _cache->c_name, data, datasize,
+                    shdr->sh_addr, 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

@@ -734,11 +794,11 @@
 #endif
 
         exception_range_entry   scratch, *ent, *cur_ent = &scratch;
         char                    index[MAXNDXSIZE];
         Word                    i, nelts;
-        Addr                    addr, addr0, offset = 0;
+        Addr                    addr, addr0 = 0, offset = 0;
         Addr                    exc_addr = _cache->c_shdr->sh_addr;
 
         dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
         ent = (exception_range_entry *)(_cache->c_data->d_buf);
         nelts = _cache->c_data->d_size / sizeof (exception_range_entry);

@@ -761,11 +821,10 @@
                  * The table is required to be sorted by the address
                  * derived from ret_addr, to allow binary searching. Ensure
                  * that addresses grow monotonically.
                  */
                 addr = SRELPTR(ret_addr);
-                /*LINTED:E_VAR_USED_BEFORE_SET*/
                 if ((i != 0) && (addr0 > addr))
                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
                             file, _cache->c_name, EC_WORD(i));
 
                 (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),

@@ -3679,10 +3738,13 @@
 
                                 corenote_ret = corenote(ehdr->e_machine,
                                     do_swap, pnstate.pn_type, pnstate.pn_desc,
                                     pnstate.pn_descsz);
                                 switch (corenote_ret) {
+                                case CORENOTE_R_OK_DUMP:
+                                        hexdump = 1;
+                                        break;
                                 case CORENOTE_R_OK:
                                         hexdump = 0;
                                         break;
                                 case CORENOTE_R_BADDATA:
                                         (void) fprintf(stderr,

@@ -3696,10 +3758,17 @@
                                             MSG_INTL(MSG_NOTE_BADCOREARCH),
                                             file,
                                             conv_ehdr_mach(ehdr->e_machine,
                                             0, &inv_buf));
                                         break;
+                                case CORENOTE_R_BADTYPE:
+                                        (void) fprintf(stderr,
+                                            MSG_INTL(MSG_NOTE_BADCORETYPE),
+                                            file,
+                                            EC_WORD(pnstate.pn_type));
+                                        break;
+
                                 }
                         }
 
                         /*
                          * The default thing when we don't understand

@@ -4916,10 +4985,12 @@
         case CACHE_NEEDED:
                 if (create_cache(file, fd, elf, ehdr, &cache, shstrndx,
                     &shnum, &flags) == 0)
                         return (ret);
                 break;
+        case CACHE_OK:
+                break;
         case CACHE_FAIL:
                 return (ret);
         }
         if (shnum <= 1)
                 goto done;