scc

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

elf64getsec.c (1603B)


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