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) {