/[gentoo-projects]/pax-utils/paxelf.c
Gentoo

Contents of /pax-utils/paxelf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.80 - (show annotations) (download) (as text)
Sat Jan 11 00:57:16 2014 UTC (7 months, 2 weeks ago) by vapier
Branch: MAIN
Changes since 1.79: +10 -1 lines
File MIME type: text/x-csrc
paxelf: add more DT defines

1 /*
2 * Copyright 2003-2012 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/paxelf.c,v 1.79 2014/01/11 00:35:43 vapier Exp $
5 *
6 * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
8 */
9
10 #include "paxinc.h"
11
12 /*
13 * Setup a bunch of helper functions to translate
14 * binary defines into readable strings.
15 */
16 #define QUERY(n) { #n, n }
17 typedef const struct {
18 const char *str;
19 int value;
20 } pairtype;
21 static inline const char *find_pairtype(pairtype *pt, int type)
22 {
23 int i;
24 for (i = 0; pt[i].str; ++i)
25 if (type == pt[i].value)
26 return pt[i].str;
27 return "UNKNOWN_TYPE";
28 }
29
30 /* translate misc elf EI_ defines */
31 static pairtype elf_ei_class[] = {
32 QUERY(ELFCLASSNONE),
33 QUERY(ELFCLASS32),
34 QUERY(ELFCLASS64),
35 { 0, 0 }
36 };
37 static pairtype elf_ei_data[] = {
38 QUERY(ELFDATANONE),
39 QUERY(ELFDATA2LSB),
40 QUERY(ELFDATA2MSB),
41 { 0, 0 }
42 };
43 static pairtype elf_ei_version[] = {
44 QUERY(EV_NONE),
45 QUERY(EV_CURRENT),
46 { 0, 0 }
47 };
48 static pairtype elf_ei_osabi[] = {
49 QUERY(ELFOSABI_NONE),
50 QUERY(ELFOSABI_SYSV),
51 QUERY(ELFOSABI_HPUX),
52 QUERY(ELFOSABI_NETBSD),
53 QUERY(ELFOSABI_GNU),
54 QUERY(ELFOSABI_LINUX),
55 QUERY(ELFOSABI_SOLARIS),
56 QUERY(ELFOSABI_AIX),
57 QUERY(ELFOSABI_IRIX),
58 QUERY(ELFOSABI_FREEBSD),
59 QUERY(ELFOSABI_TRU64),
60 QUERY(ELFOSABI_MODESTO),
61 QUERY(ELFOSABI_OPENBSD),
62 QUERY(ELFOSABI_ARM_AEABI),
63 QUERY(ELFOSABI_ARM),
64 QUERY(ELFOSABI_STANDALONE),
65 { 0, 0 }
66 };
67 const char *get_elfeitype(int ei_type, int type)
68 {
69 switch (ei_type) {
70 case EI_CLASS: return find_pairtype(elf_ei_class, type);
71 case EI_DATA: return find_pairtype(elf_ei_data, type);
72 case EI_VERSION: return find_pairtype(elf_ei_version, type);
73 case EI_OSABI: return find_pairtype(elf_ei_osabi, type);
74 }
75 return "UNKNOWN_EI_TYPE";
76 }
77
78 /* translate elf ET_ defines */
79 static pairtype elf_etypes[] = {
80 QUERY(ET_NONE),
81 QUERY(ET_REL),
82 QUERY(ET_EXEC),
83 QUERY(ET_DYN),
84 QUERY(ET_CORE),
85 { 0, 0 }
86 };
87
88 int get_etype(elfobj *elf)
89 {
90 int type;
91 if (elf->elf_class == ELFCLASS32)
92 type = EGET(EHDR32(elf->ehdr)->e_type);
93 else
94 type = EGET(EHDR64(elf->ehdr)->e_type);
95 return type;
96 }
97
98 const char *get_elfetype(elfobj *elf)
99 {
100 return find_pairtype(elf_etypes, get_etype(elf));
101 }
102
103 const char *get_endian(elfobj *elf)
104 {
105 switch (elf->data[EI_DATA]) {
106 case ELFDATA2LSB: return "LE";
107 case ELFDATA2MSB: return "BE";
108 default: return "??";
109 }
110 }
111
112 static int arm_eabi_poker(elfobj *elf)
113 {
114 unsigned int emachine, eflags;
115
116 if (ELFOSABI_NONE != elf->data[EI_OSABI])
117 return -1;
118
119 if (elf->elf_class == ELFCLASS32) {
120 emachine = EHDR32(elf->ehdr)->e_machine;
121 eflags = EHDR32(elf->ehdr)->e_flags;
122 } else {
123 emachine = EHDR64(elf->ehdr)->e_machine;
124 eflags = EHDR64(elf->ehdr)->e_flags;
125 }
126
127 if (EGET(emachine) == EM_ARM)
128 return EF_ARM_EABI_VERSION(EGET(eflags)) >> 24;
129 else
130 return -1;
131 }
132
133 const char *get_elf_eabi(elfobj *elf)
134 {
135 static char buf[26];
136 int eabi = arm_eabi_poker(elf);
137 if (eabi >= 0)
138 snprintf(buf, sizeof(buf), "%i", eabi);
139 else
140 strcpy(buf, "?");
141 return buf;
142 }
143
144 const char *get_elfosabi(elfobj *elf)
145 {
146 const char *str = get_elfeitype(EI_OSABI, elf->data[EI_OSABI]);
147 if (strncmp(str, "ELFOSABI_", 9) == 0)
148 str += 9;
149 return str;
150 }
151
152 void print_etypes(FILE *stream)
153 {
154 int i, wrap = 0;
155 for (i = 0; elf_etypes[i].str; ++i) {
156 fprintf(stream, " (%4x) = %-10s", elf_etypes[i].value, elf_etypes[i].str);
157 if (++wrap >= 4) {
158 fprintf(stream, "\n");
159 wrap = 0;
160 }
161 }
162 if (wrap)
163 fprintf(stream, "\n");
164 }
165
166 int etype_lookup(const char *str)
167 {
168 if (*str == 'E') {
169 int i;
170 for (i = 0; elf_etypes[i].str; ++i) {
171 if (strcmp(str, elf_etypes[i].str) == 0)
172 return elf_etypes[i].value;
173 }
174 }
175 return atoi(str);
176 }
177
178 /* translate elf EM_ defines */
179 static pairtype elf_emtypes[] = {
180 QUERY(EM_NONE),
181 QUERY(EM_M32),
182 QUERY(EM_SPARC),
183 QUERY(EM_386),
184 QUERY(EM_68K),
185 QUERY(EM_88K),
186 QUERY(EM_860),
187 QUERY(EM_MIPS),
188 QUERY(EM_S370),
189 QUERY(EM_MIPS_RS3_LE),
190 QUERY(EM_PARISC),
191 QUERY(EM_VPP500),
192 QUERY(EM_SPARC32PLUS),
193 QUERY(EM_960),
194 QUERY(EM_PPC),
195 QUERY(EM_PPC64),
196 QUERY(EM_S390),
197 QUERY(EM_V800),
198 QUERY(EM_FR20),
199 QUERY(EM_RH32),
200 QUERY(EM_RCE),
201 QUERY(EM_ARM),
202 QUERY(EM_FAKE_ALPHA),
203 QUERY(EM_SH),
204 QUERY(EM_SPARCV9),
205 QUERY(EM_TRICORE),
206 QUERY(EM_ARC),
207 QUERY(EM_H8_300),
208 QUERY(EM_H8_300H),
209 QUERY(EM_H8S),
210 QUERY(EM_H8_500),
211 QUERY(EM_IA_64),
212 QUERY(EM_MIPS_X),
213 QUERY(EM_COLDFIRE),
214 QUERY(EM_68HC12),
215 QUERY(EM_MMA),
216 QUERY(EM_PCP),
217 QUERY(EM_NCPU),
218 QUERY(EM_NDR1),
219 QUERY(EM_STARCORE),
220 QUERY(EM_ME16),
221 QUERY(EM_ST100),
222 QUERY(EM_TINYJ),
223 QUERY(EM_X86_64),
224 QUERY(EM_PDSP),
225 QUERY(EM_FX66),
226 QUERY(EM_ST9PLUS),
227 QUERY(EM_ST7),
228 QUERY(EM_68HC16),
229 QUERY(EM_68HC11),
230 QUERY(EM_68HC08),
231 QUERY(EM_68HC05),
232 QUERY(EM_SVX),
233 QUERY(EM_ST19),
234 QUERY(EM_VAX),
235 QUERY(EM_CRIS),
236 QUERY(EM_JAVELIN),
237 QUERY(EM_FIREPATH),
238 QUERY(EM_ZSP),
239 QUERY(EM_MMIX),
240 QUERY(EM_HUANY),
241 QUERY(EM_PRISM),
242 QUERY(EM_AVR),
243 QUERY(EM_FR30),
244 QUERY(EM_D10V),
245 QUERY(EM_D30V),
246 QUERY(EM_V850),
247 QUERY(EM_M32R),
248 QUERY(EM_MN10300),
249 QUERY(EM_MN10200),
250 QUERY(EM_PJ),
251 QUERY(EM_OPENRISC),
252 QUERY(EM_ARC_A5),
253 QUERY(EM_XTENSA),
254 QUERY(EM_VIDEOCORE),
255 QUERY(EM_TMM_GPP),
256 QUERY(EM_NS32K),
257 QUERY(EM_TPC),
258 QUERY(EM_SNP1K),
259 QUERY(EM_ST200),
260 QUERY(EM_IP2K),
261 QUERY(EM_MAX),
262 QUERY(EM_CR),
263 QUERY(EM_F2MC16),
264 QUERY(EM_MSP430),
265 QUERY(EM_BLACKFIN),
266 QUERY(EM_SE_C33),
267 QUERY(EM_SEP),
268 QUERY(EM_ARCA),
269 QUERY(EM_UNICORE),
270 QUERY(EM_AARCH64),
271 QUERY(EM_TILEPRO),
272 QUERY(EM_MICROBLAZE),
273 QUERY(EM_TILEGX),
274 QUERY(EM_ALPHA),
275 { 0, 0 }
276 };
277
278 int get_emtype(elfobj *elf)
279 {
280 int type;
281 if (elf->elf_class == ELFCLASS32)
282 type = EGET(EHDR32(elf->ehdr)->e_machine);
283 else
284 type = EGET(EHDR64(elf->ehdr)->e_machine);
285 return type;
286 }
287
288 const char *get_elfemtype(elfobj *elf)
289 {
290 return find_pairtype(elf_emtypes, get_emtype(elf));
291 }
292
293 /* translate elf PT_ defines */
294 static pairtype elf_ptypes[] = {
295 QUERY(PT_NULL),
296 QUERY(PT_LOAD),
297 QUERY(PT_DYNAMIC),
298 QUERY(PT_INTERP),
299 QUERY(PT_NOTE),
300 QUERY(PT_SHLIB),
301 QUERY(PT_PHDR),
302 QUERY(PT_TLS),
303 QUERY(PT_GNU_EH_FRAME),
304 QUERY(PT_GNU_STACK),
305 QUERY(PT_GNU_RELRO),
306 QUERY(PT_PAX_FLAGS),
307 { 0, 0 }
308 };
309 const char *get_elfptype(int type)
310 {
311 return find_pairtype(elf_ptypes, type);
312 }
313
314 /* translate elf PT_ defines */
315 static pairtype elf_dtypes[] = {
316 QUERY(DT_NULL),
317 QUERY(DT_NEEDED),
318 QUERY(DT_PLTRELSZ),
319 QUERY(DT_PLTGOT),
320 QUERY(DT_HASH),
321 QUERY(DT_STRTAB),
322 QUERY(DT_SYMTAB),
323 QUERY(DT_RELA),
324 QUERY(DT_RELASZ),
325 QUERY(DT_RELAENT),
326 QUERY(DT_STRSZ),
327 QUERY(DT_SYMENT),
328 QUERY(DT_INIT),
329 QUERY(DT_FINI),
330 QUERY(DT_SONAME),
331 QUERY(DT_RPATH),
332 QUERY(DT_SYMBOLIC),
333 QUERY(DT_REL),
334 QUERY(DT_RELSZ),
335 QUERY(DT_RELENT),
336 QUERY(DT_PLTREL),
337 QUERY(DT_DEBUG),
338 QUERY(DT_TEXTREL),
339 QUERY(DT_JMPREL),
340 QUERY(DT_BIND_NOW),
341 QUERY(DT_INIT_ARRAY),
342 QUERY(DT_FINI_ARRAY),
343 QUERY(DT_INIT_ARRAYSZ),
344 QUERY(DT_FINI_ARRAYSZ),
345 QUERY(DT_RUNPATH),
346 QUERY(DT_FLAGS),
347 QUERY(DT_ENCODING),
348 QUERY(DT_PREINIT_ARRAY),
349 QUERY(DT_PREINIT_ARRAYSZ),
350 QUERY(DT_GNU_PRELINKED),
351 QUERY(DT_GNU_CONFLICTSZ),
352 QUERY(DT_GNU_LIBLISTSZ),
353 QUERY(DT_CHECKSUM),
354 QUERY(DT_PLTPADSZ),
355 QUERY(DT_MOVEENT),
356 QUERY(DT_MOVESZ),
357 QUERY(DT_GNU_HASH),
358 QUERY(DT_TLSDESC_PLT),
359 QUERY(DT_TLSDESC_GOT),
360 QUERY(DT_GNU_CONFLICT),
361 QUERY(DT_GNU_LIBLIST),
362 QUERY(DT_CONFIG),
363 QUERY(DT_DEPAUDIT),
364 QUERY(DT_AUDIT),
365 QUERY(DT_PLTPAD),
366 QUERY(DT_MOVETAB),
367 QUERY(DT_SYMINFO),
368 QUERY(DT_VERSYM),
369 QUERY(DT_RELACOUNT),
370 QUERY(DT_RELCOUNT),
371 QUERY(DT_VERDEF),
372 QUERY(DT_VERDEFNUM),
373 QUERY(DT_VERNEED),
374 QUERY(DT_VERNEEDNUM),
375 QUERY(DT_AUXILIARY),
376 QUERY(DT_FILTER),
377 { 0, 0 }
378 };
379 const char *get_elfdtype(int type)
380 {
381 return find_pairtype(elf_dtypes, type);
382 }
383
384 /* translate elf SHT_ defines */
385 static pairtype elf_shttypes[] = {
386 QUERY(SHT_NULL),
387 QUERY(SHT_PROGBITS),
388 QUERY(SHT_SYMTAB),
389 QUERY(SHT_STRTAB),
390 QUERY(SHT_RELA),
391 QUERY(SHT_HASH),
392 QUERY(SHT_DYNAMIC),
393 QUERY(SHT_NOTE),
394 QUERY(SHT_NOBITS),
395 QUERY(SHT_REL),
396 QUERY(SHT_SHLIB),
397 QUERY(SHT_DYNSYM),
398 QUERY(SHT_INIT_ARRAY),
399 QUERY(SHT_FINI_ARRAY),
400 QUERY(SHT_PREINIT_ARRAY),
401 QUERY(SHT_GROUP),
402 QUERY(SHT_SYMTAB_SHNDX),
403 QUERY(SHT_GNU_ATTRIBUTES),
404 QUERY(SHT_GNU_HASH),
405 QUERY(SHT_GNU_LIBLIST),
406 QUERY(SHT_CHECKSUM),
407 QUERY(SHT_SUNW_move),
408 QUERY(SHT_SUNW_COMDAT),
409 QUERY(SHT_SUNW_syminfo),
410 QUERY(SHT_GNU_verdef),
411 QUERY(SHT_GNU_verneed),
412 QUERY(SHT_GNU_versym),
413 { 0, 0 }
414 };
415 const char *get_elfshttype(int type)
416 {
417 return find_pairtype(elf_shttypes, type);
418 }
419
420 /* translate elf STT_ defines */
421 static pairtype elf_stttypes[] = {
422 QUERY(STT_NOTYPE),
423 QUERY(STT_OBJECT),
424 QUERY(STT_FUNC),
425 QUERY(STT_SECTION),
426 QUERY(STT_FILE),
427 QUERY(STT_COMMON),
428 QUERY(STT_TLS),
429 QUERY(STT_GNU_IFUNC),
430 { 0, 0 }
431 };
432 const char *get_elfstttype(int type)
433 {
434 return find_pairtype(elf_stttypes, type);
435 }
436
437 /* translate elf STB_ defines */
438 static pairtype elf_stbtypes[] = {
439 QUERY(STB_LOCAL),
440 QUERY(STB_GLOBAL),
441 QUERY(STB_WEAK),
442 QUERY(STB_GNU_UNIQUE),
443 { 0, 0 }
444 };
445 const char *get_elfstbtype(int type)
446 {
447 return find_pairtype(elf_stbtypes, type);
448 }
449
450 /* translate elf SHN_ defines */
451 static pairtype elf_shntypes[] = {
452 QUERY(SHN_UNDEF),
453 QUERY(SHN_BEFORE),
454 QUERY(SHN_AFTER),
455 QUERY(SHN_ABS),
456 QUERY(SHN_COMMON),
457 QUERY(SHN_XINDEX),
458 { 0, 0 }
459 };
460 const char *get_elfshntype(int type)
461 {
462 if (type && type < SHN_LORESERVE)
463 return "DEFINED";
464 return find_pairtype(elf_shntypes, type);
465 }
466
467 /* Read an ELF into memory */
468 #define IS_ELF_BUFFER(buff) \
469 (buff[EI_MAG0] == ELFMAG0 && \
470 buff[EI_MAG1] == ELFMAG1 && \
471 buff[EI_MAG2] == ELFMAG2 && \
472 buff[EI_MAG3] == ELFMAG3)
473 #define DO_WE_LIKE_ELF(buff) \
474 ((buff[EI_CLASS] == ELFCLASS32 || buff[EI_CLASS] == ELFCLASS64) && \
475 (buff[EI_DATA] == ELFDATA2LSB || buff[EI_DATA] == ELFDATA2MSB) && \
476 (buff[EI_VERSION] == EV_CURRENT))
477 elfobj *readelf_buffer(const char *filename, void *buffer, size_t buffer_len)
478 {
479 elfobj *elf;
480
481 /* make sure we have enough bytes to scan e_ident */
482 if (buffer == NULL || buffer_len < EI_NIDENT)
483 return NULL;
484
485 elf = xzalloc(sizeof(*elf));
486
487 elf->fd = -1;
488 elf->len = buffer_len;
489 elf->data = buffer;
490 elf->data_end = buffer + buffer_len;
491
492 /* make sure we have an elf */
493 if (!IS_ELF_BUFFER(elf->data)) {
494 free_elf_and_return:
495 free(elf);
496 return NULL;
497 }
498
499 /* check class and stuff */
500 if (!DO_WE_LIKE_ELF(elf->data)) {
501 warn("we no likey %s: {%s,%s,%s,%s}",
502 filename,
503 get_elfeitype(EI_CLASS, elf->data[EI_CLASS]),
504 get_elfeitype(EI_DATA, elf->data[EI_DATA]),
505 get_elfeitype(EI_VERSION, elf->data[EI_VERSION]),
506 get_elfeitype(EI_OSABI, elf->data[EI_OSABI]));
507 goto free_elf_and_return;
508 }
509
510 elf->filename = filename;
511 elf->base_filename = strrchr(filename, '/');
512 if (elf->base_filename == NULL)
513 elf->base_filename = elf->filename;
514 else
515 elf->base_filename = elf->base_filename + 1;
516 elf->elf_class = elf->data[EI_CLASS];
517 do_reverse_endian = (ELF_DATA != elf->data[EI_DATA]);
518
519 /* for arches that need alignment, we have to make sure the buffer
520 * is strictly aligned. archive (.a) files only align to 2 bytes
521 * while the arch can easily require 8. so dupe the buffer so
522 * that our local copy is always aligned (since we can't shift the
523 * file mapping back and forth a few bytes).
524 */
525 if (!__PAX_UNALIGNED_OK && ((unsigned long)elf->vdata & 0x7)) {
526 elf->_data = xmalloc(elf->len);
527 memcpy(elf->_data, elf->data, elf->len);
528 elf->data = elf->_data;
529 elf->data_end = elf->_data + elf->len;
530 }
531
532 #define READELF_HEADER(B) \
533 if (elf->elf_class == ELFCLASS ## B) { \
534 char invalid; \
535 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
536 Elf ## B ## _Off size; \
537 /* verify program header */ \
538 invalid = 0; \
539 if (EGET(ehdr->e_phnum) <= 0) \
540 invalid = 1; /* this is not abnormal so dont warn */ \
541 else if (EGET(ehdr->e_phentsize) != sizeof(Elf ## B ## _Phdr)) \
542 invalid = 3; \
543 else { \
544 elf->phdr = elf->vdata + EGET(ehdr->e_phoff); \
545 size = EGET(ehdr->e_phnum) * EGET(ehdr->e_phentsize); \
546 if (elf->phdr < elf->ehdr || /* check overflow */ \
547 elf->phdr + size < elf->phdr || /* before start of mem */ \
548 elf->phdr + size > elf->ehdr + elf->len) /* before end of mem */ \
549 invalid = 2; \
550 } \
551 if (invalid > 1) \
552 warn("%s: Invalid program header info (%i)", filename, invalid); \
553 if (invalid) \
554 elf->phdr = NULL; \
555 /* verify section header */ \
556 invalid = 0; \
557 if (EGET(ehdr->e_shnum) <= 0) \
558 invalid = 1; /* this is not abnormal so dont warn */ \
559 else if (EGET(ehdr->e_shentsize) != sizeof(Elf ## B ## _Shdr)) \
560 invalid = 3; \
561 else { \
562 elf->shdr = elf->vdata + EGET(ehdr->e_shoff); \
563 size = EGET(ehdr->e_shnum) * EGET(ehdr->e_shentsize); \
564 if (elf->shdr < elf->ehdr || /* check overflow */ \
565 elf->shdr + size < elf->shdr || /* before start of mem */ \
566 elf->shdr + size > elf->ehdr + elf->len) /* before end of mem */ \
567 invalid = 2; \
568 } \
569 if (invalid > 1) \
570 warn("%s: Invalid section header info (%i)", filename, invalid); \
571 if (invalid) \
572 elf->shdr = NULL; \
573 }
574 READELF_HEADER(32)
575 READELF_HEADER(64)
576 /* { char *p; strncpy(elf->basename, (p = strrchr(filename, '/')) == NULL ? "?" : p+1 , sizeof(elf->basename)); } */
577
578 return elf;
579 }
580 elfobj *_readelf_fd(const char *filename, int fd, size_t len, int read_only)
581 {
582 char *buffer;
583 elfobj *ret;
584
585 if (len == 0) {
586 struct stat st;
587 if (fstat(fd, &st) == -1)
588 return NULL;
589 len = st.st_size;
590 if (len == 0)
591 return NULL;
592 }
593
594 buffer = mmap(0, len, PROT_READ | (read_only ? 0 : PROT_WRITE), (read_only ? MAP_PRIVATE : MAP_SHARED), fd, 0);
595 if (buffer == MAP_FAILED) {
596 warn("mmap on '%s' of %li bytes failed :(", filename, (unsigned long)len);
597 return NULL;
598 }
599
600 ret = readelf_buffer(filename, buffer, len);
601 if (ret == NULL)
602 munmap(buffer, len);
603 else {
604 ret->fd = fd;
605 ret->is_mmap = 1;
606 }
607
608 return ret;
609 }
610 elfobj *_readelf(const char *filename, int read_only)
611 {
612 elfobj *ret;
613 struct stat st;
614 int fd;
615
616 if (stat(filename, &st) == -1)
617 return NULL;
618
619 if ((fd = open(filename, (read_only ? O_RDONLY : O_RDWR))) == -1)
620 return NULL;
621
622 /* make sure we have enough bytes to scan e_ident */
623 if (st.st_size <= EI_NIDENT) {
624 close_fd_and_return:
625 close(fd);
626 return NULL;
627 }
628
629 ret = readelf_fd(filename, fd, st.st_size);
630 if (ret == NULL)
631 goto close_fd_and_return;
632
633 return ret;
634 }
635
636 /* undo the readelf() stuff */
637 void unreadelf(elfobj *elf)
638 {
639 if (elf->is_mmap) munmap(elf->vdata, elf->len);
640 if (elf->fd != -1) close(elf->fd);
641 if (!__PAX_UNALIGNED_OK) free(elf->_data);
642 free(elf);
643 }
644
645 char *pax_short_hf_flags(unsigned long flags)
646 {
647 static char buffer[7];
648
649 buffer[0] = (flags & HF_PAX_PAGEEXEC ? 'p' : 'P');
650 buffer[1] = (flags & HF_PAX_EMUTRAMP ? 'E' : 'e');
651 buffer[2] = (flags & HF_PAX_MPROTECT ? 'm' : 'M');
652 buffer[3] = (flags & HF_PAX_RANDMMAP ? 'r' : 'R');
653 buffer[4] = (flags & HF_PAX_RANDEXEC ? 'X' : 'x');
654 buffer[5] = (flags & HF_PAX_SEGMEXEC ? 's' : 'S');
655 buffer[6] = 0;
656
657 return buffer;
658 }
659
660 /* PT_PAX_FLAGS are tristate ...
661 * the display logic is:
662 * lower case: explicitly disabled
663 * upper case: explicitly enabled
664 * - : default */
665 char *pax_short_pf_flags(unsigned long flags)
666 {
667 static char buffer[7];
668
669 #define PAX_STATE(pf_on, pf_off, disp_on, disp_off) \
670 (flags & pf_on ? disp_on : (flags & pf_off ? disp_off : '-'))
671
672 buffer[0] = PAX_STATE(PF_PAGEEXEC, PF_NOPAGEEXEC, 'P', 'p');
673 buffer[1] = PAX_STATE(PF_SEGMEXEC, PF_NOSEGMEXEC, 'S', 's');
674 buffer[2] = PAX_STATE(PF_MPROTECT, PF_NOMPROTECT, 'M', 'm');
675 buffer[3] = PAX_STATE(PF_RANDEXEC, PF_NORANDEXEC, 'X', 'x');
676 buffer[4] = PAX_STATE(PF_EMUTRAMP, PF_NOEMUTRAMP, 'E', 'e');
677 buffer[5] = PAX_STATE(PF_RANDMMAP, PF_NORANDMMAP, 'R', 'r');
678 buffer[6] = 0;
679
680 if (((flags & PF_PAGEEXEC) && (flags & PF_NOPAGEEXEC)) || \
681 ((flags & PF_SEGMEXEC) && (flags & PF_NOSEGMEXEC)) || \
682 ((flags & PF_RANDMMAP) && (flags & PF_NORANDMMAP)) || \
683 ((flags & PF_RANDEXEC) && (flags & PF_NORANDEXEC)) || \
684 ((flags & PF_EMUTRAMP) && (flags & PF_NOEMUTRAMP)) || \
685 ((flags & PF_RANDMMAP) && (flags & PF_NORANDMMAP)))
686 warn("inconsistent state detected. flags=%lX\n", flags);
687
688 return buffer;
689 }
690
691 char *gnu_short_stack_flags(unsigned long flags)
692 {
693 static char buffer[4];
694
695 buffer[0] = (flags & PF_R ? 'R' : '-');
696 buffer[1] = (flags & PF_W ? 'W' : '-');
697 buffer[2] = (flags & PF_X ? 'X' : '-');
698 buffer[3] = 0;
699
700 return buffer;
701 }
702
703 void *elf_findsecbyname(elfobj *elf, const char *name)
704 {
705 unsigned int i;
706 char *shdr_name;
707 void *ret = NULL;
708
709 if (elf->shdr == NULL) return NULL;
710
711 #define FINDSEC(B) \
712 if (elf->elf_class == ELFCLASS ## B) { \
713 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
714 Elf ## B ## _Shdr *shdr = SHDR ## B (elf->shdr); \
715 Elf ## B ## _Shdr *strtbl; \
716 Elf ## B ## _Off offset; \
717 uint16_t shstrndx = EGET(ehdr->e_shstrndx); \
718 uint16_t shnum = EGET(ehdr->e_shnum); \
719 if (shstrndx >= shnum) return NULL; \
720 strtbl = &(shdr[shstrndx]); \
721 for (i = 0; i < shnum; ++i) { \
722 offset = EGET(strtbl->sh_offset) + EGET(shdr[i].sh_name); \
723 if (offset >= (Elf ## B ## _Off)elf->len) continue; \
724 shdr_name = elf->data + offset; \
725 if (!strcmp(shdr_name, name)) { \
726 if (ret) warnf("Multiple '%s' sections !?", name); \
727 ret = (void*)&(shdr[i]); \
728 } \
729 } }
730 FINDSEC(32)
731 FINDSEC(64)
732
733 return ret;
734 }
735
736 #if 0
737 # define ELFOSABI_NONE 0 /* UNIX System V ABI */
738 # define ELFOSABI_SYSV 0 /* Alias. */
739 # define ELFOSABI_HPUX 1 /* HP-UX */
740 # define ELFOSABI_NETBSD 2 /* NetBSD. */
741 # define ELFOSABI_LINUX 3 /* Linux. */
742 # define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
743 # define ELFOSABI_AIX 7 /* IBM AIX. */
744 # define ELFOSABI_IRIX 8 /* SGI Irix. */
745 # define ELFOSABI_FREEBSD 9 /* FreeBSD. */
746 # define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
747 # define ELFOSABI_MODESTO 11 /* Novell Modesto. */
748 # define ELFOSABI_OPENBSD 12 /* OpenBSD. */
749 # define ELFOSABI_ARM 97 /* ARM */
750 # define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
751
752 /* These 3 ABIs should be in elf.h but are not.
753 * http://www.caldera.com/developers/gabi/latest/ch4.eheader.html#generic_osabi_values
754 */
755
756 # define ELFOSABI_OPENVMS 13 /* OpenVMS */
757 # define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */
758 # define ELFOSABI_AROS 15 /* Amiga Research OS */
759
760 #4 reserved for IA32 GNU Mach/Hurd
761 #5 reserved for 86Open common IA32 ABI
762
763 #endif

  ViewVC Help
Powered by ViewVC 1.1.20