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