summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2018-12-11 17:09:07 +0000
committerguenther <guenther@openbsd.org>2018-12-11 17:09:07 +0000
commitf244d5f5cf50cebece55bf767d5b7e10ab218f62 (patch)
tree753524a97369a26d5243cc23ef8d2c73df1a2990
parentadd a non regression test that triggers the nettle bug (diff)
downloadwireguard-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.h15
-rw-r--r--gnu/usr.bin/binutils-2.17/bfd/elfcore.h25
-rw-r--r--gnu/usr.bin/binutils/bfd/elfcode.h15
-rw-r--r--gnu/usr.bin/binutils/bfd/elfcore.h25
-rw-r--r--gnu/usr.bin/binutils/binutils/readelf.c7
-rw-r--r--gnu/usr.bin/binutils/include/elf/common.h3
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 */