/[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.76 Revision 1.77
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.76 2005/06/08 04:24:19 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.77 2005/06/08 05:43:01 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.76 2005/06/08 04:24:19 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.77 2005/06/08 05:43:01 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
79static char *search_path = NULL; 79static char *search_path = NULL;
80 80
81 81
82 82
83/* sub-funcs for scanelf_file() */ 83/* sub-funcs for scanelf_file() */
84static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
85{
86 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
87#define GET_SYMTABS(B) \
88 if (elf->elf_class == ELFCLASS ## B) { \
89 Elf ## B ## _Shdr *symtab, *strtab, *dynsym, *dynstr; \
90 /* debug sections */ \
91 symtab = SHDR ## B (elf_findsecbyname(elf, ".symtab")); \
92 strtab = SHDR ## B (elf_findsecbyname(elf, ".strtab")); \
93 /* runtime sections */ \
94 dynsym = SHDR ## B (elf_findsecbyname(elf, ".dynsym")); \
95 dynstr = SHDR ## B (elf_findsecbyname(elf, ".dynstr")); \
96 if (symtab && dynsym) { \
97 *sym = (void*)((EGET(symtab->sh_size) > EGET(dynsym->sh_size)) ? symtab : dynsym); \
98 } else { \
99 *sym = (void*)(symtab ? symtab : dynsym); \
100 } \
101 if (strtab && dynstr) { \
102 *tab = (void*)((EGET(strtab->sh_size) > EGET(dynstr->sh_size)) ? strtab : dynstr); \
103 } else { \
104 *tab = (void*)(strtab ? strtab : dynstr); \
105 } \
106 }
107 GET_SYMTABS(32)
108 GET_SYMTABS(64)
109}
84static char *scanelf_file_pax(elfobj *elf, char *found_pax) 110static char *scanelf_file_pax(elfobj *elf, char *found_pax)
85{ 111{
86 static char *paxflags; 112 static char *paxflags;
87 static char ret[7]; 113 static char ret[7];
88 unsigned long i, shown; 114 unsigned long i, shown;
221 else 247 else
222 return (char *)" - "; 248 return (char *)" - ";
223} 249}
224static char *scanelf_file_textrels(elfobj *elf, char *found_textrels) 250static char *scanelf_file_textrels(elfobj *elf, char *found_textrels)
225{ 251{
226 /* To locate TEXTREL symbols:
227 * for each shdr of type SHT_REL:
228 * for each phdr of type PT_LOAD:
229 * if phdr is not writable (why?)
230 * if shdr offset is inside of load (shdr->offset, phdr->{vaddr,memsz}
231 * look up shdr's symbol name
232 */
233 unsigned long p, s, r, rmax; 252 unsigned long p, s, r, rmax;
234 char *symtab_void, *strtab_void; 253 void *symtab_void, *strtab_void;
235 254
236 if (!show_textrels) return NULL; 255 if (!show_textrels) return NULL;
237 256
238 /* debug sections */ 257 scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void);
239 symtab_void = elf_findsecbyname(elf, ".symtab");
240 strtab_void = elf_findsecbyname(elf, ".strtab");
241 /* fall back to runtime sections */
242 if (!symtab_void || !strtab_void) {
243 symtab_void = elf_findsecbyname(elf, ".dynsym");
244 strtab_void = elf_findsecbyname(elf, ".dynstr");
245 }
246 258
247 if (elf->phdr && elf->shdr) { 259 if (symtab_void && strtab_void && elf->phdr && elf->shdr) {
248#define SHOW_TEXTRELS(B) \ 260#define SHOW_TEXTRELS(B) \
249 if (elf->elf_class == ELFCLASS ## B) { \ 261 if (elf->elf_class == ELFCLASS ## B) { \
250 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 262 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
251 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 263 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
252 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \ 264 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \
291 r_offset = EGET(rela[r].r_offset); \ 303 r_offset = EGET(rela[r].r_offset); \
292 r_info = EGET(rela[r].r_info); \ 304 r_info = EGET(rela[r].r_info); \
293 } \ 305 } \
294 /* make sure this relocation is inside of the .text */ \ 306 /* make sure this relocation is inside of the .text */ \
295 if (r_offset < vaddr || r_offset >= vaddr + memsz) continue; \ 307 if (r_offset < vaddr || r_offset >= vaddr + memsz) continue; \
296 sym_max = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
297 /* locate this relocation symbol name */ \ 308 /* locate this relocation symbol name */ \
298 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ 309 sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
299 sym += ELF ## B ## _R_SYM(r_info); \ 310 sym_max = ELF ## B ## _R_SYM(r_info); \
311 if (sym_max * EGET(symtab->sh_entsize) < symtab->sh_size) \
312 sym += sym_max; \
313 else \
314 sym = NULL; \
315 sym_max = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
300 /* show the raw details about this reloc */ \ 316 /* show the raw details about this reloc */ \
301 printf("\tTEXTREL %s: ", elf->base_filename); \ 317 printf("\tTEXTREL %s: ", elf->base_filename); \
302 if (sym->st_name) \ 318 if (sym && sym->st_name) \
303 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name))); \ 319 printf("%s", (char*)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name))); \
304 else \ 320 else \
305 printf("(NULL: fake?)"); \ 321 printf("(NULL: fake?)"); \
306 printf(" [0x%lX]", (unsigned long)r_offset); \ 322 printf(" [0x%lX]", (unsigned long)r_offset); \
307 /* now try to find the closest symbol that this rel is probably in */ \ 323 /* now try to find the closest symbol that this rel is probably in */ \
542 unsigned long i; 558 unsigned long i;
543 void *symtab_void, *strtab_void; 559 void *symtab_void, *strtab_void;
544 560
545 if (!find_sym) return NULL; 561 if (!find_sym) return NULL;
546 562
547 /* debug sections */ 563 scanelf_file_get_symtabs(elf, &symtab_void, &strtab_void);
548 symtab_void = elf_findsecbyname(elf, ".symtab");
549 strtab_void = elf_findsecbyname(elf, ".strtab");
550 /* fall back to runtime sections */
551 if (!symtab_void || !strtab_void) {
552 symtab_void = elf_findsecbyname(elf, ".dynsym");
553 strtab_void = elf_findsecbyname(elf, ".dynstr");
554 }
555 564
556 if (symtab_void && strtab_void) { 565 if (symtab_void && strtab_void) {
557#define FIND_SYM(B) \ 566#define FIND_SYM(B) \
558 if (elf->elf_class == ELFCLASS ## B) { \ 567 if (elf->elf_class == ELFCLASS ## B) { \
559 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 568 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \

Legend:
Removed from v.1.76  
changed lines
  Added in v.1.77

  ViewVC Help
Powered by ViewVC 1.1.20