svn commit: r367462 - in stable/12: contrib/elftoolchain/elfcopy contrib/elftoolchain/libelf contrib/elftoolchain/libelftc contrib/elftoolchain/readelf contrib/elftoolchain/strings lib/libelf sys/s...

Dimitry Andric dim at FreeBSD.org
Sat Nov 7 19:55:07 UTC 2020


Author: dim
Date: Sat Nov  7 19:55:03 2020
New Revision: 367462
URL: https://svnweb.freebsd.org/changeset/base/367462

Log:
  Sync up elftoolchain with head, except for the capsicum-related commits,
  which are incompatible with stable/12.
  
  MFC r345360 (by oshogbo):
  
  strings: do not depend on stdin
  
  Instead of depending on one stdin FILE structure and use freopen(3), pass to
  the functions appropriate FILE structure.
  
  Reviewed by:	cem
  Discussed with:	emaste
  Differential Revision:	https://reviews.freebsd.org/D18037
  
  MFC r345361 (by oshogbo):
  
  strings: do not continue if getc or getcharacter returns EOF
  
  Reported by:	cem
  
  MFC r345362 (by oshogbo):
  
  Fix powerpc and arm builds after r345361.
  
  Reported by:	jenkins
  
  MFC r345364 (by oshogbo):
  
  In case of ENCODING_8BIT the EOF code will be pass to putchar.
  EOF check should be done before (uint8_t)c > 127 test.
  
  Reported by:	cem
  
  MFC r345431 (by oshogbo):
  
  strings: return an error code and the char value separately
  
  If we returning 32 bits value it's hard to distinguish if the returned value
  is a valid one or if its an error (in case of EOF). For that reason separate
  exit code of the function from the returned character.
  
  Reported by:	cem, se
  
  MFC r346323 (by emaste):
  
  readelf: speed up readelf -wo
  
  Use an array instead of STAILQ, and sort at the end instead of while
  adding new elements.
  
  PR:		212539
  Submitted by:	Bora Özarslan <borako.ozarslan at gmail.com>
  Reviewed by:	markj
  Sponsored by:	The FreeBSD Foundation
  
  MFC r346327 (by emaste):
  
  readelf: use size_t for object counts
  
  PR:		212539
  Reported by:	cem
  Sponsored by:	The FreeBSD Foundation
  
  MFC r348776 (by csjp):
  
  Teach readelf about some OpenBSD ELF program headers
  
  - Add constants for OpenBSD wxneeded, bootdata and randomize to the
    FreeBSD elf_common.h file. This is the file that gets used by the
    elftoolchain library.
  - Update readelf and elfdump utilities to decode these program headers
    if they are encountered.
  
  Note: FreeBSD has it's own version of elfdump(1), which will be updated
  in a subsequent commit. I am adding it here anyway because this diff is
  going to be submitted upstream.
  
  Discussed with:	emaste
  Reviewed by:	imp
  MFC afer:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D20548
  
  M    contrib/elftoolchain/elfdump/elfdump.c
  M    contrib/elftoolchain/readelf/readelf.c
  M    sys/sys/elf_common.h
  
  MFC r349510 (by luporl):
  
  [PowerPC64] readelf: print description for 'e_flags' in ELF header (ABI type)
  
  This prints out description text with the meaning of 'Flags' value in PowerPC64.
  
  Example:
  
  $ readelf -h ~/tmp/t1-Flag2
  ELF Header:
  
  Magic:   7f 45 4c 46 02 02 01 09 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            FreeBSD
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           PowerPC 64-bit
  Version:                           0x1
  Entry point address:               0x10010000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          209368 (bytes into file)
  Flags:                             0x2, OpenPOWER ELF V2 ABI
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         10
  Size of section headers:           64 (bytes)
  Number of section headers:         34
  Section header string table index: 31
  
  Submitted by:	 alfredo.junior_eldorado.org.br
  Reviewed by:	luporl
  Differential Revision:	https://reviews.freebsd.org/D20782
  
  MFC r350511 (by emaste):
  
  readelf: decode NT_GNU_PROPERTY_TYPE_0 / GNU_PROPERTY_X86_FEATURE_1_AND
  
  These bits are used for Intel CET IBT/Shadow Stack.
  
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D20516
  
  MFC r354544 (by emaste):
  
  elfcopy/strip: Ensure sections have required alignment on output
  
  Object files may specify insufficient alignment on certain sections, for
  example due to a bug in NASM[1].  When we detect that case in elfcopy or
  strip, emit a warning and increase the alignment to the minimum
  required.
  
  The NASM bug was fixed in 2015[2], but we might as well have this fixup
  (and warning) in elfcopy in case we encounter such a file for any other
  reason.
  
  This might be reworked somewhat upstream - see ELF Tool Chain
  ticket 485[3].
  
  [1] https://bugzilla.nasm.us/show_bug.cgi?id=3392307
  [2] https://repo.or.cz/w/nasm.git/commit/1f0cb0f2c1ba632c0fab02424928cfb756a9160c
  [3] https://sourceforge.net/p/elftoolchain/tickets/485/
  
  PR:		198611
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D2292
  
  MFC r357540 (by markj):
  
  readelf: Fix a double close of the input file.
  
  The caller of dump_object() is responsible for opening the file, let it
  be responsible for closing too.
  
  CID:		1411588
  Sponsored by:	The FreeBSD Foundation
  
  MFC r357541 (by markj):
  
  readelf: Fix the check for an error from realloc().
  
  Use err() instead of errx() while here, since realloc() sets errno.
  
  CID:		1401326
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358499 (by emaste):
  
  readelf: add PROTMAX_DISABLE and STKGAP_DISABLE
  
  From r349609 (PROTMAX_DISABLE) and r354790 (STKGAP_DISABLE).  Commited
  upstream (in a slightly different form) as r3831.
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358631 (by emaste):
  
  Reserve WXNEEDED ELF feature control flag
  
  This will be used to tag binaries that require W+X mappings, in advance
  of the ability to prevent W^X in mmap/mprotect.
  
  There is still some discussion about the flag's name, but the ABI won't
  change even if the name does (as kib pointed out in the review).
  
  Reviewed by:	csjp, kib
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D23909
  
  MFC r358637 (by emaste):
  
  readelf: check note namesz and descsz
  
  Previously corrupt note namesz or descsz (perhaps caused by readelf's
  current lack of endian support for notes) resulted in a crash.  Check
  that namesz and descsz do not extend beyond the end of the buffer before
  trying to access name and desc data.
  
  Reported by:	jhb
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358639 (by emaste):
  
  readelf: simplify namesz / descsz checks
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358685 (by emaste):
  
  libelf: rationalize error handling in ELF note conversion
  
  Previously _libelf_cvt_NOTE_tom (to host) returned false if a note's
  namesz + descsz exceeded the buffer size, while _libelf_cvt_NOTE_tof
  (to file) silently truncated.  Return false in the latter case too.
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358706 (by emaste):
  
  readelf: add XEN_ELFNOTE_PHYS32_ENTRY note
  
  See r336469 for details.
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358708 (by emaste):
  
  readelf: decode and print Xen ELF note strings
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r358713 (by emaste):
  
  readelf: print GNU Build-ID
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r359189 (by emaste):
  
  readelf: simplify Xen string note printing
  
  Reviewed by:	markj
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D24140
  
  MFC r361662 (by emaste):
  
  readelf: add more DT_FLAGS_1 flags
  
  Reference:
  https://docs.oracle.com/cd/E36784_01/html/E36857/chapter6-42444.html
  
  > DF_1_SINGLETON  Singleton symbols exist.
  > DF_1_STUB       Object is a stub.
  > DF_1_PIE        Object is a position-independent executable.
  
  Sponsored by:	The FreeBSD Foundation
  
  MFC r364517 (by kib):
  
  Reserve FreeBSD ELF feature control bit LA48 to control VA layout on amd64.
  
  Tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  Differential revision:	https://reviews.freebsd.org/D25273
  
  MFC r365489 (by bdragon):
  
  [PowerPC64LE] PPC64LE support for libelf.
  
  Fix native detection when building on powerpc64le.
  
  I will be submitting this and r361104 upstream shortly.
  
  Sponsored by:	Tag1 Consulting, Inc.
  
  MFC r366977 (by emaste):
  
  libelf: add compression header support
  
  GNU and Oracle libelf implementations added support for section
  compression, intended to reduce the size of DWARF debug info (which
  might be an order of magnitude larger than the code).
  
  There are two compressed ELF section formats:
  
  1. Old GNU - sections are renmaed to start with 'z'.  Section contains
     a magic number, uncompressed size, and compressed data.
  
  2. Oracle and New GNU - compressed sections use the SHF_COMPRESSED flag.
     The compression header contains the compression type, uncompressed
     size, and uncompressed alignment.
  
  The second style is preferred and this change implements only that one.
  
  Submitted by:	Tiger Gao <tig at FreeBSDFoundation.org>
  Reviewed by:	markj
  Relnotes:	Yes
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D24566
  
  MFC r367209 (by emaste):
  
  readelf: Add -z decompression support
  
  Compatible with GNU readelf, -z decompresses sections displayed by
  -x or -p.
  
  ELF Tool Chain ticket #555
  https://sourceforge.net/p/elftoolchain/tickets/555/
  
  Submitted by:	Tiger Gao <tig at FreeBSDFoundation.org>
  Reviewed by:	markj
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:    https://reviews.freebsd.org/D26909
  
  MFC r367238 (by bdragon):
  
  Fix 32-bit build after r367209
  
  Fix build on systems with a 32-bit size_t.
  
  Since it's being passed as a pointer, a 64-bit write to it will overflow.
  
  MFC with:	r367209
  
  MFC r367322 (by dim):
  
  Merge elftoolchain r3877 (by jkoshy):
  
    Incorporate fixes from Dimitry Andric:
  
    - Use a BUFFER_GROW() macro to avoid rounding errors in capacity
      calculations.
    - Fix a bug introduced in [r3531].
    - Fix handling of nested template parameters.
  
    Ticket:	#581
  
  This should fix a number of assertions on elftoolchain's cxxfilt, and
  allow it to correctly demangle several names that it could not handle
  before.
  
  Obtained from:	https://sourceforge.net/p/elftoolchain/code/3877/
  PR:		250702

