Blame SOURCES/file-5.33-static-PIE-binaries-1.patch

a800e3
From 493e2676626b530a45fcc17040915f34fa0c5dd3 Mon Sep 17 00:00:00 2001
a800e3
From: Vincent Mihalkovic <vmihalko@redhat.com>
a800e3
Date: Mon, 6 Feb 2023 14:39:29 +0100
a800e3
Subject: [PATCH] add parsing for dynamic sections
a800e3
a800e3
9109a696f3289ba00eaa222fd432755ec4287e28
a800e3
---
a800e3
 src/readelf.c | 295 +++++++++++++++++++++++++++++++-------------------
a800e3
 src/readelf.h | 103 ++++++++++++++++++
a800e3
 2 files changed, 289 insertions(+), 109 deletions(-)
a800e3
a800e3
diff --git a/src/readelf.c b/src/readelf.c
a800e3
index c101483..cdc211f 100644
a800e3
--- a/src/readelf.c
a800e3
+++ b/src/readelf.c
a800e3
@@ -62,13 +62,12 @@ private uint64_t getu64(int, uint64_t);
a800e3
 
a800e3
 #define MAX_PHNUM	128
a800e3
 #define	MAX_SHNUM	32768
a800e3
-#define SIZE_UNKNOWN	((off_t)-1)
a800e3
+#define SIZE_UNKNOWN	CAST(off_t, -1)
a800e3
 
a800e3
 private int
a800e3
 toomany(struct magic_set *ms, const char *name, uint16_t num)
a800e3
 {
a800e3
-	if (file_printf(ms, ", too many %s (%u)", name, num
a800e3
-	    ) == -1)
a800e3
+	if (file_printf(ms, ", too many %s (%u)", name, num) == -1)
a800e3
 		return -1;
a800e3
 	return 0;
a800e3
 }
a800e3
@@ -143,54 +142,55 @@ getu64(int swap, uint64_t value)
a800e3
 #define elf_getu64(swap, value) getu64(swap, value)
a800e3
 
a800e3
 #define xsh_addr	(clazz == ELFCLASS32			\
a800e3
-			 ? (void *)&sh32			\
a800e3
-			 : (void *)&sh64)
a800e3
+			 ? CAST(void *, &sh32)			\
a800e3
+			 : CAST(void *, &sh64))
a800e3
 #define xsh_sizeof	(clazz == ELFCLASS32			\
a800e3
 			 ? sizeof(sh32)				\
a800e3
 			 : sizeof(sh64))
a800e3
-#define xsh_size	(size_t)(clazz == ELFCLASS32		\
a800e3
+#define xsh_size	CAST(size_t, (clazz == ELFCLASS32	\
a800e3
 			 ? elf_getu32(swap, sh32.sh_size)	\
a800e3
-			 : elf_getu64(swap, sh64.sh_size))
a800e3
-#define xsh_offset	(off_t)(clazz == ELFCLASS32		\
a800e3
+			 : elf_getu64(swap, sh64.sh_size)))
a800e3
+#define xsh_offset	CAST(off_t, (clazz == ELFCLASS32	\
a800e3
 			 ? elf_getu32(swap, sh32.sh_offset)	\
a800e3
-			 : elf_getu64(swap, sh64.sh_offset))
a800e3
+			 : elf_getu64(swap, sh64.sh_offset)))
a800e3
 #define xsh_type	(clazz == ELFCLASS32			\
a800e3
 			 ? elf_getu32(swap, sh32.sh_type)	\
a800e3
 			 : elf_getu32(swap, sh64.sh_type))
a800e3
 #define xsh_name    	(clazz == ELFCLASS32			\
a800e3
 			 ? elf_getu32(swap, sh32.sh_name)	\
a800e3
 			 : elf_getu32(swap, sh64.sh_name))
a800e3
+
a800e3
 #define xph_addr	(clazz == ELFCLASS32			\
a800e3
-			 ? (void *) &ph32			\
a800e3
-			 : (void *) &ph64)
a800e3
+			 ? CAST(void *, &ph32)			\
a800e3
+			 : CAST(void *, &ph64))
a800e3
 #define xph_sizeof	(clazz == ELFCLASS32			\
a800e3
 			 ? sizeof(ph32)				\
a800e3
 			 : sizeof(ph64))
a800e3
 #define xph_type	(clazz == ELFCLASS32			\
a800e3
 			 ? elf_getu32(swap, ph32.p_type)	\
a800e3
 			 : elf_getu32(swap, ph64.p_type))
a800e3
-#define xph_offset	(off_t)(clazz == ELFCLASS32		\
a800e3
+#define xph_offset	CAST(off_t, (clazz == ELFCLASS32	\
a800e3
 			 ? elf_getu32(swap, ph32.p_offset)	\
