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