scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

elfgetsec.c (1434B)


      1 #include <stdio.h>
      2 
      3 #include <scc/mach.h>
      4 #include <scc/elf/elftypes.h>
      5 #include <scc/elf/elfshdr.h>
      6 #include <scc/elf.h>
      7 
      8 #include "../libmach.h"
      9 #include "fun.h"
     10 
     11 Section *
     12 elfgetsec(Obj *obj, int *idx, Section *sec)
     13 {
     14 	int stype, n = *idx;
     15 	unsigned long flags, type;
     16 	unsigned sflags;
     17 	Elf *elf = obj->data;
     18 	Elfsec *shdr;
     19 
     20 	if (n >= elf->nsec) {
     21 		if (n == SHN_ABS)
     22 			sec->name = "*ABS";
     23 		else if (n == SHN_COMMON)
     24 			sec->name = "*COM*";
     25 		else
     26 			sec->name = "*UNK*";
     27 		return NULL;
     28 	}
     29 
     30 	shdr = &elf->secs[n];
     31 	flags = shdr->flags;
     32 	type = shdr->type;
     33 
     34 	if (flags & SHF_ALLOC) {
     35 		if (type == SHT_NOBITS)
     36 			stype = 'B';
     37 		else if (flags & SHF_WRITE)
     38 			stype = 'D';
     39 		else
     40 			stype = 'T';
     41 	} else {
     42 		stype = 'N';
     43 	}
     44 
     45 	sflags = 0;
     46 	if (flags & SHF_WRITE)
     47 		sflags |= SWRITE;
     48 	if (flags  & SHF_EXECINSTR)
     49 		sflags |= SEXEC;
     50 	if (flags & SHF_ALLOC)
     51 		sflags |= SLOAD|SREAD;
     52 	if (type != SHT_NOBITS)
     53 		sflags |= SALLOC;
     54 	if (stype == 'T' || stype == 'D')
     55 		sflags |= SRELOC;
     56 
     57 	/*
     58 	 * We cannot differentiate between load and base address
     59 	 * in a section, while we can use the physical address
     60 	 * for that when dealing with segments.
     61 	 */
     62 	if (n == SHN_UNDEF)
     63 		sec->name = "*UND*";
     64 	else
     65 		sec->name = shdr->name;
     66 
     67 	sec->index = n;
     68 	sec->size = shdr->size;
     69 	sec->base = shdr->addr;
     70 	sec->load = shdr->addr;
     71 	sec->offset = shdr->offset;
     72 	sec->type = stype;
     73 	sec->flags = sflags;
     74 	sec->align = shdr->addralign;
     75 
     76 	return sec;
     77 }