]> git.pld-linux.org Git - packages/rpm.git/blob - rpm-file-readelf.patch
- updated amd64 patch
[packages/rpm.git] / rpm-file-readelf.patch
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.277461 seconds and 3 git commands to generate.