# HG changeset patch # User Richard Lowe # Date 1375912164 14400 # Node ID 9cc418183ceec42c4d2010a23e536721918e026e # Parent fe28bd72580863d2b7737675229b1e8d39da6179 4011 ar does weird things with extended ELF sections Reviewed by: Jason King Reviewed by: Josef 'Jeff' Sipek Approved by: Robert Mustacchi diff -r fe28bd725808 -r 9cc418183cee usr/src/cmd/sgs/ar/common/ar.msg --- a/usr/src/cmd/sgs/ar/common/ar.msg Wed Aug 07 01:00:48 2013 -0400 +++ b/usr/src/cmd/sgs/ar/common/ar.msg Wed Aug 07 17:49:24 2013 -0400 @@ -70,6 +70,8 @@ @ MSG_ELF_GETSCN_FILE "ar: %s has no section header or bad elf format: %s\n" @ MSG_ELF_GETSCN_AR "ar: %s(%s) has no section header or bad elf \ format: %s\n" +@ MSG_ELF_GETSHSTRNDX_FILE "ar: %s has no string table index: %s\n" +@ MSG_ELF_GETSHSTRNDX_AR "ar: %s(%s) has no string table index: %s\n" @ MSG_ELF_MALARCHIVE "ar: %s: offset %lld: malformed archive: %s\n" @ MSG_ELF_RAWFILE "ar: elf_rawfile() failed: %s\n" @ MSG_ELF_VERSION "ar: libelf.a out of date: %s\n" diff -r fe28bd725808 -r 9cc418183cee usr/src/cmd/sgs/ar/common/file.c --- a/usr/src/cmd/sgs/ar/common/file.c Wed Aug 07 01:00:48 2013 -0400 +++ b/usr/src/cmd/sgs/ar/common/file.c Wed Aug 07 17:49:24 2013 -0400 @@ -205,6 +205,7 @@ { size_t extent; size_t padding; + size_t shnum; GElf_Ehdr ehdr; @@ -222,8 +223,11 @@ * 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 + (ehdr.e_shnum * ehdr.e_shentsize)) : 0; + ? (ehdr.e_shoff + (shnum * ehdr.e_shentsize)) : 0; /* * If the extent exceeds the end of the archive member @@ -552,11 +556,33 @@ 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; - scn = elf_getscn(elf, ehdr.e_shstrndx); + + if (elf_getshdrstrndx(elf, &shstrndx) == -1) { + if (fptr->ar_pathname != NULL) { + (void) fprintf(stderr, + MSG_INTL(MSG_ELF_GETSHSTRNDX_FILE), + fptr->ar_pathname, elf_errmsg(-1)); + } else { + (void) fprintf(stderr, + MSG_INTL(MSG_ELF_GETSHSTRNDX_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, @@ -640,7 +666,7 @@ continue; } *found_obj = 1; - if (shdr.sh_type == SHT_SYMTAB) + if (shdr.sh_type == SHT_SYMTAB) { if (search_sym_tab(arname, fptr, elf, scn, &nsyms, symlist, &num_errs) == -1) { @@ -650,6 +676,7 @@ } continue; } + } } } mem_offset += sizeof (struct ar_hdr) + fptr->ar_size;