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 }