/[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.69 Revision 1.70
1/* 1/*
2 * Copyright 2003-2005 Gentoo Foundation 2 * Copyright 2003-2005 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.69 2005/06/03 23:18:01 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.70 2005/06/03 23:41:59 vapier Exp $
5 * 5 *
6 ******************************************************************** 6 ********************************************************************
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * 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
9 * published by the Free Software Foundation; either version 2 of the 9 * published by the Free Software Foundation; either version 2 of the
33#include <dirent.h> 33#include <dirent.h>
34#include <getopt.h> 34#include <getopt.h>
35#include <assert.h> 35#include <assert.h>
36#include "paxelf.h" 36#include "paxelf.h"
37 37
38static const char *rcsid = "$Id: scanelf.c,v 1.69 2005/06/03 23:18:01 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.70 2005/06/03 23:41:59 vapier Exp $";
39#define argv0 "scanelf" 39#define argv0 "scanelf"
40
41#define IS_MODIFIER(c) (c == '%' || c == '#')
40 42
41 43
42 44
43/* prototypes */ 45/* prototypes */
44static void scanelf_file(const char *filename); 46static void scanelf_file(const char *filename);
67static char show_interp = 0; 69static char show_interp = 0;
68static char show_bind = 0; 70static char show_bind = 0;
69static char show_banner = 1; 71static char show_banner = 1;
70static char be_quiet = 0; 72static char be_quiet = 0;
71static char be_verbose = 0; 73static char be_verbose = 0;
74static char be_wewy_wewy_quiet = 0;
72static char *find_sym = NULL, *versioned_symname = NULL; 75static char *find_sym = NULL, *versioned_symname = NULL;
73static char *out_format = NULL; 76static char *out_format = NULL;
74static char *search_path = 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{
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 (char *)" - "; 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)
267 } } 271 } }
268 SHOW_RPATH(32) 272 SHOW_RPATH(32)
269 SHOW_RPATH(64) 273 SHOW_RPATH(64)
270 } 274 }
271 275
276 if (be_wewy_wewy_quiet) return;
277
272 if (rpath && runpath) { 278 if (rpath && runpath) {
273 if (!strcmp(rpath, runpath)) { 279 if (!strcmp(rpath, runpath)) {
274 xstrcat(ret, runpath, ret_len); 280 xstrcat(ret, runpath, ret_len);
275 } else { 281 } else {
276 fprintf(stderr, "RPATH [%s] != RUNPATH [%s]\n", rpath, runpath); 282 fprintf(stderr, "RPATH [%s] != RUNPATH [%s]\n", rpath, runpath);
315 ++dyn; \ 321 ++dyn; \
316 continue; \ 322 continue; \
317 } \ 323 } \
318 needed = (char*)(elf->data + offset); \ 324 needed = (char*)(elf->data + offset); \
319 if (*found_needed) xchrcat(ret, ',', ret_len); \ 325 if (*found_needed) xchrcat(ret, ',', ret_len); \
320 xstrcat(ret, needed, ret_len); \ 326 if (!be_wewy_wewy_quiet) xstrcat(ret, needed, ret_len); \
321 *found_needed = 1; \ 327 *found_needed = 1; \
322 } \ 328 } \
323 ++dyn; \ 329 ++dyn; \
324 } \ 330 } \
325 } } 331 } }
338 if (strtbl_void) { 344 if (strtbl_void) {
339#define SHOW_INTERP(B) \ 345#define SHOW_INTERP(B) \
340 if (elf->elf_class == ELFCLASS ## B) { \ 346 if (elf->elf_class == ELFCLASS ## B) { \
341 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 347 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
342 *found_interp = 1; \ 348 *found_interp = 1; \
343 return elf->data + EGET(strtbl->sh_offset); \ 349 return (be_wewy_wewy_quiet ? NULL : elf->data + EGET(strtbl->sh_offset)); \
344 } 350 }
345 SHOW_INTERP(32) 351 SHOW_INTERP(32)
346 SHOW_INTERP(64) 352 SHOW_INTERP(64)
347 } 353 }
348 return NULL; 354 return NULL;
370 if (EGET(dyn->d_tag) == DT_BIND_NOW || \ 376 if (EGET(dyn->d_tag) == DT_BIND_NOW || \
371 (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)) \
372 { \ 378 { \
373 if (be_quiet) return NULL; \ 379 if (be_quiet) return NULL; \
374 *found_bind = 1; \ 380 *found_bind = 1; \
375 return (char *) "NOW"; \ 381 return (char *)(be_wewy_wewy_quiet ? NULL : "NOW"); \
376 } \ 382 } \
377 ++dyn; \ 383 ++dyn; \
378 } \ 384 } \
379 } \ 385 } \
380 } 386 }
381 SHOW_BIND(32) 387 SHOW_BIND(32)
382 SHOW_BIND(64) 388 SHOW_BIND(64)
389
390 if (be_wewy_wewy_quiet) return NULL;
383 391
384 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)) {
385 return NULL; 393 return NULL;
386 } else { 394 } else {
387 *found_bind = 1; 395 *found_bind = 1;
434 } } 442 } }
435 FIND_SYM(32) 443 FIND_SYM(32)
436 FIND_SYM(64) 444 FIND_SYM(64)
437 free(basemem); 445 free(basemem);
438 } 446 }
447
448 if (be_wewy_wewy_quiet) return NULL;
449
439 if (*find_sym != '*' && *found_sym) 450 if (*find_sym != '*' && *found_sym)
440 return find_sym; 451 return find_sym;
441 if (be_quiet) 452 if (be_quiet)
442 return NULL; 453 return NULL;
443 else 454 else
444 return (char *)" - "; 455 return (char *)" - ";
445} 456}
446/* scan an elf file and show all the fun stuff */ 457/* scan an elf file and show all the fun stuff */
447// #define prints(str) fputs(str, stdout)
448#define prints(str) write(fileno(stdout), str, strlen(str)) 458#define prints(str) write(fileno(stdout), str, strlen(str))
449static void scanelf_file(const char *filename) 459static void scanelf_file(const char *filename)
450{ 460{
451 unsigned long i; 461 unsigned long i;
452 char found_pax, found_stack, found_relro, found_textrel, 462 char found_pax, found_stack, found_relro, found_textrel,
497 *out_buffer = '\0'; 507 *out_buffer = '\0';
498 508
499 /* show the header */ 509 /* show the header */
500 if (!be_quiet && show_banner) { 510 if (!be_quiet && show_banner) {
501 for (i = 0; out_format[i]; ++i) { 511 for (i = 0; out_format[i]; ++i) {
502 if (out_format[i] != '%') continue; 512 if (!IS_MODIFIER(out_format[i])) continue;
503 513
504 switch (out_format[++i]) { 514 switch (out_format[++i]) {
505 case '%': break; 515 case '%': break;
516 case '#': break;
506 case 'F': 517 case 'F':
507 case 'p': 518 case 'p':
508 case 'f': prints("FILE "); found_file = 1; break; 519 case 'f': prints("FILE "); found_file = 1; break;
509 case 'o': prints(" TYPE "); break; 520 case 'o': prints(" TYPE "); break;
510 case 'x': prints(" PAX "); break; 521 case 'x': prints(" PAX "); break;
530 541
531 /* make sure we trim leading spaces in quiet mode */ 542 /* make sure we trim leading spaces in quiet mode */
532 if (be_quiet && *out_buffer == ' ' && !out_buffer[1]) 543 if (be_quiet && *out_buffer == ' ' && !out_buffer[1])
533 *out_buffer = '\0'; 544 *out_buffer = '\0';
534 545
535 if (out_format[i] != '%') { 546 if (!IS_MODIFIER(out_format[i])) {
536 xchrcat(&out_buffer, out_format[i], &out_len); 547 xchrcat(&out_buffer, out_format[i], &out_len);
537 continue; 548 continue;
538 } 549 }
539 550
540 out = NULL; 551 out = NULL;
552 be_wewy_wewy_quiet = (out_format[i] == '#');
541 switch (out_format[++i]) { 553 switch (out_format[++i]) {
554 case '%':
555 case '#':
542 case '%': xchrcat(&out_buffer, '%', &out_len); break; 556 xchrcat(&out_buffer, out_format[i], &out_len); break;
543 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;
544 case 'p': 562 case 'p':
563 if (be_wewy_wewy_quiet) break;
545 found_file = 1; 564 found_file = 1;
546 tmp = filename; 565 tmp = filename;
547 if (search_path) { 566 if (search_path) {
548 ssize_t len_search = strlen(search_path); 567 ssize_t len_search = strlen(search_path);
549 ssize_t len_file = strlen(filename); 568 ssize_t len_file = strlen(filename);
553 if (*tmp == '/' && search_path[len_search-1] == '/') tmp++; 572 if (*tmp == '/' && search_path[len_search-1] == '/') tmp++;
554 } 573 }
555 xstrcat(&out_buffer, tmp, &out_len); 574 xstrcat(&out_buffer, tmp, &out_len);
556 break; 575 break;
557 case 'f': 576 case 'f':
577 if (be_wewy_wewy_quiet) break;
558 found_file = 1; 578 found_file = 1;
559 tmp = strrchr(filename, '/'); 579 tmp = strrchr(filename, '/');
560 tmp = (tmp == NULL ? filename : tmp+1); 580 tmp = (tmp == NULL ? filename : tmp+1);
561 xstrcat(&out_buffer, tmp, &out_len); 581 xstrcat(&out_buffer, tmp, &out_len);
562 break; 582 break;
804 824
805 if (status != EXIT_SUCCESS) 825 if (status != EXIT_SUCCESS)
806 exit(status); 826 exit(status);
807 827
808 puts("\nThe format modifiers for the -F option are:"); 828 puts("\nThe format modifiers for the -F option are:");
809 puts(" %F Filename \t%x PaX Flags \t%e STACK/RELRO"); 829 puts(" F Filename \tx PaX Flags \te STACK/RELRO");
810 puts(" %t TEXTREL \t%r RPATH \t%n NEEDED"); 830 puts(" t TEXTREL \tr RPATH \tn NEEDED");
811 puts(" %i INTERP \t%b BIND \t%s symbol"); 831 puts(" i INTERP \tb BIND \ts symbol");
812 puts(" %p filename (with search path removed)"); 832 puts(" p filename (with search path removed)");
813 puts(" %f base filename"); 833 puts(" f base filename");
834 puts("Prefix each modifier with '%' (verbose) or '#' (silent)");
814 835
815 exit(status); 836 exit(status);
816} 837}
817 838
818/* parse command line arguments and preform needed actions */ 839/* parse command line arguments and preform needed actions */
890 /* let the format option override all other options */ 911 /* let the format option override all other options */
891 if (out_format) { 912 if (out_format) {
892 show_pax = show_stack = show_textrel = show_rpath = \ 913 show_pax = show_stack = show_textrel = show_rpath = \
893 show_needed = show_interp = show_bind = 0; 914 show_needed = show_interp = show_bind = 0;
894 for (i = 0; out_format[i]; ++i) { 915 for (i = 0; out_format[i]; ++i) {
895 if (out_format[i] != '%') continue; 916 if (!IS_MODIFIER(out_format[i])) continue;
896 917
897 switch (out_format[++i]) { 918 switch (out_format[++i]) {
898 case '%': break; 919 case '%': break;
920 case '#': break;
899 case 'F': break; 921 case 'F': break;
900 case 'p': break; 922 case 'p': break;
901 case 'f': break; 923 case 'f': break;
902 case 's': break; 924 case 's': break;
903 case 'o': break; 925 case 'o': break;

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

  ViewVC Help
Powered by ViewVC 1.1.20