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