elf64getsym.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
       ---
       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 }