elf64getsym.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
elf64getsym.c (1969B)
---
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <scc/mach.h>
7 #include <scc/elf64.h>
8
9 #include "../libmach.h"
10 #include "fun.h"
11
12 static int
13 typeof(Elf64 *elf, Elf_Sym *ent, char *name)
14 {
15 int c, bind;
16 unsigned long flags, type;
17 Elf_Shdr *shdr;
18
19 switch (ent->st_shndx) {
20 case SHN_UNDEF:
21 c = 'U';
22 break;
23 case SHN_ABS:
24 c = 'a';
25 break;
26 case SHN_COMMON:
27 c = 'C';
28 break;
29 case SHN_XINDEX:
30 abort();
31 default:
32 shdr = &elf->shdr[ent->st_shndx];
33 flags = shdr->sh_flags;
34 type = shdr->sh_type;
35
36 if (flags & SHF_ALLOC) {
37 if (type == SHT_NOBITS)
38 c = 'b';
39 else if (flags & SHF_WRITE)
40 c = 'd';
41 else if (flags & SHF_EXECINSTR)
42 c = 't';
43 else
44 c = 'r';
45 } else if (strncmp(name, ".debug", 6) == 0) {
46 c = 'N';
47 } else if (strcmp(name, ".comment") == 0) {
48 c = 'N';
49 } else if (strcmp(name, ".line") == 0) {
50 c = 'N';
51 } else if (strcmp(name, ".stab") == 0) {
52 c = 'N';
53 } else {
54 c = '?';
55 }
56 }
57
58 if (ELF_ST_BIND(ent->st_info) != STB_LOCAL)
59 c = toupper(c);
60
61 return c;
62 }
63
64 static int
65 stypeof(Elf_Sym *ent)
66 {
67 switch (ELF_ST_TYPE(ent->st_info)) {
68 case STT_OBJECT:
69 return SYMOBJECT;
70 case STT_FUNC:
71 return SYMFUNC;
72 case STT_SECTION:
73 return SYMSECTION;
74 case STT_FILE:
75 return SYMFILE;
76 case STT_COMMON:
77 return SYMCOMMON;
78 default:
79 case STT_NOTYPE:
80 return SYMNOTYPE;
81 }
82 }
83
84 Symbol *
85 elf64getsym(Obj *obj, int *idx, Symbol *sym)
86 {
87 int n = *idx;
88 Elf_Sym *ent;
89 Elf64 *elf = obj->data;
90
91 if (n == 0)
92 n++;
93
94 if (!elf->symtab || n >= elf->nsym)
95 return NULL;
96 ent = &elf->syms[n];
97
98 if (ELF_ST_TYPE(ent->st_info) == STT_SECTION) {
99 Elf_Shdr *shdr = &elf->shdr[ent->st_shndx];
100 sym->name = elf64str(obj, SEC_STRTBL, shdr->sh_name);
101 } else {
102 sym->name = elf64str(obj, SYM_STRTBL, ent->st_name);
103 }
104
105 sym->type = typeof(elf, ent, sym->name);
106 sym->stype = stypeof(ent);
107 sym->value = ent->st_value;
108 sym->size = ent->st_size;
109 sym->index = *idx = n;
110
111 return sym;
112 }