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


 188                 r = align - r;
 189 
 190         return (r);
 191 }
 192 
 193 /*
 194  * If the current archive item is an ELF object, then ar(1) may have added
 195  * newline padding at the end in order to bring the following object
 196  * into PADSZ alignment within the file. This padding cannot be
 197  * distinguished from data using the information kept in the member header.
 198  * This routine examines the objects, using knowledge of
 199  * ELF and how our tools lay out objects to determine whether padding was
 200  * added to an archive item. If so, it adjusts the st_size and
 201  * st_padding fields of the file argument to reflect it.
 202  */
 203 static void
 204 recover_padding(Elf *elf, ARFILE *file)
 205 {
 206         size_t          extent;
 207         size_t          padding;

 208         GElf_Ehdr       ehdr;
 209 
 210 
 211         /* ar(1) only pads objects, so bail if not looking at one */
 212         if (gelf_getclass(elf) == ELFCLASSNONE)
 213                 return;
 214 
 215         /*
 216          * libelf always puts the section header array at the end
 217          * of the object, and all of our compilers and other tools
 218          * use libelf or follow this convention. So, it is extremely
 219          * likely that the section header array is at the end of this
 220          * object: Find the address at the end of the array and compare
 221          * it to the archive ar_size. If they are within PADSZ bytes, then
 222          * we've found the end, and the difference is padding (We assume
 223          * that no ELF section can fit into PADSZ bytes).
 224          */



 225         extent = gelf_getehdr(elf, &ehdr)
 226             ? (ehdr.e_shoff + (ehdr.e_shnum * ehdr.e_shentsize)) : 0;
 227 
 228         /*
 229          * If the extent exceeds the end of the archive member
 230          * (negative padding), then we don't know what is going on
 231          * and simply leave things alone.
 232          */
 233         if (extent > file->ar_size)
 234                 return;
 235 
 236         padding = file->ar_size - extent;
 237         if (padding >= PADSZ) {
 238                 /*
 239                  * The section header array is not at the end of the object.
 240                  * Traverse the section headers and look for the one with
 241                  * the highest used address. If this address is within
 242                  * PADSZ bytes of ar_size, then this is the end of the object.
 243                  */
 244                 Elf_Scn *scn = NULL;
 245 
 246                 do {


 535                                     MSG_INTL(MSG_ELF_BEGIN_FILE),
 536                                     fptr->ar_pathname, elf_errmsg(-1));
 537                                 (void) close(newfd);
 538                                 newfd = 0;
 539                                 num_errs++;
 540                                 continue;
 541                         }
 542                         if (elf_kind(elf) == ELF_K_AR) {
 543                                 if (newfd) {
 544                                         (void) close(newfd);
 545                                         newfd = 0;
 546                                 }
 547                                 (void) elf_end(elf);
 548                                 continue;
 549                         }
 550                 } else {
 551                         (void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_01));
 552                         exit(1);
 553                 }
 554                 if (gelf_getehdr(elf, &ehdr) != 0) {

 555                         if ((class = gelf_getclass(elf)) == ELFCLASS64) {
 556                                 fptr->ar_flag |= F_CLASS64;
 557                         } else if (class == ELFCLASS32)
 558                                 fptr->ar_flag |= F_CLASS32;
 559                         scn = elf_getscn(elf, ehdr.e_shstrndx);





















 560                         if (scn == NULL) {
 561                                 if (fptr->ar_pathname != NULL)
 562                                         (void) fprintf(stderr,
 563                                             MSG_INTL(MSG_ELF_GETSCN_FILE),
 564                                             fptr->ar_pathname, elf_errmsg(-1));
 565                                 else
 566                                         (void) fprintf(stderr,
 567                                             MSG_INTL(MSG_ELF_GETSCN_AR),
 568                                             arname, fptr->ar_longname,
 569                                             elf_errmsg(-1));
 570                                 num_errs++;
 571                                 if (newfd) {
 572                                         (void) close(newfd);
 573                                         newfd = 0;
 574                                 }
 575                                 (void) elf_end(elf);
 576                                 continue;
 577                         }
 578 
 579                         data = 0;


 623                                         if (fptr->ar_pathname != NULL)
 624                                             (void) fprintf(stderr,
 625                                                 MSG_INTL(MSG_ELF_GETDATA_FILE),
 626                                                 fptr->ar_pathname,
 627                                                 elf_errmsg(-1));
 628                                         else
 629                                             (void) fprintf(stderr,
 630                                                 MSG_INTL(MSG_ELF_GETDATA_AR),
 631                                                 arname, fptr->ar_longname,
 632                                                 elf_errmsg(-1));
 633                                         /* END CSTYLED */
 634                                         if (newfd) {
 635                                                 (void) close(newfd);
 636                                                 newfd = 0;
 637                                         }
 638                                         num_errs++;
 639                                         (void) elf_end(elf);
 640                                         continue;
 641                                 }
 642                                 *found_obj = 1;
 643                                 if (shdr.sh_type == SHT_SYMTAB)
 644                                         if (search_sym_tab(arname, fptr, elf,
 645                                             scn, &nsyms, symlist,
 646                                             &num_errs) == -1) {
 647                                                 if (newfd) {
 648                                                         (void) close(newfd);
 649                                                         newfd = 0;
 650                                                 }
 651                                                 continue;
 652                                         }
 653                         }
 654                 }

 655                 mem_offset += sizeof (struct ar_hdr) + fptr->ar_size;
 656                 if (fptr->ar_size & 01)
 657                         mem_offset++;
 658                 (void) elf_end(elf);
 659                 if (newfd) {
 660                         (void) close(newfd);
 661                         newfd = 0;
 662                 }
 663         }
 664         if (num_errs)
 665                 exit(1);
 666 
 667         if (found_obj) {
 668                 if (nsyms == 0) {
 669                         /*
 670                          * It is possible, though rare, to have ELF objects
 671                          * that do not export any global symbols. Presumably
 672                          * such objects operate via their .init/.fini
 673                          * sections. In this case, we produce an empty
 674                          * symbol table, so that applications that rely




 188                 r = align - r;
 189 
 190         return (r);
 191 }
 192 
 193 /*
 194  * If the current archive item is an ELF object, then ar(1) may have added
 195  * newline padding at the end in order to bring the following object
 196  * into PADSZ alignment within the file. This padding cannot be
 197  * distinguished from data using the information kept in the member header.
 198  * This routine examines the objects, using knowledge of
 199  * ELF and how our tools lay out objects to determine whether padding was
 200  * added to an archive item. If so, it adjusts the st_size and
 201  * st_padding fields of the file argument to reflect it.
 202  */
 203 static void
 204 recover_padding(Elf *elf, ARFILE *file)
 205 {
 206         size_t          extent;
 207         size_t          padding;
 208         size_t          shnum;
 209         GElf_Ehdr       ehdr;
 210 
 211 
 212         /* ar(1) only pads objects, so bail if not looking at one */
 213         if (gelf_getclass(elf) == ELFCLASSNONE)
 214                 return;
 215 
 216         /*
 217          * libelf always puts the section header array at the end
 218          * of the object, and all of our compilers and other tools
 219          * use libelf or follow this convention. So, it is extremely
 220          * likely that the section header array is at the end of this
 221          * object: Find the address at the end of the array and compare
 222          * it to the archive ar_size. If they are within PADSZ bytes, then
 223          * we've found the end, and the difference is padding (We assume
 224          * that no ELF section can fit into PADSZ bytes).
 225          */
 226         if (elf_getshdrnum(elf, &shnum) == -1)
 227                 return;
 228 
 229         extent = gelf_getehdr(elf, &ehdr)
 230             ? (ehdr.e_shoff + (shnum * ehdr.e_shentsize)) : 0;
 231 
 232         /*
 233          * If the extent exceeds the end of the archive member
 234          * (negative padding), then we don't know what is going on
 235          * and simply leave things alone.
 236          */
 237         if (extent > file->ar_size)
 238                 return;
 239 
 240         padding = file->ar_size - extent;
 241         if (padding >= PADSZ) {
 242                 /*
 243                  * The section header array is not at the end of the object.
 244                  * Traverse the section headers and look for the one with
 245                  * the highest used address. If this address is within
 246                  * PADSZ bytes of ar_size, then this is the end of the object.
 247                  */
 248                 Elf_Scn *scn = NULL;
 249 
 250                 do {


 539                                     MSG_INTL(MSG_ELF_BEGIN_FILE),
 540                                     fptr->ar_pathname, elf_errmsg(-1));
 541                                 (void) close(newfd);
 542                                 newfd = 0;
 543                                 num_errs++;
 544                                 continue;
 545                         }
 546                         if (elf_kind(elf) == ELF_K_AR) {
 547                                 if (newfd) {
 548                                         (void) close(newfd);
 549                                         newfd = 0;
 550                                 }
 551                                 (void) elf_end(elf);
 552                                 continue;
 553                         }
 554                 } else {
 555                         (void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_01));
 556                         exit(1);
 557                 }
 558                 if (gelf_getehdr(elf, &ehdr) != 0) {
 559                         size_t shstrndx = 0;
 560                         if ((class = gelf_getclass(elf)) == ELFCLASS64) {
 561                                 fptr->ar_flag |= F_CLASS64;
 562                         } else if (class == ELFCLASS32)
 563                                 fptr->ar_flag |= F_CLASS32;
 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);
 586                         if (scn == NULL) {
 587                                 if (fptr->ar_pathname != NULL)
 588                                         (void) fprintf(stderr,
 589                                             MSG_INTL(MSG_ELF_GETSCN_FILE),
 590                                             fptr->ar_pathname, elf_errmsg(-1));
 591                                 else
 592                                         (void) fprintf(stderr,
 593                                             MSG_INTL(MSG_ELF_GETSCN_AR),
 594                                             arname, fptr->ar_longname,
 595                                             elf_errmsg(-1));
 596                                 num_errs++;
 597                                 if (newfd) {
 598                                         (void) close(newfd);
 599                                         newfd = 0;
 600                                 }
 601                                 (void) elf_end(elf);
 602                                 continue;
 603                         }
 604 
 605                         data = 0;


 649                                         if (fptr->ar_pathname != NULL)
 650                                             (void) fprintf(stderr,
 651                                                 MSG_INTL(MSG_ELF_GETDATA_FILE),
 652                                                 fptr->ar_pathname,
 653                                                 elf_errmsg(-1));
 654                                         else
 655                                             (void) fprintf(stderr,
 656                                                 MSG_INTL(MSG_ELF_GETDATA_AR),
 657                                                 arname, fptr->ar_longname,
 658                                                 elf_errmsg(-1));
 659                                         /* END CSTYLED */
 660                                         if (newfd) {
 661                                                 (void) close(newfd);
 662                                                 newfd = 0;
 663                                         }
 664                                         num_errs++;
 665                                         (void) elf_end(elf);
 666                                         continue;
 667                                 }
 668                                 *found_obj = 1;
 669                                 if (shdr.sh_type == SHT_SYMTAB) {
 670                                         if (search_sym_tab(arname, fptr, elf,
 671                                             scn, &nsyms, symlist,
 672                                             &num_errs) == -1) {
 673                                                 if (newfd) {
 674                                                         (void) close(newfd);
 675                                                         newfd = 0;
 676                                                 }
 677                                                 continue;
 678                                         }
 679                                 }
 680                         }
 681                 }
 682                 mem_offset += sizeof (struct ar_hdr) + fptr->ar_size;
 683                 if (fptr->ar_size & 01)
 684                         mem_offset++;
 685                 (void) elf_end(elf);
 686                 if (newfd) {
 687                         (void) close(newfd);
 688                         newfd = 0;
 689                 }
 690         }
 691         if (num_errs)
 692                 exit(1);
 693 
 694         if (found_obj) {
 695                 if (nsyms == 0) {
 696                         /*
 697                          * It is possible, though rare, to have ELF objects
 698                          * that do not export any global symbols. Presumably
 699                          * such objects operate via their .init/.fini
 700                          * sections. In this case, we produce an empty
 701                          * symbol table, so that applications that rely