/[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.57 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.57 2005/05/21 17:58:30 solar 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.57 2005/05/21 17:58:30 solar 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);
54 55
55/* variables to control behavior */ 56/* variables to control behavior */
71static char be_verbose = 0; 72static char be_verbose = 0;
72static char *find_sym = NULL, *versioned_symname = NULL; 73static char *find_sym = NULL, *versioned_symname = NULL;
73static char *out_format = NULL; 74static char *out_format = NULL;
74 75
75 76
76
77/* sub-funcs for scanelf_file() */ 77/* sub-funcs for scanelf_file() */
78static char *scanelf_file_pax(elfobj *elf, char *found_pax) 78static char *scanelf_file_pax(elfobj *elf, char *found_pax)
79{ 79{
80 static char *paxflags; 80 static char *paxflags;
81 static char ret[7];
82 unsigned long i, shown;
83
81 84
82 if (!show_pax) return NULL; 85 if (!show_pax) return NULL;
83 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) {
84 paxflags = pax_short_hf_flags(PAX_FLAGS(elf)); 112 paxflags = pax_short_hf_flags(EI_PAX_FLAGS(elf));
85 if (!be_quiet || (be_quiet && strncmp(paxflags, "PeMRxS", 6))) { 113 if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) {
86 *found_pax = 1; 114 *found_pax = 1;
87 return paxflags; 115 return paxflags;
88 } 116 }
117 strncpy(ret, paxflags, sizeof(ret));
118 // ++shown;
119 }
89 120
121 if (be_quiet && !shown)
90 return NULL; 122 return NULL;
123 return ret;
124
91} 125}
92static 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)
93{ 127{
94 static char ret[8] = "--- ---"; 128 static char ret[8] = "--- ---";
95 char *found; 129 char *found;
142 Elf ## B ## _Dyn *dyn; \ 176 Elf ## B ## _Dyn *dyn; \
143 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 177 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
144 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 178 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
145 Elf ## B ## _Off offset; \ 179 Elf ## B ## _Off offset; \
146 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 180 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
147 if (phdr[i].p_type != PT_DYNAMIC) continue; \ 181 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
148 offset = EGET(phdr[i].p_offset); \ 182 offset = EGET(phdr[i].p_offset); \
149 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 183 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
150 dyn = DYN ## B (elf->data + offset); \ 184 dyn = DYN ## B (elf->data + offset); \
151 while (EGET(dyn->d_tag) != DT_NULL) { \ 185 while (EGET(dyn->d_tag) != DT_NULL) { \
152 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)*/ \
184 Elf ## B ## _Dyn *dyn; \ 218 Elf ## B ## _Dyn *dyn; \
185 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 219 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
186 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 220 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
187 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 221 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
188 Elf ## B ## _Off offset; \ 222 Elf ## B ## _Off offset; \
189 Elf ## B ## _Sxword word; \ 223 Elf ## B ## _Xword word; \
190 /* Scan all the program headers */ \ 224 /* Scan all the program headers */ \
191 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 225 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
192 /* Just scan dynamic headers */ \ 226 /* Just scan dynamic headers */ \
193 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 227 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
194 offset = EGET(phdr[i].p_offset); \ 228 offset = EGET(phdr[i].p_offset); \
353 387
354 symtab_void = elf_findsecbyname(elf, ".symtab"); 388 symtab_void = elf_findsecbyname(elf, ".symtab");
355 strtab_void = elf_findsecbyname(elf, ".strtab"); 389 strtab_void = elf_findsecbyname(elf, ".strtab");
356 390
357 if (symtab_void && strtab_void) { 391 if (symtab_void && strtab_void) {
392 char *base, *basemem;
393 basemem = xstrdup(filename);
394 base = basename(basemem);
358#define FIND_SYM(B) \ 395#define FIND_SYM(B) \
359 if (elf->elf_class == ELFCLASS ## B) { \ 396 if (elf->elf_class == ELFCLASS ## B) { \
360 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 397 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
361 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 398 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
362 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)); \
366 if (sym->st_name) { \ 403 if (sym->st_name) { \
367 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)); \
368 if (*find_sym == '*') { \ 405 if (*find_sym == '*') { \
369 printf("%s(%s) %5lX %15s %s\n", \ 406 printf("%s(%s) %5lX %15s %s\n", \
370 ((*found_sym == 0) ? "\n\t" : "\t"), \ 407 ((*found_sym == 0) ? "\n\t" : "\t"), \
371 (char *)basename(filename), \ 408 base, \
372 (long)sym->st_size, \ 409 (long)sym->st_size, \
373 (char *)get_elfstttype(sym->st_info), \ 410 (char *)get_elfstttype(sym->st_info), \
374 symname); \ 411 symname); \
375 *found_sym = 1; \ 412 *found_sym = 1; \
376 } else if ((strcmp(find_sym, symname) == 0) || \ 413 } else if ((strcmp(find_sym, symname) == 0) || \
379 } \ 416 } \
380 ++sym; \ 417 ++sym; \
381 } } 418 } }
382 FIND_SYM(32) 419 FIND_SYM(32)
383 FIND_SYM(64) 420 FIND_SYM(64)
421 free(basemem);
384 } 422 }
385 if (*find_sym != '*' && *found_sym) 423 if (*find_sym != '*' && *found_sym)
386 return find_sym; 424 return find_sym;
387 if (be_quiet) 425 if (be_quiet)
388 return NULL; 426 return NULL;
774 sprintf(versioned_symname, "%s@", find_sym); 812 sprintf(versioned_symname, "%s@", find_sym);
775 break; 813 break;
776 } 814 }
777 815
778 case 'F': { 816 case 'F': {
817 if (!out_format)
779 out_format = xstrdup(optarg); 818 out_format = xstrdup(optarg);
780 break; 819 break;
781 } 820 }
782 821
783 case 'y': scan_symlink = 0; break; 822 case 'y': scan_symlink = 0; break;
784 case 'B': show_banner = 0; break; 823 case 'B': show_banner = 0; break;
807 } 846 }
808 } 847 }
809 848
810 /* let the format option override all other options */ 849 /* let the format option override all other options */
811 if (out_format) { 850 if (out_format) {
812 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;
813 for (i = 0; out_format[i]; ++i) { 853 for (i = 0; out_format[i]; ++i) {
814 if (out_format[i] != '%') continue; 854 if (out_format[i] != '%') continue;
815 855
816 switch (out_format[++i]) { 856 switch (out_format[++i]) {
817 case '%': break; 857 case '%': break;
874} 914}
875 915
876 916
877 917
878/* utility funcs */ 918/* utility funcs */
879static char *xstrdup(char *s) 919static char *xstrdup(const char *s)
880{ 920{
881 char *ret = strdup(s); 921 char *ret = strdup(s);
882 if (!ret) err("Could not strdup(): %s", strerror(errno)); 922 if (!ret) err("Could not strdup(): %s", strerror(errno));
883 return ret; 923 return ret;
884} 924}
918{ 958{
919 if (argc < 2) 959 if (argc < 2)
920 usage(EXIT_FAILURE); 960 usage(EXIT_FAILURE);
921 parseargs(argc, argv); 961 parseargs(argc, argv);
922 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
923 return EXIT_SUCCESS; 966 return EXIT_SUCCESS;
924} 967}

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

  ViewVC Help
Powered by ViewVC 1.1.20