/[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.90 Revision 1.91
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.90 2005/12/04 18:12:44 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.91 2005/12/07 01:04:52 vapier Exp $
5 * 5 *
6 * Copyright 2003-2005 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2005 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2005 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2005 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
20#include <dirent.h> 20#include <dirent.h>
21#include <getopt.h> 21#include <getopt.h>
22#include <assert.h> 22#include <assert.h>
23#include "paxinc.h" 23#include "paxinc.h"
24 24
25static const char *rcsid = "$Id: scanelf.c,v 1.90 2005/12/04 18:12:44 vapier Exp $"; 25static const char *rcsid = "$Id: scanelf.c,v 1.91 2005/12/07 01:04:52 vapier Exp $";
26#define argv0 "scanelf" 26#define argv0 "scanelf"
27 27
28#define IS_MODIFIER(c) (c == '%' || c == '#') 28#define IS_MODIFIER(c) (c == '%' || c == '#')
29 29
30 30
144 144
145static char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_relro, char *found_load) 145static char *scanelf_file_phdr(elfobj *elf, char *found_phdr, char *found_relro, char *found_load)
146{ 146{
147 static char ret[12]; 147 static char ret[12];
148 char *found; 148 char *found;
149 unsigned long i, off, shown, check_flags; 149 unsigned long i, shown;
150 unsigned char multi_stack, multi_relro, multi_load; 150 unsigned char multi_stack, multi_relro, multi_load;
151 151
152 if (!show_phdr) return NULL; 152 if (!show_phdr) return NULL;
153 153
154 memcpy(ret, "--- --- ---\0", 12); 154 memcpy(ret, "--- --- ---\0", 12);
155 155
156 shown = 0; 156 shown = 0;
157 multi_stack = multi_relro = multi_load = 0; 157 multi_stack = multi_relro = multi_load = 0;
158 158
159 if (elf->phdr) {
160#define SHOW_PHDR(B) \ 159#define SHOW_PHDR(B) \
161 if (elf->elf_class == ELFCLASS ## B) { \ 160 if (elf->elf_class == ELFCLASS ## B) { \
162 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 161 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
162 Elf ## B ## _Off offset; \
163 uint32_t flags, check_flags; \
164 if (elf->phdr != NULL) { \
163 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 165 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
164 uint32_t flags; \
165 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 166 for (i = 0; i < EGET(ehdr->e_phnum); ++i) { \
166 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \ 167 if (EGET(phdr[i].p_type) == PT_GNU_STACK) { \
167 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \ 168 if (multi_stack++) warnf("%s: multiple PT_GNU_STACK's !?", elf->filename); \
168 found = found_phdr; \ 169 found = found_phdr; \
169 off = 0; \ 170 offset = 0; \
170 check_flags = PF_X; \ 171 check_flags = PF_X; \
171 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \ 172 } else if (EGET(phdr[i].p_type) == PT_GNU_RELRO) { \
172 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ 173 if (multi_relro++) warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \
173 found = found_relro; \ 174 found = found_relro; \
174 off = 4; \ 175 offset = 4; \
175 check_flags = PF_X; \ 176 check_flags = PF_X; \
176 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \ 177 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \
177 if (multi_load++ > 2) warnf("%s: more than 2 PT_LOAD's !?", elf->filename); \ 178 if (multi_load++ > 2) warnf("%s: more than 2 PT_LOAD's !?", elf->filename); \
178 found = found_load; \ 179 found = found_load; \
179 off = 8; \ 180 offset = 8; \
180 check_flags = PF_W|PF_X; \ 181 check_flags = PF_W|PF_X; \
181 } else \ 182 } else \
182 continue; \ 183 continue; \
183 flags = EGET(phdr[i].p_flags); \ 184 flags = EGET(phdr[i].p_flags); \
184 if (be_quiet && ((flags & check_flags) != check_flags)) \ 185 if (be_quiet && ((flags & check_flags) != check_flags)) \
185 continue; \ 186 continue; \
186 memcpy(ret+off, gnu_short_stack_flags(flags), 3); \ 187 memcpy(ret+offset, gnu_short_stack_flags(flags), 3); \
187 *found = 1; \ 188 *found = 1; \
188 ++shown; \ 189 ++shown; \
190 } \
191 } else if (elf->shdr != NULL) { \
192 /* no program headers which means this is prob an object file */ \
193 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \
194 Elf ## B ## _Shdr *strtbl = shdr + EGET(ehdr->e_shstrndx); \
195 check_flags = SHF_WRITE|SHF_EXECINSTR; \
196 for (i = 0; i < EGET(ehdr->e_shnum); ++i) { \
197 if (EGET(shdr[i].sh_type) != SHT_PROGBITS) continue; \
198 offset = EGET(strtbl->sh_offset) + EGET(shdr[i].sh_name); \
199 if (!strcmp((char*)(elf->data + offset), ".note.GNU-stack")) { \
200 if (multi_stack++) warnf("%s: multiple .note.GNU-stack's !?", elf->filename); \
201 flags = EGET(shdr[i].sh_flags); \
202 if (be_quiet && ((flags & check_flags) != check_flags)) \
203 continue; \
204 ++*found_phdr; \
205 shown = 1; \
206 if (flags & SHF_WRITE) ret[0] = 'W'; \
207 if (flags & SHF_ALLOC) ret[1] = 'A'; \
208 if (flags & SHF_EXECINSTR) ret[2] = 'X'; \
209 if (flags & 0xFFFFFFF8) warn("Invalid section flags for GNU-stack"); \
210 break; \
211 } \
212 } \
213 if (!multi_stack) { \
214 *found_phdr = 1; \
215 shown = 1; \
216 memcpy(ret, "!WX", 3); \
217 } \
189 } \ 218 } \
190 } 219 }
191 SHOW_PHDR(32) 220 SHOW_PHDR(32)
192 SHOW_PHDR(64) 221 SHOW_PHDR(64)
193 }
194 222
195 if (be_wewy_wewy_quiet || (be_quiet && !shown)) 223 if (be_wewy_wewy_quiet || (be_quiet && !shown))
196 return NULL; 224 return NULL;
197 else 225 else
198 return ret; 226 return ret;

Legend:
Removed from v.1.90  
changed lines
  Added in v.1.91

  ViewVC Help
Powered by ViewVC 1.1.20