/[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.43 Revision 1.44
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.43 2005/05/06 02:55:27 vapier Exp $ 5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.44 2005/05/10 22:54:25 vapier 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
33#include <getopt.h> 33#include <getopt.h>
34#include <assert.h> 34#include <assert.h>
35 35
36#include "paxelf.h" 36#include "paxelf.h"
37 37
38static const char *rcsid = "$Id: scanelf.c,v 1.43 2005/05/06 02:55:27 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.44 2005/05/10 22:54:25 vapier Exp $";
39#define argv0 "scanelf" 39#define argv0 "scanelf"
40 40
41 41
42 42
43/* prototypes */ 43/* prototypes */
90} 90}
91static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro) 91static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro)
92{ 92{
93 static char ret[8]; 93 static char ret[8];
94 char *found; 94 char *found;
95 int i, off, shown; 95 unsigned long i, off, shown;
96 96
97 if (!show_stack) return NULL; 97 if (!show_stack) return NULL;
98 98
99 shown = 0; 99 shown = 0;
100 strcpy(ret, "--- ---"); 100 strcpy(ret, "--- ---");
101
102 if (elf->phdr) {
101#define SHOW_STACK(B) \ 103#define SHOW_STACK(B) \
102 if (elf->elf_class == ELFCLASS ## B) { \ 104 if (elf->elf_class == ELFCLASS ## B) { \
103 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 105 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
104 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 106 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
105 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 107 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
118 ++shown; \ 120 ++shown; \
119 } \ 121 } \
120 } 122 }
121 SHOW_STACK(32) 123 SHOW_STACK(32)
122 SHOW_STACK(64) 124 SHOW_STACK(64)
125 }
126
123 if (be_quiet && !shown) 127 if (be_quiet && !shown)
124 return NULL; 128 return NULL;
125 else 129 else
126 return ret; 130 return ret;
127} 131}
128static char *scanelf_file_textrel(elfobj *elf, char *found_textrel) 132static char *scanelf_file_textrel(elfobj *elf, char *found_textrel)
129{ 133{
130 static char *ret = "TEXTREL"; 134 static char *ret = "TEXTREL";
131 int i; 135 unsigned long i;
132 136
133 if (!show_textrel) return NULL; 137 if (!show_textrel) return NULL;
134 138
139 if (elf->phdr) {
135#define SHOW_TEXTREL(B) \ 140#define SHOW_TEXTREL(B) \
136 if (elf->elf_class == ELFCLASS ## B) { \ 141 if (elf->elf_class == ELFCLASS ## B) { \
137 Elf ## B ## _Dyn *dyn; \ 142 Elf ## B ## _Dyn *dyn; \
138 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 143 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
139 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 144 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
145 Elf ## B ## _Off offset; \
140 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 146 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
141 if (phdr[i].p_type != PT_DYNAMIC) continue; \ 147 if (phdr[i].p_type != PT_DYNAMIC) continue; \
148 offset = EGET(phdr[i].p_offset); \
149 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
142 dyn = DYN ## B (elf->data + EGET(phdr[i].p_offset)); \ 150 dyn = DYN ## B (elf->data + offset); \
143 while (EGET(dyn->d_tag) != DT_NULL) { \ 151 while (EGET(dyn->d_tag) != DT_NULL) { \
144 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ 152 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \
145 *found_textrel = 1; \ 153 *found_textrel = 1; \
146 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \ 154 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \
147 return ret; \ 155 return ret; \
149 ++dyn; \ 157 ++dyn; \
150 } \ 158 } \
151 } } 159 } }
152 SHOW_TEXTREL(32) 160 SHOW_TEXTREL(32)
153 SHOW_TEXTREL(64) 161 SHOW_TEXTREL(64)
162 }
163
154 if (be_quiet) 164 if (be_quiet)
155 return NULL; 165 return NULL;
156 else 166 else
157 return " - "; 167 return " - ";
158} 168}
159static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) 169static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len)
160{ 170{
161 /* TODO: if be_quiet, only output RPATH's which aren't in /etc/ld.so.conf */ 171 /* TODO: if be_quiet, only output RPATH's which aren't in /etc/ld.so.conf */
162 int i; 172 unsigned long i;
163 char *rpath, *runpath; 173 char *rpath, *runpath;
164 void *strtbl_void; 174 void *strtbl_void;
165 175
166 if (!show_rpath) return; 176 if (!show_rpath) return;
167 177
168 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 178 strtbl_void = elf_findsecbyname(elf, ".dynstr");
169 rpath = runpath = NULL; 179 rpath = runpath = NULL;
170 180
171 if (strtbl_void) { 181 if (elf->phdr && strtbl_void) {
172#define SHOW_RPATH(B) \ 182#define SHOW_RPATH(B) \
173 if (elf->elf_class == ELFCLASS ## B) { \ 183 if (elf->elf_class == ELFCLASS ## B) { \
174 Elf ## B ## _Dyn *dyn; \ 184 Elf ## B ## _Dyn *dyn; \
175 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 185 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
176 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 186 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
177 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 187 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
188 Elf ## B ## _Off offset; \
178 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 189 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
179 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 190 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
191 offset = EGET(phdr[i].p_offset); \
192 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
180 dyn = DYN ## B (elf->data + EGET(phdr[i].p_offset)); \ 193 dyn = DYN ## B (elf->data + offset); \
181 while (EGET(dyn->d_tag) != DT_NULL) { \ 194 while (EGET(dyn->d_tag) != DT_NULL) { \
182 if (EGET(dyn->d_tag) == DT_RPATH) { \ 195 if (EGET(dyn->d_tag) == DT_RPATH) { \
183 if (rpath) warn("ELF has multiple DT_RPATH's !?"); \ 196 if (rpath) warn("ELF has multiple DT_RPATH's !?"); \
184 rpath = elf->data + EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 197 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
198 if (offset >= elf->len) continue; \
199 rpath = (char*)(elf->data + offset); \
185 *found_rpath = 1; \ 200 *found_rpath = 1; \
186 } else if (EGET(dyn->d_tag) == DT_RUNPATH) { \ 201 } else if (EGET(dyn->d_tag) == DT_RUNPATH) { \
187 if (runpath) warn("ELF has multiple DT_RUNPATH's !?"); \ 202 if (runpath) warn("ELF has multiple DT_RUNPATH's !?"); \
188 runpath = elf->data + EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 203 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
204 if (offset >= elf->len) continue; \
205 runpath = (char*)(elf->data + offset); \
189 *found_rpath = 1; \ 206 *found_rpath = 1; \
190 } \ 207 } \
191 ++dyn; \ 208 ++dyn; \
192 } \ 209 } \
193 } } 210 } }
211 else if (!be_quiet) 228 else if (!be_quiet)
212 xstrcat(ret, " - ", ret_len); 229 xstrcat(ret, " - ", ret_len);
213} 230}
214static void scanelf_file_needed(elfobj *elf, char *found_needed, char **ret, size_t *ret_len) 231static void scanelf_file_needed(elfobj *elf, char *found_needed, char **ret, size_t *ret_len)
215{ 232{
216 int i; 233 unsigned long i;
217 char *needed; 234 char *needed;
218 void *strtbl_void; 235 void *strtbl_void;
219 236
220 if (!show_needed) return; 237 if (!show_needed) return;
221 238
222 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 239 strtbl_void = elf_findsecbyname(elf, ".dynstr");
223 240
224 if (strtbl_void) { 241 if (elf->phdr && strtbl_void) {
225#define SHOW_NEEDED(B) \ 242#define SHOW_NEEDED(B) \
226 if (elf->elf_class == ELFCLASS ## B) { \ 243 if (elf->elf_class == ELFCLASS ## B) { \
227 Elf ## B ## _Dyn *dyn; \ 244 Elf ## B ## _Dyn *dyn; \
228 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 245 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
229 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 246 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
230 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 247 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
248 Elf ## B ## _Off offset; \
231 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 249 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
232 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 250 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
251 offset = EGET(phdr[i].p_offset); \
252 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
233 dyn = DYN ## B (elf->data + EGET(phdr[i].p_offset)); \ 253 dyn = DYN ## B (elf->data + offset); \
234 while (EGET(dyn->d_tag) != DT_NULL) { \ 254 while (EGET(dyn->d_tag) != DT_NULL) { \
235 if (EGET(dyn->d_tag) == DT_NEEDED) { \ 255 if (EGET(dyn->d_tag) == DT_NEEDED) { \
236 needed = elf->data + EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 256 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
257 if (offset >= elf->len) continue; \
258 needed = (char*)(elf->data + offset); \
237 if (*found_needed) xchrcat(ret, ',', ret_len); \ 259 if (*found_needed) xchrcat(ret, ',', ret_len); \
238 xstrcat(ret, needed, ret_len); \ 260 xstrcat(ret, needed, ret_len); \
239 *found_needed = 1; \ 261 *found_needed = 1; \
240 } \ 262 } \
241 ++dyn; \ 263 ++dyn; \
265 } 287 }
266 return NULL; 288 return NULL;
267} 289}
268static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename) 290static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename)
269{ 291{
270 int i; 292 unsigned long i;
271 void *symtab_void, *strtab_void; 293 void *symtab_void, *strtab_void;
272 294
273 if (!find_sym) return NULL; 295 if (!find_sym) return NULL;
274 296
275 symtab_void = elf_findsecbyname(elf, ".symtab"); 297 symtab_void = elf_findsecbyname(elf, ".symtab");
279#define FIND_SYM(B) \ 301#define FIND_SYM(B) \
280 if (elf->elf_class == ELFCLASS ## B) { \ 302 if (elf->elf_class == ELFCLASS ## B) { \
281 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 303 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
282 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 304 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
283 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ 305 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
284 int cnt = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \ 306 unsigned long cnt = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
285 char *symname; \ 307 char *symname; \
286 for (i = 0; i < cnt; ++i) { \ 308 for (i = 0; i < cnt; ++i) { \
287 if (sym->st_name) { \ 309 if (sym->st_name) { \
288 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ 310 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
289 if (*find_sym == '*') { \ 311 if (*find_sym == '*') { \
312} 334}
313/* scan an elf file and show all the fun stuff */ 335/* scan an elf file and show all the fun stuff */
314#define prints(str) fputs(str, stdout) 336#define prints(str) fputs(str, stdout)
315static void scanelf_file(const char *filename) 337static void scanelf_file(const char *filename)
316{ 338{
317 int i; 339 unsigned long i;
318 char found_pax, found_stack, found_relro, found_textrel, 340 char found_pax, found_stack, found_relro, found_textrel,
319 found_rpath, found_needed, found_interp, found_sym, 341 found_rpath, found_needed, found_interp, found_sym,
320 found_file; 342 found_file;
321 elfobj *elf; 343 elfobj *elf;
322 struct stat st; 344 struct stat st;
573}; 595};
574 596
575/* display usage and exit */ 597/* display usage and exit */
576static void usage(int status) 598static void usage(int status)
577{ 599{
578 int i; 600 unsigned long i;
579 printf(" Scan ELF binaries for stuff\n\n" 601 printf(" Scan ELF binaries for stuff\n\n"
580 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); 602 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0);
581 printf("Options: -[%s]\n", PARSE_FLAGS); 603 printf("Options: -[%s]\n", PARSE_FLAGS);
582 for (i = 0; long_opts[i].name; ++i) 604 for (i = 0; long_opts[i].name; ++i)
583 if (long_opts[i].has_arg == no_argument) 605 if (long_opts[i].has_arg == no_argument)

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.44

  ViewVC Help
Powered by ViewVC 1.1.20