scc

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