/[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.81 Revision 1.82
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.81 2005/06/13 03:35:41 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.82 2005/06/19 05:39:31 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.81 2005/06/13 03:35:41 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.82 2005/06/19 05:39:31 vapier Exp $";
39#define argv0 "scanelf" 39#define argv0 "scanelf"
40 40
41#define IS_MODIFIER(c) (c == '%' || c == '#') 41#define IS_MODIFIER(c) (c == '%' || c == '#')
42 42
43 43
111{ 111{
112 static char *paxflags; 112 static char *paxflags;
113 static char ret[7]; 113 static char ret[7];
114 unsigned long i, shown; 114 unsigned long i, shown;
115 115
116
117 if (!show_pax) return NULL; 116 if (!show_pax) return NULL;
118 117
119 shown = 0; 118 shown = 0;
120 memset(&ret, 0, sizeof(ret)); 119 memset(&ret, 0, sizeof(ret));
121 120
145 if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) { 144 if (!be_quiet || (be_quiet && EI_PAX_FLAGS(elf))) {
146 *found_pax = 1; 145 *found_pax = 1;
147 return paxflags; 146 return paxflags;
148 } 147 }
149 strncpy(ret, paxflags, sizeof(ret)); 148 strncpy(ret, paxflags, sizeof(ret));
150 // ++shown;
151 } 149 }
152 150
153 if (be_quiet && !shown) 151 if (be_quiet && !shown)
154 return NULL; 152 return NULL;
155 return ret; 153 return ret;
247 else 245 else
248 return (char *)" - "; 246 return (char *)" - ";
249} 247}
250static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel) 248static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel)
251{ 249{
252 unsigned long p, s, r, rmax; 250 unsigned long s, r, rmax;
253 void *symtab_void, *strtab_void; 251 void *symtab_void, *strtab_void, *text_void;
254 252
255 if (!show_textrels) return NULL; 253 if (!show_textrels) return NULL;
256 254
257 /* don't search for TEXTREL's if the ELF doesn't have any */ 255 /* don't search for TEXTREL's if the ELF doesn't have any */
258 if (!*found_textrel) scanelf_file_textrel(elf, found_textrel); 256 if (!*found_textrel) scanelf_file_textrel(elf, found_textrel);
259 if (!*found_textrel) return NULL; 257 if (!*found_textrel) return NULL;
260 258
261 scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void); 259 scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void);
260 text_void = elf_findsecbyname(elf, ".text");
262 261
263 if (symtab_void && strtab_void && elf->phdr && elf->shdr) { 262 if (symtab_void && strtab_void && text_void && elf->shdr) {
264#define SHOW_TEXTRELS(B) \ 263#define SHOW_TEXTRELS(B) \
265 if (elf->elf_class == ELFCLASS ## B) { \ 264 if (elf->elf_class == ELFCLASS ## B) { \
266 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 265 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
267 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
268 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ 266 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \
269 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 267 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
270 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 268 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
269 Elf ## B ## _Shdr *text = SHDR ## B (text_void); \
270 Elf ## B ## _Addr vaddr = EGET(text->sh_addr); \
271 uint ## B ## _t memsz = EGET(text->sh_size); \
271 Elf ## B ## _Rel *rel; \ 272 Elf ## B ## _Rel *rel; \
272 Elf ## B ## _Rela *rela; \ 273 Elf ## B ## _Rela *rela; \
273 /* search the section headers for relocations */ \ 274 /* search the section headers for relocations */ \
274 for (s = 0; s < EGET(ehdr->e_shnum); ++s) { \ 275 for (s = 0; s < EGET(ehdr->e_shnum); ++s) { \
275 uint32_t sh_type = EGET(shdr[s].sh_type); \ 276 uint32_t sh_type = EGET(shdr[s].sh_type); \
281 rel = NULL; \ 282 rel = NULL; \
282 rela = RELA ## B (elf->data + EGET(shdr[s].sh_offset)); \ 283 rela = RELA ## B (elf->data + EGET(shdr[s].sh_offset)); \
283 rmax = EGET(shdr[s].sh_size) / sizeof(*rela); \ 284 rmax = EGET(shdr[s].sh_size) / sizeof(*rela); \
284 } else \ 285 } else \
285 continue; \ 286 continue; \
286 /* search the program headers for PT_LOAD headers */ \
287 for (p = 0; p < EGET(ehdr->e_phnum); ++p) { \
288 Elf ## B ## _Addr vaddr; \
289 uint ## B ## _t memsz; \
290 if (EGET(phdr[p].p_type) != PT_LOAD) continue; \
291 if (EGET(phdr[p].p_flags) & PF_W) continue; \
292 vaddr = EGET(phdr[p].p_vaddr); \
293 memsz = EGET(phdr[p].p_memsz); \
294 /* now see if any of the relocs are in the PT_LOAD */ \ 287 /* now see if any of the relocs are in the .text */ \
295 for (r = 0; r < rmax; ++r) { \ 288 for (r = 0; r < rmax; ++r) { \
296 unsigned long sym_max; \ 289 unsigned long sym_max; \
297 Elf ## B ## _Addr offset_tmp; \ 290 Elf ## B ## _Addr offset_tmp; \
298 Elf ## B ## _Sym *func; \ 291 Elf ## B ## _Sym *func; \
299 Elf ## B ## _Sym *sym; \ 292 Elf ## B ## _Sym *sym; \
300 Elf ## B ## _Addr r_offset; \ 293 Elf ## B ## _Addr r_offset; \
301 uint ## B ## _t r_info; \ 294 uint ## B ## _t r_info; \
302 if (sh_type == SHT_REL) { \ 295 if (sh_type == SHT_REL) { \
303 r_offset = EGET(rel[r].r_offset); \ 296 r_offset = EGET(rel[r].r_offset); \
304 r_info = EGET(rel[r].r_info); \ 297 r_info = EGET(rel[r].r_info); \
305 } else { \ 298 } else { \
306 r_offset = EGET(rela[r].r_offset); \ 299 r_offset = EGET(rela[r].r_offset); \
307 r_info = EGET(rela[r].r_info); \ 300 r_info = EGET(rela[r].r_info); \
301 } \
302 /* make sure this relocation is inside of the .text */ \
303 if (r_offset < vaddr || r_offset >= vaddr + memsz) { \
304 if (be_verbose <= 2) continue; \
305 } else \
306 *found_textrels = 1; \
307 /* locate this relocation symbol name */ \
308 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
309 sym_max = ELF ## B ## _R_SYM(r_info); \
310 if (sym_max * EGET(symtab->sh_entsize) < symtab->sh_size) \
311 sym += sym_max; \
312 else \
313 sym = NULL; \
314 sym_max = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
315 /* show the raw details about this reloc */ \
316 printf("\tTEXTREL %s: ", elf->base_filename); \
317 if (sym && sym->st_name) \
318 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name))); \
319 else \
320 printf("(NULL: fake?)"); \
321 printf(" [0x%lX]", (unsigned long)r_offset); \
322 /* now try to find the closest symbol that this rel is probably in */ \
323 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
324 func = NULL; \
325 offset_tmp = 0; \
326 while (sym_max--) { \
327 if (EGET(sym->st_value) < r_offset && EGET(sym->st_value) > offset_tmp) { \
328 func = sym; \
329 offset_tmp = EGET(sym->st_value); \
308 } \ 330 } \
309 /* make sure this relocation is inside of the .text */ \
310 if (r_offset < vaddr || r_offset >= vaddr + memsz) continue; \
311 *found_textrels = 1; \
312 /* locate this relocation symbol name */ \
313 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
314 sym_max = ELF ## B ## _R_SYM(r_info); \
315 if (sym_max * EGET(symtab->sh_entsize) < symtab->sh_size) \
316 sym += sym_max; \
317 else \
318 sym = NULL; \
319 sym_max = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
320 /* show the raw details about this reloc */ \
321 printf("\tTEXTREL %s: ", elf->base_filename); \
322 if (sym && sym->st_name) \
323 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name))); \
324 else \
325 printf("(NULL: fake?)"); \
326 printf(" [0x%lX]", (unsigned long)r_offset); \
327 /* now try to find the closest symbol that this rel is probably in */ \
328 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
329 func = NULL; \
330 offset_tmp = 0; \
331 while (sym_max--) { \
332 if (EGET(sym->st_value) < r_offset && EGET(sym->st_value) > offset_tmp) { \
333 func = sym; \
334 offset_tmp = EGET(sym->st_value); \
335 } \
336 ++sym; \ 331 ++sym; \
337 } \
338 printf(" in "); \
339 if (func && func->st_name) \
340 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(func->st_name))); \
341 else \
342 printf("(NULL: fake?)"); \
343 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
344 } \ 332 } \
333 printf(" in "); \
334 if (func && func->st_name) \
335 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(func->st_name))); \
336 else \
337 printf("(NULL: fake?)"); \
338 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
345 } \ 339 } \
346 } } 340 } }
347 SHOW_TEXTRELS(32) 341 SHOW_TEXTRELS(32)
348 SHOW_TEXTRELS(64) 342 SHOW_TEXTRELS(64)
349 } 343 }
344 if (!*found_textrels)
345 warnf("ELF %s has TEXTREL markings but doesnt appear to have any real TEXTREL's !?", elf->filename);
350 346
351 return NULL; 347 return NULL;
352} 348}
353static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) 349static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len)
354{ 350{
958 "Print INTERP information", 954 "Print INTERP information",
959 "Print BIND information", 955 "Print BIND information",
960 "Find a specified symbol", 956 "Find a specified symbol",
961 "Find a specified library", 957 "Find a specified library",
962 "Locate cause of TEXTREL", 958 "Locate cause of TEXTREL",
963 "Print all scanned info (-x -e -t -r -n -i -b)\n", 959 "Print all scanned info (-x -e -t -r -b)\n",
964 "Only output 'bad' things", 960 "Only output 'bad' things",
965 "Be verbose (can be specified more than once)", 961 "Be verbose (can be specified more than once)",
966 "Use specified format for output", 962 "Use specified format for output",
967 "Read input stream from a filename", 963 "Read input stream from a filename",
968 "Write output stream to a filename", 964 "Write output stream to a filename",
1066 case 'i': show_interp = 1; break; 1062 case 'i': show_interp = 1; break;
1067 case 'b': show_bind = 1; break; 1063 case 'b': show_bind = 1; break;
1068 case 'T': show_textrels = 1; break; 1064 case 'T': show_textrels = 1; break;
1069 case 'q': be_quiet = 1; break; 1065 case 'q': be_quiet = 1; break;
1070 case 'v': be_verbose = (be_verbose % 20) + 1; break; 1066 case 'v': be_verbose = (be_verbose % 20) + 1; break;
1071 case 'a': show_pax = show_phdr = show_textrel = show_rpath = \ 1067 case 'a': show_pax = show_phdr = show_textrel = show_rpath = show_bind = 1; break;
1072 show_needed = show_interp = show_bind = 1; break;
1073 1068
1074 case ':': 1069 case ':':
1075 err("Option missing parameter\n"); 1070 err("Option missing parameter\n");
1076 case '?': 1071 case '?':
1077 err("Unknown option\n"); 1072 err("Unknown option\n");

Legend:
Removed from v.1.81  
changed lines
  Added in v.1.82

  ViewVC Help
Powered by ViewVC 1.1.20