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 }