scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

 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
11Section *
12elfgetsec(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}