Added:
  stable/12/contrib/elftoolchain/libelf/gelf_chdr.c
     - copied unchanged from r366977, head/contrib/elftoolchain/libelf/gelf_chdr.c
  stable/12/contrib/elftoolchain/libelf/gelf_getchdr.3
     - copied unchanged from r366977, head/contrib/elftoolchain/libelf/gelf_getchdr.3
  stable/12/contrib/elftoolchain/libelf/libelf_chdr.c
     - copied unchanged from r366977, head/contrib/elftoolchain/libelf/libelf_chdr.c
Modified:
  stable/12/contrib/elftoolchain/elfcopy/sections.c
  stable/12/contrib/elftoolchain/libelf/Version.map
  stable/12/contrib/elftoolchain/libelf/_libelf.h
  stable/12/contrib/elftoolchain/libelf/_libelf_config.h
  stable/12/contrib/elftoolchain/libelf/gelf.3
  stable/12/contrib/elftoolchain/libelf/gelf.h
  stable/12/contrib/elftoolchain/libelf/libelf.h
  stable/12/contrib/elftoolchain/libelf/libelf_convert.m4
  stable/12/contrib/elftoolchain/libelftc/_libelftc.h
  stable/12/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
  stable/12/contrib/elftoolchain/libelftc/libelftc_vstr.c
  stable/12/contrib/elftoolchain/readelf/readelf.1
  stable/12/contrib/elftoolchain/readelf/readelf.c
  stable/12/contrib/elftoolchain/strings/strings.c
  stable/12/lib/libelf/Makefile
  stable/12/sys/sys/elf_common.h
  stable/12/usr.bin/elfctl/elfctl.c
  stable/12/usr.bin/readelf/Makefile
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/contrib/elftoolchain/elfcopy/sections.c
==============================================================================
--- stable/12/contrib/elftoolchain/elfcopy/sections.c	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/elfcopy/sections.c	Sat Nov  7 19:55:03 2020	(r367462)
@@ -890,6 +890,43 @@ pad_section(struct elfcopy *ecp, struct section *s)
 		    elf_errmsg(-1));
 }
 
