/[gentoo-projects]/pax-utils/scanelf.c
Gentoo

Diff of /pax-utils/scanelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.51 Revision 1.61
1/* 1/*
2 * Copyright 2003 Ned Ludd <solar@gentoo.org> 2 * Copyright 2003 Ned Ludd <solar@gentoo.org>
3 * Copyright 1999-2005 Gentoo Foundation 3 * Copyright 1999-2005 Gentoo Foundation
4 * Distributed under the terms of the GNU General Public License v2 4 * Distributed under the terms of the GNU General Public License v2
5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.51 2005/05/18 05:15:48 vapier Exp $ 5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.61 2005/05/28 22:09:36 solar Exp $
6 * 6 *
7 ******************************************************************** 7 ********************************************************************
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the 10 * published by the Free Software Foundation; either version 2 of the
22 */ 22 */
23 23
24#include <stdio.h> 24#include <stdio.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include <sys/types.h> 26#include <sys/types.h>
27#include <libgen.h>
28#include <limits.h>
27#define __USE_GNU 29#define __USE_GNU
28#include <string.h> 30#include <string.h>
29#include <errno.h> 31#include <errno.h>
30#include <unistd.h> 32#include <unistd.h>
31#include <sys/stat.h> 33#include <sys/stat.h>
32#include <dirent.h> 34#include <dirent.h>
33#include <getopt.h> 35#include <getopt.h>
34#include <assert.h> 36#include <assert.h>
35
36#include "paxelf.h" 37#include "paxelf.h"
37 38
38static const char *rcsid = "$Id: scanelf.c,v 1.51 2005/05/18 05:15:48 vapier Exp $"; 39static const char *rcsid = "$Id: scanelf.c,v 1.61 2005/05/28 22:09:36 solar Exp $";
39#define argv0 "scanelf" 40#define argv0 "scanelf"
40 41
41 42
42 43
43/* prototypes */ 44/* prototypes */
45static void scanelf_dir(const char *path); 46static void scanelf_dir(const char *path);
46static void scanelf_ldpath(); 47static void scanelf_ldpath();
47static void scanelf_envpath(); 48static void scanelf_envpath();
48static void usage(int status); 49static void usage(int status);
49static void parseargs(int argc, char *argv[]); 50static void parseargs(int argc, char *argv[]);
50static char *xstrdup(char *s); 51static char *xstrdup(const char *s);
51static void *xmalloc(size_t size); 52static void *xmalloc(size_t size);
52static void xstrcat(char **dst, const char *src, size_t *curr_len); 53static void xstrcat(char **dst, const char *src, size_t *curr_len);
53static inline void xchrcat(char **dst, const char append, size_t *curr_len); 54static inline void xchrcat(char **dst, const char append, size_t *curr_len);
54static int xemptybuffer(const char *buff);
55 55
56/* variables to control behavior */ 56/* variables to control behavior */
57static char *ldpaths[256]; 57static char *ldpaths[256];
58static char scan_ldpath = 0; 58static char scan_ldpath = 0;
59static char scan_envpath = 0; 59static char scan_envpath = 0;
72static char be_verbose = 0; 72static char be_verbose = 0;
73static char *find_sym = NULL, *versioned_symname = NULL; 73static char *find_sym = NULL, *versioned_symname = NULL;
74static char *out_format = NULL; 74static char *out_format = NULL;
75 75
76 76
77
78/* sub-funcs for scanelf_file() */ 77/* sub-funcs for scanelf_file() */
79static char *scanelf_file_pax(elfobj *elf, char *found_pax) 78static char *scanelf_file_pax(elfobj *elf, char *found_pax)
80{ 79{
81 static char *paxflags; 80 static char *paxflags;
81 static char ret[7];
82 unsigned long i, shown;
83
82 84
83 if (!show_pax) return NULL; 85 if (!show_pax) return NULL;
84 86
87 shown = 0;
88 memset(&ret, 0, sizeof(ret));
89
90 if (elf->phdr) {
91#define SHOW_PAX(B) \
92 if (elf->elf_class == ELFCLASS ## B) { \
93 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
94 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
95 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
96 if (EGET(phdr[i].p_type) != PT_PAX_FLAGS) \
97 continue; \
98 if (be_quiet && (EGET(phdr[i].p_flags) == 10240)) \
99 continue; \
100 memcpy(ret, pax_short_pf_flags(EGET(phdr[i].p_flags)), 6); \
101 *found_pax = 1; \
102 ++shown; \
103 break; \
104 } \
105 }
106 SHOW_PAX(32)
107 SHOW_PAX(64)
108 }
109
110 /* fall back to EI_PAX if no PT_PAX was found */
111 if (!*ret) {
85 paxflags = pax_short_hf_flags(PAX_FLAGS(elf)); 112 paxflags = pax_short_hf_flags(EI_PAX_FLAGS(elf));
86 if (!be_quiet || (be_quiet && strncmp(paxflags, "PeMRxS", 6))) { 113 if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) {
87 *found_pax = 1; 114 *found_pax = 1;
88 return paxflags; 115 return paxflags;
89 } 116 }
117 strncpy(ret, paxflags, sizeof(ret));
118 // ++shown;
119 }
90 120
121 if (be_quiet && !shown)
91 return NULL; 122 return NULL;
123 return ret;
124
92} 125}
93static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro) 126static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro)
94{ 127{
95 static char ret[8]; 128 static char ret[8] = "--- ---";
96 char *found; 129 char *found;
97 unsigned long i, off, shown; 130 unsigned long i, off, shown;
98 131
99 if (!show_stack) return NULL; 132 if (!show_stack) return NULL;
100 133
101 shown = 0; 134 shown = 0;
102 strcpy(ret, "--- ---");
103 135
104 if (elf->phdr) { 136 if (elf->phdr) {
105#define SHOW_STACK(B) \ 137#define SHOW_STACK(B) \
106 if (elf->elf_class == ELFCLASS ## B) { \ 138 if (elf->elf_class == ELFCLASS ## B) { \
107 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 139 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
110 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ 142 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \
111 found = found_stack; \ 143 found = found_stack; \
112 off = 0; \ 144 off = 0; \
113 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ 145 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \
114 found = found_relro; \ 146 found = found_relro; \
115 off = 3; \ 147 off = 4; \
116 } else \ 148 } else \
117 continue; \ 149 continue; \
118 if (be_quiet && !(EGET(phdr[i].p_flags) & PF_X)) \ 150 if (be_quiet && !(EGET(phdr[i].p_flags) & PF_X)) \
119 continue; \ 151 continue; \
120 memcpy(ret+off, gnu_short_stack_flags(EGET(phdr[i].p_flags)), 3); \ 152 memcpy(ret+off, gnu_short_stack_flags(EGET(phdr[i].p_flags)), 3); \
144 Elf ## B ## _Dyn *dyn; \ 176 Elf ## B ## _Dyn *dyn; \
145 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 177 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
146 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 178 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
147 Elf ## B ## _Off offset; \ 179 Elf ## B ## _Off offset; \
148 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 180 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
149 if (phdr[i].p_type != PT_DYNAMIC) continue; \ 181 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
150 offset = EGET(phdr[i].p_offset); \ 182 offset = EGET(phdr[i].p_offset); \
151 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 183 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
152 dyn = DYN ## B (elf->data + offset); \ 184 dyn = DYN ## B (elf->data + offset); \
153 while (EGET(dyn->d_tag) != DT_NULL) { \ 185 while (EGET(dyn->d_tag) != DT_NULL) { \
154 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ 186 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \
186 Elf ## B ## _Dyn *dyn; \ 218 Elf ## B ## _Dyn *dyn; \
187 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 219 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
188 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 220 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
189 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 221 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
190 Elf ## B ## _Off offset; \ 222 Elf ## B ## _Off offset; \
191 Elf ## B ## _Sxword word; \ 223 Elf ## B ## _Xword word; \
192 /* Scan all the program headers */ \ 224 /* Scan all the program headers */ \
193 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 225 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
194 /* Just scan dynamic headers */ \ 226 /* Just scan dynamic headers */ \
195 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 227 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
196 offset = EGET(phdr[i].p_offset); \ 228 offset = EGET(phdr[i].p_offset); \
337 } \ 369 } \
338 } 370 }
339 SHOW_BIND(32) 371 SHOW_BIND(32)
340 SHOW_BIND(64) 372 SHOW_BIND(64)
341 373
342 fstat(elf->fd, &s);
343 if (be_quiet && !(s.st_mode & S_ISUID || s.st_mode & S_ISGID)) { 374 if (be_quiet && !fstat(elf->fd, &s) && !(s.st_mode & S_ISUID || s.st_mode & S_ISGID)) {
344 return NULL; 375 return NULL;
345 } else { 376 } else {
346 *found_bind = 1; 377 *found_bind = 1;
347 return "LAZY"; 378 return "LAZY";
348 } 379 }
356 387
357 symtab_void = elf_findsecbyname(elf, ".symtab"); 388 symtab_void = elf_findsecbyname(elf, ".symtab");
358 strtab_void = elf_findsecbyname(elf, ".strtab"); 389 strtab_void = elf_findsecbyname(elf, ".strtab");
359 390
360 if (symtab_void && strtab_void) { 391 if (symtab_void && strtab_void) {
392 char *base, *basemem;
393 basemem = xstrdup(filename);
394 base = basename(basemem);
361#define FIND_SYM(B) \ 395#define FIND_SYM(B) \
362 if (elf->elf_class == ELFCLASS ## B) { \ 396 if (elf->elf_class == ELFCLASS ## B) { \
363 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 397 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
364 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 398 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
365 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ 399 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
369 if (sym->st_name) { \ 403 if (sym->st_name) { \
370 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ 404 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
371 if (*find_sym == '*') { \ 405 if (*find_sym == '*') { \
372 printf("%s(%s) %5lX %15s %s\n", \ 406 printf("%s(%s) %5lX %15s %s\n", \
373 ((*found_sym == 0) ? "\n\t" : "\t"), \ 407 ((*found_sym == 0) ? "\n\t" : "\t"), \
374 (char *)basename(filename), \ 408 base, \
375 (long)sym->st_size, \ 409 (long)sym->st_size, \
376 (char *)get_elfstttype(sym->st_info), \ 410 (char *)get_elfstttype(sym->st_info), \
377 symname); \ 411 symname); \
378 *found_sym = 1; \ 412 *found_sym = 1; \
379 } else if ((strcmp(find_sym, symname) == 0) || \ 413 } else if ((strcmp(find_sym, symname) == 0) || \
382 } \ 416 } \
383 ++sym; \ 417 ++sym; \
384 } } 418 } }
385 FIND_SYM(32) 419 FIND_SYM(32)
386 FIND_SYM(64) 420 FIND_SYM(64)
421 free(basemem);
387 } 422 }
388 if (*find_sym != '*' && *found_sym) 423 if (*find_sym != '*' && *found_sym)
389 return find_sym; 424 return find_sym;
390 if (be_quiet) 425 if (be_quiet)
391 return NULL; 426 return NULL;
392 else 427 else
393 return " - "; 428 return " - ";
394} 429}
395/* scan an elf file and show all the fun stuff */ 430/* scan an elf file and show all the fun stuff */
396#define prints(str) fputs(str, stdout) 431// #define prints(str) fputs(str, stdout)
432#define prints(str) write(fileno(stdout), str, strlen(str))
397static void scanelf_file(const char *filename) 433static void scanelf_file(const char *filename)
398{ 434{
399 unsigned long i; 435 unsigned long i;
400 char found_pax, found_stack, found_relro, found_textrel, 436 char found_pax, found_stack, found_relro, found_textrel,
401 found_rpath, found_needed, found_interp, found_bind, 437 found_rpath, found_needed, found_interp, found_bind,
409 if (lstat(filename, &st) == -1) { 445 if (lstat(filename, &st) == -1) {
410 if (be_verbose > 2) printf("%s: does not exist\n", filename); 446 if (be_verbose > 2) printf("%s: does not exist\n", filename);
411 return; 447 return;
412 } 448 }
413 /* always handle regular files and handle symlinked files if no -y */ 449 /* always handle regular files and handle symlinked files if no -y */
414 if (!(S_ISREG(st.st_mode) || (S_ISLNK(st.st_mode) && scan_symlink))) { 450 if (S_ISLNK(st.st_mode)) {
451 if (!scan_symlink) return;
452 stat(filename, &st);
453 }
454 if (!S_ISREG(st.st_mode)) {
415 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 455 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
416 return; 456 return;
417 } 457 }
418 458
419 found_pax = found_stack = found_relro = found_textrel = \ 459 found_pax = found_stack = found_relro = found_textrel = \
493 case 's': out = scanelf_file_sym(elf, &found_sym, filename); break; 533 case 's': out = scanelf_file_sym(elf, &found_sym, filename); break;
494 } 534 }
495 if (out) xstrcat(&out_buffer, out, &out_len); 535 if (out) xstrcat(&out_buffer, out, &out_len);
496 } 536 }
497 537
498 if (!found_file) { 538#define FOUND_SOMETHING() \
499 if (!be_quiet || found_pax || found_stack || found_textrel || \ 539 (found_pax || found_stack || found_textrel || found_rpath || \
500 found_rpath || found_needed || found_interp || found_bind || \ 540 found_needed || found_interp || found_bind || found_sym)
501 found_sym) 541
502 { 542 if (!found_file && (!be_quiet || (be_quiet && FOUND_SOMETHING()))) {
503 xchrcat(&out_buffer, ' ', &out_len); 543 xchrcat(&out_buffer, ' ', &out_len);
504 xstrcat(&out_buffer, filename, &out_len); 544 xstrcat(&out_buffer, filename, &out_len);
505 } 545 }
506 } 546 if (!be_quiet || (be_quiet && FOUND_SOMETHING()))
507 if (!(be_quiet && xemptybuffer(out_buffer)))
508 puts(out_buffer); 547 puts(out_buffer);
509 548
510 unreadelf(elf); 549 unreadelf(elf);
511} 550}
512 551
680 {"nobanner", no_argument, NULL, 'B'}, 719 {"nobanner", no_argument, NULL, 'B'},
681 {"help", no_argument, NULL, 'h'}, 720 {"help", no_argument, NULL, 'h'},
682 {"version", no_argument, NULL, 'V'}, 721 {"version", no_argument, NULL, 'V'},
683 {NULL, no_argument, NULL, 0x0} 722 {NULL, no_argument, NULL, 0x0}
684}; 723};
724
685static char *opts_help[] = { 725static char *opts_help[] = {
686 "Scan all directories in PATH environment", 726 "Scan all directories in PATH environment",
687 "Scan all directories in /etc/ld.so.conf", 727 "Scan all directories in /etc/ld.so.conf",
688 "Scan directories recursively", 728 "Scan directories recursively",
689 "Don't recursively cross mount points", 729 "Don't recursively cross mount points",
694 "Print RPATH information", 734 "Print RPATH information",
695 "Print NEEDED information", 735 "Print NEEDED information",
696 "Print INTERP information", 736 "Print INTERP information",
697 "Print BIND information", 737 "Print BIND information",
698 "Find a specified symbol", 738 "Find a specified symbol",
699 "Print all scanned info (-x -e -t -r -n -i)\n", 739 "Print all scanned info (-x -e -t -r -n -i -b)\n",
700 "Only output 'bad' things", 740 "Only output 'bad' things",
701 "Be verbose (can be specified more than once)", 741 "Be verbose (can be specified more than once)",
702 "Use specified format for output", 742 "Use specified format for output",
703 "Read input stream from a filename", 743 "Read input stream from a filename",
704 "Write output stream to a filename", 744 "Write output stream to a filename",
710 750
711/* display usage and exit */ 751/* display usage and exit */
712static void usage(int status) 752static void usage(int status)
713{ 753{
714 unsigned long i; 754 unsigned long i;
715 printf(" Scan ELF binaries for stuff\n\n" 755 printf("* Scan ELF binaries for stuff\n\n"
716 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); 756 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0);
717 printf("Options: -[%s]\n", PARSE_FLAGS); 757 printf("Options: -[%s]\n", PARSE_FLAGS);
718 for (i = 0; long_opts[i].name; ++i) 758 for (i = 0; long_opts[i].name; ++i)
719 if (long_opts[i].has_arg == no_argument) 759 if (long_opts[i].has_arg == no_argument)
720 printf(" -%c, --%-13s %s\n", long_opts[i].val, 760 printf(" -%c, --%-13s* %s\n", long_opts[i].val,
721 long_opts[i].name, opts_help[i]); 761 long_opts[i].name, opts_help[i]);
722 else 762 else
723 printf(" -%c, --%-6s <arg> %s\n", long_opts[i].val, 763 printf(" -%c, --%-6s <arg> * %s\n", long_opts[i].val,
724 long_opts[i].name, opts_help[i]); 764 long_opts[i].name, opts_help[i]);
725 765
726 if (status != EXIT_SUCCESS) 766 if (status != EXIT_SUCCESS)
727 exit(status); 767 exit(status);
728 768
772 sprintf(versioned_symname, "%s@", find_sym); 812 sprintf(versioned_symname, "%s@", find_sym);
773 break; 813 break;
774 } 814 }
775 815
776 case 'F': { 816 case 'F': {
817 if (!out_format)
777 out_format = xstrdup(optarg); 818 out_format = xstrdup(optarg);
778 break; 819 break;
779 } 820 }
780 821
781 case 'y': scan_symlink = 0; break; 822 case 'y': scan_symlink = 0; break;
782 case 'B': show_banner = 0; break; 823 case 'B': show_banner = 0; break;
805 } 846 }
806 } 847 }
807 848
808 /* let the format option override all other options */ 849 /* let the format option override all other options */
809 if (out_format) { 850 if (out_format) {
810 show_pax = show_stack = show_textrel = show_rpath = show_needed = show_interp = 0; 851 show_pax = show_stack = show_textrel = show_rpath = \
852 show_needed = show_interp = show_bind = 0;
811 for (i = 0; out_format[i]; ++i) { 853 for (i = 0; out_format[i]; ++i) {
812 if (out_format[i] != '%') continue; 854 if (out_format[i] != '%') continue;
813 855
814 switch (out_format[++i]) { 856 switch (out_format[++i]) {
815 case '%': break; 857 case '%': break;
872} 914}
873 915
874 916
875 917
876/* utility funcs */ 918/* utility funcs */
877static char *xstrdup(char *s) 919static char *xstrdup(const char *s)
878{ 920{
879 char *ret = strdup(s); 921 char *ret = strdup(s);
880 if (!ret) err("Could not strdup(): %s", strerror(errno)); 922 if (!ret) err("Could not strdup(): %s", strerror(errno));
881 return ret; 923 return ret;
882} 924}
925
883static void *xmalloc(size_t size) 926static void *xmalloc(size_t size)
884{ 927{
885 void *ret = malloc(size); 928 void *ret = malloc(size);
886 if (!ret) err("Could not malloc() %li bytes", (unsigned long)size); 929 if (!ret) err("Could not malloc() %li bytes", (unsigned long)size);
887 return ret; 930 return ret;
888} 931}
932
889static void xstrcat(char **dst, const char *src, size_t *curr_len) 933static void xstrcat(char **dst, const char *src, size_t *curr_len)
890{ 934{
891 long new_len; 935 long new_len;
892 936
893 new_len = strlen(*dst) + strlen(src); 937 new_len = strlen(*dst) + strlen(src);
898 err("could not realloc %li bytes", (unsigned long)*curr_len); 942 err("could not realloc %li bytes", (unsigned long)*curr_len);
899 } 943 }
900 944
901 strcat(*dst, src); 945 strcat(*dst, src);
902} 946}
947
903static inline void xchrcat(char **dst, const char append, size_t *curr_len) 948static inline void xchrcat(char **dst, const char append, size_t *curr_len)
904{ 949{
905 static char my_app[2]; 950 static char my_app[2];
906 my_app[0] = append; 951 my_app[0] = append;
907 my_app[1] = '\0'; 952 my_app[1] = '\0';
908 xstrcat(dst, my_app, curr_len); 953 xstrcat(dst, my_app, curr_len);
909} 954}
910static int xemptybuffer(const char *buff)
911{
912 long i;
913 for (i = 0; buff[i]; ++i)
914 if (buff[i] != ' ')
915 return 0;
916 return 1;
917}
918
919 955
920 956
921int main(int argc, char *argv[]) 957int main(int argc, char *argv[])
922{ 958{
923 if (argc < 2) 959 if (argc < 2)
924 usage(EXIT_FAILURE); 960 usage(EXIT_FAILURE);
925 parseargs(argc, argv); 961 parseargs(argc, argv);
926 fclose(stdout); 962 fclose(stdout);
963#ifdef __BOUNDS_CHECKING_ON
964 warn("The calls to add/delete heap should be off by 1 due to the out_buffer not being freed in scanelf_file()");
965#endif
927 return EXIT_SUCCESS; 966 return EXIT_SUCCESS;
928} 967}

Legend:
Removed from v.1.51  
changed lines
  Added in v.1.61

  ViewVC Help
Powered by ViewVC 1.1.20