scc

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