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
|