a800e3
-			 : elf_getu64(swap, ph64.p_offset))
a800e3
-#define xph_align	(size_t)((clazz == ELFCLASS32		\
a800e3
-			 ? (off_t) (ph32.p_align ? 		\
a800e3
-			    elf_getu32(swap, ph32.p_align) : 4) \
a800e3
-			 : (off_t) (ph64.p_align ?		\
a800e3
-			    elf_getu64(swap, ph64.p_align) : 4)))
a800e3
-#define xph_vaddr	(size_t)((clazz == ELFCLASS32		\
a800e3
-			 ? (off_t) (ph32.p_vaddr ? 		\
a800e3
-			    elf_getu32(swap, ph32.p_vaddr) : 4) \
a800e3
-			 : (off_t) (ph64.p_vaddr ?		\
a800e3
-			    elf_getu64(swap, ph64.p_vaddr) : 4)))
a800e3
-#define xph_filesz	(size_t)((clazz == ELFCLASS32		\
a800e3
+			 : elf_getu64(swap, ph64.p_offset)))
a800e3
+#define xph_align	CAST(size_t, (clazz == ELFCLASS32	\
a800e3
+			 ? CAST(off_t, (ph32.p_align ? 		\
a800e3
+			    elf_getu32(swap, ph32.p_align) : 4))\
a800e3
+			 : CAST(off_t, (ph64.p_align ?		\
a800e3
+			    elf_getu64(swap, ph64.p_align) : 4))))
a800e3
+#define xph_vaddr	CAST(size_t, (clazz == ELFCLASS32	\
a800e3
+			 ? CAST(off_t, (ph32.p_vaddr ? 		\
a800e3
+			    elf_getu32(swap, ph32.p_vaddr) : 4))\
a800e3
+			 : CAST(off_t, (ph64.p_vaddr ?		\
a800e3
+			    elf_getu64(swap, ph64.p_vaddr) : 4))))
a800e3
+#define xph_filesz	CAST(size_t, (clazz == ELFCLASS32	\
a800e3
 			 ? elf_getu32(swap, ph32.p_filesz)	\
a800e3
 			 : elf_getu64(swap, ph64.p_filesz)))
a800e3
-#define xnh_addr	(clazz == ELFCLASS32			\
a800e3
-			 ? (void *)&nh32			\
a800e3
-			 : (void *)&nh64)
a800e3
-#define xph_memsz	(size_t)((clazz == ELFCLASS32		\
a800e3
+#define xph_memsz	CAST(size_t, ((clazz == ELFCLASS32	\
a800e3
 			 ? elf_getu32(swap, ph32.p_memsz)	\
a800e3
-			 : elf_getu64(swap, ph64.p_memsz)))
a800e3
+			 : elf_getu64(swap, ph64.p_memsz))))
a800e3
+#define xnh_addr	(clazz == ELFCLASS32			\
a800e3
+			 ? CAST(void *, &nh32)			\
a800e3
+			 : CAST(void *, &nh64))
a800e3
 #define xnh_sizeof	(clazz == ELFCLASS32			\
a800e3
 			 ? sizeof(nh32)				\
a800e3
 			 : sizeof(nh64))
a800e3
@@ -203,24 +203,36 @@ getu64(int swap, uint64_t value)
a800e3
 #define xnh_descsz	(clazz == ELFCLASS32			\
a800e3
 			 ? elf_getu32(swap, nh32.n_descsz)	\
a800e3
 			 : elf_getu32(swap, nh64.n_descsz))
a800e3
-#define prpsoffsets(i)	(clazz == ELFCLASS32			\
a800e3
-			 ? prpsoffsets32[i]			\
a800e3
-			 : prpsoffsets64[i])
a800e3
+
a800e3
+#define xdh_addr	(clazz == ELFCLASS32			\
a800e3
+			 ? CAST(void *, &dh32)			\
a800e3
+			 : CAST(void *, &dh64))
a800e3
+#define xdh_sizeof	(clazz == ELFCLASS32			\
a800e3
+			 ? sizeof(dh32)				\
a800e3
+			 : sizeof(dh64))
a800e3
+#define xdh_tag		(clazz == ELFCLASS32			\
a800e3
+			 ? elf_getu32(swap, dh32.d_tag)		\
a800e3
+			 : elf_getu64(swap, dh64.d_tag))
a800e3
+#define xdh_val		(clazz == ELFCLASS32			\
a800e3
+			 ? elf_getu32(swap, dh32.d_un.d_val)	\
a800e3
+			 : elf_getu64(swap, dh64.d_un.d_val))
a800e3
+
a800e3
 #define xcap_addr	(clazz == ELFCLASS32			\
a800e3
-			 ? (void *)&cap32			\
a800e3
-			 : (void *)&cap64)
a800e3
+			 ? CAST(void *, &cap32)			\
a800e3
+			 : CAST(void *, &cap64))
a800e3
 #define xcap_sizeof	(clazz == ELFCLASS32			\
a800e3
-			 ? sizeof cap32				\
a800e3
-			 : sizeof cap64)
a800e3
+			 ? sizeof(cap32)			\
a800e3
+			 : sizeof(cap64))
a800e3
 #define xcap_tag	(clazz == ELFCLASS32			\
a800e3
 			 ? elf_getu32(swap, cap32.c_tag)	\
a800e3
 			 : elf_getu64(swap, cap64.c_tag))
a800e3
 #define xcap_val	(clazz == ELFCLASS32			\
a800e3
 			 ? elf_getu32(swap, cap32.c_un.c_val)	\
a800e3
 			 : elf_getu64(swap, cap64.c_un.c_val))
a800e3
+
a800e3
 #define xauxv_addr	(clazz == ELFCLASS32			\
a800e3
-			 ? (void *)&auxv32			\
a800e3
-			 : (void *)&auxv64)
a800e3
+			 ? CAST(void *, &auxv32)		\
a800e3
+			 : CAST(void *, &auxv64))
a800e3
 #define xauxv_sizeof	(clazz == ELFCLASS32			\
a800e3
 			 ? sizeof(auxv32)			\
a800e3
 			 : sizeof(auxv64))
a800e3
@@ -231,6 +243,10 @@ getu64(int swap, uint64_t value)
a800e3
 			 ? elf_getu32(swap, auxv32.a_v)		\
a800e3
 			 : elf_getu64(swap, auxv64.a_v))
a800e3
 
a800e3
+#define prpsoffsets(i)	(clazz == ELFCLASS32			\
a800e3
+			 ? prpsoffsets32[i]			\
a800e3
+			 : prpsoffsets64[i])
a800e3
+
a800e3
 #ifdef ELFCORE
a800e3
 /*
a800e3
  * Try larger offsets first to avoid false matches
a800e3
@@ -269,8 +285,8 @@ static const size_t	prpsoffsets64[] = {
a800e3
 	16,		/* FreeBSD, 64-bit */
a800e3
 };
a800e3
 
a800e3
-#define	NOFFSETS32	(sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
a800e3
-#define NOFFSETS64	(sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
a800e3
+#define	NOFFSETS32	(sizeof(prpsoffsets32) / sizeof(prpsoffsets32[0]))
a800e3
+#define NOFFSETS64	(sizeof(prpsoffsets64) / sizeof(prpsoffsets64[0]))
a800e3
 
a800e3
 #define NOFFSETS	(clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
a800e3
 
a800e3
@@ -349,7 +365,8 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 	 * Loop through all the program headers.
a800e3
 	 */
a800e3
 	for ( ; num; num--) {
a800e3
-		if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
a800e3
+		if (pread(fd, xph_addr, xph_sizeof, off) <
a800e3
+		    CAST(ssize_t, xph_sizeof)) {
a800e3
 			file_badread(ms);
a800e3
 			return -1;
a800e3
 		}
a800e3
@@ -392,7 +409,7 @@ static void
a800e3
 do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
a800e3
 {
a800e3
 	uint32_t desc;
a800e3
-	(void)memcpy(&desc, v, sizeof(desc));
a800e3
+	memcpy(&desc, v, sizeof(desc));
a800e3
 	desc = elf_getu32(swap, desc);
a800e3
 
a800e3
 	if (file_printf(ms, ", for NetBSD") == -1)
a800e3
@@ -438,7 +455,7 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
a800e3
 {
a800e3
 	uint32_t desc;
a800e3
 
a800e3
-	(void)memcpy(&desc, v, sizeof(desc));
a800e3
+	memcpy(&desc, v, sizeof(desc));
a800e3
 	desc = elf_getu32(swap, desc);
a800e3
 	if (file_printf(ms, ", for FreeBSD") == -1)
a800e3
 		return;
a800e3
@@ -536,7 +553,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
a800e3
 		}
a800e3
 		if (file_printf(ms, ", BuildID[%s]=", btype) == -1)
a800e3
 			return 1;
a800e3
-		(void)memcpy(desc, &nbuf[doff], descsz);
a800e3
+		memcpy(desc, &nbuf[doff], descsz);
a800e3
 		for (i = 0; i < descsz; i++)
a800e3
 		    if (file_printf(ms, "%02x", desc[i]) == -1)
a800e3
 			return 1;
a800e3
@@ -560,7 +577,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
a800e3
 	if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
a800e3
 	    type == NT_GNU_VERSION && descsz == 16) {
a800e3
 		uint32_t desc[4];
a800e3
-		(void)memcpy(desc, &nbuf[doff], sizeof(desc));
a800e3
+		memcpy(desc, &nbuf[doff], sizeof(desc));
a800e3
 
a800e3
 		*flags |= FLAGS_DID_OS_NOTE;
a800e3
 		if (file_printf(ms, ", for GNU/") == -1)
a800e3
@@ -627,7 +644,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
a800e3
 		*flags |= FLAGS_DID_OS_NOTE;
a800e3
 		if (file_printf(ms, ", for DragonFly") == -1)
a800e3
 			return 1;
a800e3
-		(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
a800e3
+		memcpy(&desc, &nbuf[doff], sizeof(desc));
a800e3
 		desc = elf_getu32(swap, desc);
a800e3
 		if (file_printf(ms, " %d.%d.%d", desc / 100000,
a800e3
 		    desc / 10000 % 10, desc % 10000) == -1)
a800e3
@@ -657,7 +674,7 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
a800e3
 		int did = 0;
a800e3
 
a800e3
 		*flags |= FLAGS_DID_NETBSD_PAX;
a800e3
-		(void)memcpy(&desc, &nbuf[doff], sizeof(desc));
a800e3
+		memcpy(&desc, &nbuf[doff], sizeof(desc));
a800e3
 		desc = elf_getu32(swap, desc);
a800e3
 
a800e3
 		if (desc && file_printf(ms, ", PaX: ") == -1)
a800e3
@@ -957,7 +974,7 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
a800e3
 
a800e3
 	nval = 0;
a800e3
 	for (size_t off = 0; off + elsize <= descsz; off += elsize) {
a800e3
-		(void)memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof);
a800e3
+		memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof);
a800e3
 		/* Limit processing to 50 vector entries to prevent DoS */
a800e3
 		if (nval++ >= 50) {
a800e3
 			file_error(ms, 0, "Too many ELF Auxv elements");
a800e3
@@ -1021,6 +1038,38 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
a800e3
 #endif
a800e3
 }
a800e3
 
a800e3
+private size_t
a800e3
+dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
a800e3
+    int clazz, int swap)
a800e3
+{
a800e3
+	Elf32_Dyn dh32;
a800e3
+	Elf64_Dyn dh64;
a800e3
+	unsigned char *dbuf = CAST(unsigned char *, vbuf);
a800e3
+
a800e3
+	if (xdh_sizeof + offset > size) {
a800e3
+		/*
a800e3
+		 * We're out of note headers.
a800e3
+		 */
a800e3
+		return xdh_sizeof + offset;
a800e3
+	}
a800e3
+
a800e3
+	memcpy(xdh_addr, &dbuf[offset], xdh_sizeof);
a800e3
+	offset += xdh_sizeof;
a800e3
+
a800e3
+	switch (xdh_tag) {
a800e3
+	case DT_FLAGS_1:
a800e3
+		if (xdh_val == DF_1_PIE)
a800e3
+			ms->mode |= 0111;
a800e3
+		else
a800e3
+			ms->mode &= ~0111;
a800e3
+		break;
a800e3
+	default:
a800e3
+		break;
a800e3
+	}
a800e3
+	return offset;
a800e3
+}
a800e3
+
a800e3
+
a800e3
 private size_t
a800e3
 donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
a800e3
     int clazz, int swap, size_t align, int *flags, uint16_t *notecount,
a800e3
@@ -1043,7 +1092,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
a800e3
 		return xnh_sizeof + offset;
a800e3
 	}
a800e3
 
a800e3
-	(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
a800e3
+	memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
a800e3
 	offset += xnh_sizeof;
a800e3
 
a800e3
 	namesz = xnh_namesz;
a800e3
@@ -1057,14 +1106,14 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
a800e3
 	}
a800e3
 
a800e3
 	if (namesz & 0x80000000) {
a800e3
-	    (void)file_printf(ms, ", bad note name size %#lx",
a800e3
-		(unsigned long)namesz);
a800e3
+	    file_printf(ms, ", bad note name size %#lx",
a800e3
+		CAST(unsigned long, namesz));
a800e3
 	    return 0;
a800e3
 	}
a800e3
 
a800e3
 	if (descsz & 0x80000000) {
a800e3
-	    (void)file_printf(ms, ", bad note description size %#lx",
a800e3
-		(unsigned long)descsz);
a800e3
+	    file_printf(ms, ", bad note description size %#lx",
a800e3
+		CAST(unsigned long, descsz));
a800e3
 	    return 0;
a800e3
 	}
a800e3
 
a800e3
@@ -1118,35 +1167,25 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
a800e3
 			return offset;
a800e3
 	}
a800e3
 
a800e3
-	if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
a800e3
+	if (namesz == 7 && strcmp(CAST(char *, &nbuf[noff]), "NetBSD") == 0) {
a800e3
+		int descw, flag;
a800e3
+		const char *str, *tag;
a800e3
 		if (descsz > 100)
a800e3
 			descsz = 100;
a800e3
 		switch (xnh_type) {
a800e3
 	    	case NT_NETBSD_VERSION:
a800e3
 			return offset;
a800e3
 		case NT_NETBSD_MARCH:
a800e3
-			if (*flags & FLAGS_DID_NETBSD_MARCH)
a800e3
-				return offset;
a800e3
-			*flags |= FLAGS_DID_NETBSD_MARCH;
a800e3
-			if (file_printf(ms, ", compiled for: %.*s",
a800e3
-			    (int)descsz, (const char *)&nbuf[doff]) == -1)
a800e3
-				return offset;
a800e3
+			flag = FLAGS_DID_NETBSD_MARCH;
a800e3
+			tag = "compiled for";
a800e3
 			break;
a800e3
 		case NT_NETBSD_CMODEL:
a800e3
-			if (*flags & FLAGS_DID_NETBSD_CMODEL)
a800e3
-				return offset;
a800e3
-			*flags |= FLAGS_DID_NETBSD_CMODEL;
a800e3
-			if (file_printf(ms, ", compiler model: %.*s",
a800e3
-			    (int)descsz, (const char *)&nbuf[doff]) == -1)
a800e3
-				return offset;
a800e3
+			flag = FLAGS_DID_NETBSD_CMODEL;
a800e3
+			tag = "compiler model";
a800e3
 			break;
a800e3
 		case NT_NETBSD_EMULATION:
a800e3
-			if (*flags & FLAGS_DID_NETBSD_EMULATION)
a800e3
-				return offset;
a800e3
-			*flags |= FLAGS_DID_NETBSD_EMULATION;
a800e3
-			if (file_printf(ms, ", emulation: %.*s",
a800e3
-			    (int)descsz, (const char *)&nbuf[doff]) == -1)
a800e3
-				return offset;
a800e3
+			flag = FLAGS_DID_NETBSD_EMULATION;
a800e3
+			tag = "emulation:";
a800e3
 			break;
a800e3
 		default:
a800e3
 			if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
a800e3
@@ -1154,8 +1193,15 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
a800e3
 			*flags |= FLAGS_DID_NETBSD_UNKNOWN;
a800e3
 			if (file_printf(ms, ", note=%u", xnh_type) == -1)
a800e3
 				return offset;
a800e3
-			break;
a800e3
+			return offset;
a800e3
 		}
a800e3
+
a800e3
+		if (*flags & flag)
a800e3
+			return offset;
a800e3
+		str = CAST(const char *, &nbuf[doff]);
a800e3
+		descw = CAST(int, descsz);
a800e3
+		*flags |= flag;
a800e3
+		file_printf(ms, ", %s: %.*s", tag, descw, str);
a800e3
 		return offset;
a800e3
 	}
a800e3
 
a800e3
@@ -1236,7 +1282,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 
a800e3
 	/* Read offset of name section to be able to read section names later */
a800e3
 	if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab)))
a800e3
-	    < (ssize_t)xsh_sizeof) {
a800e3
+	    < CAST(ssize_t, xsh_sizeof)) {
a800e3
 		if (file_printf(ms, ", missing section headers") == -1)
a800e3
 			return -1;
a800e3
 		return 0;
a800e3
@@ -1245,7 +1291,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 
a800e3
 	for ( ; num; num--) {
a800e3
 		/* Read the name of this section. */
a800e3
-		if ((namesize = pread(fd, name, sizeof(name) - 1, name_off + xsh_name)) == -1) {
a800e3
+		if ((namesize = pread(fd, name, sizeof(name) - 1,
a800e3
+		    name_off + xsh_name)) == -1) {
a800e3
 			file_badread(ms);
a800e3
 			return -1;
a800e3
 		}
a800e3
@@ -1255,7 +1302,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 			stripped = 0;
a800e3
 		}
a800e3
 
a800e3
-		if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) {
a800e3
+		if (pread(fd, xsh_addr, xsh_sizeof, off) <
a800e3
+		    CAST(ssize_t, xsh_sizeof)) {
a800e3
 			file_badread(ms);
a800e3
 			return -1;
a800e3
 		}
a800e3
@@ -1281,14 +1329,15 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 		/* Things we can determine when we seek */
a800e3
 		switch (xsh_type) {
a800e3
 		case SHT_NOTE:
a800e3
-			if ((uintmax_t)(xsh_size + xsh_offset) >
a800e3
-			    (uintmax_t)fsize) {
a800e3
+			if (CAST(uintmax_t, (xsh_size + xsh_offset)) >
a800e3
+			    CAST(uintmax_t, fsize)) {
a800e3
 				if (file_printf(ms,
a800e3
 				    ", note offset/size %#" INTMAX_T_FORMAT
a800e3
 				    "x+%#" INTMAX_T_FORMAT "x exceeds"
a800e3
 				    " file size %#" INTMAX_T_FORMAT "x",
a800e3
-				    (uintmax_t)xsh_offset, (uintmax_t)xsh_size,
a800e3
-				    (uintmax_t)fsize) == -1)
a800e3
+				    CAST(uintmax_t, xsh_offset),
a800e3
+				    CAST(uintmax_t, xsh_size),
a800e3
+				    CAST(uintmax_t, fsize)) == -1)
a800e3
 					return -1;
a800e3
 				return 0; 
a800e3
 			}
a800e3
@@ -1298,7 +1347,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 				return -1;
a800e3
 			}
a800e3
 			if (pread(fd, nbuf, xsh_size, xsh_offset) <
a800e3
-			    (ssize_t)xsh_size) {
a800e3
+			    CAST(ssize_t, xsh_size)) {
a800e3
 				file_badread(ms);
a800e3
 				free(nbuf);
a800e3
 				return -1;
a800e3
@@ -1306,9 +1355,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 
a800e3
 			noff = 0;
a800e3
 			for (;;) {
a800e3
-				if (noff >= (off_t)xsh_size)
a800e3
+				if (noff >= CAST(off_t, xsh_size))
a800e3
 					break;
a800e3
-				noff = donote(ms, nbuf, (size_t)noff,
a800e3
+				noff = donote(ms, nbuf, CAST(size_t, noff),
a800e3
 				    xsh_size, clazz, swap, 4, flags, notecount,
a800e3
 				    fd, 0, 0, 0);
a800e3
 				if (noff == 0)
a800e3
@@ -1330,7 +1379,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 
a800e3
 			if (nbadcap > 5)
a800e3
 				break;
a800e3
-			if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
a800e3
+			if (lseek(fd, xsh_offset, SEEK_SET)
a800e3
+			    == CAST(off_t, -1)) {
a800e3
 				file_badseek(ms);
a800e3
 				return -1;
a800e3
 			}
a800e3
@@ -1339,11 +1389,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 				Elf32_Cap cap32;
a800e3
 				Elf64_Cap cap64;
a800e3
 				char cbuf[/*CONSTCOND*/
a800e3
-				    MAX(sizeof cap32, sizeof cap64)];
a800e3
-				if ((coff += xcap_sizeof) > (off_t)xsh_size)
a800e3
+				    MAX(sizeof(cap32), sizeof(cap64))];
a800e3
+				if ((coff += xcap_sizeof) >
a800e3
+				    CAST(off_t, xsh_size))
a800e3
 					break;
a800e3
-				if (read(fd, cbuf, (size_t)xcap_sizeof) !=
a800e3
-				    (ssize_t)xcap_sizeof) {
a800e3
+				if (read(fd, cbuf, CAST(size_t, xcap_sizeof)) !=
a800e3
+				    CAST(ssize_t, xcap_sizeof)) {
a800e3
 					file_badread(ms);
a800e3
 					return -1;
a800e3
 				}
a800e3
@@ -1377,7 +1428,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 #endif
a800e3
 					break;
a800e3
 				}
a800e3
-				(void)memcpy(xcap_addr, cbuf, xcap_sizeof);
a800e3
+				memcpy(xcap_addr, cbuf, xcap_sizeof);
a800e3
 				switch (xcap_tag) {
a800e3
 				case CA_SUNW_NULL:
a800e3
 					break;
a800e3
@@ -1392,8 +1443,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 					    ", with unknown capability "
a800e3
 					    "%#" INT64_T_FORMAT "x = %#"
a800e3
 					    INT64_T_FORMAT "x",
a800e3
-					    (unsigned long long)xcap_tag,
a800e3
-					    (unsigned long long)xcap_val) == -1)
a800e3
+					    CAST(unsigned long long, xcap_tag),
a800e3
+					    CAST(unsigned long long, xcap_val))
a800e3
+					    == -1)
a800e3
 						return -1;
a800e3
 					if (nbadcap++ > 2)
a800e3
 						coff = xsh_size;
a800e3
@@ -1446,12 +1498,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 				if (file_printf(ms,
a800e3
 				    " unknown hardware capability %#"
a800e3
 				    INT64_T_FORMAT "x",
a800e3
-				    (unsigned long long)cap_hw1) == -1)
a800e3
+				    CAST(unsigned long long, cap_hw1)) == -1)
a800e3
 					return -1;
a800e3
 		} else {
a800e3
 			if (file_printf(ms,
a800e3
 			    " hardware capability %#" INT64_T_FORMAT "x",
a800e3
-			    (unsigned long long)cap_hw1) == -1)
a800e3
+			    CAST(unsigned long long, cap_hw1)) == -1)
a800e3
 				return -1;
a800e3
 		}
a800e3
 	}
a800e3
@@ -1468,7 +1520,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
a800e3
 			if (file_printf(ms,
a800e3
 			    ", with unknown software capability %#"
a800e3
 			    INT64_T_FORMAT "x",
a800e3
-			    (unsigned long long)cap_sf1) == -1)
a800e3
+			    CAST(unsigned long long, cap_sf1)) == -1)
a800e3
 				return -1;
a800e3
 	}
a800e3
 	return 0;
a800e3
@@ -1487,9 +1539,9 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 	Elf32_Phdr ph32;
a800e3
 	Elf64_Phdr ph64;
a800e3
 	const char *linking_style = "statically";
a800e3
-	const char *interp = "";
a800e3
 	unsigned char nbuf[BUFSIZ];
a800e3
 	char ibuf[BUFSIZ];
a800e3
+	char interp[BUFSIZ];
a800e3
 	ssize_t bufsize;
a800e3
 	size_t offset, align, len;
a800e3
 	
a800e3
@@ -1499,8 +1551,11 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 		return 0;
a800e3
 	}
a800e3
 
a800e3
+	interp[0] = '\0';
a800e3
   	for ( ; num; num--) {
a800e3
-		if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
a800e3
+		int doread;
a800e3
+		if (pread(fd, xph_addr, xph_sizeof, off) <
a800e3
+		    CAST(ssize_t, xph_sizeof)) {
a800e3
 			file_badread(ms);
a800e3
 			return -1;
a800e3
 		}
a800e3
@@ -1513,6 +1568,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 		switch (xph_type) {
a800e3
 		case PT_DYNAMIC:
a800e3
 			linking_style = "dynamically";
a800e3
+			doread = 1;
a800e3
 			break;
a800e3
 		case PT_NOTE:
a800e3
 			if (sh_num)	/* Did this through section headers */
a800e3
@@ -1521,21 +1577,16 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 			    align < 4) {
a800e3
 				if (file_printf(ms, 
a800e3
 				    ", invalid note alignment %#lx",
a800e3
-				    (unsigned long)align) == -1)
a800e3
+				    CAST(unsigned long, align)) == -1)
a800e3
 					return -1;
a800e3
 				align = 4;
a800e3
 			}
a800e3
 			/*FALLTHROUGH*/
a800e3
 		case PT_INTERP:
a800e3
-			len = xph_filesz < sizeof(nbuf) ? xph_filesz
a800e3
-			    : sizeof(nbuf);
a800e3
-			bufsize = pread(fd, nbuf, len, xph_offset);
a800e3
-			if (bufsize == -1) {
a800e3
-				file_badread(ms);
a800e3
-				return -1;
a800e3
-			}
a800e3
+			doread = 1;
a800e3
 			break;
a800e3
 		default:
a800e3
+			doread = 0;
a800e3
 			if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
a800e3
 				/* Maybe warn here? */
a800e3
 				continue;
a800e3
@@ -1543,14 +1594,39 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 			break;
a800e3
 		}
a800e3
 
a800e3
+		if (doread) {
a800e3
+			len = xph_filesz < sizeof(nbuf) ? xph_filesz
a800e3
+			    : sizeof(nbuf);
a800e3
+			bufsize = pread(fd, nbuf, len, xph_offset);
a800e3
+			if (bufsize == -1) {
a800e3
+				file_badread(ms);
a800e3
+				return -1;
a800e3
+			}
a800e3
+		} else
a800e3
+			len = 0;
a800e3
+
a800e3
 		/* Things we can determine when we seek */