+static int
+section_type_alignment(int sht, int class)
+{
+	switch (sht)
+	{
+	case SHT_DYNAMIC:
+	case SHT_DYNSYM:
+	case SHT_FINI_ARRAY:
+	case SHT_GNU_HASH:
+	case SHT_INIT_ARRAY:
+	case SHT_PREINIT_ARRAY:
+	case SHT_REL:
+	case SHT_RELA:
+	case SHT_SYMTAB:
+		return (class == ELFCLASS64 ? 8 : 4);
+	case SHT_SUNW_move:
+		return (8);
+	case SHT_GNU_LIBLIST:
+	case SHT_GROUP:
+	case SHT_HASH:
+	case SHT_NOTE:
+	case SHT_SUNW_verdef:	/* == SHT_GNU_verdef */
+	case SHT_SUNW_verneed:	/* == SHT_GNU_verneed */
+	case SHT_SYMTAB_SHNDX:
+		return (4);
+	case SHT_SUNW_syminfo:
+	case SHT_SUNW_versym:	/* == SHT_GNU_versym */
+		return (2);
+	case SHT_NOBITS:
+	case SHT_PROGBITS:
+	case SHT_STRTAB:
+	case SHT_SUNW_dof:
+		return (1);
+	}
+	return (1);
+}
+
 void
 resync_sections(struct elfcopy *ecp)
 {
@@ -897,6 +934,7 @@ resync_sections(struct elfcopy *ecp)
 	GElf_Shdr	 osh;
 	uint64_t	 off;
 	int		 first;
+	int		 min_alignment;
 
 	ps = NULL;
 	first = 1;
@@ -919,6 +957,12 @@ resync_sections(struct elfcopy *ecp)
 		/* Align section offset. */
 		if (s->align == 0)
 			s->align = 1;
+		min_alignment = section_type_alignment(s->type, ecp->oec);
+		if (s->align < INT_MAX && (int)s->align < min_alignment) {
+			warnx("section %s alignment %d increased to %d",
+			    s->name, (int)s->align, min_alignment);
+			s->align = min_alignment;
+		}
 		if (off <= s->off) {
 			if (!s->loadable || (ecp->flags & RELOCATABLE))
 				s->off = roundup(off, s->align);
@@ -948,6 +992,7 @@ resync_sections(struct elfcopy *ecp)
 			errx(EXIT_FAILURE, "gelf_getshdr() failed: %s",
 			    elf_errmsg(-1));
 		osh.sh_addr = s->vma;
+		osh.sh_addralign = s->align;
 		osh.sh_offset = s->off;
 		osh.sh_size = s->sz;
 		if (!gelf_update_shdr(s->os, &osh))

Modified: stable/12/contrib/elftoolchain/libelf/Version.map
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/Version.map	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/Version.map	Sat Nov  7 19:55:03 2020	(r367462)
@@ -91,6 +91,13 @@ global:
 	gelf_update_symshndx;
 	gelf_xlatetof;
 	gelf_xlatetom;
+};
+
+R1.1 {
+global:
+	elf32_getchdr;
+	elf64_getchdr;
+	gelf_getchdr;
 local:
 	*;
-};
+} R1.0;

Modified: stable/12/contrib/elftoolchain/libelf/_libelf.h
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/_libelf.h	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/_libelf.h	Sat Nov  7 19:55:03 2020	(r367462)
@@ -220,6 +220,7 @@ size_t	_libelf_fsize(Elf_Type _t, int _elfclass, unsig
     size_t count);
 _libelf_translator_function *_libelf_get_translator(Elf_Type _t,
     int _direction, int _elfclass, int _elfmachine);
+void	*_libelf_getchdr(Elf_Scn *_e, int _elfclass);
 void	*_libelf_getphdr(Elf *_e, int _elfclass);
 void	*_libelf_getshdr(Elf_Scn *_scn, int _elfclass);
 void	_libelf_init_elf(Elf *_e, Elf_Kind _kind);

Modified: stable/12/contrib/elftoolchain/libelf/_libelf_config.h
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/_libelf_config.h	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/_libelf_config.h	Sat Nov  7 19:55:03 2020	(r367462)
@@ -94,7 +94,11 @@
 #elif	defined(__powerpc64__)
 
 #define	LIBELF_ARCH		EM_PPC64
+#if	__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define	LIBELF_BYTEORDER	ELFDATA2LSB
+#else
 #define	LIBELF_BYTEORDER	ELFDATA2MSB
+#endif
 #define	LIBELF_CLASS		ELFCLASS64
 
 #elif	defined(__powerpc__)

Modified: stable/12/contrib/elftoolchain/libelf/gelf.3
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/gelf.3	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/gelf.3	Sat Nov  7 19:55:03 2020	(r367462)
@@ -23,7 +23,7 @@
 .\"
 .\" $Id: gelf.3 3743 2019-06-12 19:36:30Z jkoshy $
 .\"
-.Dd June 12, 2019
+.Dd October 23, 2020
 .Dt GELF 3
 .Os
 .Sh NAME
@@ -45,6 +45,8 @@ The GElf API defines the following class-independent d
 .Bl -tag -width GElf_Sxword
 .It Vt GElf_Addr
 A representation of ELF addresses.
+.It Vt GElf_Chdr
+A class-independent representation of an ELF Compression Header.
 .It Vt GElf_Dyn
 A class-independent representation of ELF
 .Sy .dynamic
@@ -144,6 +146,8 @@ native representation.
 .El
 .It "Retrieving ELF Data"
 .Bl -tag -compact -width indent
+.It Fn gelf_getchdr
+Retrieve an ELF Compression Header from the underlying ELF descriptor.
 .It Fn gelf_getdyn
 Retrieve an ELF
 .Sy .dynamic

Modified: stable/12/contrib/elftoolchain/libelf/gelf.h
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/gelf.h	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/gelf.h	Sat Nov  7 19:55:03 2020	(r367462)
@@ -39,6 +39,7 @@ typedef Elf64_Sxword	GElf_Sxword;	/* Signed long words
 typedef Elf64_Word	GElf_Word;	/* Unsigned words (32 bit) */
 typedef Elf64_Xword	GElf_Xword;	/* Unsigned long words (64 bit) */
 
