diff options
author | 2018-12-11 17:09:07 +0000 | |
---|---|---|
committer | 2018-12-11 17:09:07 +0000 | |
commit | f244d5f5cf50cebece55bf767d5b7e10ab218f62 (patch) | |
tree | 753524a97369a26d5243cc23ef8d2c73df1a2990 | |
parent | add a non regression test that triggers the nettle bug (diff) | |
download | wireguard-openbsd-f244d5f5cf50cebece55bf767d5b7e10ab218f62.tar.xz wireguard-openbsd-f244d5f5cf50cebece55bf767d5b7e10ab218f62.zip |
Add PN_XNUM support to libbfd so objdump and gdb can handle core
dumps with many many segments.
ok yasuoka@
-rw-r--r-- | gnu/usr.bin/binutils-2.17/bfd/elfcode.h | 15 | ||||
-rw-r--r-- | gnu/usr.bin/binutils-2.17/bfd/elfcore.h | 25 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elfcode.h | 15 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elfcore.h | 25 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/binutils/readelf.c | 7 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/include/elf/common.h | 3 |
6 files changed, 87 insertions, 3 deletions
diff --git a/gnu/usr.bin/binutils-2.17/bfd/elfcode.h b/gnu/usr.bin/binutils-2.17/bfd/elfcode.h index 1f8ec2b2b2c..430730f5f50 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elfcode.h +++ b/gnu/usr.bin/binutils-2.17/bfd/elfcode.h @@ -271,7 +271,10 @@ elf_swap_ehdr_out (bfd *abfd, H_PUT_32 (abfd, src->e_flags, dst->e_flags); H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize); H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize); - H_PUT_16 (abfd, src->e_phnum, dst->e_phnum); + tmp = src->e_phnum; + if (tmp >= PN_XNUM) + tmp = PN_XNUM; + H_PUT_16 (abfd, tmp, dst->e_phnum); H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize); tmp = src->e_shnum; if (tmp >= SHN_LORESERVE) @@ -661,6 +664,14 @@ elf_object_p (bfd *abfd) goto got_wrong_format_error; } + /* And similarly for the program header count. */ + if (i_ehdrp->e_phnum == PN_XNUM) + { + i_ehdrp->e_phnum = i_shdr.sh_info; + if (i_ehdrp->e_phnum != i_shdr.sh_info) + goto got_wrong_format_error; + } + /* Sanity check that we can read all of the section headers. It ought to be good enough to just read the last one. */ if (i_ehdrp->e_shnum != 1) @@ -1032,6 +1043,8 @@ elf_write_shdrs_and_ehdr (bfd *abfd) i_shdrp[0]->sh_size = i_ehdrp->e_shnum; if (i_ehdrp->e_shstrndx >= SHN_LORESERVE) i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx; + if (i_ehdrp->e_phnum >= PN_XNUM) + i_shdrp[0]->sh_info = i_ehdrp->e_phnum; /* at this point we've concocted all the ELF sections... */ amt = i_ehdrp->e_shnum; diff --git a/gnu/usr.bin/binutils-2.17/bfd/elfcore.h b/gnu/usr.bin/binutils-2.17/bfd/elfcore.h index b1cf42d79fa..a07b0d58637 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elfcore.h +++ b/gnu/usr.bin/binutils-2.17/bfd/elfcore.h @@ -176,6 +176,31 @@ elf_core_file_p (bfd *abfd) if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) goto wrong; + if (i_ehdrp->e_phnum == PN_XNUM) + { + Elf_External_Shdr x_shdr; /* Section header table entry, external form */ + Elf_Internal_Shdr i_shdr; /* Section header table, internal form */ + bfd_signed_vma where = i_ehdrp->e_shoff; + + if (i_ehdrp->e_shoff == 0 || i_ehdrp->e_shnum < 1 + || i_ehdrp->e_shentsize != sizeof (x_shdr) + || where != (file_ptr) where) + goto wrong; + + /* Seek to the section header table in the file. */ + if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) + goto wrong; + + /* Read the first section header at index 0, and convert to internal + form. */ + if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) + goto wrong; + elf_swap_shdr_in (abfd, &x_shdr, &i_shdr); + i_ehdrp->e_phnum = i_shdr.sh_info; + if (i_ehdrp->e_phnum != i_shdr.sh_info) + goto wrong; + } + /* Does BFD's idea of the phdr size match the size recorded in the file? */ if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr)) diff --git a/gnu/usr.bin/binutils/bfd/elfcode.h b/gnu/usr.bin/binutils/bfd/elfcode.h index bc69d48db4d..20b06cca688 100644 --- a/gnu/usr.bin/binutils/bfd/elfcode.h +++ b/gnu/usr.bin/binutils/bfd/elfcode.h @@ -269,7 +269,10 @@ elf_swap_ehdr_out (bfd *abfd, H_PUT_32 (abfd, src->e_flags, dst->e_flags); H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize); H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize); - H_PUT_16 (abfd, src->e_phnum, dst->e_phnum); + tmp = src->e_phnum; + if (tmp >= PN_XNUM) + tmp = PN_XNUM; + H_PUT_16 (abfd, tmp, dst->e_phnum); H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize); tmp = src->e_shnum; if (tmp >= SHN_LORESERVE) @@ -629,6 +632,14 @@ elf_object_p (bfd *abfd) /* And similarly for the string table index. */ if (i_ehdrp->e_shstrndx == SHN_XINDEX) i_ehdrp->e_shstrndx = i_shdr.sh_link; + + /* And similarly for the program header count. */ + if (i_ehdrp->e_phnum == PN_XNUM) + { + i_ehdrp->e_phnum = i_shdr.sh_info; + if (i_ehdrp->e_phnum != i_shdr.sh_info) + goto got_wrong_format_error; + } } /* Allocate space for a copy of the section header table in @@ -950,6 +961,8 @@ elf_write_shdrs_and_ehdr (bfd *abfd) i_shdrp[0]->sh_size = i_ehdrp->e_shnum; if (i_ehdrp->e_shstrndx >= SHN_LORESERVE) i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx; + if (i_ehdrp->e_phnum >= PN_XNUM) + i_shdrp[0]->sh_info = i_ehdrp->e_phnum; /* at this point we've concocted all the ELF sections... */ amt = i_ehdrp->e_shnum; diff --git a/gnu/usr.bin/binutils/bfd/elfcore.h b/gnu/usr.bin/binutils/bfd/elfcore.h index 81c4cff1139..4a658bffa42 100644 --- a/gnu/usr.bin/binutils/bfd/elfcore.h +++ b/gnu/usr.bin/binutils/bfd/elfcore.h @@ -176,6 +176,31 @@ elf_core_file_p (bfd *abfd) if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) goto wrong; + if (i_ehdrp->e_phnum == PN_XNUM) + { + Elf_External_Shdr x_shdr; /* Section header table entry, external form */ + Elf_Internal_Shdr i_shdr; /* Section header table, internal form */ + bfd_signed_vma where = i_ehdrp->e_shoff; + + if (i_ehdrp->e_shoff == 0 || i_ehdrp->e_shnum < 1 + || i_ehdrp->e_shentsize != sizeof (x_shdr) + || where != (file_ptr) where) + goto wrong; + + /* Seek to the section header table in the file. */ + if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0) + goto wrong; + + /* Read the first section header at index 0, and convert to internal + form. */ + if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) + goto wrong; + elf_swap_shdr_in (abfd, &x_shdr, &i_shdr); + i_ehdrp->e_phnum = i_shdr.sh_info; + if (i_ehdrp->e_phnum != i_shdr.sh_info) + goto wrong; + } + /* Does BFD's idea of the phdr size match the size recorded in the file? */ if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr)) diff --git a/gnu/usr.bin/binutils/binutils/readelf.c b/gnu/usr.bin/binutils/binutils/readelf.c index 9911e5ee7c8..12771b2c6aa 100644 --- a/gnu/usr.bin/binutils/binutils/readelf.c +++ b/gnu/usr.bin/binutils/binutils/readelf.c @@ -2835,8 +2835,11 @@ process_file_header (void) (long) elf_header.e_ehsize); printf (_(" Size of program headers: %ld (bytes)\n"), (long) elf_header.e_phentsize); - printf (_(" Number of program headers: %ld\n"), + printf (_(" Number of program headers: %ld"), (long) elf_header.e_phnum); + if (section_headers != NULL && elf_header.e_phnum == PN_XNUM) + printf (" (%ld)", (long) section_headers[0].sh_info); + putc ('\n', stdout); printf (_(" Size of section headers: %ld (bytes)\n"), (long) elf_header.e_shentsize); printf (_(" Number of section headers: %ld"), @@ -2853,6 +2856,8 @@ process_file_header (void) if (section_headers != NULL) { + if (elf_header.e_phnum == PN_XNUM) + elf_header.e_phnum = section_headers[0].sh_info; if (elf_header.e_shnum == 0) elf_header.e_shnum = section_headers[0].sh_size; if (elf_header.e_shstrndx == SHN_XINDEX) diff --git a/gnu/usr.bin/binutils/include/elf/common.h b/gnu/usr.bin/binutils/include/elf/common.h index 562543338ce..5decb810d1e 100644 --- a/gnu/usr.bin/binutils/include/elf/common.h +++ b/gnu/usr.bin/binutils/include/elf/common.h @@ -272,6 +272,9 @@ #define EV_NONE 0 /* Invalid ELF version */ #define EV_CURRENT 1 /* Current version */ +/* Magic for e_phnum: get real value from sh_info of first section header */ +#define PN_XNUM 0xffff + /* Values for program header, p_type field. */ #define PT_NULL 0 /* Program header table entry unused */ |