scc

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

elf64getsec.c (1462B)


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