[Midnightbsd-cvs] src [11565] trunk/usr.bin/elfdump/elfdump.c: sync elfdump with freebsd.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jul 7 19:13:35 EDT 2018


Revision: 11565
          http://svnweb.midnightbsd.org/src/?rev=11565
Author:   laffer1
Date:     2018-07-07 19:13:35 -0400 (Sat, 07 Jul 2018)
Log Message:
-----------
sync elfdump with freebsd.

Modified Paths:
--------------
    trunk/usr.bin/elfdump/Makefile
    trunk/usr.bin/elfdump/elfdump.1
    trunk/usr.bin/elfdump/elfdump.c

Property Changed:
----------------
    trunk/usr.bin/elfdump/elfdump.1

Modified: trunk/usr.bin/elfdump/Makefile
===================================================================
--- trunk/usr.bin/elfdump/Makefile	2018-07-07 22:59:47 UTC (rev 11564)
+++ trunk/usr.bin/elfdump/Makefile	2018-07-07 23:13:35 UTC (rev 11565)
@@ -1,4 +1,5 @@
 # $MidnightBSD$
+# $FreeBSD: stable/10/usr.bin/elfdump/Makefile 201386 2010-01-02 10:27:05Z ed $
 
 PROG=	elfdump
 

Modified: trunk/usr.bin/elfdump/elfdump.1
===================================================================
--- trunk/usr.bin/elfdump/elfdump.1	2018-07-07 22:59:47 UTC (rev 11564)
+++ trunk/usr.bin/elfdump/elfdump.1	2018-07-07 23:13:35 UTC (rev 11565)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
 .\" Copyright (c) 2003 David O'Brien
 .\" All rights reserved.
 .\"
@@ -22,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/usr.bin/elfdump/elfdump.1 273491 2014-10-22 23:55:08Z markj $
 .\"
 .Dd January 15, 2003
 .Dt ELFDUMP 1
@@ -50,7 +51,7 @@
 .It Fl a
 Dump all information.
 .It Fl c
-Dump shared headers.
+Dump section headers.
 .It Fl d
 Dump dynamic symbols.
 .It Fl e


Property changes on: trunk/usr.bin/elfdump/elfdump.1
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/usr.bin/elfdump/elfdump.c
===================================================================
--- trunk/usr.bin/elfdump/elfdump.c	2018-07-07 22:59:47 UTC (rev 11564)
+++ trunk/usr.bin/elfdump/elfdump.c	2018-07-07 23:13:35 UTC (rev 11565)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 David O'Brien.  All rights reserved.
  * Copyright (c) 2001 Jake Burkholder
@@ -26,9 +27,11 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/elfdump/elfdump.c 307834 2016-10-24 00:46:38Z emaste $");
 
 #include <sys/types.h>
+
+#include <sys/capability.h>
 #include <sys/elf32.h>
 #include <sys/elf64.h>
 #include <sys/endian.h>
@@ -35,6 +38,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <stddef.h>
@@ -83,7 +87,7 @@
 
 typedef enum elf_member elf_member_t;
 
