Print this page
4011 ar does weird things with extended ELF sections

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/ar/common/file.c
          +++ new/usr/src/cmd/sgs/ar/common/file.c
↓ open down ↓ 197 lines elided ↑ open up ↑
 198  198   * This routine examines the objects, using knowledge of
 199  199   * ELF and how our tools lay out objects to determine whether padding was
 200  200   * added to an archive item. If so, it adjusts the st_size and
 201  201   * st_padding fields of the file argument to reflect it.
 202  202   */
 203  203  static void
 204  204  recover_padding(Elf *elf, ARFILE *file)
 205  205  {
 206  206          size_t          extent;
 207  207          size_t          padding;
      208 +        size_t          shnum;
 208  209          GElf_Ehdr       ehdr;
 209  210  
 210  211  
 211  212          /* ar(1) only pads objects, so bail if not looking at one */
 212  213          if (gelf_getclass(elf) == ELFCLASSNONE)
 213  214                  return;
 214  215  
 215  216          /*
 216  217           * libelf always puts the section header array at the end
 217  218           * of the object, and all of our compilers and other tools
 218  219           * use libelf or follow this convention. So, it is extremely
 219  220           * likely that the section header array is at the end of this
 220  221           * object: Find the address at the end of the array and compare
 221  222           * it to the archive ar_size. If they are within PADSZ bytes, then
 222  223           * we've found the end, and the difference is padding (We assume
 223  224           * that no ELF section can fit into PADSZ bytes).
 224  225           */
      226 +        if (elf_getshdrnum(elf, &shnum) == -1)
      227 +                return;
      228 +
 225  229          extent = gelf_getehdr(elf, &ehdr)
 226      -            ? (ehdr.e_shoff + (ehdr.e_shnum * ehdr.e_shentsize)) : 0;
      230 +            ? (ehdr.e_shoff + (shnum * ehdr.e_shentsize)) : 0;
 227  231  
 228  232          /*
 229  233           * If the extent exceeds the end of the archive member
 230  234           * (negative padding), then we don't know what is going on
 231  235           * and simply leave things alone.
 232  236           */
 233  237          if (extent > file->ar_size)
 234  238                  return;
 235  239  
 236  240          padding = file->ar_size - extent;
↓ open down ↓ 308 lines elided ↑ open up ↑
 545  549                                          newfd = 0;
 546  550                                  }
 547  551                                  (void) elf_end(elf);
 548  552                                  continue;
 549  553                          }
 550  554                  } else {
 551  555                          (void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_01));
 552  556                          exit(1);
 553  557                  }
 554  558                  if (gelf_getehdr(elf, &ehdr) != 0) {
      559 +                        size_t shstrndx = 0;
 555  560                          if ((class = gelf_getclass(elf)) == ELFCLASS64) {
 556  561                                  fptr->ar_flag |= F_CLASS64;
 557  562                          } else if (class == ELFCLASS32)
 558  563                                  fptr->ar_flag |= F_CLASS32;
 559      -                        scn = elf_getscn(elf, ehdr.e_shstrndx);
      564 +
      565 +                        if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
      566 +                                if (fptr->ar_pathname != NULL) {
      567 +                                        (void) fprintf(stderr,
      568 +                                            MSG_INTL(MSG_ELF_GETSHDRSTRNDX_FILE),
      569 +                                            fptr->ar_pathname, elf_errmsg(-1));
      570 +                                } else {
      571 +                                        (void) fprintf(stderr,
      572 +                                            MSG_INTL(MSG_ELF_GETSHDRSTRNDX_AR),
      573 +                                            arname, fptr->ar_longname,
      574 +                                            elf_errmsg(-1));
      575 +                                }
      576 +                                num_errs++;
      577 +                                if (newfd) {
      578 +                                        (void) close(newfd);
      579 +                                        newfd = 0;
      580 +                                }
      581 +                                (void) elf_end(elf);
      582 +                                continue;
      583 +                        }
      584 +
      585 +                        scn = elf_getscn(elf, shstrndx);
 560  586                          if (scn == NULL) {
 561  587                                  if (fptr->ar_pathname != NULL)
 562  588                                          (void) fprintf(stderr,
 563  589                                              MSG_INTL(MSG_ELF_GETSCN_FILE),
 564  590                                              fptr->ar_pathname, elf_errmsg(-1));
 565  591                                  else
 566  592                                          (void) fprintf(stderr,
 567  593                                              MSG_INTL(MSG_ELF_GETSCN_AR),
 568  594                                              arname, fptr->ar_longname,
 569  595                                              elf_errmsg(-1));
↓ open down ↓ 63 lines elided ↑ open up ↑
 633  659                                          /* END CSTYLED */
 634  660                                          if (newfd) {
 635  661                                                  (void) close(newfd);
 636  662                                                  newfd = 0;
 637  663                                          }
 638  664                                          num_errs++;
 639  665                                          (void) elf_end(elf);
 640  666                                          continue;
 641  667                                  }
 642  668                                  *found_obj = 1;
 643      -                                if (shdr.sh_type == SHT_SYMTAB)
      669 +                                if (shdr.sh_type == SHT_SYMTAB) {
 644  670                                          if (search_sym_tab(arname, fptr, elf,
 645  671                                              scn, &nsyms, symlist,
 646  672                                              &num_errs) == -1) {
 647  673                                                  if (newfd) {
 648  674                                                          (void) close(newfd);
 649  675                                                          newfd = 0;
 650  676                                                  }
 651  677                                                  continue;
 652  678                                          }
      679 +                                }
 653  680                          }
 654  681                  }
 655  682                  mem_offset += sizeof (struct ar_hdr) + fptr->ar_size;
 656  683                  if (fptr->ar_size & 01)
 657  684                          mem_offset++;
 658  685                  (void) elf_end(elf);
 659  686                  if (newfd) {
 660  687                          (void) close(newfd);
 661  688                          newfd = 0;
 662  689                  }
↓ open down ↓ 956 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX