]> git.pld-linux.org Git - packages/rpm.git/blame - rpm-file-readelf.patch
- updated
[packages/rpm.git] / rpm-file-readelf.patch
CommitLineData
0749e45a
AM
1diff -ur rpm.org/file/src/readelf.c rpm/file/src/readelf.c
2--- rpm.org/file/src/readelf.c 2004-06-14 16:30:54.607870936 +0200
3+++ rpm/file/src/readelf.c 2004-03-22 21:28:40.000000000 +0100
4@@ -1,25 +1,70 @@
5-#include "system.h"
b6942f9f
JB
6+/*
7+ * Copyright (c) Christos Zoulas 2003.
8+ * All Rights Reserved.
9+ *
10+ * Redistribution and use in source and binary forms, with or without
11+ * modification, are permitted provided that the following conditions
12+ * are met:
13+ * 1. Redistributions of source code must retain the above copyright
14+ * notice immediately at the beginning of the file, without modification,
15+ * this list of conditions, and the following disclaimer.
16+ * 2. Redistributions in binary form must reproduce the above copyright
17+ * notice, this list of conditions and the following disclaimer in the
18+ * documentation and/or other materials provided with the distribution.
19+ * 3. The name of the author may not be used to endorse or promote products
20+ * derived from this software without specific prior written permission.
21+ *
22+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
26+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32+ * SUCH DAMAGE.
33+ */
0749e45a 34+#include "file.h"
b6942f9f
JB
35
36 #ifdef BUILTIN_ELF
0749e45a
AM
37-#include "file.h"
38+#include <string.h>
39+#include <ctype.h>
40+#include <stdlib.h>
41+#ifdef HAVE_UNISTD_H
42+#include <unistd.h>
43+#endif
44+
45 #include "readelf.h"
46-#include "debug.h"
47
48-FILE_RCSID("@(#)Id: readelf.c,v 1.22 2002/07/03 18:26:38 christos Exp ")
49+#ifndef lint
50+FILE_RCSID("@(#)$Id$")
51+#endif
b6942f9f 52
0749e45a
AM
53-/*@access fmagic @*/
54+#ifdef ELFCORE
55+private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t);
56+#endif
57+private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t);
58+private int doshn(struct magic_set *, int, int, int, off_t, int, size_t);
59+private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int,
60+ int, size_t);
b6942f9f
JB
61+
62+#define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
0749e45a
AM
63+
64+private uint16_t getu16(int, uint16_t);
65+private uint32_t getu32(int, uint32_t);
66+private uint64_t getu64(int, uint64_t);
67
68-/*@-bounds@*/
69-static uint16_t
70-getu16(const fmagic fm, uint16_t value)
71- /*@*/
72+private uint16_t
73+getu16(int swap, uint16_t value)
74 {
75 union {
76 uint16_t ui;
77 char c[2];
78 } retval, tmpval;
79
80- if (fm->swap) {
81+ if (swap) {
82 tmpval.ui = value;
83
84 retval.c[0] = tmpval.c[1];
85@@ -30,16 +75,15 @@
86 return value;
87 }
88
89-static uint32_t
90-getu32(const fmagic fm, uint32_t value)
91- /*@*/
92+private uint32_t
93+getu32(int swap, uint32_t value)
94 {
95 union {
96 uint32_t ui;
97 char c[4];
98 } retval, tmpval;
99
100- if (fm->swap) {
101+ if (swap) {
102 tmpval.ui = value;
b6942f9f 103
0749e45a
AM
104 retval.c[0] = tmpval.c[3];
105@@ -52,16 +96,15 @@
106 return value;
107 }
108
109-static uint64_t
110-getu64(const fmagic fm, uint64_t value)
111- /*@*/
112+private uint64_t
113+getu64(int swap, uint64_t value)
114 {
115 union {
116 uint64_t ui;
117 char c[8];
118 } retval, tmpval;
119
120- if (fm->swap) {
121+ if (swap) {
122 tmpval.ui = value;
123
124 retval.c[0] = tmpval.c[7];
125@@ -77,294 +120,65 @@
126 } else
127 return value;
128 }
129-/*@=bounds@*/
130
131-#define sh_addr (fm->cls == ELFCLASS32 \
132+#define sh_addr (class == ELFCLASS32 \
133 ? (void *) &sh32 \
134 : (void *) &sh64)
135-#define sh_size (fm->cls == ELFCLASS32 \
136+#define sh_size (class == ELFCLASS32 \
137 ? sizeof sh32 \
138 : sizeof sh64)
139-#define shs_type (fm->cls == ELFCLASS32 \
140- ? getu32(fm, sh32.sh_type) \
141- : getu32(fm, sh64.sh_type))
142-
143-#define ph_addr (fm->cls == ELFCLASS32 \
144+#define shs_type (class == ELFCLASS32 \
145+ ? getu32(swap, sh32.sh_type) \
146+ : getu32(swap, sh64.sh_type))
147+#define ph_addr (class == ELFCLASS32 \
148 ? (void *) &ph32 \
149 : (void *) &ph64)
150-#define ph_size (fm->cls == ELFCLASS32 \
151+#define ph_size (class == ELFCLASS32 \
152 ? sizeof ph32 \
153 : sizeof ph64)
154-#define ph_type (fm->cls == ELFCLASS32 \
155- ? getu32(fm, ph32.p_type) \
156- : getu32(fm, ph64.p_type))
157-#define ph_offset (fm->cls == ELFCLASS32 \
158- ? getu32(fm, ph32.p_offset) \
159- : getu64(fm, ph64.p_offset))
b6942f9f
JB
160-#define ph_align (fm->cls == ELFCLASS32 \
161- ? (ph32.p_align ? getu32(fm, ph32.p_align) : 4) \
162- : (ph64.p_align ? getu64(fm, ph64.p_align) : 4))
0749e45a
AM
163-#define ph_filesz (fm->cls == ELFCLASS32 \
164- ? getu32(fm, ph32.p_filesz) \
165- : getu64(fm, ph64.p_filesz))
166-
167-#define nh_type (fm->cls == ELFCLASS32 \
b6942f9f
JB
168- ? getu32(fm, nh32->n_type) \
169- : getu32(fm, nh64->n_type))
0749e45a 170-#define nh_namesz (fm->cls == ELFCLASS32 \
b6942f9f
JB
171- ? getu32(fm, nh32->n_namesz) \
172- : getu32(fm, nh64->n_namesz))
0749e45a 173-#define nh_descsz (fm->cls == ELFCLASS32 \
b6942f9f
JB
174- ? getu32(fm, nh32->n_descsz) \
175- : getu32(fm, nh64->n_descsz))
0749e45a
AM
176-#define prpsoffsets(i) (fm->cls == ELFCLASS32 \
177+#define ph_type (class == ELFCLASS32 \
178+ ? getu32(swap, ph32.p_type) \
179+ : getu32(swap, ph64.p_type))
180+#define ph_offset (class == ELFCLASS32 \
181+ ? getu32(swap, ph32.p_offset) \
182+ : getu64(swap, ph64.p_offset))
183+#define ph_align (size_t)((class == ELFCLASS32 \
184+ ? (off_t) (ph32.p_align ? \
185+ getu32(swap, ph32.p_align) : 4) \
186+ : (off_t) (ph64.p_align ? \
187+ getu64(swap, ph64.p_align) : 4)))
188+#define nh_size (class == ELFCLASS32 \
189+ ? sizeof nh32 \
190+ : sizeof nh64)
191+#define nh_type (class == ELFCLASS32 \
192+ ? getu32(swap, nh32.n_type) \
193+ : getu32(swap, nh64.n_type))
194+#define nh_namesz (class == ELFCLASS32 \
195+ ? getu32(swap, nh32.n_namesz) \
196+ : getu32(swap, nh64.n_namesz))
197+#define nh_descsz (class == ELFCLASS32 \
198+ ? getu32(swap, nh32.n_descsz) \
199+ : getu32(swap, nh64.n_descsz))
200+#define prpsoffsets(i) (class == ELFCLASS32 \
b6942f9f
JB
201 ? prpsoffsets32[i] \
202 : prpsoffsets64[i])
203
204-/*@-bounds@*/
205-static void
206-doshn(fmagic fm, off_t off, int num, size_t size)
207- /*@globals fileSystem @*/
208- /*@modifies fm, fileSystem @*/
209-{
210- Elf32_Shdr sh32;
211- Elf64_Shdr sh64;
212-
213- if (size != sh_size) {
214- error(EXIT_FAILURE, 0, "corrupted program header size.\n");
215- /*@notreached@*/
216- }
217-
218- if (lseek(fm->fd, off, SEEK_SET) == -1) {
219- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
220- /*@notreached@*/
221- }
222-
223- for ( ; num; num--) {
224- if (read(fm->fd, sh_addr, size) == -1) {
225- error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
226- /*@notreached@*/
227- }
228- if (shs_type == SHT_SYMTAB /* || shs_type == SHT_DYNSYM */) {
229- file_printf(fm, ", not stripped");
230- return;
231- }
232- }
233- file_printf(fm, ", stripped");
234-}
235-/*@=bounds@*/
236-
237-/*
238- * Look through the program headers of an executable image, searching
239- * for a PT_INTERP section; if one is found, it's dynamically linked,
240- * otherwise it's statically linked.
241- */
242-/*@-bounds@*/
243-static void
244-dophn_exec(fmagic fm, off_t off, int num, size_t size)
245- /*@globals fileSystem @*/
246- /*@modifies fm, fileSystem @*/
247-{
248- Elf32_Phdr ph32;
249- Elf32_Nhdr *nh32 = NULL;
250- Elf64_Phdr ph64;
251- Elf64_Nhdr *nh64 = NULL;
252- char *linking_style = "statically";
253- char *shared_libraries = "";
254- char nbuf[BUFSIZ];
0749e45a
AM
255- int nb;
256- size_t nbufsize, offset, end, noff, doff;
257- size_t align = (fm->cls == ELFCLASS32 ? 4 : 8);
258-#define ALIGNED_LEN(len) (((len) + align - 1) & ~(align - 1))
259- int printed;
b6942f9f
JB
260-
261- if (size != ph_size) {
262- error(EXIT_FAILURE, 0, "corrupted program header size.\n");
263- /*@notreached@*/
264- }
265-
266- if (lseek(fm->fd, off, SEEK_SET) == -1) {
267- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
268- /*@notreached@*/
269- }
270-
271- for ( ; num; num--) {
0749e45a
AM
272- /* Read the program header data. */
273- nb = read(fm->fd, ph_addr, size);
274- if (nb == -1) {
b6942f9f
JB
275- error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
276- /*@notreached@*/
277- }
278-
0749e45a
AM
279- /* XXX Elf64 notes cannot be read, so don't attempt for now. */
280-#if !defined(__i386__)
281- if (ph_type == PT_NOTE)
282- break;
283-#endif
284-
b6942f9f
JB
285- switch (ph_type) {
286- case PT_DYNAMIC:
287- linking_style = "dynamically";
288- /*@switchbreak@*/ break;
289- case PT_INTERP:
290- shared_libraries = " (uses shared libs)";
291- /*@switchbreak@*/ break;
292- case PT_NOTE:
293- /*
294- * This is a PT_NOTE section; loop through all the notes
295- * in the section.
296- */
297- if (lseek(fm->fd, (off_t) ph_offset, SEEK_SET) == -1) {
298- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
299- /*@notreached@*/
300- }
0749e45a
AM
301-
302- /* XXX Read only the notes section. */
303- nbufsize = (ph_filesz < sizeof(nbuf)
304- ? ph_filesz : sizeof(nbuf));
305- nb = read(fm->fd, nbuf, nbufsize);
306- if (nb == -1) {
b6942f9f
JB
307- error(EXIT_FAILURE, 0, ": " "read failed (%s).\n",
308- strerror(errno));
309- /*@notreached@*/
310- }
311- offset = 0;
0749e45a 312- printed = 0;
b6942f9f 313- for (;;) {
0749e45a
AM
314- end = offset + 12;
315- if (end >= nb)
b6942f9f 316- /*@innerbreak@*/ break;
0749e45a 317-
b6942f9f
JB
318- if (fm->cls == ELFCLASS32)
319- nh32 = (Elf32_Nhdr *)&nbuf[offset];
320- else
321- nh64 = (Elf64_Nhdr *)&nbuf[offset];
b6942f9f 322-
0749e45a 323- offset = end; /* skip note header. */
b6942f9f 324-
0749e45a
AM
325- /* XXX Avoid notes that are not 1-16 bytes */
326- if (nh_namesz <= 0 || nh_descsz <= 0)
327- break;
328- if (nh_namesz > 16 || nh_descsz > 16)
329- break;
b6942f9f 330-
0749e45a
AM
331- end = offset + ALIGNED_LEN (nh_namesz)
332- + ALIGNED_LEN (nh_descsz);
333- if (end > nb)
b6942f9f
JB
334- /*@innerbreak@*/ break;
335-
0749e45a
AM
336- noff = offset;
337- doff = ALIGNED_LEN(offset + nh_namesz);
338- offset = end;
339-
340- if (printed)
341- continue;
342-
b6942f9f 343- if (nh_namesz == 4 &&
0749e45a 344- strcmp(&nbuf[noff], "GNU") == 0 &&
b6942f9f
JB
345- nh_type == NT_GNU_VERSION &&
346- nh_descsz == 16) {
347- uint32_t *desc =
0749e45a 348- (uint32_t *)&nbuf[doff];
b6942f9f 349-
0749e45a 350- if (!printed)
b6942f9f
JB
351- file_printf(fm, ", for GNU/");
352- switch (getu32(fm, desc[0])) {
353- case GNU_OS_LINUX:
354- file_printf(fm, "Linux");
355- /*@switchbreak@*/ break;
356- case GNU_OS_HURD:
357- file_printf(fm, "Hurd");
358- /*@switchbreak@*/ break;
359- case GNU_OS_SOLARIS:
360- file_printf(fm, "Solaris");
361- /*@switchbreak@*/ break;
362- default:
363- file_printf(fm, "<unknown>");
364- /*@switchbreak@*/ break;
365- }
366- file_printf(fm, " %d.%d.%d",
367- getu32(fm, desc[1]),
368- getu32(fm, desc[2]),
369- getu32(fm, desc[3]));
0749e45a 370- printed = 1;
b6942f9f
JB
371- }
372-
373- if (nh_namesz == 7 &&
0749e45a 374- strcmp(&nbuf[noff], "NetBSD") == 0 &&
b6942f9f
JB
375- nh_type == NT_NETBSD_VERSION &&
376- nh_descsz == 4) {
377- file_printf(fm, ", for NetBSD");
378- /*
379- * Version number is stuck at 199905,
380- * and hence is basically content-free.
381- */
0749e45a 382- printed = 1;
b6942f9f
JB
383- }
384-
385- if (nh_namesz == 8 &&
0749e45a 386- strcmp(&nbuf[noff], "FreeBSD") == 0 &&
b6942f9f
JB
387- nh_type == NT_FREEBSD_VERSION &&
388- nh_descsz == 4) {
389- uint32_t desc = getu32(fm,
0749e45a 390- *(uint32_t *)&nbuf[doff]);
b6942f9f
JB
391- file_printf(fm, ", for FreeBSD");
392- /*
393- * Contents is __FreeBSD_version,
394- * whose relation to OS versions is
395- * defined by a huge table in the
396- * Porters' Handbook. Happily, the
397- * first three digits are the version
398- * number, at least in versions of
399- * FreeBSD that use this note.
400- */
401-
402- file_printf(fm, " %d.%d", desc / 100000,
403- desc / 10000 % 10);
404- if (desc / 1000 % 10 > 0)
405- file_printf(fm, ".%d",
406- desc / 1000 % 10);
0749e45a 407- printed = 1;
b6942f9f
JB
408- }
409-
410- if (nh_namesz == 8 &&
0749e45a 411- strcmp(&nbuf[noff], "OpenBSD") == 0 &&
b6942f9f
JB
412- nh_type == NT_OPENBSD_VERSION &&
413- nh_descsz == 4) {
414- file_printf(fm, ", for OpenBSD");
415- /* Content of note is always 0 */
0749e45a 416- printed = 1;
b6942f9f
JB
417- }
418- }
419- if ((lseek(fm->fd, ph_offset + offset, SEEK_SET)) == -1) {
420- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
421- /*@notreached@*/
422- }
423- /*@switchbreak@*/ break;
424- }
425- }
426- file_printf(fm, ", %s linked%s", linking_style, shared_libraries);
427-}
428-/*@=bounds@*/
429-
430 #ifdef ELFCORE
0749e45a
AM
431-/*@unchecked@*/ /*@observer@*/
432-static size_t prpsoffsets32[] = {
433+size_t prpsoffsets32[] = {
434 8, /* FreeBSD */
435 28, /* Linux 2.0.36 */
436 32, /* Linux (I forget which kernel version) */
437- 84 /* SunOS 5.x */
438+ 84, /* SunOS 5.x */
439 };
440
441-/*@unchecked@*/ /*@observer@*/
442-static size_t prpsoffsets64[] = {
443- 120 /* SunOS 5.x, 64-bit */
444+size_t prpsoffsets64[] = {
445+ 120, /* SunOS 5.x, 64-bit */
446 };
447
448 #define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
449 #define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
450
451-#define NOFFSETS (fm->cls == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
452+#define NOFFSETS (class == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
453
454 /*
455 * Look through the program headers of an executable image, searching
456@@ -391,46 +205,38 @@
457 #define OS_STYLE_FREEBSD 1
458 #define OS_STYLE_NETBSD 2
459
460-/*@unchecked@*/ /*@observer@*/
461-static const char *os_style_names[] = {
462+private const char *os_style_names[] = {
463 "SVR4",
464 "FreeBSD",
465 "NetBSD",
466 };
467
468-/*@-bounds@*/
469-static void
470-dophn_core(fmagic fm, off_t off, int num, size_t size)
471- /*@globals fileSystem @*/
472- /*@modifies fm, fileSystem @*/
473+private int
474+dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off,
475+ int num, size_t size)
b6942f9f
JB
476 {
477 Elf32_Phdr ph32;
478- Elf32_Nhdr *nh32 = NULL;
479 Elf64_Phdr ph64;
480- Elf64_Nhdr *nh64 = NULL;
481- size_t offset, nameoffset, noffset, reloffset;
482- unsigned char c;
483- int i, j;
484- char nbuf[BUFSIZ];
0749e45a 485- int nb;
b6942f9f
JB
486- int os_style = -1;
487+ size_t offset;
488+ unsigned char nbuf[BUFSIZ];
489+ ssize_t bufsize;
490
491 if (size != ph_size) {
0749e45a
AM
492- error(EXIT_FAILURE, 0, "corrupted program header size.\n");
493- /*@notreached@*/
494+ if (file_printf(ms, ", corrupted program header size") == -1)
495+ return -1;
496+ return 0;
497 }
498-
499 /*
b6942f9f
JB
500 * Loop through all the program headers.
501 */
502 for ( ; num; num--) {
503- if (lseek(fm->fd, off, SEEK_SET) == -1) {
0749e45a
AM
504- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
505- /*@notreached@*/
506- }
b6942f9f 507- if (read(fm->fd, ph_addr, size) == -1) {
0749e45a
AM
508- error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
509- /*@notreached@*/
510+ if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
511+ file_badseek(ms);
512+ return -1;
513+ }
514+ if (read(fd, ph_addr, ph_size) == -1) {
515+ file_badread(ms);
516+ return -1;
b6942f9f 517 }
0749e45a
AM
518 off += size;
519 if (ph_type != PT_NOTE)
520@@ -440,192 +246,475 @@
b6942f9f
JB
521 * This is a PT_NOTE section; loop through all the notes
522 * in the section.
523 */
524- if (lseek(fm->fd, (off_t) ph_offset, SEEK_SET) == -1) {
0749e45a
AM
525- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
526- /*@notreached@*/
527- }
528- nb = read(fm->fd, nbuf, BUFSIZ);
529- if (nb == -1) {
530- error(EXIT_FAILURE, 0, ": " "read failed (%s).\n", strerror(errno));
531- /*@notreached@*/
532+ if (lseek(fd, (off_t) ph_offset, SEEK_SET) == (off_t)-1) {
533+ file_badseek(ms);
534+ return -1;
535+ }
536+ bufsize = read(fd, nbuf, BUFSIZ);
537+ if (bufsize == -1) {
538+ file_badread(ms);
539+ return -1;
b6942f9f
JB
540 }
541 offset = 0;
542 for (;;) {
0749e45a
AM
543- if (offset >= nb)
544- /*@innerbreak@*/ break;
b6942f9f
JB
545- if (fm->cls == ELFCLASS32)
546- nh32 = (Elf32_Nhdr *)&nbuf[offset];
547- else
548- nh64 = (Elf64_Nhdr *)&nbuf[offset];
0749e45a
AM
549- offset += 12;
550+ if (offset >= (size_t)bufsize)
551+ break;
552+ offset = donote(ms, nbuf, offset, (size_t)bufsize,
553+ class, swap, 4);
554+ if (offset == 0)
555+ break;
b6942f9f
JB
556
557- /*
558- * Check whether this note has the name "CORE" or
559- * "FreeBSD", or "NetBSD-CORE".
560- */
0749e45a 561- if (offset + nh_namesz >= nb) {
b6942f9f
JB
562- /*
563- * We're past the end of the buffer.
564- */
565- /*@innerbreak@*/ break;
b6942f9f
JB
566+ }
567+ }
0749e45a 568+ return 0;
b6942f9f 569+}
b6942f9f
JB
570+#endif
571+
0749e45a
AM
572+private size_t
573+donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
574+ int class, int swap, size_t align)
b6942f9f
JB
575+{
576+ Elf32_Nhdr nh32;
577+ Elf64_Nhdr nh64;
578+ size_t noff, doff;
579+#ifdef ELFCORE
580+ int os_style = -1;
581+#endif
0749e45a
AM
582+ uint32_t namesz, descsz;
583+
584+ if (class == ELFCLASS32)
b6942f9f
JB
585+ memcpy(&nh32, &nbuf[offset], sizeof(nh32));
586+ else
587+ memcpy(&nh64, &nbuf[offset], sizeof(nh64));
588+ offset += nh_size;
0749e45a
AM
589+
590+ namesz = nh_namesz;
591+ descsz = nh_descsz;
592+ if ((namesz == 0) && (descsz == 0)) {
b6942f9f
JB
593+ /*
594+ * We're out of note headers.
595+ */
596+ return offset;
597+ }
598+
0749e45a
AM
599+ if (namesz & 0x80000000) {
600+ (void)file_printf(ms, ", bad note name size 0x%lx",
601+ (unsigned long)namesz);
602+ return offset;
603+ }
604+
605+ if (descsz & 0x80000000) {
606+ (void)file_printf(ms, ", bad note description size 0x%lx",
607+ (unsigned long)descsz);
608+ return offset;
609+ }
610+
611+
b6942f9f 612+ noff = offset;
0749e45a 613+ doff = ELF_ALIGN(offset + namesz);
b6942f9f 614+
0749e45a 615+ if (offset + namesz >= size) {
b6942f9f
JB
616+ /*
617+ * We're past the end of the buffer.
618+ */
619+ return doff;
620+ }
621+
0749e45a
AM
622+ offset = ELF_ALIGN(doff + descsz);
623+ if (offset + descsz >= size) {
b6942f9f 624+ return offset;
0749e45a 625+ }
b6942f9f 626+
0749e45a
AM
627+ if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
628+ nh_type == NT_GNU_VERSION && descsz == 16) {
b6942f9f
JB
629+ uint32_t desc[4];
630+ (void)memcpy(desc, &nbuf[doff], sizeof(desc));
631+
0749e45a
AM
632+ if (file_printf(ms, ", for GNU/") == -1)
633+ return size;
634+ switch (getu32(swap, desc[0])) {
b6942f9f 635+ case GNU_OS_LINUX:
0749e45a
AM
636+ if (file_printf(ms, "Linux") == -1)
637+ return size;
b6942f9f
JB
638+ break;
639+ case GNU_OS_HURD:
0749e45a
AM
640+ if (file_printf(ms, "Hurd") == -1)
641+ return size;
b6942f9f
JB
642+ break;
643+ case GNU_OS_SOLARIS:
0749e45a
AM
644+ if (file_printf(ms, "Solaris") == -1)
645+ return size;
b6942f9f
JB
646+ break;
647+ default:
0749e45a
AM
648+ if (file_printf(ms, "<unknown>") == -1)
649+ return size;
b6942f9f 650+ }
0749e45a
AM
651+ if (file_printf(ms, " %d.%d.%d", getu32(swap, desc[1]),
652+ getu32(swap, desc[2]), getu32(swap, desc[3])) == -1)
653+ return size;
b6942f9f
JB
654+ return size;
655+ }
656+
0749e45a
AM
657+ if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
658+ nh_type == NT_NETBSD_VERSION && descsz == 4) {
b6942f9f
JB
659+ uint32_t desc;
660+ (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
0749e45a 661+ desc = getu32(swap, desc);
b6942f9f 662+
0749e45a
AM
663+ if (file_printf(ms, ", for NetBSD") == -1)
664+ return size;
b6942f9f
JB
665+ /*
666+ * The version number used to be stuck as 199905, and was thus
667+ * basically content-free. Newer versions of NetBSD have fixed
668+ * this and now use the encoding of __NetBSD_Version__:
669+ *
670+ * MMmmrrpp00
671+ *
672+ * M = major version
673+ * m = minor version
674+ * r = release ["",A-Z,Z[A-Z] but numeric]
675+ * p = patchlevel
676+ */
677+ if (desc > 100000000U) {
678+ u_int ver_patch = (desc / 100) % 100;
679+ u_int ver_rel = (desc / 10000) % 100;
680+ u_int ver_min = (desc / 1000000) % 100;
681+ u_int ver_maj = desc / 100000000;
682+
0749e45a
AM
683+ if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
684+ return size;
b6942f9f 685+ if (ver_rel == 0 && ver_patch != 0) {
0749e45a
AM
686+ if (file_printf(ms, ".%u", ver_patch) == -1)
687+ return size;
b6942f9f
JB
688+ } else if (ver_rel != 0) {
689+ while (ver_rel > 26) {
0749e45a 690+ file_printf(ms, "Z");
b6942f9f
JB
691+ ver_rel -= 26;
692+ }
0749e45a 693+ file_printf(ms, "%c", 'A' + ver_rel - 1);
b6942f9f
JB
694 }
695+ }
696+ return size;
697+ }
698
0749e45a
AM
699- nameoffset = offset;
700- offset += nh_namesz;
701- offset = ((offset + 3)/4)*4;
702+ if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
703+ nh_type == NT_FREEBSD_VERSION && descsz == 4) {
b6942f9f
JB
704+ uint32_t desc;
705+ (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
0749e45a
AM
706+ desc = getu32(swap, desc);
707+ if (file_printf(ms, ", for FreeBSD") == -1)
708+ return size;
709
710- /*
711- * Sigh. The 2.0.36 kernel in Debian 2.1, at
712- * least, doesn't correctly implement name
713- * sections, in core dumps, as specified by
714- * the "Program Linking" section of "UNIX(R) System
715- * V Release 4 Programmer's Guide: ANSI C and
716- * Programming Support Tools", because my copy
717- * clearly says "The first 'namesz' bytes in 'name'
718- * contain a *null-terminated* [emphasis mine]
719- * character representation of the entry's owner
720- * or originator", but the 2.0.36 kernel code
721- * doesn't include the terminating null in the
722- * name....
723- */
724- if (os_style == -1) {
725- if ((nh_namesz == 4 &&
726- strncmp(&nbuf[nameoffset],
727- "CORE", 4) == 0) ||
728- (nh_namesz == 5 &&
729- strcmp(&nbuf[nameoffset],
730- "CORE") == 0)) {
731- os_style = OS_STYLE_SVR4;
732- } else
733- if ((nh_namesz == 8 &&
734- strcmp(&nbuf[nameoffset],
735- "FreeBSD") == 0)) {
736- os_style = OS_STYLE_FREEBSD;
737- } else
738- if ((nh_namesz >= 11 &&
739- strncmp(&nbuf[nameoffset],
740- "NetBSD-CORE", 11) == 0)) {
741- os_style = OS_STYLE_NETBSD;
742- } else
743- /*@innercontinue@*/ continue;
744- file_printf(fm, ", %s-style", os_style_names[os_style]);
b6942f9f 745+ /*
0749e45a
AM
746+ * Contents is __FreeBSD_version, whose relation to OS
747+ * versions is defined by a huge table in the Porters'
748+ * Handbook. For up to 5.x, the first three digits are
749+ * the version number. For 5.x and higher, the scheme
750+ * is: <major><two digit minor> <0 if release branch,
751+ * otherwise 1>xx
b6942f9f 752+ */
0749e45a
AM
753+ if (desc / 100000 < 5) {
754+ if (file_printf(ms, " %d.%d", desc / 100000,
755+ desc / 10000 % 10) == -1)
756+ return size;
757+ if (desc / 1000 % 10 > 0)
758+ if (file_printf(ms, ".%d", desc / 1000 % 10)
759+ == -1)
760+ return size;
761+ } else {
762+ if (file_printf(ms, " %d.%d", desc / 100000,
763+ desc / 1000 % 100) == -1)
764+ return size;
765+ desc %= 1000;
766+ if (desc > 100) {
767+ if (file_printf(ms, "-CURRENT (rev %d)",
768+ desc % 100) == -1)
769+ return size;
770+ } else if (desc != 0) {
771+ if (file_printf(ms, ".%d", desc / 10) == -1)
772+ return size;
773 }
774+ }
b6942f9f
JB
775+ return size;
776+ }
777
0749e45a
AM
778- if (os_style == OS_STYLE_NETBSD &&
779- nh_type == NT_NETBSD_CORE_PROCINFO) {
780- uint32_t signo;
781+ if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
782+ nh_type == NT_OPENBSD_VERSION && descsz == 4) {
783+ if (file_printf(ms, ", for OpenBSD") == -1)
784+ return size;
b6942f9f
JB
785+ /* Content of note is always 0 */
786+ return size;
787+ }
0749e45a 788
b6942f9f
JB
789+ /*
790+ * Sigh. The 2.0.36 kernel in Debian 2.1, at
791+ * least, doesn't correctly implement name
792+ * sections, in core dumps, as specified by
793+ * the "Program Linking" section of "UNIX(R) System
794+ * V Release 4 Programmer's Guide: ANSI C and
795+ * Programming Support Tools", because my copy
796+ * clearly says "The first 'namesz' bytes in 'name'
797+ * contain a *null-terminated* [emphasis mine]
798+ * character representation of the entry's owner
799+ * or originator", but the 2.0.36 kernel code
800+ * doesn't include the terminating null in the
801+ * name....
802+ */
0749e45a
AM
803+ if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
804+ (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
b6942f9f
JB
805+ os_style = OS_STYLE_SVR4;
806+ }
807+
0749e45a 808+ if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
b6942f9f
JB
809+ os_style = OS_STYLE_FREEBSD;
810+ }
811+
0749e45a 812+ if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
b6942f9f
JB
813+ == 0)) {
814+ os_style = OS_STYLE_NETBSD;
815+ }
816+
817+#ifdef ELFCORE
818+ if (os_style != -1)
0749e45a
AM
819+ if (file_printf(ms, ", %s-style", os_style_names[os_style]) == -1)
820+ return size;
b6942f9f
JB
821+
822+ if (os_style == OS_STYLE_NETBSD && nh_type == NT_NETBSD_CORE_PROCINFO) {
823+ uint32_t signo;
824+ /*
825+ * Extract the program name. It is at
826+ * offset 0x7c, and is up to 32-bytes,
827+ * including the terminating NUL.
828+ */
0749e45a
AM
829+ if (file_printf(ms, ", from '%.31s'", &nbuf[doff + 0x7c]) == -1)
830+ return size;
b6942f9f
JB
831+
832+ /*
833+ * Extract the signal number. It is at
834+ * offset 0x08.
835+ */
836+ memcpy(&signo, &nbuf[doff + 0x08],
837+ sizeof(signo));
0749e45a
AM
838+ if (file_printf(ms, " (signal %u)", getu32(swap, signo)) == -1)
839+ return size;
b6942f9f
JB
840+ return size;
841+ } else if (os_style != OS_STYLE_NETBSD && nh_type == NT_PRPSINFO) {
842+ size_t i, j;
843+ unsigned char c;
844+ /*
845+ * Extract the program name. We assume
846+ * it to be 16 characters (that's what it
847+ * is in SunOS 5.x and Linux).
848+ *
849+ * Unfortunately, it's at a different offset
850+ * in varous OSes, so try multiple offsets.
851+ * If the characters aren't all printable,
852+ * reject it.
853+ */
854+ for (i = 0; i < NOFFSETS; i++) {
855+ size_t reloffset = prpsoffsets(i);
856+ size_t noffset = doff + reloffset;
857+ for (j = 0; j < 16; j++, noffset++, reloffset++) {
858 /*
859- * Extract the program name. It is at
860- * offset 0x7c, and is up to 32-bytes,
861- * including the terminating NUL.
862- */
863- file_printf(fm, ", from '%.31s'", &nbuf[offset + 0x7c]);
864-
865- /*
866- * Extract the signal number. It is at
867- * offset 0x08.
868+ * Make sure we're not past
869+ * the end of the buffer; if
870+ * we are, just give up.
871 */
872- memcpy(&signo, &nbuf[offset + 0x08],
873- sizeof(signo));
874- file_printf(fm, " (signal %u)", getu32(fm, signo));
875- } else
876- if (os_style != OS_STYLE_NETBSD &&
877- nh_type == NT_PRPSINFO) {
878+ if (noffset >= size)
879+ goto tryanother;
880+
881 /*
882- * Extract the program name. We assume
883- * it to be 16 characters (that's what it
884- * is in SunOS 5.x and Linux).
885- *
886- * Unfortunately, it's at a different offset
887- * in varous OSes, so try multiple offsets.
888- * If the characters aren't all printable,
889- * reject it.
890+ * Make sure we're not past
891+ * the end of the contents;
892+ * if we are, this obviously
893+ * isn't the right offset.
894 */
895- for (i = 0; i < NOFFSETS; i++) {
896- reloffset = prpsoffsets(i);
897- noffset = offset + reloffset;
898- for (j = 0; j < 16;
899- j++, noffset++, reloffset++) {
900- /*
901- * Make sure we're not past
902- * the end of the buffer; if
903- * we are, just give up.
904- */
0749e45a 905- if (noffset >= nb)
b6942f9f
JB
906- goto tryanother;
907-
908- /*
909- * Make sure we're not past
910- * the end of the contents;
911- * if we are, this obviously
912- * isn't the right offset.
913- */
914- if (reloffset >= nh_descsz)
915- goto tryanother;
916-
917- c = nbuf[noffset];
918- if (c == '\0') {
919- /*
920- * A '\0' at the
921- * beginning is
922- * obviously wrong.
923- * Any other '\0'
924- * means we're done.
925- */
926- if (j == 0)
927- goto tryanother;
928- else
929- /*@innerbreak@*/ break;
930- } else {
931- /*
932- * A nonprintable
933- * character is also
934- * wrong.
935- */
936-#define isquote(c) (strchr("'\"`", (c)) != NULL)
937- if (!isprint(c) ||
938- isquote(c))
939- goto tryanother;
940- }
941- }
0749e45a 942+ if (reloffset >= descsz)
b6942f9f
JB
943+ goto tryanother;
944
945+ c = nbuf[noffset];
946+ if (c == '\0') {
947 /*
948- * Well, that worked.
949+ * A '\0' at the
950+ * beginning is
951+ * obviously wrong.
952+ * Any other '\0'
953+ * means we're done.
954 */
955- file_printf(fm, ", from '%.16s'",
956- &nbuf[offset + prpsoffsets(i)]);
957- /*@innerbreak@*/ break;
958-
959- tryanother:
960- ;
961+ if (j == 0)
962+ goto tryanother;
963+ else
964+ break;
965+ } else {
966+ /*
967+ * A nonprintable
968+ * character is also
969+ * wrong.
970+ */
971+#define isquote(c) (strchr("'\"`", (c)) != NULL)
972+ if (!isprint(c) || isquote(c))
973+ goto tryanother;
974 }
975- /*@innerbreak@*/ break;
976 }
977- offset += nh_descsz;
978- offset = ((offset + 3)/4)*4;
979+
980+ /*
981+ * Well, that worked.
982+ */
0749e45a
AM
983+ if (file_printf(ms, ", from '%.16s'",
984+ &nbuf[doff + prpsoffsets(i)]) == -1)
985+ return size;
b6942f9f
JB
986+ return size;
987+
988+ tryanother:
989+ ;
0749e45a 990 }
b6942f9f 991+ return offset;
0749e45a
AM
992 }
993-}
994-/*@=bounds@*/
995 #endif
b6942f9f
JB
996+ return offset;
997+}
0749e45a
AM
998
999-/*@-bounds@*/
1000-void
1001-fmagicE(fmagic fm)
1002+private int
1003+doshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num,
1004+ size_t size)
b6942f9f
JB
1005+{
1006+ Elf32_Shdr sh32;
1007+ Elf64_Shdr sh64;
1008+
1009+ if (size != sh_size) {
0749e45a
AM
1010+ if (file_printf(ms, ", corrupted section header size") == -1)
1011+ return -1;
1012+ return 0;
b6942f9f
JB
1013+ }
1014+
0749e45a
AM
1015+ if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
1016+ file_badseek(ms);
1017+ return -1;
b6942f9f
JB
1018+ }
1019+
1020+ for ( ; num; num--) {
0749e45a
AM
1021+ if (read(fd, sh_addr, sh_size) == -1) {
1022+ file_badread(ms);
1023+ return -1;
b6942f9f
JB
1024+ }
1025+ if (shs_type == SHT_SYMTAB /* || shs_type == SHT_DYNSYM */) {
0749e45a
AM
1026+ if (file_printf(ms, ", not stripped") == -1)
1027+ return -1;
1028+ return 0;
b6942f9f
JB
1029+ }
1030+ }
0749e45a
AM
1031+ if (file_printf(ms, ", stripped") == -1)
1032+ return -1;
1033+ return 0;
b6942f9f 1034+}
b6942f9f
JB
1035+
1036+/*
1037+ * Look through the program headers of an executable image, searching
1038+ * for a PT_INTERP section; if one is found, it's dynamically linked,
1039+ * otherwise it's statically linked.
1040+ */
0749e45a
AM
1041+private int
1042+dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
1043+ int num, size_t size)
b6942f9f
JB
1044+{
1045+ Elf32_Phdr ph32;
1046+ Elf64_Phdr ph64;
1047+ const char *linking_style = "statically";
1048+ const char *shared_libraries = "";
1049+ unsigned char nbuf[BUFSIZ];
1050+ int bufsize;
0749e45a 1051+ size_t offset, align;
b6942f9f
JB
1052+ off_t savedoffset;
1053+
1054+ if (size != ph_size) {
0749e45a
AM
1055+ if (file_printf(ms, ", corrupted program header size") == -1)
1056+ return -1;
1057+ return 0;
b6942f9f 1058+ }
0749e45a
AM
1059+ if (lseek(fd, off, SEEK_SET) == (off_t)-1) {
1060+ file_badseek(ms);
1061+ return -1;
b6942f9f
JB
1062+ }
1063+
1064+ for ( ; num; num--) {
0749e45a
AM
1065+ if (read(fd, ph_addr, ph_size) == -1) {
1066+ file_badread(ms);
1067+ return -1;
b6942f9f 1068+ }
0749e45a
AM
1069+ if ((savedoffset = lseek(fd, (off_t)0, SEEK_CUR)) == (off_t)-1) {
1070+ file_badseek(ms);
1071+ return -1;
b6942f9f
JB
1072+ }
1073+
1074+ switch (ph_type) {
1075+ case PT_DYNAMIC:
1076+ linking_style = "dynamically";
0749e45a 1077+ break;
b6942f9f
JB
1078+ case PT_INTERP:
1079+ shared_libraries = " (uses shared libs)";
0749e45a 1080+ break;
b6942f9f 1081+ case PT_NOTE:
0749e45a
AM
1082+ if ((align = ph_align) & 0x80000000) {
1083+ if (file_printf(ms,
1084+ ", invalid note alignment 0x%lx",
1085+ (unsigned long)align) == -1)
1086+ return -1;
1087+ align = 4;
1088+ }
b6942f9f
JB
1089+ /*
1090+ * This is a PT_NOTE section; loop through all the notes
1091+ * in the section.
1092+ */
0749e45a
AM
1093+ if (lseek(fd, (off_t) ph_offset, SEEK_SET)
1094+ == (off_t)-1) {
1095+ file_badseek(ms);
1096+ return -1;
b6942f9f 1097+ }
0749e45a 1098+ bufsize = read(fd, nbuf, sizeof(nbuf));
b6942f9f 1099+ if (bufsize == -1) {
0749e45a
AM
1100+ file_badread(ms);
1101+ return -1;
b6942f9f
JB
1102+ }
1103+ offset = 0;
1104+ for (;;) {
1105+ if (offset >= (size_t)bufsize)
0749e45a
AM
1106+ break;
1107+ offset = donote(ms, nbuf, offset,
1108+ (size_t)bufsize, class, swap, align);
1109+ if (offset == 0)
1110+ break;
b6942f9f 1111+ }
0749e45a
AM
1112+ if (lseek(fd, savedoffset + offset, SEEK_SET)
1113+ == (off_t)-1) {
1114+ file_badseek(ms);
1115+ return -1;
b6942f9f 1116+ }
0749e45a
AM
1117+ break;
1118+ }
1119+ }
1120+ if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries)
1121+ == -1)
1122+ return -1;
1123+ return 0;
1124+}
1125+
1126+
1127+protected int
1128+file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
1129+ size_t nbytes)
1130 {
1131-/*@-sizeoftype@*/
1132 union {
1133 int32_t l;
1134 char c[sizeof (int32_t)];
1135 } u;
1136-/*@=sizeoftype@*/
1137+ int class;
1138+ int swap;
1139
1140 /*
1141- * If we can't seek, it must be a pipe, socket or fifo.
1142+ * If we cannot seek, it must be a pipe, socket or fifo.
1143 */
1144- if((lseek(fm->fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
1145- fm->fd = file_pipe2file(fm->fd, fm->buf, fm->nb);
1146+ if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
1147+ fd = file_pipe2file(ms, fd, buf, nbytes);
1148
1149 /*
1150 * ELF executables have multiple section headers in arbitrary
1151@@ -633,96 +722,101 @@
1152 * Instead we traverse thru all section headers until a symbol table
1153 * one is found or else the binary is stripped.
1154 */
1155- if (fm->buf[EI_MAG0] != ELFMAG0
1156- || (fm->buf[EI_MAG1] != ELFMAG1 && fm->buf[EI_MAG1] != OLFMAG1)
1157- || fm->buf[EI_MAG2] != ELFMAG2 || fm->buf[EI_MAG3] != ELFMAG3)
1158- return;
1159+ if (buf[EI_MAG0] != ELFMAG0
1160+ || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
1161+ || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
1162+ return 0;
1163
1164- fm->cls = fm->buf[EI_CLASS];
1165
1166- if (fm->cls == ELFCLASS32) {
1167+ class = buf[4];
1168+
1169+ if (class == ELFCLASS32) {
1170 Elf32_Ehdr elfhdr;
1171- if (fm->nb <= sizeof (elfhdr))
1172- return;
1173+ if (nbytes <= sizeof (Elf32_Ehdr))
1174+ return 0;
1175
1176
1177 u.l = 1;
1178- (void) memcpy(&elfhdr, fm->buf, sizeof elfhdr);
1179-/*@-sizeoftype@*/
1180- fm->swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
1181-/*@=sizeoftype@*/
1182+ (void) memcpy(&elfhdr, buf, sizeof elfhdr);
1183+ swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
1184
1185- if (getu16(fm, elfhdr.e_type) == ET_CORE)
1186+ if (getu16(swap, elfhdr.e_type) == ET_CORE) {
1187 #ifdef ELFCORE
1188- dophn_core(fm,
1189- getu32(fm, elfhdr.e_phoff),
1190- getu16(fm, elfhdr.e_phnum),
1191- getu16(fm, elfhdr.e_phentsize));
1192+ if (dophn_core(ms, class, swap, fd,
1193+ (off_t)getu32(swap, elfhdr.e_phoff),
1194+ getu16(swap, elfhdr.e_phnum),
1195+ (size_t)getu16(swap, elfhdr.e_phentsize)) == -1)
1196+ return -1;
1197 #else
1198 ;
1199 #endif
1200- else {
1201- if (getu16(fm, elfhdr.e_type) == ET_EXEC) {
1202- dophn_exec(fm,
1203- getu32(fm, elfhdr.e_phoff),
1204- getu16(fm, elfhdr.e_phnum),
1205- getu16(fm, elfhdr.e_phentsize));
1206+ } else {
1207+ if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
1208+ if (dophn_exec(ms, class, swap,
1209+ fd, (off_t)getu32(swap, elfhdr.e_phoff),
1210+ getu16(swap, elfhdr.e_phnum),
1211+ (size_t)getu16(swap, elfhdr.e_phentsize))
1212+ == -1)
1213+ return -1;
1214 }
1215- doshn(fm,
1216- getu32(fm, elfhdr.e_shoff),
1217- getu16(fm, elfhdr.e_shnum),
1218- getu16(fm, elfhdr.e_shentsize));
1219+ if (doshn(ms, class, swap, fd,
1220+ (off_t)getu32(swap, elfhdr.e_shoff),
1221+ getu16(swap, elfhdr.e_shnum),
1222+ (size_t)getu16(swap, elfhdr.e_shentsize)) == -1)
1223+ return -1;
b6942f9f 1224 }
0749e45a
AM
1225- return;
1226+ return 1;
b6942f9f 1227 }
b6942f9f 1228
0749e45a
AM
1229- if (fm->cls == ELFCLASS64) {
1230+ if (class == ELFCLASS64) {
1231 Elf64_Ehdr elfhdr;
1232- if (fm->nb <= sizeof (elfhdr))
1233- return;
1234+ if (nbytes <= sizeof (Elf64_Ehdr))
1235+ return 0;
1236+
1237
1238 u.l = 1;
1239- (void) memcpy(&elfhdr, fm->buf, sizeof elfhdr);
1240-/*@-sizeoftype@*/
1241- fm->swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
1242-/*@=sizeoftype@*/
1243+ (void) memcpy(&elfhdr, buf, sizeof elfhdr);
1244+ swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[5];
1245
1246- if (getu16(fm, elfhdr.e_type) == ET_CORE)
1247+ if (getu16(swap, elfhdr.e_type) == ET_CORE) {
1248 #ifdef ELFCORE
1249- dophn_core(fm,
1250+ if (dophn_core(ms, class, swap, fd,
1251 #ifdef USE_ARRAY_FOR_64BIT_TYPES
1252- getu32(fm, elfhdr.e_phoff[1]),
1253+ (off_t)getu32(swap, elfhdr.e_phoff[1]),
1254 #else
1255- getu64(fm, elfhdr.e_phoff),
1256+ (off_t)getu64(swap, elfhdr.e_phoff),
1257 #endif
1258- getu16(fm, elfhdr.e_phnum),
1259- getu16(fm, elfhdr.e_phentsize));
1260+ getu16(swap, elfhdr.e_phnum),
1261+ (size_t)getu16(swap, elfhdr.e_phentsize)) == -1)
1262+ return -1;
1263 #else
1264 ;
1265 #endif
1266- else
1267- {
1268- if (getu16(fm, elfhdr.e_type) == ET_EXEC) {
1269- dophn_exec(fm,
1270+ } else {
1271+ if (getu16(swap, elfhdr.e_type) == ET_EXEC) {
1272+ if (dophn_exec(ms, class, swap, fd,
1273 #ifdef USE_ARRAY_FOR_64BIT_TYPES
1274- getu32(fm, elfhdr.e_phoff[1]),
1275+ (off_t)getu32(swap, elfhdr.e_phoff[1]),
1276 #else
1277- getu64(fm, elfhdr.e_phoff),
1278+ (off_t)getu64(swap, elfhdr.e_phoff),
1279 #endif
1280- getu16(fm, elfhdr.e_phnum),
1281- getu16(fm, elfhdr.e_phentsize));
1282+ getu16(swap, elfhdr.e_phnum),
1283+ (size_t)getu16(swap, elfhdr.e_phentsize))
1284+ == -1)
1285+ return -1;
1286 }
1287- doshn(fm,
1288+ if (doshn(ms, class, swap, fd,
1289 #ifdef USE_ARRAY_FOR_64BIT_TYPES
1290- getu32(fm, elfhdr.e_shoff[1]),
1291+ (off_t)getu32(swap, elfhdr.e_shoff[1]),
1292 #else
1293- getu64(fm, elfhdr.e_shoff),
1294+ (off_t)getu64(swap, elfhdr.e_shoff),
1295 #endif
1296- getu16(fm, elfhdr.e_shnum),
1297- getu16(fm, elfhdr.e_shentsize));
1298+ getu16(swap, elfhdr.e_shnum),
1299+ (size_t)getu16(swap, elfhdr.e_shentsize)) == -1)
1300+ return -1;
1301 }
1302- return;
1303+ return 1;
1304 }
1305+ return 0;
1306 }
1307-/*@=bounds@*/
1308-#endif /* BUILTIN_ELF */
1309+#endif
This page took 2.636622 seconds and 4 git commands to generate.