/[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.61 Revision 1.70
1/* 1/*
2 * Copyright 2003 Ned Ludd <solar@gentoo.org>
3 * Copyright 1999-2005 Gentoo Foundation 2 * Copyright 2003-2005 Gentoo Foundation
4 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.61 2005/05/28 22:09:36 solar Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.70 2005/06/03 23:41:59 vapier Exp $
6 * 5 *
7 ******************************************************************** 6 ********************************************************************
8 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the 9 * published by the Free Software Foundation; either version 2 of the
34#include <dirent.h> 33#include <dirent.h>
35#include <getopt.h> 34#include <getopt.h>
36#include <assert.h> 35#include <assert.h>
37#include "paxelf.h" 36#include "paxelf.h"
38 37
39static const char *rcsid = "$Id: scanelf.c,v 1.61 2005/05/28 22:09:36 solar Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.70 2005/06/03 23:41:59 vapier Exp $";
40#define argv0 "scanelf" 39#define argv0 "scanelf"
40
41#define IS_MODIFIER(c) (c == '%' || c == '#')
41 42
42 43
43 44
44/* prototypes */ 45/* prototypes */
45static void scanelf_file(const char *filename); 46static void scanelf_file(const char *filename);
68static char show_interp = 0; 69static char show_interp = 0;
69static char show_bind = 0; 70static char show_bind = 0;
70static char show_banner = 1; 71static char show_banner = 1;
71static char be_quiet = 0; 72static char be_quiet = 0;
72static char be_verbose = 0; 73static char be_verbose = 0;
74static char be_wewy_wewy_quiet = 0;
73static char *find_sym = NULL, *versioned_symname = NULL; 75static char *find_sym = NULL, *versioned_symname = NULL;
74static char *out_format = NULL; 76static char *out_format = NULL;
77static char *search_path = NULL;
78
75 79
76 80
77/* sub-funcs for scanelf_file() */ 81/* sub-funcs for scanelf_file() */
78static char *scanelf_file_pax(elfobj *elf, char *found_pax) 82static char *scanelf_file_pax(elfobj *elf, char *found_pax)
79{ 83{
163 else 167 else
164 return ret; 168 return ret;
165} 169}
166static char *scanelf_file_textrel(elfobj *elf, char *found_textrel) 170static char *scanelf_file_textrel(elfobj *elf, char *found_textrel)
167{ 171{
168 static char *ret = "TEXTREL"; 172 static char ret[] = "TEXTREL";
169 unsigned long i; 173 unsigned long i;
170 174
171 if (!show_textrel) return NULL; 175 if (!show_textrel) return NULL;
172 176
173 if (elf->phdr) { 177 if (elf->phdr) {
184 dyn = DYN ## B (elf->data + offset); \ 188 dyn = DYN ## B (elf->data + offset); \
185 while (EGET(dyn->d_tag) != DT_NULL) { \ 189 while (EGET(dyn->d_tag) != DT_NULL) { \
186 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ 190 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \
187 *found_textrel = 1; \ 191 *found_textrel = 1; \
188 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \ 192 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \
189 return ret; \ 193 return (be_wewy_wewy_quiet ? NULL : ret); \
190 } \ 194 } \
191 ++dyn; \ 195 ++dyn; \
192 } \ 196 } \
193 } } 197 } }
194 SHOW_TEXTREL(32) 198 SHOW_TEXTREL(32)
195 SHOW_TEXTREL(64) 199 SHOW_TEXTREL(64)
196 } 200 }
197 201
198 if (be_quiet) 202 if (be_quiet || be_wewy_wewy_quiet)
199 return NULL; 203 return NULL;
200 else 204 else
201 return " - "; 205 return (char *)" - ";
202} 206}
203static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) 207static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len)
204{ 208{
205 /* TODO: when checking RPATH entries, check each subpath (between :) in ld.so.conf */
206 unsigned long i, s; 209 unsigned long i, s;
207 char *rpath, *runpath, **r; 210 char *rpath, *runpath, **r;
208 void *strtbl_void; 211 void *strtbl_void;
209 212
210 if (!show_rpath) return; 213 if (!show_rpath) return;
238 ++dyn; \ 241 ++dyn; \
239 continue; \ 242 continue; \
240 } \ 243 } \
241 /* Verify the memory is somewhat sane */ \ 244 /* Verify the memory is somewhat sane */ \
242 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 245 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
243 if (offset < elf->len) { \ 246 if (offset < (Elf ## B ## _Off)elf->len) { \
244 if (*r) warn("ELF has multiple %s's !?", get_elfdtype(word)); \ 247 if (*r) warn("ELF has multiple %s's !?", get_elfdtype(word)); \
245 *r = (char*)(elf->data + offset); \ 248 *r = (char*)(elf->data + offset); \
246 /* If quiet, don't output paths in ld.so.conf */ \ 249 /* If quiet, don't output paths in ld.so.conf */ \
247 if (be_quiet) \ 250 if (be_quiet) { \
251 size_t len; \
252 char *start, *end; \
248 for (s = 0; ldpaths[s]; ++s) \ 253 for (s = 0; *r && ldpaths[s]; ++s) { \
249 if (!strcmp(ldpaths[s], *r)) { \ 254 /* scan each path in : delimited list */ \
250 *r = NULL; \ 255 start = *r; \
256 end = strchr(start, ':'); \
257 while ((start && ((end = strchr(start, ':')) != NULL)) || start) { \
258 len = (end ? abs(end - start) : strlen(start)); \
259 if (!strncmp(ldpaths[s], start, len) && !ldpaths[s][len]) { \
260 *r = (end ? end + 1 : NULL); \
251 break; \ 261 break; \
262 } \
263 start = (end ? start + len + 1 : NULL); \
252 } \ 264 } \
265 } \
266 } \
253 if (*r) *found_rpath = 1; \ 267 if (*r) *found_rpath = 1; \
254 } \ 268 } \
255 ++dyn; \ 269 ++dyn; \
256 } \ 270 } \
257 } } 271 } }
258 SHOW_RPATH(32) 272 SHOW_RPATH(32)
259 SHOW_RPATH(64) 273 SHOW_RPATH(64)
260 } 274 }
275
276 if (be_wewy_wewy_quiet) return;
261 277
262 if (rpath && runpath) { 278 if (rpath && runpath) {
263 if (!strcmp(rpath, runpath)) { 279 if (!strcmp(rpath, runpath)) {
264 xstrcat(ret, runpath, ret_len); 280 xstrcat(ret, runpath, ret_len);
265 } else { 281 } else {
299 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 315 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
300 dyn = DYN ## B (elf->data + offset); \ 316 dyn = DYN ## B (elf->data + offset); \
301 while (EGET(dyn->d_tag) != DT_NULL) { \ 317 while (EGET(dyn->d_tag) != DT_NULL) { \
302 if (EGET(dyn->d_tag) == DT_NEEDED) { \ 318 if (EGET(dyn->d_tag) == DT_NEEDED) { \
303 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 319 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
304 if (offset >= elf->len) { \ 320 if (offset >= (Elf ## B ## _Off)elf->len) { \
305 ++dyn; \ 321 ++dyn; \
306 continue; \ 322 continue; \
307 } \ 323 } \
308 needed = (char*)(elf->data + offset); \ 324 needed = (char*)(elf->data + offset); \
309 if (*found_needed) xchrcat(ret, ',', ret_len); \ 325 if (*found_needed) xchrcat(ret, ',', ret_len); \
310 xstrcat(ret, needed, ret_len); \ 326 if (!be_wewy_wewy_quiet) xstrcat(ret, needed, ret_len); \
311 *found_needed = 1; \ 327 *found_needed = 1; \
312 } \ 328 } \
313 ++dyn; \ 329 ++dyn; \
314 } \ 330 } \
315 } } 331 } }
328 if (strtbl_void) { 344 if (strtbl_void) {
329#define SHOW_INTERP(B) \ 345#define SHOW_INTERP(B) \
330 if (elf->elf_class == ELFCLASS ## B) { \ 346 if (elf->elf_class == ELFCLASS ## B) { \
331 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 347 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
332 *found_interp = 1; \ 348 *found_interp = 1; \
333 return elf->data + EGET(strtbl->sh_offset); \ 349 return (be_wewy_wewy_quiet ? NULL : elf->data + EGET(strtbl->sh_offset)); \
334 } 350 }
335 SHOW_INTERP(32) 351 SHOW_INTERP(32)
336 SHOW_INTERP(64) 352 SHOW_INTERP(64)
337 } 353 }
338 return NULL; 354 return NULL;
360 if (EGET(dyn->d_tag) == DT_BIND_NOW || \ 376 if (EGET(dyn->d_tag) == DT_BIND_NOW || \
361 (EGET(dyn->d_tag) == DT_FLAGS && EGET(dyn->d_un.d_val) & DF_BIND_NOW)) \ 377 (EGET(dyn->d_tag) == DT_FLAGS && EGET(dyn->d_un.d_val) & DF_BIND_NOW)) \
362 { \ 378 { \
363 if (be_quiet) return NULL; \ 379 if (be_quiet) return NULL; \
364 *found_bind = 1; \ 380 *found_bind = 1; \
365 return "NOW"; \ 381 return (char *)(be_wewy_wewy_quiet ? NULL : "NOW"); \
366 } \ 382 } \
367 ++dyn; \ 383 ++dyn; \
368 } \ 384 } \
369 } \ 385 } \
370 } 386 }
371 SHOW_BIND(32) 387 SHOW_BIND(32)
372 SHOW_BIND(64) 388 SHOW_BIND(64)
373 389
390 if (be_wewy_wewy_quiet) return NULL;
391
374 if (be_quiet && !fstat(elf->fd, &s) && !(s.st_mode & S_ISUID || s.st_mode & S_ISGID)) { 392 if (be_quiet && !fstat(elf->fd, &s) && !(s.st_mode & S_ISUID || s.st_mode & S_ISGID)) {
375 return NULL; 393 return NULL;
376 } else { 394 } else {
377 *found_bind = 1; 395 *found_bind = 1;
378 return "LAZY"; 396 return (char *) "LAZY";
379 } 397 }
380} 398}
381static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename) 399static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename)
382{ 400{
383 unsigned long i; 401 unsigned long i;
384 void *symtab_void, *strtab_void; 402 void *symtab_void, *strtab_void;
385 403
386 if (!find_sym) return NULL; 404 if (!find_sym) return NULL;
387 405
406 /* debug sections */
388 symtab_void = elf_findsecbyname(elf, ".symtab"); 407 symtab_void = elf_findsecbyname(elf, ".symtab");
389 strtab_void = elf_findsecbyname(elf, ".strtab"); 408 strtab_void = elf_findsecbyname(elf, ".strtab");
409 /* fall back to runtime sections */
410 if (!symtab_void || !strtab_void) {
411 symtab_void = elf_findsecbyname(elf, ".dynsym");
412 strtab_void = elf_findsecbyname(elf, ".dynstr");
413 }
390 414
391 if (symtab_void && strtab_void) { 415 if (symtab_void && strtab_void) {
392 char *base, *basemem; 416 char *base, *basemem;
393 basemem = xstrdup(filename); 417 basemem = xstrdup(filename);
394 base = basename(basemem); 418 base = basename(basemem);
418 } } 442 } }
419 FIND_SYM(32) 443 FIND_SYM(32)
420 FIND_SYM(64) 444 FIND_SYM(64)
421 free(basemem); 445 free(basemem);
422 } 446 }
447
448 if (be_wewy_wewy_quiet) return NULL;
449
423 if (*find_sym != '*' && *found_sym) 450 if (*find_sym != '*' && *found_sym)
424 return find_sym; 451 return find_sym;
425 if (be_quiet) 452 if (be_quiet)
426 return NULL; 453 return NULL;
427 else 454 else
428 return " - "; 455 return (char *)" - ";
429} 456}
430/* scan an elf file and show all the fun stuff */ 457/* scan an elf file and show all the fun stuff */
431// #define prints(str) fputs(str, stdout)
432#define prints(str) write(fileno(stdout), str, strlen(str)) 458#define prints(str) write(fileno(stdout), str, strlen(str))
433static void scanelf_file(const char *filename) 459static void scanelf_file(const char *filename)
434{ 460{
435 unsigned long i; 461 unsigned long i;
436 char found_pax, found_stack, found_relro, found_textrel, 462 char found_pax, found_stack, found_relro, found_textrel,
466 return; 492 return;
467 } 493 }
468 494
469 if (be_verbose > 1) 495 if (be_verbose > 1)
470 printf("%s: scanning file {%s,%s}\n", filename, 496 printf("%s: scanning file {%s,%s}\n", filename,
471 get_elfeitype(elf, EI_CLASS, elf->elf_class), 497 get_elfeitype(EI_CLASS, elf->elf_class),
472 get_elfeitype(elf, EI_DATA, elf->data[EI_DATA])); 498 get_elfeitype(EI_DATA, elf->data[EI_DATA]));
473 else if (be_verbose) 499 else if (be_verbose)
474 printf("%s: scanning file\n", filename); 500 printf("%s: scanning file\n", filename);
475 501
476 /* init output buffer */ 502 /* init output buffer */
477 if (!out_buffer) { 503 if (!out_buffer) {
481 *out_buffer = '\0'; 507 *out_buffer = '\0';
482 508
483 /* show the header */ 509 /* show the header */
484 if (!be_quiet && show_banner) { 510 if (!be_quiet && show_banner) {
485 for (i = 0; out_format[i]; ++i) { 511 for (i = 0; out_format[i]; ++i) {
486 if (out_format[i] != '%') continue; 512 if (!IS_MODIFIER(out_format[i])) continue;
487 513
488 switch (out_format[++i]) { 514 switch (out_format[++i]) {
489 case '%': break; 515 case '%': break;
516 case '#': break;
517 case 'F':
518 case 'p':
490 case 'F': prints("FILE "); found_file = 1; break; 519 case 'f': prints("FILE "); found_file = 1; break;
491 case 'o': prints(" TYPE "); break; 520 case 'o': prints(" TYPE "); break;
492 case 'x': prints(" PAX "); break; 521 case 'x': prints(" PAX "); break;
493 case 'e': prints("STK/REL "); break; 522 case 'e': prints("STK/REL "); break;
494 case 't': prints("TEXTREL "); break; 523 case 't': prints("TEXTREL "); break;
495 case 'r': prints("RPATH "); break; 524 case 'r': prints("RPATH "); break;
506 } 535 }
507 536
508 /* dump all the good stuff */ 537 /* dump all the good stuff */
509 for (i = 0; out_format[i]; ++i) { 538 for (i = 0; out_format[i]; ++i) {
510 const char *out; 539 const char *out;
540 const char *tmp;
511 541
512 /* make sure we trim leading spaces in quiet mode */ 542 /* make sure we trim leading spaces in quiet mode */
513 if (be_quiet && *out_buffer == ' ' && !out_buffer[1]) 543 if (be_quiet && *out_buffer == ' ' && !out_buffer[1])
514 *out_buffer = '\0'; 544 *out_buffer = '\0';
515 545
516 if (out_format[i] != '%') { 546 if (!IS_MODIFIER(out_format[i])) {
517 xchrcat(&out_buffer, out_format[i], &out_len); 547 xchrcat(&out_buffer, out_format[i], &out_len);
518 continue; 548 continue;
519 } 549 }
520 550
521 out = NULL; 551 out = NULL;
552 be_wewy_wewy_quiet = (out_format[i] == '#');
522 switch (out_format[++i]) { 553 switch (out_format[++i]) {
554 case '%':
555 case '#':
523 case '%': xchrcat(&out_buffer, '%', &out_len); break; 556 xchrcat(&out_buffer, out_format[i], &out_len); break;
524 case 'F': found_file = 1; xstrcat(&out_buffer, filename, &out_len); break; 557 case 'F':
558 if (be_wewy_wewy_quiet) break;
559 found_file = 1;
560 xstrcat(&out_buffer, filename, &out_len);
561 break;
562 case 'p':
563 if (be_wewy_wewy_quiet) break;
564 found_file = 1;
565 tmp = filename;
566 if (search_path) {
567 ssize_t len_search = strlen(search_path);
568 ssize_t len_file = strlen(filename);
569 if (!strncmp(filename, search_path, len_search) && \
570 len_file > len_search)
571 tmp += len_search;
572 if (*tmp == '/' && search_path[len_search-1] == '/') tmp++;
573 }
574 xstrcat(&out_buffer, tmp, &out_len);
575 break;
576 case 'f':
577 if (be_wewy_wewy_quiet) break;
578 found_file = 1;
579 tmp = strrchr(filename, '/');
580 tmp = (tmp == NULL ? filename : tmp+1);
581 xstrcat(&out_buffer, tmp, &out_len);
582 break;
525 case 'o': out = get_elfetype(elf); break; 583 case 'o': out = get_elfetype(elf); break;
526 case 'x': out = scanelf_file_pax(elf, &found_pax); break; 584 case 'x': out = scanelf_file_pax(elf, &found_pax); break;
527 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro); break; 585 case 'e': out = scanelf_file_stack(elf, &found_stack, &found_relro); break;
528 case 't': out = scanelf_file_textrel(elf, &found_textrel); break; 586 case 't': out = scanelf_file_textrel(elf, &found_textrel); break;
529 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break; 587 case 'r': scanelf_file_rpath(elf, &found_rpath, &out_buffer, &out_len); break;
611 return 1; 669 return 1;
612 670
613 while ((fgets(path, _POSIX_PATH_MAX, fp)) != NULL) { 671 while ((fgets(path, _POSIX_PATH_MAX, fp)) != NULL) {
614 if ((p = strchr(path, '\n')) != NULL) 672 if ((p = strchr(path, '\n')) != NULL)
615 *p = 0; 673 *p = 0;
674 search_path = path;
616 scanelf_dir(path); 675 scanelf_dir(path);
617 } 676 }
618 if (fp != stdin) 677 if (fp != stdin)
619 fclose(fp); 678 fclose(fp);
620 return 0; 679 return 0;
720 {"help", no_argument, NULL, 'h'}, 779 {"help", no_argument, NULL, 'h'},
721 {"version", no_argument, NULL, 'V'}, 780 {"version", no_argument, NULL, 'V'},
722 {NULL, no_argument, NULL, 0x0} 781 {NULL, no_argument, NULL, 0x0}
723}; 782};
724 783
725static char *opts_help[] = { 784static const char *opts_help[] = {
726 "Scan all directories in PATH environment", 785 "Scan all directories in PATH environment",
727 "Scan all directories in /etc/ld.so.conf", 786 "Scan all directories in /etc/ld.so.conf",
728 "Scan directories recursively", 787 "Scan directories recursively",
729 "Don't recursively cross mount points", 788 "Don't recursively cross mount points",
730 "Don't scan symlinks\n", 789 "Don't scan symlinks\n",
765 824
766 if (status != EXIT_SUCCESS) 825 if (status != EXIT_SUCCESS)
767 exit(status); 826 exit(status);
768 827
769 puts("\nThe format modifiers for the -F option are:"); 828 puts("\nThe format modifiers for the -F option are:");
770 puts(" %F Filename \t%x PaX Flags \t%e STACK/RELRO"); 829 puts(" F Filename \tx PaX Flags \te STACK/RELRO");
771 puts(" %t TEXTREL \t%r RPATH \t%n NEEDED"); 830 puts(" t TEXTREL \tr RPATH \tn NEEDED");
772 puts(" %i INTERP \t%b BIND \t%s symbol"); 831 puts(" i INTERP \tb BIND \ts symbol");
832 puts(" p filename (with search path removed)");
833 puts(" f base filename");
834 puts("Prefix each modifier with '%' (verbose) or '#' (silent)");
773 835
774 exit(status); 836 exit(status);
775} 837}
776 838
777/* parse command line arguments and preform needed actions */ 839/* parse command line arguments and preform needed actions */
790 __FILE__, __DATE__, rcsid, argv0); 852 __FILE__, __DATE__, rcsid, argv0);
791 exit(EXIT_SUCCESS); 853 exit(EXIT_SUCCESS);
792 break; 854 break;
793 case 'h': usage(EXIT_SUCCESS); break; 855 case 'h': usage(EXIT_SUCCESS); break;
794 case 'f': 856 case 'f':
795 if (from_file == NULL) 857 if (from_file) err("Don't specify -f twice");
796 from_file = xstrdup(optarg); 858 from_file = xstrdup(optarg);
797 break; 859 break;
798 case 'o': { 860 case 'o': {
799 FILE *fp = NULL; 861 FILE *fp = NULL;
800 fp = freopen(optarg, "w", stdout); 862 if ((fp = freopen(optarg, "w", stdout)) == NULL)
801 if (fp == NULL)
802 err("Could not open output stream '%s': %s", optarg, strerror(errno)); 863 err("Could not open output stream '%s': %s", optarg, strerror(errno));
803 stdout = fp; 864 SET_STDOUT(fp);
804 break; 865 break;
805 } 866 }
806 867
807 case 's': { 868 case 's': {
808 size_t len; 869 size_t len;
870 if (find_sym) err("Don't specify -s twice");
809 find_sym = xstrdup(optarg); 871 find_sym = xstrdup(optarg);
810 len = strlen(find_sym) + 1; 872 len = strlen(find_sym) + 1;
811 versioned_symname = (char*)xmalloc(sizeof(char) * (len+1)); 873 versioned_symname = (char*)xmalloc(sizeof(char) * (len+1));
812 sprintf(versioned_symname, "%s@", find_sym); 874 sprintf(versioned_symname, "%s@", find_sym);
813 break; 875 break;
814 } 876 }
815 877
816 case 'F': { 878 case 'F': {
817 if (!out_format) 879 if (out_format) err("Don't specify -F twice");
818 out_format = xstrdup(optarg); 880 out_format = xstrdup(optarg);
819 break; 881 break;
820 } 882 }
821 883
822 case 'y': scan_symlink = 0; break; 884 case 'y': scan_symlink = 0; break;
823 case 'B': show_banner = 0; break; 885 case 'B': show_banner = 0; break;
849 /* let the format option override all other options */ 911 /* let the format option override all other options */
850 if (out_format) { 912 if (out_format) {
851 show_pax = show_stack = show_textrel = show_rpath = \ 913 show_pax = show_stack = show_textrel = show_rpath = \
852 show_needed = show_interp = show_bind = 0; 914 show_needed = show_interp = show_bind = 0;
853 for (i = 0; out_format[i]; ++i) { 915 for (i = 0; out_format[i]; ++i) {
854 if (out_format[i] != '%') continue; 916 if (!IS_MODIFIER(out_format[i])) continue;
855 917
856 switch (out_format[++i]) { 918 switch (out_format[++i]) {
857 case '%': break; 919 case '%': break;
920 case '#': break;
858 case 'F': break; 921 case 'F': break;
922 case 'p': break;
923 case 'f': break;
859 case 's': break; 924 case 's': break;
860 case 'o': break; 925 case 'o': break;
861 case 'x': show_pax = 1; break; 926 case 'x': show_pax = 1; break;
862 case 'e': show_stack = 1; break; 927 case 'e': show_stack = 1; break;
863 case 't': show_textrel = 1; break; 928 case 't': show_textrel = 1; break;
898 free(from_file); 963 free(from_file);
899 from_file = *argv; 964 from_file = *argv;
900 } 965 }
901 if (optind == argc && !scan_ldpath && !scan_envpath && !from_file) 966 if (optind == argc && !scan_ldpath && !scan_envpath && !from_file)
902 err("Nothing to scan !?"); 967 err("Nothing to scan !?");
903 while (optind < argc) 968 while (optind < argc) {
904 scanelf_dir(argv[optind++]); 969 search_path = argv[optind++];
970 scanelf_dir(search_path);
971 }
905 972
906 /* clean up */ 973 /* clean up */
907 if (find_sym) { 974 if (find_sym) {
908 free(find_sym); 975 free(find_sym);
909 free(versioned_symname); 976 free(versioned_symname);
930 return ret; 997 return ret;
931} 998}
932 999
933static void xstrcat(char **dst, const char *src, size_t *curr_len) 1000static void xstrcat(char **dst, const char *src, size_t *curr_len)
934{ 1001{
935 long new_len; 1002 size_t new_len;
936 1003
937 new_len = strlen(*dst) + strlen(src); 1004 new_len = strlen(*dst) + strlen(src);
938 if (*curr_len <= new_len) { 1005 if (*curr_len <= new_len) {
939 *curr_len = new_len + (*curr_len / 2); 1006 *curr_len = new_len + (*curr_len / 2);
940 *dst = realloc(*dst, *curr_len); 1007 *dst = realloc(*dst, *curr_len);
959 if (argc < 2) 1026 if (argc < 2)
960 usage(EXIT_FAILURE); 1027 usage(EXIT_FAILURE);
961 parseargs(argc, argv); 1028 parseargs(argc, argv);
962 fclose(stdout); 1029 fclose(stdout);
963#ifdef __BOUNDS_CHECKING_ON 1030#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()"); 1031 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 1032#endif
966 return EXIT_SUCCESS; 1033 return EXIT_SUCCESS;
967} 1034}

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

  ViewVC Help
Powered by ViewVC 1.1.20