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