1#include <ctype.h>2#include <stdio.h>3#include <stdlib.h>4#include <string.h>56#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>1112#include "../libmach.h"13#include "fun.h"1415static int16gettype(Elf *elf, Elfsym *ent, char *name)17{18 int c, bind, weak;19 unsigned long flags, type;20 Elfsec *shdr;2122 weak = ELF_ST_BIND(ent->info) == STB_WEAK;2324 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;4041 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 else52 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 }6869 return c;70}7172static int73sgettype(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}9192#include <assert.h>9394Symbol *95elfgetsym(Obj *obj, int *idx, Symbol *sym)96{97 int n = *idx;98 Elfsym *ent;99 Elf *elf = obj->data;100101 if (n == 0)102 n++;103104 if (!elf->syms || n >= elf->nsym)105 return NULL;106 ent = &elf->syms[n];107108 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 }114115 // assert(strlen(sym->name) > 0);116 sym->type = gettype(elf, ent, sym->name);117 sym->stype = sgettype(ent);118 sym->value = ent->value;119 sym->size = ent->size;120 sym->index = *idx = n;121122 return sym;123}