a800e3
 		switch (xph_type) {
a800e3
+		case PT_DYNAMIC:
a800e3
+			offset = 0;
a800e3
+			for (;;) {
a800e3
+				if (offset >= (size_t)bufsize)
a800e3
+					break;
a800e3
+				offset = dodynamic(ms, nbuf, offset,
a800e3
+				    CAST(size_t, bufsize), clazz, swap);
a800e3
+				if (offset == 0)
a800e3
+					break;
a800e3
+			}
a800e3
+                        if (ms->flags & MAGIC_MIME)
a800e3
+                                continue;
a800e3
+			break;
a800e3
+
a800e3
 		case PT_INTERP:
a800e3
 			if (bufsize && nbuf[0]) {
a800e3
 				nbuf[bufsize - 1] = '\0';
a800e3
-				interp = (const char *)nbuf;
a800e3
+				memcpy(interp, nbuf, bufsize);
a800e3
 			} else
a800e3
-				interp = "*empty*";
a800e3
+				strlcpy(interp, "*empty*", sizeof(interp));
a800e3
 			break;
a800e3
 		case PT_NOTE:
a800e3
 			/*
a800e3
@@ -1562,7 +1638,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
a800e3
 				if (offset >= (size_t)bufsize)
a800e3
 					break;
a800e3
 				offset = donote(ms, nbuf, offset,
a800e3
-				    (size_t)bufsize, clazz, swap, align,
a800e3
+				    CAST(size_t, bufsize), clazz, swap, align,
a800e3
 				    flags, notecount, fd, 0, 0, 0);
a800e3
 				if (offset == 0)
a800e3
 					break;
a800e3
@@ -1591,7 +1667,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
a800e3
 	size_t nbytes = b->flen;
a800e3
 	union {
a800e3
 		int32_t l;
a800e3
-		char c[sizeof (int32_t)];
a800e3
+		char c[sizeof(int32_t)];
a800e3
 	} u;
a800e3
 	int clazz;
a800e3
 	int swap;
a800e3
@@ -1619,7 +1695,8 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
a800e3
 	/*
a800e3
 	 * If we cannot seek, it must be a pipe, socket or fifo.
a800e3
 	 */
a800e3
-	if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
a800e3
+	if((lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1))
a800e3
+	    && (errno == ESPIPE))
a800e3
 		fd = file_pipe2file(ms, fd, buf, nbytes);
a800e3
 
