Print this page
4011 ar does weird things with extended ELF sections
*** 203,212 ****
--- 203,213 ----
static void
recover_padding(Elf *elf, ARFILE *file)
{
size_t extent;
size_t padding;
+ size_t shnum;
GElf_Ehdr ehdr;
/* ar(1) only pads objects, so bail if not looking at one */
if (gelf_getclass(elf) == ELFCLASSNONE)
*** 220,231 ****
* object: Find the address at the end of the array and compare
* it to the archive ar_size. If they are within PADSZ bytes, then
* we've found the end, and the difference is padding (We assume
* that no ELF section can fit into PADSZ bytes).
*/
extent = gelf_getehdr(elf, &ehdr)
! ? (ehdr.e_shoff + (ehdr.e_shnum * ehdr.e_shentsize)) : 0;
/*
* If the extent exceeds the end of the archive member
* (negative padding), then we don't know what is going on
* and simply leave things alone.
--- 221,235 ----
* object: Find the address at the end of the array and compare
* it to the archive ar_size. If they are within PADSZ bytes, then
* we've found the end, and the difference is padding (We assume
* that no ELF section can fit into PADSZ bytes).
*/
+ if (elf_getshdrnum(elf, &shnum) == -1)
+ return;
+
extent = gelf_getehdr(elf, &ehdr)
! ? (ehdr.e_shoff + (shnum * ehdr.e_shentsize)) : 0;
/*
* If the extent exceeds the end of the archive member
* (negative padding), then we don't know what is going on
* and simply leave things alone.
*** 550,564 ****
} else {
(void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_01));
exit(1);
}
if (gelf_getehdr(elf, &ehdr) != 0) {
if ((class = gelf_getclass(elf)) == ELFCLASS64) {
fptr->ar_flag |= F_CLASS64;
} else if (class == ELFCLASS32)
fptr->ar_flag |= F_CLASS32;
! scn = elf_getscn(elf, ehdr.e_shstrndx);
if (scn == NULL) {
if (fptr->ar_pathname != NULL)
(void) fprintf(stderr,
MSG_INTL(MSG_ELF_GETSCN_FILE),
fptr->ar_pathname, elf_errmsg(-1));
--- 554,590 ----
} else {
(void) fprintf(stderr, MSG_INTL(MSG_INTERNAL_01));
exit(1);
}
if (gelf_getehdr(elf, &ehdr) != 0) {
+ size_t shstrndx = 0;
if ((class = gelf_getclass(elf)) == ELFCLASS64) {
fptr->ar_flag |= F_CLASS64;
} else if (class == ELFCLASS32)
fptr->ar_flag |= F_CLASS32;
!
! if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
! if (fptr->ar_pathname != NULL) {
! (void) fprintf(stderr,
! MSG_INTL(MSG_ELF_GETSHDRSTRNDX_FILE),
! fptr->ar_pathname, elf_errmsg(-1));
! } else {
! (void) fprintf(stderr,
! MSG_INTL(MSG_ELF_GETSHDRSTRNDX_AR),
! arname, fptr->ar_longname,
! elf_errmsg(-1));
! }
! num_errs++;
! if (newfd) {
! (void) close(newfd);
! newfd = 0;
! }
! (void) elf_end(elf);
! continue;
! }
!
! scn = elf_getscn(elf, shstrndx);
if (scn == NULL) {
if (fptr->ar_pathname != NULL)
(void) fprintf(stderr,
MSG_INTL(MSG_ELF_GETSCN_FILE),
fptr->ar_pathname, elf_errmsg(-1));
*** 638,648 ****
num_errs++;
(void) elf_end(elf);
continue;
}
*found_obj = 1;
! if (shdr.sh_type == SHT_SYMTAB)
if (search_sym_tab(arname, fptr, elf,
scn, &nsyms, symlist,
&num_errs) == -1) {
if (newfd) {
(void) close(newfd);
--- 664,674 ----
num_errs++;
(void) elf_end(elf);
continue;
}
*found_obj = 1;
! if (shdr.sh_type == SHT_SYMTAB) {
if (search_sym_tab(arname, fptr, elf,
scn, &nsyms, symlist,
&num_errs) == -1) {
if (newfd) {
(void) close(newfd);
*** 650,659 ****
--- 676,686 ----
}
continue;
}
}
}
+ }
mem_offset += sizeof (struct ar_hdr) + fptr->ar_size;
if (fptr->ar_size & 01)
mem_offset++;
(void) elf_end(elf);
if (newfd) {