Home
       elf64getsym.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       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 }