| 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/scanelf.c,v 1.60 2005/05/27 02:58:39 vapier Exp $ |
5 | * $Header: /var/cvsroot/gentoo-projects/pax-utils/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 |
| … | |
… | |
| 32 | #include <unistd.h> |
32 | #include <unistd.h> |
| 33 | #include <sys/stat.h> |
33 | #include <sys/stat.h> |
| 34 | #include <dirent.h> |
34 | #include <dirent.h> |
| 35 | #include <getopt.h> |
35 | #include <getopt.h> |
| 36 | #include <assert.h> |
36 | #include <assert.h> |
| 37 | |
|
|
| 38 | #include "paxelf.h" |
37 | #include "paxelf.h" |
| 39 | |
38 | |
| 40 | static const char *rcsid = "$Id: scanelf.c,v 1.60 2005/05/27 02:58:39 vapier Exp $"; |
39 | static const char *rcsid = "$Id: scanelf.c,v 1.61 2005/05/28 22:09:36 solar Exp $"; |
| 41 | #define argv0 "scanelf" |
40 | #define argv0 "scanelf" |
| 42 | |
41 | |
| 43 | |
42 | |
| 44 | |
43 | |
| 45 | /* prototypes */ |
44 | /* prototypes */ |
| … | |
… | |
| 73 | static char be_verbose = 0; |
72 | static char be_verbose = 0; |
| 74 | static char *find_sym = NULL, *versioned_symname = NULL; |
73 | static char *find_sym = NULL, *versioned_symname = NULL; |
| 75 | static char *out_format = NULL; |
74 | static char *out_format = NULL; |
| 76 | |
75 | |
| 77 | |
76 | |
| 78 | |
|
|
| 79 | /* sub-funcs for scanelf_file() */ |
77 | /* sub-funcs for scanelf_file() */ |
| 80 | static char *scanelf_file_pax(elfobj *elf, char *found_pax) |
78 | static char *scanelf_file_pax(elfobj *elf, char *found_pax) |
| 81 | { |
79 | { |
| 82 | static char *paxflags; |
80 | static char *paxflags; |
|
|
81 | static char ret[7]; |
|
|
82 | unsigned long i, shown; |
|
|
83 | |
| 83 | |
84 | |
| 84 | if (!show_pax) return NULL; |
85 | if (!show_pax) return NULL; |
| 85 | |
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) { |
| 86 | paxflags = pax_short_hf_flags(PAX_FLAGS(elf)); |
112 | paxflags = pax_short_hf_flags(EI_PAX_FLAGS(elf)); |
| 87 | if (!be_quiet || (be_quiet && strncmp(paxflags, "PeMRxS", 6))) { |
113 | if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) { |
| 88 | *found_pax = 1; |
114 | *found_pax = 1; |
| 89 | return paxflags; |
115 | return paxflags; |
| 90 | } |
116 | } |
|
|
117 | strncpy(ret, paxflags, sizeof(ret)); |
|
|
118 | // ++shown; |
|
|
119 | } |
| 91 | |
120 | |
|
|
121 | if (be_quiet && !shown) |
| 92 | return NULL; |
122 | return NULL; |
|
|
123 | return ret; |
|
|
124 | |
| 93 | } |
125 | } |
| 94 | static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro) |
126 | static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro) |
| 95 | { |
127 | { |
| 96 | static char ret[8] = "--- ---"; |
128 | static char ret[8] = "--- ---"; |
| 97 | char *found; |
129 | char *found; |
| … | |
… | |
| 780 | sprintf(versioned_symname, "%s@", find_sym); |
812 | sprintf(versioned_symname, "%s@", find_sym); |
| 781 | break; |
813 | break; |
| 782 | } |
814 | } |
| 783 | |
815 | |
| 784 | case 'F': { |
816 | case 'F': { |
|
|
817 | if (!out_format) |
| 785 | out_format = xstrdup(optarg); |
818 | out_format = xstrdup(optarg); |
| 786 | break; |
819 | break; |
| 787 | } |
820 | } |
| 788 | |
821 | |
| 789 | case 'y': scan_symlink = 0; break; |
822 | case 'y': scan_symlink = 0; break; |
| 790 | case 'B': show_banner = 0; break; |
823 | case 'B': show_banner = 0; break; |
| … | |
… | |
| 925 | { |
958 | { |
| 926 | if (argc < 2) |
959 | if (argc < 2) |
| 927 | usage(EXIT_FAILURE); |
960 | usage(EXIT_FAILURE); |
| 928 | parseargs(argc, argv); |
961 | parseargs(argc, argv); |
| 929 | 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 |
| 930 | return EXIT_SUCCESS; |
966 | return EXIT_SUCCESS; |
| 931 | } |
967 | } |