-int elf32_offsets[] = {
+static int elf32_offsets[] = {
 	0,
 
 	offsetof(Elf32_Dyn, d_tag), offsetof(Elf32_Dyn, d_un.d_ptr),
@@ -124,7 +128,7 @@
 	offsetof(Elf32_Rela, r_addend)
 };
 
-int elf64_offsets[] = {
+static int elf64_offsets[] = {
 	0,
 
 	offsetof(Elf64_Dyn, d_tag), offsetof(Elf64_Dyn, d_un.d_ptr),
@@ -167,77 +171,83 @@
 
 /* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#tag_encodings */
 static const char *
-d_tags(u_int64_t tag) {
+d_tags(u_int64_t tag)
+{
+	static char unknown_tag[48];
+
 	switch (tag) {
-	case 0: return "DT_NULL";
-	case 1: return "DT_NEEDED";
-	case 2: return "DT_PLTRELSZ";
-	case 3: return "DT_PLTGOT";
-	case 4: return "DT_HASH";
-	case 5: return "DT_STRTAB";
-	case 6: return "DT_SYMTAB";
-	case 7: return "DT_RELA";
-	case 8: return "DT_RELASZ";
-	case 9: return "DT_RELAENT";
-	case 10: return "DT_STRSZ";
-	case 11: return "DT_SYMENT";
-	case 12: return "DT_INIT";
-	case 13: return "DT_FINI";
-	case 14: return "DT_SONAME";
-	case 15: return "DT_RPATH";
-	case 16: return "DT_SYMBOLIC";
-	case 17: return "DT_REL";
-	case 18: return "DT_RELSZ";
-	case 19: return "DT_RELENT";
-	case 20: return "DT_PLTREL";
-	case 21: return "DT_DEBUG";
-	case 22: return "DT_TEXTREL";
-	case 23: return "DT_JMPREL";
-	case 24: return "DT_BIND_NOW";
-	case 25: return "DT_INIT_ARRAY";
-	case 26: return "DT_FINI_ARRAY";
-	case 27: return "DT_INIT_ARRAYSZ";
-	case 28: return "DT_FINI_ARRAYSZ";
-	case 29: return "DT_RUNPATH";
-	case 30: return "DT_FLAGS";
-	case 32: return "DT_PREINIT_ARRAY"; /* XXX: DT_ENCODING */
-	case 33: return "DT_PREINIT_ARRAYSZ";
+	case DT_NULL:		return "DT_NULL";
+	case DT_NEEDED:		return "DT_NEEDED";
+	case DT_PLTRELSZ:	return "DT_PLTRELSZ";
+	case DT_PLTGOT:		return "DT_PLTGOT";
+	case DT_HASH:		return "DT_HASH";
+	case DT_STRTAB:		return "DT_STRTAB";
+	case DT_SYMTAB:		return "DT_SYMTAB";
+	case DT_RELA:		return "DT_RELA";
+	case DT_RELASZ:		return "DT_RELASZ";
+	case DT_RELAENT:	return "DT_RELAENT";
+	case DT_STRSZ:		return "DT_STRSZ";
+	case DT_SYMENT:		return "DT_SYMENT";
+	case DT_INIT:		return "DT_INIT";
+	case DT_FINI:		return "DT_FINI";
+	case DT_SONAME:		return "DT_SONAME";
+	case DT_RPATH:		return "DT_RPATH";
+	case DT_SYMBOLIC:	return "DT_SYMBOLIC";
+	case DT_REL:		return "DT_REL";
+	case DT_RELSZ:		return "DT_RELSZ";
+	case DT_RELENT:		return "DT_RELENT";
+	case DT_PLTREL:		return "DT_PLTREL";
+	case DT_DEBUG:		return "DT_DEBUG";
+	case DT_TEXTREL:	return "DT_TEXTREL";
+	case DT_JMPREL:		return "DT_JMPREL";
+	case DT_BIND_NOW:	return "DT_BIND_NOW";
+	case DT_INIT_ARRAY:	return "DT_INIT_ARRAY";
+	case DT_FINI_ARRAY:	return "DT_FINI_ARRAY";
+	case DT_INIT_ARRAYSZ:	return "DT_INIT_ARRAYSZ";
+	case DT_FINI_ARRAYSZ:	return "DT_FINI_ARRAYSZ";
+	case DT_RUNPATH:	return "DT_RUNPATH";
+	case DT_FLAGS:		return "DT_FLAGS";
+	case DT_PREINIT_ARRAY:	return "DT_PREINIT_ARRAY"; /* XXX DT_ENCODING */
+	case DT_PREINIT_ARRAYSZ:return "DT_PREINIT_ARRAYSZ";
 	/* 0x6000000D - 0x6ffff000 operating system-specific semantics */
-	case 0x6ffffdf5: return "DT_GNU_PRELINKED";
-	case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ";
-	case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ";
-	case 0x6ffffdf8: return "DT_SUNW_CHECKSUM";
-	case 0x6ffffdf9: return "DT_PLTPADSZ";
-	case 0x6ffffdfa: return "DT_MOVEENT";
-	case 0x6ffffdfb: return "DT_MOVESZ";
-	case 0x6ffffdfc: return "DT_FEATURE";
-	case 0x6ffffdfd: return "DT_POSFLAG_1";
-	case 0x6ffffdfe: return "DT_SYMINSZ";
-	case 0x6ffffdff: return "DT_SYMINENT (DT_VALRNGHI)";
-	case 0x6ffffe00: return "DT_ADDRRNGLO";
-	case 0x6ffffef8: return "DT_GNU_CONFLICT";
-	case 0x6ffffef9: return "DT_GNU_LIBLIST";
-	case 0x6ffffefa: return "DT_SUNW_CONFIG";
-	case 0x6ffffefb: return "DT_SUNW_DEPAUDIT";
-	case 0x6ffffefc: return "DT_SUNW_AUDIT";
-	case 0x6ffffefd: return "DT_SUNW_PLTPAD";
-	case 0x6ffffefe: return "DT_SUNW_MOVETAB";
-	case 0x6ffffeff: return "DT_SYMINFO (DT_ADDRRNGHI)";
-	case 0x6ffffff9: return "DT_RELACOUNT";
-	case 0x6ffffffa: return "DT_RELCOUNT";
-	case 0x6ffffffb: return "DT_FLAGS_1";
-	case 0x6ffffffc: return "DT_VERDEF";
-	case 0x6ffffffd: return "DT_VERDEFNUM";
-	case 0x6ffffffe: return "DT_VERNEED";
-	case 0x6fffffff: return "DT_VERNEEDNUM";
-	case 0x6ffffff0: return "DT_GNU_VERSYM";
+	case 0x6ffffdf5:	return "DT_GNU_PRELINKED";
+	case 0x6ffffdf6:	return "DT_GNU_CONFLICTSZ";
+	case 0x6ffffdf7:	return "DT_GNU_LIBLISTSZ";
+	case 0x6ffffdf8:	return "DT_SUNW_CHECKSUM";
+	case DT_PLTPADSZ:	return "DT_PLTPADSZ";
+	case DT_MOVEENT:	return "DT_MOVEENT";
+	case DT_MOVESZ:		return "DT_MOVESZ";
+	case DT_FEATURE:	return "DT_FEATURE";
+	case DT_POSFLAG_1:	return "DT_POSFLAG_1";
+	case DT_SYMINSZ:	return "DT_SYMINSZ";
+	case DT_SYMINENT :	return "DT_SYMINENT (DT_VALRNGHI)";
+	case DT_ADDRRNGLO:	return "DT_ADDRRNGLO";
+	case DT_GNU_HASH:	return "DT_GNU_HASH";
+	case 0x6ffffef8:	return "DT_GNU_CONFLICT";
+	case 0x6ffffef9:	return "DT_GNU_LIBLIST";
+	case DT_CONFIG:		return "DT_CONFIG";
+	case DT_DEPAUDIT:	return "DT_DEPAUDIT";
+	case DT_AUDIT:		return "DT_AUDIT";
+	case DT_PLTPAD:		return "DT_PLTPAD";
+	case DT_MOVETAB:	return "DT_MOVETAB";
+	case DT_SYMINFO :	return "DT_SYMINFO (DT_ADDRRNGHI)";
+	case DT_RELACOUNT:	return "DT_RELACOUNT";
+	case DT_RELCOUNT:	return "DT_RELCOUNT";
+	case DT_FLAGS_1:	return "DT_FLAGS_1";
+	case DT_VERDEF:		return "DT_VERDEF";
+	case DT_VERDEFNUM:	return "DT_VERDEFNUM";
+	case DT_VERNEED:	return "DT_VERNEED";
+	case DT_VERNEEDNUM:	return "DT_VERNEEDNUM";
+	case 0x6ffffff0:	return "DT_GNU_VERSYM";
 	/* 0x70000000 - 0x7fffffff processor-specific semantics */
-	case 0x70000000: return "DT_IA_64_PLT_RESERVE";
-	case 0x7ffffffd: return "DT_SUNW_AUXILIARY";
-	case 0x7ffffffe: return "DT_SUNW_USED";
-	case 0x7fffffff: return "DT_SUNW_FILTER";
-	default: return "ERROR: TAG NOT DEFINED";
+	case 0x70000000:	return "DT_IA_64_PLT_RESERVE";
+	case DT_AUXILIARY:	return "DT_AUXILIARY";
+	case DT_USED:		return "DT_USED";
+	case DT_FILTER:		return "DT_FILTER";
 	}
+	snprintf(unknown_tag, sizeof(unknown_tag),
+		"ERROR: TAG NOT DEFINED -- tag 0x%jx", (uintmax_t)tag);
+	return (unknown_tag);
 }
 
 static const char *
@@ -252,14 +262,18 @@
 	case EM_386:	return "EM_386";
 	case EM_68K:	return "EM_68K";
 	case EM_88K:	return "EM_88K";
+	case EM_IAMCU:	return "EM_IAMCU";
 	case EM_860:	return "EM_860";
 	case EM_MIPS:	return "EM_MIPS";
 	case EM_PPC:	return "EM_PPC";
+	case EM_PPC64:	return "EM_PPC64";
 	case EM_ARM:	return "EM_ARM";
 	case EM_ALPHA:	return "EM_ALPHA (legacy)";
 	case EM_SPARCV9:return "EM_SPARCV9";
 	case EM_IA_64:	return "EM_IA_64";
 	case EM_X86_64:	return "EM_X86_64";
+	case EM_AARCH64:return "EM_AARCH64";
+	case EM_RISCV:	return "EM_RISCV";
 	}
 	snprintf(machdesc, sizeof(machdesc),
 	    "(unknown machine) -- type 0x%x", mach);
@@ -266,35 +280,36 @@
 	return (machdesc);
 }
 
-const char *e_types[] = {
+static const char *e_types[] = {
 	"ET_NONE", "ET_REL", "ET_EXEC", "ET_DYN", "ET_CORE"
 };
 
-const char *ei_versions[] = {
+static const char *ei_versions[] = {
 	"EV_NONE", "EV_CURRENT"
 };
 
-const char *ei_classes[] = {
+static const char *ei_classes[] = {
 	"ELFCLASSNONE", "ELFCLASS32", "ELFCLASS64"
 };
 
-const char *ei_data[] = {
+static const char *ei_data[] = {
 	"ELFDATANONE", "ELFDATA2LSB", "ELFDATA2MSB"
 };
 
-const char *ei_abis[] = {
+static const char *ei_abis[256] = {
 	"ELFOSABI_SYSV", "ELFOSABI_HPUX", "ELFOSABI_NETBSD", "ELFOSABI_LINUX",
-	"ELFOSABI_HURD", "ELFOSABI_86OPEN", "ELFOSABI_SOLARIS",
-	"ELFOSABI_MONTEREY", "ELFOSABI_IRIX", "ELFOSABI_FREEBSD",
-	"ELFOSABI_TRU64", "ELFOSABI_MODESTO", "ELFOSABI_OPENBSD"
+	"ELFOSABI_HURD", "ELFOSABI_86OPEN", "ELFOSABI_SOLARIS", "ELFOSABI_AIX",
+	"ELFOSABI_IRIX", "ELFOSABI_FREEBSD", "ELFOSABI_TRU64",
+	"ELFOSABI_MODESTO", "ELFOSABI_OPENBSD",
+	[255] = "ELFOSABI_STANDALONE"
 };
 
-const char *p_types[] = {
+static const char *p_types[] = {
 	"PT_NULL", "PT_LOAD", "PT_DYNAMIC", "PT_INTERP", "PT_NOTE",
 	"PT_SHLIB", "PT_PHDR", "PT_TLS"
 };
 
-const char *p_flags[] = {
+static const char *p_flags[] = {
 	"", "PF_X", "PF_W", "PF_X|PF_W", "PF_R", "PF_X|PF_R", "PF_W|PF_R",
 	"PF_X|PF_W|PF_R"
 };
@@ -301,85 +316,166 @@
 
 /* http://www.sco.com/developers/gabi/latest/ch4.sheader.html#sh_type */
 static const char *
-sh_types(u_int64_t sht) {
-	switch (sht) {
-	case 0:	return "SHT_NULL";
-	case 1: return "SHT_PROGBITS";
-	case 2: return "SHT_SYMTAB";
-	case 3: return "SHT_STRTAB";
-	case 4: return "SHT_RELA";
-	case 5: return "SHT_HASH";
-	case 6: return "SHT_DYNAMIC";
-	case 7: return "SHT_NOTE";
-	case 8: return "SHT_NOBITS";
-	case 9: return "SHT_REL";
-	case 10: return "SHT_SHLIB";
-	case 11: return "SHT_DYNSYM";
-	case 14: return "SHT_INIT_ARRAY";
-	case 15: return "SHT_FINI_ARRAY";
-	case 16: return "SHT_PREINIT_ARRAY";
-	case 17: return "SHT_GROUP";
-	case 18: return "SHT_SYMTAB_SHNDX";
-	/* 0x60000000 - 0x6fffffff operating system-specific semantics */
-	case 0x6ffffff0: return "XXX:VERSYM";
-	case 0x6ffffff4: return "SHT_SUNW_dof";
-	case 0x6ffffff7: return "SHT_GNU_LIBLIST";
-	case 0x6ffffffc: return "XXX:VERDEF";
-	case 0x6ffffffd: return "SHT_SUNW(GNU)_verdef";
-	case 0x6ffffffe: return "SHT_SUNW(GNU)_verneed";
-	case 0x6fffffff: return "SHT_SUNW(GNU)_versym";
-	/* 0x70000000 - 0x7fffffff processor-specific semantics */
-	case 0x70000000: return "SHT_IA_64_EXT";
-	case 0x70000001: return "SHT_IA_64_UNWIND";
-	case 0x7ffffffd: return "XXX:AUXILIARY";
-	case 0x7fffffff: return "XXX:FILTER";
-	/* 0x80000000 - 0xffffffff application programs */
-	default: return "ERROR: SHT NOT DEFINED";
+sh_types(uint64_t machine, uint64_t sht) {
+	static char unknown_buf[64]; 
+
+	if (sht < 0x60000000) {
+		switch (sht) {
+		case SHT_NULL:		return "SHT_NULL";
+		case SHT_PROGBITS:	return "SHT_PROGBITS";
+		case SHT_SYMTAB:	return "SHT_SYMTAB";
+		case SHT_STRTAB:	return "SHT_STRTAB";
+		case SHT_RELA:		return "SHT_RELA";
+		case SHT_HASH:		return "SHT_HASH";
+		case SHT_DYNAMIC:	return "SHT_DYNAMIC";
+		case SHT_NOTE:		return "SHT_NOTE";
+		case SHT_NOBITS:	return "SHT_NOBITS";
+		case SHT_REL:		return "SHT_REL";
+		case SHT_SHLIB:		return "SHT_SHLIB";
+		case SHT_DYNSYM:	return "SHT_DYNSYM";
+		case SHT_INIT_ARRAY:	return "SHT_INIT_ARRAY";
+		case SHT_FINI_ARRAY:	return "SHT_FINI_ARRAY";
+		case SHT_PREINIT_ARRAY:	return "SHT_PREINIT_ARRAY";
+		case SHT_GROUP:		return "SHT_GROUP";
+		case SHT_SYMTAB_SHNDX:	return "SHT_SYMTAB_SHNDX";
+		}
+		snprintf(unknown_buf, sizeof(unknown_buf),
+		    "ERROR: SHT %ju NOT DEFINED", (uintmax_t)sht);
+		return (unknown_buf);
+	} else if (sht < 0x70000000) {
+		/* 0x60000000-0x6fffffff operating system-specific semantics */
+		switch (sht) {
+		case 0x6ffffff0:	return "XXX:VERSYM";
+		case SHT_SUNW_dof:	return "SHT_SUNW_dof";
+		case SHT_GNU_HASH:	return "SHT_GNU_HASH";
+		case 0x6ffffff7:	return "SHT_GNU_LIBLIST";
+		case 0x6ffffffc:	return "XXX:VERDEF";
+		case SHT_SUNW_verdef:	return "SHT_SUNW(GNU)_verdef";
+		case SHT_SUNW_verneed:	return "SHT_SUNW(GNU)_verneed";
+		case SHT_SUNW_versym:	return "SHT_SUNW(GNU)_versym";
+		}
+		snprintf(unknown_buf, sizeof(unknown_buf),
+		    "ERROR: OS-SPECIFIC SHT 0x%jx NOT DEFINED",
+		     (uintmax_t)sht);
+		return (unknown_buf);
+	} else if (sht < 0x80000000) {
+		/* 0x70000000-0x7fffffff processor-specific semantics */
+		switch (machine) {
+		case EM_ARM:
+			switch (sht) {
+			case SHT_ARM_EXIDX: return "SHT_ARM_EXIDX";
+			case SHT_ARM_PREEMPTMAP:return "SHT_ARM_PREEMPTMAP";
+			case SHT_ARM_ATTRIBUTES:return "SHT_ARM_ATTRIBUTES";
+			case SHT_ARM_DEBUGOVERLAY:
+			    return "SHT_ARM_DEBUGOVERLAY";
+			case SHT_ARM_OVERLAYSECTION:
+			    return "SHT_ARM_OVERLAYSECTION";
+			}
+			break;
+		case EM_IA_64:
+			switch (sht) {
+			case 0x70000000: return "SHT_IA_64_EXT";
+			case 0x70000001: return "SHT_IA_64_UNWIND";
+			}
+			break;
+		case EM_MIPS:
+			switch (sht) {
+			case SHT_MIPS_REGINFO: return "SHT_MIPS_REGINFO";
+			case SHT_MIPS_OPTIONS: return "SHT_MIPS_OPTIONS";
+			case SHT_MIPS_ABIFLAGS: return "SHT_MIPS_ABIFLAGS";
+			}
+			break;
+		}
+		switch (sht) {
+		case 0x7ffffffd: return "XXX:AUXILIARY";
+		case 0x7fffffff: return "XXX:FILTER";
+		}
+		snprintf(unknown_buf, sizeof(unknown_buf),
+		    "ERROR: PROCESSOR-SPECIFIC SHT 0x%jx NOT DEFINED",
+		     (uintmax_t)sht);
+		return (unknown_buf);
+	} else {
+		/* 0x80000000-0xffffffff application programs */
+		snprintf(unknown_buf, sizeof(unknown_buf),
+		    "ERROR: SHT 0x%jx NOT DEFINED",
+		     (uintmax_t)sht);
+		return (unknown_buf);
 	}
 }
 
-const char *sh_flags[] = {
+static const char *sh_flags[] = {
 	"", "SHF_WRITE", "SHF_ALLOC", "SHF_WRITE|SHF_ALLOC", "SHF_EXECINSTR",
 	"SHF_WRITE|SHF_EXECINSTR", "SHF_ALLOC|SHF_EXECINSTR",
 	"SHF_WRITE|SHF_ALLOC|SHF_EXECINSTR"
 };
 
-const char *st_types[] = {
+static const char *st_types[] = {
 	"STT_NOTYPE", "STT_OBJECT", "STT_FUNC", "STT_SECTION", "STT_FILE"
 };
 
-const char *st_bindings[] = {
+static const char *st_bindings[] = {
 	"STB_LOCAL", "STB_GLOBAL", "STB_WEAK"
 };
 
-char *dynstr;
-char *shstrtab;
-char *strtab;
-FILE *out;
+static char *dynstr;
+static char *shstrtab;
+static char *strtab;
+static FILE *out;
 
-u_int64_t elf_get_byte(Elf32_Ehdr *e, void *base, elf_member_t member);
-u_int64_t elf_get_quarter(Elf32_Ehdr *e, void *base, elf_member_t member);
-u_int64_t elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member);
-u_int64_t elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member);
-u_int64_t elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member);
+static u_int64_t elf_get_byte(Elf32_Ehdr *e, void *base, elf_member_t member);
+static u_int64_t elf_get_quarter(Elf32_Ehdr *e, void *base,
+    elf_member_t member);
+#if 0
+static u_int64_t elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member);
+#endif
+static u_int64_t elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member);
+static u_int64_t elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member);
 
-void elf_print_ehdr(Elf32_Ehdr *e);
-void elf_print_phdr(Elf32_Ehdr *e, void *p);
-void elf_print_shdr(Elf32_Ehdr *e, void *sh);
-void elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str);
-void elf_print_dynamic(Elf32_Ehdr *e, void *sh);
-void elf_print_rel(Elf32_Ehdr *e, void *r);
-void elf_print_rela(Elf32_Ehdr *e, void *ra);
-void elf_print_interp(Elf32_Ehdr *e, void *p);
-void elf_print_got(Elf32_Ehdr *e, void *sh);
-void elf_print_hash(Elf32_Ehdr *e, void *sh);
-void elf_print_note(Elf32_Ehdr *e, void *sh);
+static void elf_print_ehdr(Elf32_Ehdr *e, void *sh);
+static void elf_print_phdr(Elf32_Ehdr *e, void *p);
+static void elf_print_shdr(Elf32_Ehdr *e, void *sh);
+static void elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str);
+static void elf_print_dynamic(Elf32_Ehdr *e, void *sh);
+static void elf_print_rel(Elf32_Ehdr *e, void *r);
+static void elf_print_rela(Elf32_Ehdr *e, void *ra);
+static void elf_print_interp(Elf32_Ehdr *e, void *p);
+static void elf_print_got(Elf32_Ehdr *e, void *sh);
+static void elf_print_hash(Elf32_Ehdr *e, void *sh);
+static void elf_print_note(Elf32_Ehdr *e, void *sh);
 
-void usage(void);
+static void usage(void);
 
+/*
+ * Helpers for ELF files with shnum or shstrndx values that don't fit in the
+ * ELF header.  If the values are too large then an escape value is used to
+ * indicate that the actual value is found in one of section 0's fields.
+ */
+static uint64_t
+elf_get_shnum(Elf32_Ehdr *e, void *sh)
+{
+	uint64_t shnum;
+
+	shnum = elf_get_quarter(e, e, E_SHNUM);
+	if (shnum == 0)
+		shnum = elf_get_word(e, (char *)sh, SH_SIZE);
+	return shnum;
+}
+
+static uint64_t
+elf_get_shstrndx(Elf32_Ehdr *e, void *sh)
+{
+	uint64_t shstrndx;
+
+	shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
+	if (shstrndx == SHN_XINDEX)
+		shstrndx = elf_get_word(e, (char *)sh, SH_LINK);
+	return shstrndx;
+}
+
 int
 main(int ac, char **av)
 {
+	cap_rights_t rights;
 	u_int64_t phoff;
 	u_int64_t shoff;
 	u_int64_t phentsize;
@@ -440,6 +536,9 @@
 		case 'w':
 			if ((out = fopen(optarg, "w")) == NULL)
 				err(1, "%s", optarg);
+			cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE);
+			if (cap_rights_limit(fileno(out), &rights) < 0 && errno != ENOSYS)
+				err(1, "unable to limit rights for %s", optarg);
 			break;
 		case '?':
 		default:
@@ -452,6 +551,17 @@
 	if ((fd = open(*av, O_RDONLY)) < 0 ||
 	    fstat(fd, &sb) < 0)
 		err(1, "%s", *av);
+	cap_rights_init(&rights, CAP_MMAP_R);
+	if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS)
+		err(1, "unable to limit rights for %s", *av);
+	close(STDIN_FILENO);
+	cap_rights_init(&rights, CAP_WRITE);
+	if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
+		err(1, "unable to limit rights for stdout");
+	if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
+		err(1, "unable to limit rights for stderr");
+	if (cap_enter() < 0 && errno != ENOSYS)
+		err(1, "unable to enter capability mode");
 	e = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
 	if (e == MAP_FAILED)
 		err(1, NULL);
@@ -462,12 +572,20 @@
 	phentsize = elf_get_quarter(e, e, E_PHENTSIZE);
 	phnum = elf_get_quarter(e, e, E_PHNUM);
 	shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
-	shnum = elf_get_quarter(e, e, E_SHNUM);
-	shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
 	p = (char *)e + phoff;
-	sh = (char *)e + shoff;
-	offset = elf_get_off(e, (char *)sh + shstrndx * shentsize, SH_OFFSET);
-	shstrtab = (char *)e + offset;
+	if (shoff > 0) {
+		sh = (char *)e + shoff;
+		shnum = elf_get_shnum(e, sh);
+		shstrndx = elf_get_shstrndx(e, sh);
+		offset = elf_get_off(e, (char *)sh + shstrndx * shentsize,
+		    SH_OFFSET);
+		shstrtab = (char *)e + offset;
+	} else {
+		sh = NULL;
+		shnum = 0;
+		shstrndx = 0;
+		shstrtab = NULL;
+	}
 	for (i = 0; (u_int64_t)i < shnum; i++) {
 		name = elf_get_word(e, (char *)sh + i * shentsize, SH_NAME);
 		offset = elf_get_off(e, (char *)sh + i * shentsize, SH_OFFSET);
@@ -477,7 +595,7 @@
 			dynstr = (char *)e + offset;
 	}
 	if (flags & ED_EHDR)
-		elf_print_ehdr(e);
+		elf_print_ehdr(e, sh);
 	if (flags & ED_PHDR)
 		elf_print_phdr(e, p);
 	if (flags & ED_SHDR)
@@ -550,8 +668,8 @@
 	return 0;
 }
 
-void
-elf_print_ehdr(Elf32_Ehdr *e)
+static void
+elf_print_ehdr(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t class;
 	u_int64_t data;
@@ -584,8 +702,6 @@
 	phentsize = elf_get_quarter(e, e, E_PHENTSIZE);
 	phnum = elf_get_quarter(e, e, E_PHNUM);
 	shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
-	shnum = elf_get_quarter(e, e, E_SHNUM);
-	shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
 	fprintf(out, "\nelf header:\n");
 	fprintf(out, "\n");
 	fprintf(out, "\te_ident: %s %s %s\n", ei_classes[class], ei_data[data],
@@ -601,11 +717,15 @@
 	fprintf(out, "\te_phentsize: %jd\n", (intmax_t)phentsize);
 	fprintf(out, "\te_phnum: %jd\n", (intmax_t)phnum);
 	fprintf(out, "\te_shentsize: %jd\n", (intmax_t)shentsize);
-	fprintf(out, "\te_shnum: %jd\n", (intmax_t)shnum);
-	fprintf(out, "\te_shstrndx: %jd\n", (intmax_t)shstrndx);
+	if (sh != NULL) {
+		shnum = elf_get_shnum(e, sh);
+		shstrndx = elf_get_shstrndx(e, sh);
+		fprintf(out, "\te_shnum: %jd\n", (intmax_t)shnum);
+		fprintf(out, "\te_shstrndx: %jd\n", (intmax_t)shstrndx);
+	}
 }
 
-void
+static void
 elf_print_phdr(Elf32_Ehdr *e, void *p)
 {
 	u_int64_t phentsize;
@@ -647,7 +767,7 @@
 	}
 }
 
-void
+static void
 elf_print_shdr(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t shentsize;
@@ -662,11 +782,18 @@
 	u_int64_t info;
 	u_int64_t addralign;
 	u_int64_t entsize;
+	u_int64_t machine;
 	void *v;
 	int i;
 
+	if (sh == NULL) {
+		fprintf(out, "\nNo section headers\n");
+		return;
+	}
+
+	machine = elf_get_quarter(e, e, E_MACHINE);
 	shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
-	shnum = elf_get_quarter(e, e, E_SHNUM);
+	shnum = elf_get_shnum(e, sh);
 	fprintf(out, "\nsection header:\n");
 	for (i = 0; (u_int64_t)i < shnum; i++) {
 		v = (char *)sh + i * shentsize;
@@ -683,7 +810,7 @@
 		fprintf(out, "\n");
 		fprintf(out, "entry: %d\n", i);
 		fprintf(out, "\tsh_name: %s\n", shstrtab + name);
-		fprintf(out, "\tsh_type: %s\n", sh_types(type));
+		fprintf(out, "\tsh_type: %s\n", sh_types(machine, type));
 		fprintf(out, "\tsh_flags: %s\n", sh_flags[flags & 0x7]);
 		fprintf(out, "\tsh_addr: %#jx\n", addr);
 		fprintf(out, "\tsh_offset: %jd\n", (intmax_t)offset);
@@ -695,7 +822,7 @@
 	}
 }
 
-void
+static void
 elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str)
 {
 	u_int64_t offset;
@@ -734,7 +861,7 @@
 	}
 }
 
-void
+static void
 elf_print_dynamic(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t offset;
@@ -794,7 +921,7 @@
 	}
 }
 
-void
+static void
 elf_print_rela(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t offset;
@@ -826,7 +953,7 @@
 	}
 }
 