+typedef Elf64_Chdr	GElf_Chdr;	/* Compressed section header */
 typedef Elf64_Dyn	GElf_Dyn;	/* ".dynamic" section entries */
 typedef Elf64_Ehdr	GElf_Ehdr;	/* ELF header */
 typedef Elf64_Phdr	GElf_Phdr;	/* Program header */
@@ -73,6 +74,7 @@ extern "C" {
 long		gelf_checksum(Elf *_elf);
 size_t		gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count,
 			unsigned int _version);
+GElf_Chdr	*gelf_getchdr(Elf_Scn *_scn, GElf_Chdr *_dst);
 int		gelf_getclass(Elf *_elf);
 GElf_Dyn	*gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst);
 GElf_Ehdr	*gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst);

Copied: stable/12/contrib/elftoolchain/libelf/gelf_chdr.c (from r366977, head/contrib/elftoolchain/libelf/gelf_chdr.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/contrib/elftoolchain/libelf/gelf_chdr.c	Sat Nov  7 19:55:03 2020	(r367462, copy of r366977, head/contrib/elftoolchain/libelf/gelf_chdr.c)
@@ -0,0 +1,82 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
+ * This software was developed by Tiger Gao under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include "_libelf.h"
+
+Elf32_Chdr *
+elf32_getchdr(Elf_Scn *s)
+{
+	return (_libelf_getchdr(s, ELFCLASS32));
+}
+
+Elf64_Chdr *
+elf64_getchdr(Elf_Scn *s)
+{
+	return (_libelf_getchdr(s, ELFCLASS64));
+}
+
+GElf_Chdr *
+gelf_getchdr(Elf_Scn *s, GElf_Chdr *d)
+{
+	int ec;
+	void *ch;
+	Elf32_Chdr *ch32;
+	Elf64_Chdr *ch64;
+
+	if (d == NULL) {
+		LIBELF_SET_ERROR(ARGUMENT, 0);
+		return (NULL);
+	}
+
+	if ((ch = _libelf_getchdr(s, ELFCLASSNONE)) == NULL)
+		return (NULL);
+
+	ec = s->s_elf->e_class;
+	assert(ec == ELFCLASS32 || ec == ELFCLASS64);
+
+	if (ec == ELFCLASS32) {
+		ch32 = (Elf32_Chdr *)ch;
+
+		d->ch_type = (Elf64_Word)ch32->ch_type;
+		d->ch_size = (Elf64_Xword)ch32->ch_size;
+		d->ch_addralign = (Elf64_Xword)ch32->ch_addralign;
+	} else {
+		ch64 = (Elf64_Chdr *)ch;
+		*d = *ch64;
+	}
+
+	return (d);
+}

Copied: stable/12/contrib/elftoolchain/libelf/gelf_getchdr.3 (from r366977, head/contrib/elftoolchain/libelf/gelf_getchdr.3)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/contrib/elftoolchain/libelf/gelf_getchdr.3	Sat Nov  7 19:55:03 2020	(r367462, copy of r366977, head/contrib/elftoolchain/libelf/gelf_getchdr.3)
@@ -0,0 +1,117 @@
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2020 The FreeBSD Foundation
+.\"
+.\" This document was written by Tiger Gao under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are
+.\" met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in
+.\"    the documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: gelf_getchdr.3 3639 2020-10-20 16:07:02Z tig $
+.\"
+.Dd October 23, 2020
+.Dt GELF_GETCHDR 3
+.Os
+.Sh NAME
+.Nm elf32_getchdr ,
+.Nm elf64_getchdr ,
+.Nm gelf_getchdr
+.Nd retrieve the compression header of a section
+.Sh LIBRARY
+.Lb libelf
+.Sh SYNOPSIS
+.In libelf.h
+.Ft "Elf32_Chdr *"
+.Fn elf32_getchdr "Elf_Scn *s"
+.Ft "Elf64_Chdr *"
+.Fn elf64_getchdr "Elf_Scn *s"
+.In gelf.h
+.Ft "GElf_Chdr *"
+.Fn gelf_getchdr "Elf_Scn *scn" "GElf_Chdr *chdr"
+.Sh DESCRIPTION
+These functions return a pointer to the ELF Compression Header data
+structure associated with section descriptor
+.Ar scn .
+.Pp
+Function
+.Fn elf32_getchdr
+retrieves a pointer to an
+.Vt Elf32_Chdr
+structure.
+Section descriptor
+.Ar scn
+must be associated with an ELF descriptor of class
+.Dv ELFCLASS32 .
+.Pp
+Function
+.Fn elf64_getchdr
+retrieves a pointer to an
+.Vt Elf64_Chdr
+structure.
+Section descriptor
+.Ar scn
+must be associated with an ELF descriptor of class
+.Dv ELFCLASS64 .
+.Pp
+Function
+.Fn gelf_getchdr
+copies the values in the compression header associated with argument
+.Ar scn
+to the structure pointed to be argument
+.Ar dst .
+The
+.Vt GElf_Chdr
+data structure is described in
+.Xr gelf 3 .
+.Sh RETURN VALUES
+Functions
+.Fn elf32_getchdr
+and
+.Fn elf64_getchdr
+return a valid pointer to the appropriate compression header on success
+or NULL if an error was encountered.
+.Pp
+Function
+.Fn gelf_getchdr
+returns argument
+.Ar dst
+if successful, or NULL if an error was encountered.
+.Sh ERRORS
+These functions may fail with the following errors:
+.Bl -tag -width "[ELF_E_RESOURCE]"
+.It Bq Er ELF_E_INVALID_SECTION_FLAGS
+Arguments
+.Ar scn
+has invalid flags.
+.It Bq Er ELF_E_INVALID_SECTION_TYPE
+Argument
+.Ar scn
+has invalid type.
+.It Bq Er ELF_E_NOT_COMPRESSED
+Argument
+.Ar scn
+is not compressed.
+.El
+.Sh SEE ALSO
+.Xr elf 3 ,
+.Xr elf_getscn 3 ,
+.Xr gelf 3 ,

Modified: stable/12/contrib/elftoolchain/libelf/libelf.h
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/libelf.h	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/libelf.h	Sat Nov  7 19:55:03 2020	(r367462)
@@ -162,6 +162,9 @@ enum Elf_Error {
 	ELF_E_SEQUENCE,	/* API calls out of sequence */
 	ELF_E_UNIMPL,	/* Feature is unimplemented */
 	ELF_E_VERSION,	/* Unknown API version */
+	ELF_E_INVALID_SECTION_FLAGS, /* Invalid ELF section header flags */
+	ELF_E_INVALID_SECTION_TYPE, /* Invalid ELF section header type */
+	ELF_E_NOT_COMPRESSED, /* Section is not compressed */
 	ELF_E_NUM	/* Max error number */
 };
 
@@ -227,6 +230,7 @@ unsigned int	elf_version(unsigned int _version);
 long		elf32_checksum(Elf *_elf);
 size_t		elf32_fsize(Elf_Type _type, size_t _count,
 			unsigned int _version);
+Elf32_Chdr	*elf32_getchdr(Elf_Scn *_scn);
 Elf32_Ehdr	*elf32_getehdr(Elf *_elf);
 Elf32_Phdr	*elf32_getphdr(Elf *_elf);
 Elf32_Shdr	*elf32_getshdr(Elf_Scn *_scn);
@@ -240,6 +244,7 @@ Elf_Data	*elf32_xlatetom(Elf_Data *_dst, const Elf_Dat
 long		elf64_checksum(Elf *_elf);
 size_t		elf64_fsize(Elf_Type _type, size_t _count,
 			unsigned int _version);
+Elf64_Chdr	*elf64_getchdr(Elf_Scn *_scn);
 Elf64_Ehdr	*elf64_getehdr(Elf *_elf);
 Elf64_Phdr	*elf64_getphdr(Elf *_elf);
 Elf64_Shdr	*elf64_getshdr(Elf_Scn *_scn);

Copied: stable/12/contrib/elftoolchain/libelf/libelf_chdr.c (from r366977, head/contrib/elftoolchain/libelf/libelf_chdr.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/contrib/elftoolchain/libelf/libelf_chdr.c	Sat Nov  7 19:55:03 2020	(r367462, copy of r366977, head/contrib/elftoolchain/libelf/libelf_chdr.c)
@@ -0,0 +1,104 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
+ * This software was developed by Tiger Gao under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gelf.h>
+#include <libelf.h>
+
+#include "_libelf.h"
+
+void *
+_libelf_getchdr(Elf_Scn *s, int ec)
+{
+	Elf *e;
+	void *sh;
+	Elf32_Shdr *sh32;
+	Elf64_Shdr *sh64;
+
+	sh32 = NULL;
+	sh64 = NULL;
+
+	if (s == NULL || (e = s->s_elf) == NULL || e->e_kind != ELF_K_ELF) {
+		LIBELF_SET_ERROR(ARGUMENT, 0);
+		return (NULL);
+	}
+
+	if (ec == ELFCLASSNONE) {
+		ec = e->e_class;
+	} else if (ec != e->e_class) {
+		LIBELF_SET_ERROR(CLASS, 0);
+		return (NULL);
+	}
+
+	if ((sh = _libelf_getshdr(s, ec)) == NULL) {
+		LIBELF_SET_ERROR(HEADER, 0);
+		return (NULL);
+	}
+
+	if (ec == ELFCLASS32) {
+		sh32 = (Elf32_Shdr *)sh;
+		if ((sh32->sh_flags & SHF_ALLOC) != 0) {
+			LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0);
+			return (NULL);
+		}
+
+		if (sh32->sh_type == SHT_NULL || sh32->sh_type == SHT_NOBITS) {
+			LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0);
+			return (NULL);
+		}
+
+		if ((sh32->sh_flags & SHF_COMPRESSED) == 0) {
+			LIBELF_SET_ERROR(NOT_COMPRESSED, 0);
+			return (NULL);
+		}
+	} else {
+		sh64 = (Elf64_Shdr *)sh;
+		if ((sh64->sh_flags & SHF_ALLOC) != 0) {
+			LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0);
+			return (NULL);
+		}
+
+		if (sh64->sh_type == SHT_NULL || sh64->sh_type == SHT_NOBITS) {
+			LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0);
+			return (NULL);
+		}
+
+		if ((sh64->sh_flags & SHF_COMPRESSED) == 0) {
+			LIBELF_SET_ERROR(NOT_COMPRESSED, 0);
+			return (NULL);
+		}
+	}
+
+	Elf_Data *d = elf_getdata(s, NULL);
+
+	if (!d)
+		return (NULL);
+
+	return ((void *)d->d_buf);
+}

