]> git.pld-linux.org Git - packages/rpm.git/blame - rpm-file-readelf.patch
- fixed (s/-bi/-bb/) and enhanced comment
[packages/rpm.git] / rpm-file-readelf.patch
CommitLineData
b6942f9f
JB
1--- rpm-4.3/file/src/readelf.c.orig 2003-04-15 17:19:30.000000000 +0200
2+++ rpm-4.3/file/src/readelf.c 2004-02-24 22:15:06.302161792 +0100
3@@ -1,3 +1,31 @@
4+/*
5+ * Copyright (c) Christos Zoulas 2003.
6+ * All Rights Reserved.
7+ *
8+ * Redistribution and use in source and binary forms, with or without
9+ * modification, are permitted provided that the following conditions
10+ * are met:
11+ * 1. Redistributions of source code must retain the above copyright
12+ * notice immediately at the beginning of the file, without modification,
13+ * this list of conditions, and the following disclaimer.
14+ * 2. Redistributions in binary form must reproduce the above copyright
15+ * notice, this list of conditions and the following disclaimer in the
16+ * documentation and/or other materials provided with the distribution.
17+ * 3. The name of the author may not be used to endorse or promote products
18+ * derived from this software without specific prior written permission.
19+ *
20+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30+ * SUCH DAMAGE.
31+ */
32 #include "system.h"
33
34 #ifdef BUILTIN_ELF
35@@ -8,6 +36,9 @@
36 FILE_RCSID("@(#)Id: readelf.c,v 1.22 2002/07/03 18:26:38 christos Exp ")
37
38 /*@access fmagic @*/
39+static size_t donote(const fmagic fm, unsigned char *, size_t, size_t, int);
40+
41+#define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
42
43 /*@-bounds@*/
44 static uint16_t
45@@ -100,230 +131,27 @@
46 #define ph_offset (fm->cls == ELFCLASS32 \
47 ? getu32(fm, ph32.p_offset) \
48 : getu64(fm, ph64.p_offset))
49-#define ph_align (fm->cls == ELFCLASS32 \
50- ? (ph32.p_align ? getu32(fm, ph32.p_align) : 4) \
51- : (ph64.p_align ? getu64(fm, ph64.p_align) : 4))
52+#define ph_align (int)((fm->cls == ELFCLASS32 \
53+ ? (off_t) (ph32.p_align ? \
54+ getu32(fm, ph32.p_align) : 4) \
55+ : (off_t) (ph64.p_align ? \
56+ getu64(fm, ph64.p_align) : 4)))
57 #define nh_size (fm->cls == ELFCLASS32 \
58- ? sizeof *nh32 \
59- : sizeof *nh64)
60+ ? sizeof nh32 \
61+ : sizeof nh64)
62 #define nh_type (fm->cls == ELFCLASS32 \
63- ? getu32(fm, nh32->n_type) \
64- : getu32(fm, nh64->n_type))
65+ ? getu32(fm, nh32.n_type) \
66+ : getu32(fm, nh64.n_type))
67 #define nh_namesz (fm->cls == ELFCLASS32 \
68- ? getu32(fm, nh32->n_namesz) \
69- : getu32(fm, nh64->n_namesz))
70+ ? getu32(fm, nh32.n_namesz) \
71+ : getu32(fm, nh64.n_namesz))
72 #define nh_descsz (fm->cls == ELFCLASS32 \
73- ? getu32(fm, nh32->n_descsz) \
74- : getu32(fm, nh64->n_descsz))
75+ ? getu32(fm, nh32.n_descsz) \
76+ : getu32(fm, nh64.n_descsz))
77 #define prpsoffsets(i) (fm->cls == ELFCLASS32 \
78 ? prpsoffsets32[i] \
79 : prpsoffsets64[i])
80
81-/*@-bounds@*/
82-static void
83-doshn(fmagic fm, off_t off, int num, size_t size)
84- /*@globals fileSystem @*/
85- /*@modifies fm, fileSystem @*/
86-{
87- Elf32_Shdr sh32;
88- Elf64_Shdr sh64;
89-
90- if (size != sh_size) {
91- error(EXIT_FAILURE, 0, "corrupted program header size.\n");
92- /*@notreached@*/
93- }
94-
95- if (lseek(fm->fd, off, SEEK_SET) == -1) {
96- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
97- /*@notreached@*/
98- }
99-
100- for ( ; num; num--) {
101- if (read(fm->fd, sh_addr, size) == -1) {
102- error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
103- /*@notreached@*/
104- }
105- if (shs_type == SHT_SYMTAB /* || shs_type == SHT_DYNSYM */) {
106- file_printf(fm, ", not stripped");
107- return;
108- }
109- }
110- file_printf(fm, ", stripped");
111-}
112-/*@=bounds@*/
113-
114-/*
115- * Look through the program headers of an executable image, searching
116- * for a PT_INTERP section; if one is found, it's dynamically linked,
117- * otherwise it's statically linked.
118- */
119-/*@-bounds@*/
120-static void
121-dophn_exec(fmagic fm, off_t off, int num, size_t size)
122- /*@globals fileSystem @*/
123- /*@modifies fm, fileSystem @*/
124-{
125- Elf32_Phdr ph32;
126- Elf32_Nhdr *nh32 = NULL;
127- Elf64_Phdr ph64;
128- Elf64_Nhdr *nh64 = NULL;
129- char *linking_style = "statically";
130- char *shared_libraries = "";
131- char nbuf[BUFSIZ];
132- int bufsize;
133- size_t offset, nameoffset;
134-
135- if (size != ph_size) {
136- error(EXIT_FAILURE, 0, "corrupted program header size.\n");
137- /*@notreached@*/
138- }
139-
140- if (lseek(fm->fd, off, SEEK_SET) == -1) {
141- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
142- /*@notreached@*/
143- }
144-
145- for ( ; num; num--) {
146- if (read(fm->fd, ph_addr, size) == -1) {
147- error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
148- /*@notreached@*/
149- }
150-
151- switch (ph_type) {
152- case PT_DYNAMIC:
153- linking_style = "dynamically";
154- /*@switchbreak@*/ break;
155- case PT_INTERP:
156- shared_libraries = " (uses shared libs)";
157- /*@switchbreak@*/ break;
158- case PT_NOTE:
159- /*
160- * This is a PT_NOTE section; loop through all the notes
161- * in the section.
162- */
163- if (lseek(fm->fd, (off_t) ph_offset, SEEK_SET) == -1) {
164- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
165- /*@notreached@*/
166- }
167- bufsize = read(fm->fd, nbuf, sizeof(nbuf));
168- if (bufsize == -1) {
169- error(EXIT_FAILURE, 0, ": " "read failed (%s).\n",
170- strerror(errno));
171- /*@notreached@*/
172- }
173- offset = 0;
174- for (;;) {
175- if (offset >= bufsize)
176- /*@innerbreak@*/ break;
177- if (fm->cls == ELFCLASS32)
178- nh32 = (Elf32_Nhdr *)&nbuf[offset];
179- else
180- nh64 = (Elf64_Nhdr *)&nbuf[offset];
181- offset += nh_size;
182-
183- if (offset + nh_namesz >= bufsize) {
184- /*
185- * We're past the end of the buffer.
186- */
187- /*@innerbreak@*/ break;
188- }
189-
190- nameoffset = offset;
191- offset += nh_namesz;
192- offset = ((offset+ph_align-1)/ph_align)*ph_align;
193-
194- if ((nh_namesz == 0) && (nh_descsz == 0)) {
195- /*
196- * We're out of note headers.
197- */
198- /*@innerbreak@*/ break;
199- }
200-
201- if (offset + nh_descsz >= bufsize)
202- /*@innerbreak@*/ break;
203-
204- if (nh_namesz == 4 &&
205- strcmp(&nbuf[nameoffset], "GNU") == 0 &&
206- nh_type == NT_GNU_VERSION &&
207- nh_descsz == 16) {
208- uint32_t *desc =
209- (uint32_t *)&nbuf[offset];
210-
211- file_printf(fm, ", for GNU/");
212- switch (getu32(fm, desc[0])) {
213- case GNU_OS_LINUX:
214- file_printf(fm, "Linux");
215- /*@switchbreak@*/ break;
216- case GNU_OS_HURD:
217- file_printf(fm, "Hurd");
218- /*@switchbreak@*/ break;
219- case GNU_OS_SOLARIS:
220- file_printf(fm, "Solaris");
221- /*@switchbreak@*/ break;
222- default:
223- file_printf(fm, "<unknown>");
224- /*@switchbreak@*/ break;
225- }
226- file_printf(fm, " %d.%d.%d",
227- getu32(fm, desc[1]),
228- getu32(fm, desc[2]),
229- getu32(fm, desc[3]));
230- }
231-
232- if (nh_namesz == 7 &&
233- strcmp(&nbuf[nameoffset], "NetBSD") == 0 &&
234- nh_type == NT_NETBSD_VERSION &&
235- nh_descsz == 4) {
236- file_printf(fm, ", for NetBSD");
237- /*
238- * Version number is stuck at 199905,
239- * and hence is basically content-free.
240- */
241- }
242-
243- if (nh_namesz == 8 &&
244- strcmp(&nbuf[nameoffset], "FreeBSD") == 0 &&
245- nh_type == NT_FREEBSD_VERSION &&
246- nh_descsz == 4) {
247- uint32_t desc = getu32(fm,
248- *(uint32_t *)&nbuf[offset]);
249- file_printf(fm, ", for FreeBSD");
250- /*
251- * Contents is __FreeBSD_version,
252- * whose relation to OS versions is
253- * defined by a huge table in the
254- * Porters' Handbook. Happily, the
255- * first three digits are the version
256- * number, at least in versions of
257- * FreeBSD that use this note.
258- */
259-
260- file_printf(fm, " %d.%d", desc / 100000,
261- desc / 10000 % 10);
262- if (desc / 1000 % 10 > 0)
263- file_printf(fm, ".%d",
264- desc / 1000 % 10);
265- }
266-
267- if (nh_namesz == 8 &&
268- strcmp(&nbuf[nameoffset], "OpenBSD") == 0 &&
269- nh_type == NT_OPENBSD_VERSION &&
270- nh_descsz == 4) {
271- file_printf(fm, ", for OpenBSD");
272- /* Content of note is always 0 */
273- }
274- }
275- if ((lseek(fm->fd, ph_offset + offset, SEEK_SET)) == -1) {
276- error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
277- /*@notreached@*/
278- }
279- /*@switchbreak@*/ break;
280- }
281- }
282- file_printf(fm, ", %s linked%s", linking_style, shared_libraries);
283-}
284-/*@=bounds@*/
285-
286 #ifdef ELFCORE
287 /*@unchecked@*/ /*@observer@*/
288 static size_t prpsoffsets32[] = {
289@@ -382,15 +210,10 @@
290 /*@modifies fm, fileSystem @*/
291 {
292 Elf32_Phdr ph32;
293- Elf32_Nhdr *nh32 = NULL;
294 Elf64_Phdr ph64;
295- Elf64_Nhdr *nh64 = NULL;
296- size_t offset, nameoffset, noffset, reloffset;
297- unsigned char c;
298- int i, j;
299- char nbuf[BUFSIZ];
300- int bufsize;
301- int os_style = -1;
302+ size_t offset;
303+ unsigned char nbuf[BUFSIZ];
304+ ssize_t bufsize;
305
306 if (size != ph_size) {
307 error(EXIT_FAILURE, 0, "corrupted program header size.\n");
308@@ -401,11 +224,11 @@
309 * Loop through all the program headers.
310 */
311 for ( ; num; num--) {
312- if (lseek(fm->fd, off, SEEK_SET) == -1) {
313+ if (lseek(fm->fd, off, SEEK_SET) == (off_t)-1) {
314 error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
315 /*@notreached@*/
316 }
317- if (read(fm->fd, ph_addr, size) == -1) {
318+ if (read(fm->fd, ph_addr, ph_size) == -1) {
319 error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
320 /*@notreached@*/
321 }
322@@ -417,7 +240,7 @@
323 * This is a PT_NOTE section; loop through all the notes
324 * in the section.
325 */
326- if (lseek(fm->fd, (off_t) ph_offset, SEEK_SET) == -1) {
327+ if (lseek(fm->fd, (off_t) ph_offset, SEEK_SET) == (off_t)-1) {
328 error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
329 /*@notreached@*/
330 }
331@@ -428,164 +251,379 @@
332 }
333 offset = 0;
334 for (;;) {
335- if (offset >= bufsize)
336+ if (offset >= (size_t)bufsize)
337 /*@innerbreak@*/ break;
338- if (fm->cls == ELFCLASS32)
339- nh32 = (Elf32_Nhdr *)&nbuf[offset];
340- else
341- nh64 = (Elf64_Nhdr *)&nbuf[offset];
342- offset += nh_size;
343+ offset = donote(fm, nbuf, offset, (size_t)bufsize,
344+ 4);
345
346- /*
347- * Check whether this note has the name "CORE" or
348- * "FreeBSD", or "NetBSD-CORE".
349- */
350- if (offset + nh_namesz >= bufsize) {
351- /*
352- * We're past the end of the buffer.
353- */
354- /*@innerbreak@*/ break;
355- }
356+ }
357+ }
358+}
359+/*@=bounds@*/
360+#endif
361+
362+/*@-bounds@*/
363+static size_t
364+donote(const fmagic fm, unsigned char *nbuf, size_t offset, size_t size,
365+ int align)
366+{
367+ Elf32_Nhdr nh32;
368+ Elf64_Nhdr nh64;
369+ size_t noff, doff;
370+#ifdef ELFCORE
371+ int os_style = -1;
372+#endif
373
374- nameoffset = offset;
375- offset += nh_namesz;
376- offset = ((offset + 3)/4)*4;
377+ if (fm->cls == ELFCLASS32)
378+ memcpy(&nh32, &nbuf[offset], sizeof(nh32));
379+ else
380+ memcpy(&nh64, &nbuf[offset], sizeof(nh64));
381+ offset += nh_size;
382
383- /*
384- * Sigh. The 2.0.36 kernel in Debian 2.1, at
385- * least, doesn't correctly implement name
386- * sections, in core dumps, as specified by
387- * the "Program Linking" section of "UNIX(R) System
388- * V Release 4 Programmer's Guide: ANSI C and
389- * Programming Support Tools", because my copy
390- * clearly says "The first 'namesz' bytes in 'name'
391- * contain a *null-terminated* [emphasis mine]
392- * character representation of the entry's owner
393- * or originator", but the 2.0.36 kernel code
394- * doesn't include the terminating null in the
395- * name....
396- */
397- if (os_style == -1) {
398- if ((nh_namesz == 4 &&
399- strncmp(&nbuf[nameoffset],
400- "CORE", 4) == 0) ||
401- (nh_namesz == 5 &&
402- strcmp(&nbuf[nameoffset],
403- "CORE") == 0)) {
404- os_style = OS_STYLE_SVR4;
405- } else
406- if ((nh_namesz == 8 &&
407- strcmp(&nbuf[nameoffset],
408- "FreeBSD") == 0)) {
409- os_style = OS_STYLE_FREEBSD;
410- } else
411- if ((nh_namesz >= 11 &&
412- strncmp(&nbuf[nameoffset],
413- "NetBSD-CORE", 11) == 0)) {
414- os_style = OS_STYLE_NETBSD;
415- } else
416- /*@innercontinue@*/ continue;
417- file_printf(fm, ", %s-style", os_style_names[os_style]);
418+ if ((nh_namesz == 0) && (nh_descsz == 0)) {
419+ /*
420+ * We're out of note headers.
421+ */
422+ return offset;
423+ }
424+
425+ noff = offset;
426+ doff = ELF_ALIGN(offset + nh_namesz);
427+
428+ if (offset + nh_namesz >= size) {
429+ /*
430+ * We're past the end of the buffer.
431+ */
432+ return doff;
433+ }
434+
435+ offset = ELF_ALIGN(doff + nh_descsz);
436+ if (offset + nh_descsz >= size)
437+ return offset;
438+
439+ if (nh_namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
440+ nh_type == NT_GNU_VERSION && nh_descsz == 16) {
441+ uint32_t desc[4];
442+ (void)memcpy(desc, &nbuf[doff], sizeof(desc));
443+
444+ file_printf(fm, ", for GNU/");
445+ switch (getu32(fm, desc[0])) {
446+ case GNU_OS_LINUX:
447+ file_printf(fm, "Linux");
448+ break;
449+ case GNU_OS_HURD:
450+ file_printf(fm, "Hurd");
451+ break;
452+ case GNU_OS_SOLARIS:
453+ file_printf(fm, "Solaris");
454+ break;
455+ default:
456+ file_printf(fm, "<unknown>");
457+ }
458+ file_printf(fm, " %d.%d.%d", getu32(fm, desc[1]),
459+ getu32(fm, desc[2]), getu32(fm, desc[3]));
460+ return size;
461+ }
462+
463+ if (nh_namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
464+ nh_type == NT_NETBSD_VERSION && nh_descsz == 4) {
465+ uint32_t desc;
466+ (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
467+ desc = getu32(fm, desc);
468+
469+ file_printf(fm, ", for NetBSD");
470+ /*
471+ * The version number used to be stuck as 199905, and was thus
472+ * basically content-free. Newer versions of NetBSD have fixed
473+ * this and now use the encoding of __NetBSD_Version__:
474+ *
475+ * MMmmrrpp00
476+ *
477+ * M = major version
478+ * m = minor version
479+ * r = release ["",A-Z,Z[A-Z] but numeric]
480+ * p = patchlevel
481+ */
482+ if (desc > 100000000U) {
483+ u_int ver_patch = (desc / 100) % 100;
484+ u_int ver_rel = (desc / 10000) % 100;
485+ u_int ver_min = (desc / 1000000) % 100;
486+ u_int ver_maj = desc / 100000000;
487+
488+ file_printf(fm, " %u.%u", ver_maj, ver_min);
489+ if (ver_rel == 0 && ver_patch != 0) {
490+ file_printf(fm, ".%u", ver_patch);
491+ } else if (ver_rel != 0) {
492+ while (ver_rel > 26) {
493+ file_printf(fm, "Z");
494+ ver_rel -= 26;
495+ }
496+ file_printf(fm, "%c", 'A' + ver_rel - 1);
497 }
498+ }
499+ return size;
500+ }
501
502- if (os_style == OS_STYLE_NETBSD &&
503- nh_type == NT_NETBSD_CORE_PROCINFO) {
504- uint32_t signo;
505+ if (nh_namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
506+ nh_type == NT_FREEBSD_VERSION && nh_descsz == 4) {
507+ uint32_t desc;
508+ (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
509+ desc = getu32(fm, desc);
510+ file_printf(fm, ", for FreeBSD");
511+ /*
512+ * Contents is __FreeBSD_version, whose relation to OS versions
513+ * is defined by a huge table in the Porters' Handbook. Happily,
514+ * the first three digits are the version number, at least in
515+ * versions of FreeBSD that use this note.
516+ */
517+ file_printf(fm, " %d.%d", desc / 100000, desc / 10000 % 10);
518+ if (desc / 1000 % 10 > 0)
519+ file_printf(fm, ".%d", desc / 1000 % 10);
520+ return size;
521+ }
522
523+ if (nh_namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
524+ nh_type == NT_OPENBSD_VERSION && nh_descsz == 4) {
525+ file_printf(fm, ", for OpenBSD");
526+ /* Content of note is always 0 */
527+ return size;
528+ }
529+
530+ /*
531+ * Sigh. The 2.0.36 kernel in Debian 2.1, at
532+ * least, doesn't correctly implement name
533+ * sections, in core dumps, as specified by
534+ * the "Program Linking" section of "UNIX(R) System
535+ * V Release 4 Programmer's Guide: ANSI C and
536+ * Programming Support Tools", because my copy
537+ * clearly says "The first 'namesz' bytes in 'name'
538+ * contain a *null-terminated* [emphasis mine]
539+ * character representation of the entry's owner
540+ * or originator", but the 2.0.36 kernel code
541+ * doesn't include the terminating null in the
542+ * name....
543+ */
544+ if ((nh_namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
545+ (nh_namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
546+ os_style = OS_STYLE_SVR4;
547+ }
548+
549+ if ((nh_namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
550+ os_style = OS_STYLE_FREEBSD;
551+ }
552+
553+ if ((nh_namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
554+ == 0)) {
555+ os_style = OS_STYLE_NETBSD;
556+ }
557+
558+#ifdef ELFCORE
559+ if (os_style != -1)
560+ file_printf(fm, ", %s-style", os_style_names[os_style]);
561+
562+ if (os_style == OS_STYLE_NETBSD && nh_type == NT_NETBSD_CORE_PROCINFO) {
563+ uint32_t signo;
564+ /*
565+ * Extract the program name. It is at
566+ * offset 0x7c, and is up to 32-bytes,
567+ * including the terminating NUL.
568+ */
569+ file_printf(fm, ", from '%.31s'", &nbuf[doff + 0x7c]);
570+
571+ /*
572+ * Extract the signal number. It is at
573+ * offset 0x08.
574+ */
575+ memcpy(&signo, &nbuf[doff + 0x08],
576+ sizeof(signo));
577+ file_printf(fm, " (signal %u)", getu32(fm, signo));
578+ return size;
579+ } else if (os_style != OS_STYLE_NETBSD && nh_type == NT_PRPSINFO) {
580+ size_t i, j;
581+ unsigned char c;
582+ /*
583+ * Extract the program name. We assume
584+ * it to be 16 characters (that's what it
585+ * is in SunOS 5.x and Linux).
586+ *
587+ * Unfortunately, it's at a different offset
588+ * in varous OSes, so try multiple offsets.
589+ * If the characters aren't all printable,
590+ * reject it.
591+ */
592+ for (i = 0; i < NOFFSETS; i++) {
593+ size_t reloffset = prpsoffsets(i);
594+ size_t noffset = doff + reloffset;
595+ for (j = 0; j < 16; j++, noffset++, reloffset++) {
596 /*
597- * Extract the program name. It is at
598- * offset 0x7c, and is up to 32-bytes,
599- * including the terminating NUL.
600- */
601- file_printf(fm, ", from '%.31s'", &nbuf[offset + 0x7c]);
602-
603- /*
604- * Extract the signal number. It is at
605- * offset 0x08.
606+ * Make sure we're not past
607+ * the end of the buffer; if
608+ * we are, just give up.
609 */
610- memcpy(&signo, &nbuf[offset + 0x08],
611- sizeof(signo));
612- file_printf(fm, " (signal %u)", getu32(fm, signo));
613- } else
614- if (os_style != OS_STYLE_NETBSD &&
615- nh_type == NT_PRPSINFO) {
616+ if (noffset >= size)
617+ goto tryanother;
618+
619 /*
620- * Extract the program name. We assume
621- * it to be 16 characters (that's what it
622- * is in SunOS 5.x and Linux).
623- *
624- * Unfortunately, it's at a different offset
625- * in varous OSes, so try multiple offsets.
626- * If the characters aren't all printable,
627- * reject it.
628+ * Make sure we're not past
629+ * the end of the contents;
630+ * if we are, this obviously
631+ * isn't the right offset.
632 */
633- for (i = 0; i < NOFFSETS; i++) {
634- reloffset = prpsoffsets(i);
635- noffset = offset + reloffset;
636- for (j = 0; j < 16;
637- j++, noffset++, reloffset++) {
638- /*
639- * Make sure we're not past
640- * the end of the buffer; if
641- * we are, just give up.
642- */
643- if (noffset >= bufsize)
644- goto tryanother;
645-
646- /*
647- * Make sure we're not past
648- * the end of the contents;
649- * if we are, this obviously
650- * isn't the right offset.
651- */
652- if (reloffset >= nh_descsz)
653- goto tryanother;
654-
655- c = nbuf[noffset];
656- if (c == '\0') {
657- /*
658- * A '\0' at the
659- * beginning is
660- * obviously wrong.
661- * Any other '\0'
662- * means we're done.
663- */
664- if (j == 0)
665- goto tryanother;
666- else
667- /*@innerbreak@*/ break;
668- } else {
669- /*
670- * A nonprintable
671- * character is also
672- * wrong.
673- */
674-#define isquote(c) (strchr("'\"`", (c)) != NULL)
675- if (!isprint(c) ||
676- isquote(c))
677- goto tryanother;
678- }
679- }
680+ if (reloffset >= nh_descsz)
681+ goto tryanother;
682
683+ c = nbuf[noffset];
684+ if (c == '\0') {
685 /*
686- * Well, that worked.
687+ * A '\0' at the
688+ * beginning is
689+ * obviously wrong.
690+ * Any other '\0'
691+ * means we're done.
692 */
693- file_printf(fm, ", from '%.16s'",
694- &nbuf[offset + prpsoffsets(i)]);
695- /*@innerbreak@*/ break;
696-
697- tryanother:
698- ;
699+ if (j == 0)
700+ goto tryanother;
701+ else
702+ break;
703+ } else {
704+ /*
705+ * A nonprintable
706+ * character is also
707+ * wrong.
708+ */
709+#define isquote(c) (strchr("'\"`", (c)) != NULL)
710+ if (!isprint(c) || isquote(c))
711+ goto tryanother;
712 }
713- /*@innerbreak@*/ break;
714 }
715- offset += nh_descsz;
716- offset = ((offset + 3)/4)*4;
717+
718+ /*
719+ * Well, that worked.
720+ */
721+ file_printf(fm, ", from '%.16s'",
722+ &nbuf[doff + prpsoffsets(i)]);
723+ return size;
724+
725+ tryanother:
726+ ;
727+ }
728+ return offset;
729+ }
730+#endif
731+ return offset;
732+}
733+
734+static void
735+doshn(fmagic fm, off_t off, int num, size_t size)
736+ /*@globals fileSystem @*/
737+ /*@modifies fm, fileSystem @*/
738+{
739+ Elf32_Shdr sh32;
740+ Elf64_Shdr sh64;
741+
742+ if (size != sh_size) {
743+ error(EXIT_FAILURE, 0, "corrupted program header size.\n");
744+ /*@notreached@*/
745+ }
746+
747+ if (lseek(fm->fd, off, SEEK_SET) == (off_t)-1) {
748+ error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
749+ /*@notreached@*/
750+ }
751+
752+ for ( ; num; num--) {
753+ if (read(fm->fd, sh_addr, sh_size) == -1) {
754+ error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
755+ /*@notreached@*/
756+ }
757+ if (shs_type == SHT_SYMTAB /* || shs_type == SHT_DYNSYM */) {
758+ file_printf(fm, ", not stripped");
759+ return;
760+ }
761+ }
762+ file_printf(fm, ", stripped");
763+}
764+/*@=bounds@*/
765+
766+/*
767+ * Look through the program headers of an executable image, searching
768+ * for a PT_INTERP section; if one is found, it's dynamically linked,
769+ * otherwise it's statically linked.
770+ */
771+/*@-bounds@*/
772+static void
773+dophn_exec(fmagic fm, off_t off, int num, size_t size)
774+ /*@globals fileSystem @*/
775+ /*@modifies fm, fileSystem @*/
776+{
777+ Elf32_Phdr ph32;
778+ Elf64_Phdr ph64;
779+ const char *linking_style = "statically";
780+ const char *shared_libraries = "";
781+ unsigned char nbuf[BUFSIZ];
782+ int bufsize;
783+ size_t offset;
784+ off_t savedoffset;
785+
786+ if (size != ph_size) {
787+ error(EXIT_FAILURE, 0, "corrupted program header size.\n");
788+ /*@notreached@*/
789+ }
790+
791+ if (lseek(fm->fd, off, SEEK_SET) == (off_t)-1) {
792+ error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
793+ /*@notreached@*/
794+ }
795+
796+ for ( ; num; num--) {
797+ if (read(fm->fd, ph_addr, ph_size) == -1) {
798+ error(EXIT_FAILURE, 0, "read failed (%s).\n", strerror(errno));
799+ /*@notreached@*/
800+ }
801+ if ((savedoffset = lseek(fm->fd, (off_t)0, SEEK_CUR)) == (off_t)-1) {
802+ error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
803+ /*@notreached@*/
804+ }
805+
806+ switch (ph_type) {
807+ case PT_DYNAMIC:
808+ linking_style = "dynamically";
809+ /*@switchbreak@*/ break;
810+ case PT_INTERP:
811+ shared_libraries = " (uses shared libs)";
812+ /*@switchbreak@*/ break;
813+ case PT_NOTE:
814+ /*
815+ * This is a PT_NOTE section; loop through all the notes
816+ * in the section.
817+ */
818+ if (lseek(fm->fd, (off_t) ph_offset, SEEK_SET) == -1) {
819+ error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
820+ /*@notreached@*/
821+ }
822+ bufsize = read(fm->fd, nbuf, sizeof(nbuf));
823+ if (bufsize == -1) {
824+ error(EXIT_FAILURE, 0, ": " "read failed (%s).\n",
825+ strerror(errno));
826+ /*@notreached@*/
827+ }
828+ offset = 0;
829+ for (;;) {
830+ if (offset >= (size_t)bufsize)
831+ /*@innerbreak@*/ break;
832+ offset = donote(fm, nbuf, offset,
833+ (size_t)bufsize, ph_align);
834+ }
835+ if ((lseek(fm->fd, savedoffset + offset, SEEK_SET)) == (off_t)-1) {
836+ error(EXIT_FAILURE, 0, "lseek failed (%s).\n", strerror(errno));
837+ /*@notreached@*/
838+ }
839+ /*@switchbreak@*/ break;
840 }
841 }
842+ file_printf(fm, ", %s linked%s", linking_style, shared_libraries);
843 }
844 /*@=bounds@*/
845-#endif
846
847 /*@-bounds@*/
848 void
This page took 0.152244 seconds and 4 git commands to generate.