-void
+static void
 elf_print_rel(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t offset;
@@ -855,7 +982,7 @@
 	}
 }
 
-void
+static void
 elf_print_interp(Elf32_Ehdr *e, void *p)
 {
 	u_int64_t offset;
@@ -867,7 +994,7 @@
 	fprintf(out, "\t%s\n", s);
 }
 
-void
+static void
 elf_print_got(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t offset;
@@ -890,12 +1017,12 @@
 	}
 }
 
-void
+static void
 elf_print_hash(Elf32_Ehdr *e __unused, void *sh __unused)
 {
 }
 
-void
+static void
 elf_print_note(Elf32_Ehdr *e, void *sh)
 {
 	u_int64_t offset;
@@ -903,7 +1030,6 @@
 	u_int64_t name;
 	u_int32_t namesz;
 	u_int32_t descsz;
-	u_int32_t type;
 	u_int32_t desc;
 	char *n, *s;
 
@@ -915,7 +1041,6 @@
  	while (n < ((char *)e + offset + size)) {
 		namesz = elf_get_word(e, n, N_NAMESZ);
 		descsz = elf_get_word(e, n, N_DESCSZ);
-		type = elf_get_word(e, n, N_TYPE);
  		s = n + sizeof(Elf_Note);
  		desc = elf_get_word(e, n + sizeof(Elf_Note) + namesz, 0);
 		fprintf(out, "\t%s %d\n", s, desc);
@@ -923,7 +1048,7 @@
 	}
 }
 