Modified: stable/12/contrib/elftoolchain/libelf/libelf_convert.m4
==============================================================================
--- stable/12/contrib/elftoolchain/libelf/libelf_convert.m4	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelf/libelf_convert.m4	Sat Nov  7 19:55:03 2020	(r367462)
@@ -1022,7 +1022,7 @@ _libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, u
 		count -= sizeof(Elf_Note);
 
 		if (count < sz)
-			sz = count;
+			return (0);
 
 		(void) memcpy(dst, src, sz);
 

Modified: stable/12/contrib/elftoolchain/libelftc/_libelftc.h
==============================================================================
--- stable/12/contrib/elftoolchain/libelftc/_libelftc.h	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelftc/_libelftc.h	Sat Nov  7 19:55:03 2020	(r367462)
@@ -56,6 +56,7 @@ struct vector_str {
 };
 
 #define BUFFER_GROWFACTOR	1.618
+#define BUFFER_GROW(x)		(((x)+0.5)*BUFFER_GROWFACTOR)
 
 #define	ELFTC_FAILURE		0
 #define	ELFTC_ISDIGIT(C) 	(isdigit((C) & 0xFF))

Modified: stable/12/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
==============================================================================
--- stable/12/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c	Sat Nov  7 19:55:03 2020	(r367462)
@@ -2135,10 +2135,10 @@ cpp_demangle_read_sname(struct cpp_demangle_data *ddat
 	if (err == 0)
 		return (0);
 
-	assert(ddata->output.size > 0);
+	assert(ddata->cur_output->size > 0);
 	if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL)
 		ddata->last_sname =
