elfgetsym.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
---
elfgetsym.c (2182B)
---
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/elf/elftypes.h>
8 #include <scc/elf/elfent.h>
9 #include <scc/elf/elfshdr.h>
10 #include <scc/elf.h>
11
12 #include "../libmach.h"
13 #include "fun.h"
14
15 static int
16 typeof(Elf *elf, Elfsym *ent, char *name)
17 {
18 int c, bind, weak;
19 unsigned long flags, type;
20 Elfsec *shdr;
21
22 weak = ELF_ST_BIND(ent->info) == STB_WEAK;
23
24 switch (ent->shndx) {
25 case SHN_UNDEF:
26 c = 'U';
27 break;
28 case SHN_ABS:
29 c = 'a';
30 break;
31 case SHN_COMMON:
32 c = 'C';
33 break;
34 case SHN_XINDEX:
35 abort();
36 default:
37 shdr = &elf->secs[ent->shndx];
38 flags = shdr->flags;
39 type = shdr->type;
40
41 if (ELF_ST_BIND(ent->info) == STB_WEAK) {
42 c = (flags & SHF_EXECINSTR) ? 'W' : 'V';
43 } else {
44 if (flags & SHF_ALLOC) {
45 if (type == SHT_NOBITS)
46 c = 'b';
47 else if (flags & SHF_WRITE)
48 c = 'd';
49 else if (flags & SHF_EXECINSTR)
50 c = 't';
51 else
52 c = 'r';
53 } else if (strncmp(name, ".debug", 6) == 0) {
54 c = 'N';
55 } else if (strcmp(name, ".comment") == 0) {
56 c = 'N';
57 } else if (strcmp(name, ".line") == 0) {
58 c = 'N';
59 } else if (strcmp(name, ".stab") == 0) {
60 c = 'N';
61 } else {
62 c = '?';
63 }
64 if (ELF_ST_BIND(ent->info) != STB_LOCAL)
65 c = toupper(c);
66 }
67 }
68
69 return c;
70 }
71
72 static int
73 stypeof(Elfsym *ent)
74 {
75 switch (ELF_ST_TYPE(ent->info)) {
76 case STT_OBJECT:
77 return SYMOBJECT;
78 case STT_FUNC:
79 return SYMFUNC;
80 case STT_SECTION:
81 return SYMSECTION;
82 case STT_FILE:
83 return SYMFILE;
84 case STT_COMMON:
85 return SYMCOMMON;
86 default:
87 case STT_NOTYPE:
88 return SYMNOTYPE;
89 }
90 }
91
92 #include <assert.h>
93
94 Symbol *
95 elfgetsym(Obj *obj, int *idx, Symbol *sym)
96 {
97 int n = *idx;
98 Elfsym *ent;
99 Elf *elf = obj->data;
100
101 if (n == 0)
102 n++;
103
104 if (!elf->syms || n >= elf->nsym)
105 return NULL;
106 ent = &elf->syms[n];
107
108 if (ELF_ST_TYPE(ent->info) == STT_SECTION) {
109 Elfsec *shdr = &elf->secs[ent->shndx];
110 sym->name = shdr->name;
111 } else {
112 sym->name = ent->name;
113 }
114
115 // assert(strlen(sym->name) > 0);
116 sym->type = typeof(elf, ent, sym->name);
117 sym->stype = stypeof(ent);
118 sym->value = ent->value;
119 sym->size = ent->size;
120 sym->index = *idx = n;
121
122 return sym;
123 }