a800e3
 	if (fstat(fd, &st) == -1) {
a800e3
diff --git a/src/readelf.h b/src/readelf.h
a800e3
index ef880b9..f2f3dc3 100644
a800e3
--- a/src/readelf.h
a800e3
+++ b/src/readelf.h
a800e3
@@ -430,4 +430,107 @@ typedef struct {
a800e3
 #define	AV_386_SSE4_1		0x00800000
a800e3
 #define	AV_386_SSE4_2		0x01000000
a800e3
 
a800e3
+/*
a800e3
+ * Dynamic Section structure array
a800e3
+ */
a800e3
+typedef struct {
a800e3
+	Elf32_Word		d_tag;	/* entry tag value */
a800e3
+	union {
a800e3
+		Elf32_Addr	d_ptr;
a800e3
+		Elf32_Word	d_val;
a800e3
+	} d_un;
a800e3
+} Elf32_Dyn;
a800e3
+
a800e3
+typedef struct {
a800e3
+	Elf64_Xword		d_tag;	/* entry tag value */
a800e3
+	union {
a800e3
+		Elf64_Addr	d_ptr;
a800e3
+		Elf64_Xword	d_val;
a800e3
+	} d_un;
a800e3
+} Elf64_Dyn;
a800e3
+
a800e3
+/* d_tag */
a800e3
+#define DT_NULL		0	/* Marks end of dynamic array */
a800e3
+#define DT_NEEDED	1	/* Name of needed library (DT_STRTAB offset) */
a800e3
+#define DT_PLTRELSZ	2	/* Size, in bytes, of relocations in PLT */
a800e3
+#define DT_PLTGOT	3	/* Address of PLT and/or GOT */
a800e3
+#define DT_HASH		4	/* Address of symbol hash table */
a800e3
+#define DT_STRTAB	5	/* Address of string table */
a800e3
+#define DT_SYMTAB	6	/* Address of symbol table */
a800e3
+#define DT_RELA		7	/* Address of Rela relocation table */
a800e3
+#define DT_RELASZ	8	/* Size, in bytes, of DT_RELA table */
a800e3
+#define DT_RELAENT	9	/* Size, in bytes, of one DT_RELA entry */
a800e3
+#define DT_STRSZ	10	/* Size, in bytes, of DT_STRTAB table */
a800e3
+#define DT_SYMENT	11	/* Size, in bytes, of one DT_SYMTAB entry */
a800e3
+#define DT_INIT		12	/* Address of initialization function */
a800e3
+#define DT_FINI		13	/* Address of termination function */
a800e3
+#define DT_SONAME	14	/* Shared object name (DT_STRTAB offset) */
a800e3
+#define DT_RPATH	15	/* Library search path (DT_STRTAB offset) */
a800e3
+#define DT_SYMBOLIC	16	/* Start symbol search within local object */
a800e3
+#define DT_REL		17	/* Address of Rel relocation table */
a800e3
+#define DT_RELSZ	18	/* Size, in bytes, of DT_REL table */
a800e3
+#define DT_RELENT	19	/* Size, in bytes, of one DT_REL entry */
a800e3
+#define DT_PLTREL	20	/* Type of PLT relocation entries */
a800e3
+#define DT_DEBUG	21	/* Used for debugging; unspecified */
a800e3
+#define DT_TEXTREL	22	/* Relocations might modify non-writable seg */
a800e3
+#define DT_JMPREL	23	/* Address of relocations associated with PLT */
a800e3
+#define DT_BIND_NOW	24	/* Process all relocations at load-time */
a800e3
+#define DT_INIT_ARRAY	25	/* Address of initialization function array */
a800e3
+#define DT_FINI_ARRAY	26	/* Size, in bytes, of DT_INIT_ARRAY array */
a800e3
+#define DT_INIT_ARRAYSZ 27	/* Address of termination function array */
a800e3
+#define DT_FINI_ARRAYSZ 28	/* Size, in bytes, of DT_FINI_ARRAY array*/
a800e3
+#define DT_RUNPATH	29	/* overrides DT_RPATH */
a800e3
+#define DT_FLAGS	30	/* Encodes ORIGIN, SYMBOLIC, TEXTREL, BIND_NOW, STATIC_TLS */
a800e3
+#define DT_ENCODING	31	/* ??? */
a800e3
+#define DT_PREINIT_ARRAY 32	/* Address of pre-init function array */
a800e3
+#define DT_PREINIT_ARRAYSZ 33	/* Size, in bytes, of DT_PREINIT_ARRAY array */
a800e3
+#define DT_NUM		34
a800e3
+
a800e3
+#define DT_LOOS		0x60000000	/* Operating system specific range */
a800e3
+#define DT_VERSYM	0x6ffffff0	/* Symbol versions */
a800e3
+#define DT_FLAGS_1	0x6ffffffb	/* ELF dynamic flags */
a800e3
+#define DT_VERDEF	0x6ffffffc	/* Versions defined by file */
a800e3
+#define DT_VERDEFNUM	0x6ffffffd	/* Number of versions defined by file */
a800e3
+#define DT_VERNEED	0x6ffffffe	/* Versions needed by file */
a800e3
+#define DT_VERNEEDNUM	0x6fffffff	/* Number of versions needed by file */
a800e3
+#define DT_HIOS		0x6fffffff
a800e3
+#define DT_LOPROC	0x70000000	/* Processor-specific range */
a800e3
+#define DT_HIPROC	0x7fffffff
a800e3
+
a800e3
+/* Flag values for DT_FLAGS */
a800e3
+#define DF_ORIGIN	0x00000001	/* uses $ORIGIN */
a800e3
+#define DF_SYMBOLIC	0x00000002	/* */
a800e3
+#define DF_TEXTREL	0x00000004	/* */
a800e3
+#define DF_BIND_NOW	0x00000008	/* */
a800e3
+#define DF_STATIC_TLS	0x00000010	/* */
a800e3
+
a800e3
+/* Flag values for DT_FLAGS_1 */
a800e3
+#define	DF_1_NOW	0x00000001	/* Same as DF_BIND_NOW */
a800e3
+#define	DF_1_GLOBAL	0x00000002	/* Unused */
a800e3
+#define	DF_1_GROUP	0x00000004	/* Is member of group */
a800e3
+#define	DF_1_NODELETE	0x00000008	/* Cannot be deleted from process */
a800e3
+#define	DF_1_LOADFLTR	0x00000010	/* Immediate loading of filters */
a800e3
+#define	DF_1_INITFIRST	0x00000020	/* init/fini takes priority */
a800e3
+#define	DF_1_NOOPEN	0x00000040	/* Do not allow loading on dlopen() */
a800e3
+#define	DF_1_ORIGIN	0x00000080 	/* Require $ORIGIN processing */
a800e3
+#define	DF_1_DIRECT	0x00000100	/* Enable direct bindings */
a800e3
+#define	DF_1_INTERPOSE 	0x00000400	/* Is an interposer */
a800e3
+#define	DF_1_NODEFLIB	0x00000800 	/* Ignore default library search path */
a800e3
+#define	DF_1_NODUMP	0x00001000 	/* Cannot be dumped with dldump(3C) */
a800e3
+#define	DF_1_CONFALT	0x00002000 	/* Configuration alternative */
a800e3
+#define	DF_1_ENDFILTEE	0x00004000	/* Filtee ends filter's search */
a800e3
+#define	DF_1_DISPRELDNE	0x00008000	/* Did displacement relocation */
a800e3
+#define	DF_1_DISPRELPND 0x00010000	/* Pending displacement relocation */
a800e3
+#define	DF_1_NODIRECT	0x00020000 	/* Has non-direct bindings */
a800e3
+#define	DF_1_IGNMULDEF	0x00040000	/* Used internally */
a800e3
+#define	DF_1_NOKSYMS	0x00080000	/* Used internally */
a800e3
+#define	DF_1_NOHDR	0x00100000	/* Used internally */
a800e3
+#define	DF_1_EDITED	0x00200000	/* Has been modified since build */
a800e3
+#define	DF_1_NORELOC	0x00400000 	/* Used internally */
a800e3
+#define	DF_1_SYMINTPOSE 0x00800000 	/* Has individual symbol interposers */
a800e3
+#define	DF_1_GLOBAUDIT	0x01000000	/* Require global auditing */
a800e3
+#define	DF_1_SINGLETON	0x02000000	/* Has singleton symbols */
a800e3
+#define	DF_1_STUB	0x04000000	/* Stub */
a800e3
+#define	DF_1_PIE	0x08000000	/* Position Independent Executable */
a800e3
+
a800e3
 #endif
a800e3
-- 
a800e3
2.39.1
a800e3