-		    ddata->output.container[ddata->output.size - 1];
+		    ddata->cur_output->container[ddata->output.size - 1];
 
 	ddata->cur += len;
 
@@ -2421,7 +2421,7 @@ cpp_demangle_read_tmpl_args(struct cpp_demangle_data *
 		return (0);
 
 	limit = 0;
-	v = &ddata->output;
+	v = ddata->cur_output;
 	for (;;) {
 		idx = v->size;
 		if (!cpp_demangle_read_tmpl_arg(ddata))
@@ -3909,7 +3909,7 @@ vector_read_cmd_push(struct vector_read_cmd *v, enum r
 		return (0);
 
 	if (v->size == v->capacity) {
-		tmp_cap = v->capacity * BUFFER_GROWFACTOR;
+		tmp_cap = BUFFER_GROW(v->capacity);
 		if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL)
 			return (0);
 		for (i = 0; i < v->size; ++i)
@@ -3974,7 +3974,7 @@ vector_type_qualifier_push(struct vector_type_qualifie
 		return (0);
 
 	if (v->size == v->capacity) {
-		tmp_cap = v->capacity * BUFFER_GROWFACTOR;
+		tmp_cap = BUFFER_GROW(v->capacity);
 		if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap))
 		    == NULL)
 			return (0);

Modified: stable/12/contrib/elftoolchain/libelftc/libelftc_vstr.c
==============================================================================
--- stable/12/contrib/elftoolchain/libelftc/libelftc_vstr.c	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/libelftc/libelftc_vstr.c	Sat Nov  7 19:55:03 2020	(r367462)
@@ -152,7 +152,7 @@ vector_str_grow(struct vector_str *v)
 
 	assert(v->capacity > 0);
 
-	tmp_cap = v->capacity * BUFFER_GROWFACTOR;
+	tmp_cap = BUFFER_GROW(v->capacity);
 
 	assert(tmp_cap > v->capacity);
 
@@ -253,7 +253,7 @@ vector_str_push_vector_head(struct vector_str *dst, st
 	if (dst == NULL || org == NULL)
 		return (false);
 
-	tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR;
+	tmp_cap = BUFFER_GROW(dst->size + org->size);
 
 	if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
 		return (false);
@@ -293,7 +293,7 @@ vector_str_push_vector(struct vector_str *dst, struct 
 	if (dst == NULL || org == NULL)
 		return (false);
 
-	tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR;
+	tmp_cap = BUFFER_GROW(dst->size + org->size);
 
 	if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
 		return (false);

Modified: stable/12/contrib/elftoolchain/readelf/readelf.1
==============================================================================
--- stable/12/contrib/elftoolchain/readelf/readelf.1	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/readelf/readelf.1	Sat Nov  7 19:55:03 2020	(r367462)
@@ -24,7 +24,7 @@
 .\"
 .\" $Id: readelf.1 3753 2019-06-28 01:13:13Z emaste $
 .\"
-.Dd June 27, 2019
+.Dd October 31, 2020
 .Dt READELF 1
 .Os
 .Sh NAME
@@ -49,6 +49,7 @@
 .Fl -debug-dump Ns Op Ns = Ns Ar long-option-name , Ns ...
 .Oc
 .Op Fl x Ar section | Fl -hex-dump Ns = Ns Ar section
+.Op Fl z | Fl -decompress
 .Op Fl A | Fl -arch-specific
 .Op Fl D | Fl -use-dynamic
 .Op Fl H | Fl -help
@@ -157,6 +158,13 @@ Display the contents of the specified section in hexad
 The argument
 .Ar section
 should be the name of a section or a numeric section index.
+.It Fl z | Fl -decompress
+Decompress contents of sections specified by
+.Fl x
+or
+.Fl p
+before displaying.
+If the specified section is not compressed, it is displayed as is.
 .It Fl A | Fl -arch-specific
 This option is accepted but is currently unimplemented.
 .It Fl D | Fl -use-dynamic

Modified: stable/12/contrib/elftoolchain/readelf/readelf.c
==============================================================================
--- stable/12/contrib/elftoolchain/readelf/readelf.c	Sat Nov  7 19:42:15 2020	(r367461)
+++ stable/12/contrib/elftoolchain/readelf/readelf.c	Sat Nov  7 19:55:03 2020	(r367462)
@@ -38,12 +38,14 @@
 #include <libelftc.h>
 #include <libgen.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <zlib.h>
 
 #include "_elftc.h"
 
@@ -82,6 +84,7 @@ ELFTC_VCSID("$Id: readelf.c 3769 2019-06-29 15:15:02Z 
 #define	RE_WW	0x00040000
 #define	RE_W	0x00080000
 #define	RE_X	0x00100000
+#define	RE_Z	0x00200000
 
 /*
  * dwarf dump options.
@@ -184,6 +187,7 @@ static struct option longopts[] = {
 	{"arch-specific", no_argument, NULL, 'A'},
 	{"archive-index", no_argument, NULL, 'c'},
 	{"debug-dump", optional_argument, NULL, OPTION_DEBUG_DUMP},
+	{"decompress", no_argument, 0, 'z'},
 	{"dynamic", no_argument, NULL, 'd'},
 	{"file-header", no_argument, NULL, 'h'},
 	{"full-section-name", no_argument, NULL, 'N'},
@@ -225,6 +229,15 @@ struct mips_option {
 	const char *desc;
 };
 
+struct loc_at {
+	Dwarf_Attribute la_at;
+	Dwarf_Unsigned la_off;
+	Dwarf_Unsigned la_lowpc;
+	Dwarf_Half la_cu_psize;
+	Dwarf_Half la_cu_osize;
+	Dwarf_Half la_cu_ver;
+};
+
 static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op,
     int t);
 static const char *aeabi_adv_simd_arch(uint64_t simd);
@@ -313,11 +326,13 @@ static void dump_mips_specific_info(struct readelf *re
 static void dump_notes(struct readelf *re);
 static void dump_notes_content(struct readelf *re, const char *buf, size_t sz,
     off_t off);
-static void dump_notes_data(const char *name, uint32_t type, const char *buf,
-    size_t sz);
+static void dump_notes_data(struct readelf *re, const char *name,
+    uint32_t type, const char *buf, size_t sz);
 static void dump_svr4_hash(struct section *s);
 static void dump_svr4_hash64(struct readelf *re, struct section *s);
 static void dump_gnu_hash(struct readelf *re, struct section *s);
+static void dump_gnu_property_type_0(struct readelf *re, const char *buf,
+    size_t sz);
 static void dump_hash(struct readelf *re);
 static void dump_phdr(struct readelf *re);
 static void dump_ppc_attributes(uint8_t *p, uint8_t *pe);
@@ -341,6 +356,7 @@ static const char *get_string(struct readelf *re, int 
 static const char *get_symbol_name(struct readelf *re, int symtab, int i);
 static uint64_t get_symbol_value(struct readelf *re, int symtab, int i);
 static void load_sections(struct readelf *re);
+static int loc_at_comparator(const void *la1, const void *la2);
 static const char *mips_abi_fp(uint64_t fp);
 static const char *note_type(const char *note_name, unsigned int et,
     unsigned int nt);
@@ -359,7 +375,8 @@ static const char *ppc_abi_vector(uint64_t vec);
 static void readelf_usage(int status);
 static void readelf_version(void);
 static void search_loclist_at(struct readelf *re, Dwarf_Die die,
-    Dwarf_Unsigned lowpc);
+    Dwarf_Unsigned lowpc, struct loc_at **la_list,
+    size_t *la_list_len, size_t *la_list_cap);
 static void search_ver(struct readelf *re);
 static const char *section_type(unsigned int mach, unsigned int stype);
 static void set_cu_context(struct readelf *re, Dwarf_Half psize,
@@ -1265,6 +1282,7 @@ note_type_xen(unsigned int nt)
 	case 15: return "XEN_ELFNOTE_INIT_P2M";
 	case 16: return "XEN_ELFNOTE_MOD_START_PFN";
 	case 17: return "XEN_ELFNOTE_SUPPORTED_FEATURES";
+	case 18: return "XEN_ELFNOTE_PHYS32_ENTRY";
 	default: return (note_type_unknown(nt));
 	}
 }
@@ -2882,6 +2900,9 @@ static struct flag_desc dt_flags_1[] = {
 	{ 0x400000,		"NORELOC" },
 	{ 0x800000,		"SYMINTPOSE" },
 	{ 0x1000000,		"GLOBAUDIT" },
+	{ 0x02000000,		"SINGLETON" },
+	{ 0x04000000,		"STUB" },
+	{ DF_1_PIE,		"PIE" },
 	{ 0, NULL }
 };
 
@@ -3508,7 +3529,63 @@ dump_gnu_hash(struct readelf *re, struct section *s)
 	free(bl);
 }
 
+static struct flag_desc gnu_property_x86_feature_1_and_bits[] = {
+	{ GNU_PROPERTY_X86_FEATURE_1_IBT,	"IBT" },
+	{ GNU_PROPERTY_X86_FEATURE_1_SHSTK,	"SHSTK" },
+	{ 0, NULL }
+};
+
 static void
+dump_gnu_property_type_0(struct readelf *re, const char *buf, size_t sz)
+{
+	size_t i;
+	uint32_t type, prop_sz;
+
+	printf("      Properties: ");
+	while (sz > 0) {
+		if (sz < 8)
+			goto bad;
+
+		type = *(const uint32_t *)(const void *)buf;
+		prop_sz = *(const uint32_t *)(const void *)(buf + 4);
+		buf += 8;
+		sz -= 8;
+
+		if (prop_sz > sz)
+			goto bad;
+
+		if (type >= GNU_PROPERTY_LOPROC &&
+		    type <= GNU_PROPERTY_HIPROC) {
+			if (re->ehdr.e_machine != EM_X86_64) {
+				printf("machine type %x unknown\n",
+				    re->ehdr.e_machine);
+				goto unknown;
+			}
+			switch (type) {
+			case GNU_PROPERTY_X86_FEATURE_1_AND:
+				printf("x86 features:");
+				if (prop_sz != 4)
+					goto bad;
+				dump_flags(gnu_property_x86_feature_1_and_bits,
+				    *(const uint32_t *)(const void *)buf);
+				break;
+			}
+		}
+
+		buf += roundup2(prop_sz, 8);
+		sz -= roundup2(prop_sz, 8);
+	}
+	return;
+bad:
+	printf("corrupt GNU property\n");
+unknown:
+	printf("remaining description data:");
+	for (i = 0; i < sz; i++)
+		printf(" %02x", (unsigned char)buf[i]);
+	printf("\n");
+}
+
+static void
 dump_hash(struct readelf *re)
 {
 	struct section	*s;
@@ -3595,12 +3672,51 @@ dump_notes(struct readelf *re)
 
 static struct flag_desc note_feature_ctl_flags[] = {
 	{ NT_FREEBSD_FCTL_ASLR_DISABLE,		"ASLR_DISABLE" },
+	{ NT_FREEBSD_FCTL_PROTMAX_DISABLE,	"PROTMAX_DISABLE" },
+	{ NT_FREEBSD_FCTL_STKGAP_DISABLE,	"STKGAP_DISABLE" },
+	{ NT_FREEBSD_FCTL_WXNEEDED,		"WXNEEDED" },
 	{ 0, NULL }
 };
 
+static bool
+dump_note_string(const char *description, const char *s, size_t len)
+{
+	size_t i;
+
+	if (len == 0 || s[--len] != '\0') {
+		return (false);
+	} else {
+		for (i = 0; i < len; i++)
+			if (!isprint(s[i]))
+				return (false);
+	}
+
+	printf("   %s: %s\n", description, s);
+	return (true);
+}
+
+struct note_desc {
+	uint32_t type;
+	const char *description;
+	bool (*fp)(const char *, const char *, size_t);
+};
+
+static struct note_desc xen_notes[] = {
+	{ 5, "Xen version", dump_note_string },
+	{ 6, "Guest OS", dump_note_string },
+	{ 7, "Guest version", dump_note_string },
+	{ 8, "Loader", dump_note_string },
+	{ 9, "PAE mode", dump_note_string },
+	{ 10, "Features", dump_note_string },
+	{ 11, "BSD symtab", dump_note_string },
+	{ 0, NULL, NULL }
+};
+
 static void
-dump_notes_data(const char *name, uint32_t type, const char *buf, size_t sz)
+dump_notes_data(struct readelf *re, const char *name, uint32_t type,
+    const char *buf, size_t sz)
 {
+	struct note_desc *nd;
 	size_t i;
 	const uint32_t *ubuf;
 
@@ -3631,6 +3747,27 @@ dump_notes_data(const char *name, uint32_t type, const
 			dump_flags(note_feature_ctl_flags, ubuf[0]);
 			return;
 		}
+	} else if (strcmp(name, "GNU") == 0) {
+		switch (type) {
+		case NT_GNU_PROPERTY_TYPE_0:
+			dump_gnu_property_type_0(re, buf, sz);
+			return;
+		case NT_GNU_BUILD_ID:
+			printf("   Build ID: ");
+			for (i = 0; i < sz; i++)
+				printf("%02x", (unsigned char)buf[i]);
+			printf("\n");
+			return;
+		}
+	} else if (strcmp(name, "Xen") == 0) {
+		for (nd = xen_notes; nd->description != NULL; nd++) {
+			if (nd->type == type) {
+				if (nd->fp(nd->description, buf, sz))
+					return;
+				else
+					break;
+			}
+		}
 	}
 unknown:
 	printf("   description data:");
@@ -3644,6 +3781,7 @@ dump_notes_content(struct readelf *re, const char *buf
 {
 	Elf_Note *note;
 	const char *end, *name;
+	uint32_t namesz, descsz;
 
 	printf("\nNotes at offset %#010jx with length %#010jx:\n",
 	    (uintmax_t) off, (uintmax_t) sz);
@@ -3655,9 +3793,16 @@ dump_notes_content(struct readelf *re, const char *buf
 			return;
 		}
 		note = (Elf_Note *)(uintptr_t) buf;
+		namesz = roundup2(note->n_namesz, 4);
+		descsz = roundup2(note->n_descsz, 4);
+		if (namesz < note->n_namesz || descsz < note->n_descsz ||
+		    buf + namesz + descsz > end) {
+			warnx("invalid note header");
+			return;
+		}
 		buf += sizeof(Elf_Note);
 		name = buf;
-		buf += roundup2(note->n_namesz, 4);
+		buf += namesz;
 		/*
 		 * The name field is required to be nul-terminated, and
 		 * n_namesz includes the terminating nul in observed
@@ -3675,8 +3820,8 @@ dump_notes_content(struct readelf *re, const char *buf
 		printf("  %-13s %#010jx", name, (uintmax_t) note->n_descsz);
 		printf("      %s\n", note_type(name, re->ehdr.e_type,
 		    note->n_type));
-		dump_notes_data(name, note->n_type, buf, note->n_descsz);
-		buf += roundup2(note->n_descsz, 4);
+		dump_notes_data(re, name, note->n_type, buf, note->n_descsz);
+		buf += descsz;
 	}
 }
 
@@ -6140,21 +6285,27 @@ dump_dwarf_str(struct readelf *re)
 	}
 }
 
-struct loc_at {
-	Dwarf_Attribute la_at;
-	Dwarf_Unsigned la_off;
-	Dwarf_Unsigned la_lowpc;
-	Dwarf_Half la_cu_psize;
-	Dwarf_Half la_cu_osize;
-	Dwarf_Half la_cu_ver;
-	TAILQ_ENTRY(loc_at) la_next;
-};
+static int
+loc_at_comparator(const void *la1, const void *la2)
+{
+	const struct loc_at *left, *right;
 
-static TAILQ_HEAD(, loc_at) lalist = TAILQ_HEAD_INITIALIZER(lalist);
+	left = (const struct loc_at *)la1;
+	right = (const struct loc_at *)la2;
 
+	if (left->la_off > right->la_off)
+		return (1);
+	else if (left->la_off < right->la_off)
+		return (-1);
+	else
+		return (0);
+}
+
 static void
-search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc)
+search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc,
+    struct loc_at **la_list, size_t *la_list_len, size_t *la_list_cap)
 {
+	struct loc_at *la;
 	Dwarf_Attribute *attr_list;
 	Dwarf_Die ret_die;
 	Dwarf_Unsigned off;
@@ -6163,7 +6314,6 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, D
 	Dwarf_Half attr, form;
 	Dwarf_Bool is_info;
 	Dwarf_Error de;
-	struct loc_at *la, *nla;
 	int i, ret;
 
 	is_info = dwarf_get_die_infotypes_flag(die);
@@ -6211,33 +6361,21 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, D
 		} else
 			continue;
 
-		TAILQ_FOREACH(la, &lalist, la_next) {
-			if (off == la->la_off)
-				break;
-			if (off < la->la_off) {
-				if ((nla = malloc(sizeof(*nla))) == NULL)
-					err(EXIT_FAILURE, "malloc failed");
-				nla->la_at = attr_list[i];
-				nla->la_off = off;
-				nla->la_lowpc = lowpc;
-				nla->la_cu_psize = re->cu_psize;
-				nla->la_cu_osize = re->cu_osize;
-				nla->la_cu_ver = re->cu_ver;
-				TAILQ_INSERT_BEFORE(la, nla, la_next);
-				break;
-			}
+		if (*la_list_cap == *la_list_len) {
+			*la_list = realloc(*la_list,
+			    *la_list_cap * 2 * sizeof(**la_list));
+			if (*la_list == NULL)
+				err(EXIT_FAILURE, "realloc failed");
+			*la_list_cap *= 2;
 		}
-		if (la == NULL) {
-			if ((nla = malloc(sizeof(*nla))) == NULL)
-				err(EXIT_FAILURE, "malloc failed");
-			nla->la_at = attr_list[i];
-			nla->la_off = off;
-			nla->la_lowpc = lowpc;
-			nla->la_cu_psize = re->cu_psize;
-			nla->la_cu_osize = re->cu_osize;
-			nla->la_cu_ver = re->cu_ver;
-			TAILQ_INSERT_TAIL(&lalist, nla, la_next);
-		}
+		la = &((*la_list)[*la_list_len]);
+		la->la_at = attr_list[i];
+		la->la_off = off;
+		la->la_lowpc = lowpc;
+		la->la_cu_psize = re->cu_psize;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list