diff options
author | Richard Lowe <richlowe@richlowe.net> | 2013-08-07 17:49:24 -0400 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2013-08-18 12:13:39 -0400 |
commit | f0a0736fb13261a73aa20b1516bcc521f0fb7f15 (patch) | |
tree | dbf1e066cdc882bfef5bc7c5b8bdeb405e89d188 | |
parent | c894effd15e1470607e79c76f273f4565720d0f6 (diff) | |
download | illumos-joyent-f0a0736fb13261a73aa20b1516bcc521f0fb7f15.tar.gz |
4011 ar does weird things with extended ELF sections
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/cmd/sgs/ar/common/ar.msg | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/ar/common/file.c | 33 |
2 files changed, 32 insertions, 3 deletions
diff --git a/usr/src/cmd/sgs/ar/common/ar.msg b/usr/src/cmd/sgs/ar/common/ar.msg index f82a689966..a0da94da04 100644 --- a/usr/src/cmd/sgs/ar/common/ar.msg +++ b/usr/src/cmd/sgs/ar/common/ar.msg @@ -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 --git a/usr/src/cmd/sgs/ar/common/file.c b/usr/src/cmd/sgs/ar/common/file.c index 0c48b9f622..e3aa7fa0a5 100644 --- a/usr/src/cmd/sgs/ar/common/file.c +++ b/usr/src/cmd/sgs/ar/common/file.c @@ -205,6 +205,7 @@ recover_padding(Elf *elf, ARFILE *file) { size_t extent; size_t padding; + size_t shnum; GElf_Ehdr ehdr; @@ -222,8 +223,11 @@ recover_padding(Elf *elf, ARFILE *file) * 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 @@ mksymtab(const char *arname, ARFILEP **symlist, int *found_obj) 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 @@ mksymtab(const char *arname, ARFILEP **symlist, int *found_obj) 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 @@ mksymtab(const char *arname, ARFILEP **symlist, int *found_obj) } continue; } + } } } mem_offset += sizeof (struct ar_hdr) + fptr->ar_size; |