-u_int64_t
+static u_int64_t
 elf_get_byte(Elf32_Ehdr *e, void *base, elf_member_t member)
 {
 	u_int64_t val;
@@ -931,10 +1056,10 @@
 	val = 0;
 	switch (e->e_ident[EI_CLASS]) {
 	case ELFCLASS32:
-		val = ((char *)base)[elf32_offsets[member]];
+		val = ((uint8_t *)base)[elf32_offsets[member]];
 		break;
 	case ELFCLASS64:
-		val = ((char *)base)[elf64_offsets[member]];
+		val = ((uint8_t *)base)[elf64_offsets[member]];
 		break;
 	case ELFCLASSNONE:
 		errx(1, "invalid class");
@@ -943,7 +1068,7 @@
 	return val;
 }
 
-u_int64_t
+static u_int64_t
 elf_get_quarter(Elf32_Ehdr *e, void *base, elf_member_t member)
 {
 	u_int64_t val;
@@ -983,7 +1108,8 @@
 	return val;
 }
 
-u_int64_t
+#if 0
+static u_int64_t
 elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member)
 {
 	u_int64_t val;
@@ -1022,8 +1148,9 @@
 
 	return val;
 }
+#endif
 
-u_int64_t
+static u_int64_t
 elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member)
 {
 	u_int64_t val;
@@ -1063,7 +1190,7 @@
 	return val;
 }
 
-u_int64_t
+static u_int64_t
 elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member)
 {
 	u_int64_t val;
@@ -1103,7 +1230,7 @@
 	return val;
 }
 
-void
+static void
 usage(void)
 {
 	fprintf(stderr, "usage: elfdump -a | -cdeGhinprs [-w file] file\n");



More information about the Midnightbsd-cvs mailing list