scc

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

commit 129b80feb976b22ba4eacaed59bd1c1f54804e1a
parent 893983575da0f76075ffd8f3d60cb23d6c3475e6
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 30 Oct 2021 11:21:08 +0200

libmach: Add elf64getsec()

This function can be used to run over the full list of sections
of a file and retrieve information for every one of them.

Diffstat:
Msrc/libmach/deps.mk | 3+++
Msrc/libmach/elf64/elf64.c | 3+--
Asrc/libmach/elf64/elf64getsec.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/elf64/rules.mk | 1+
4 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/src/libmach/deps.mk b/src/libmach/deps.mk @@ -56,6 +56,9 @@ elf64/elf64.o: elf64/elf64.h elf64/elf64del.o: $(INCDIR)/scc/scc/mach.h elf64/elf64del.o: elf64/../libmach.h elf64/elf64del.o: elf64/elf64.h +elf64/elf64getsec.o: $(INCDIR)/scc/scc/mach.h +elf64/elf64getsec.o: elf64/../libmach.h +elf64/elf64getsec.o: elf64/elf64.h elf64/elf64new.o: $(INCDIR)/scc/scc/mach.h elf64/elf64new.o: elf64/../libmach.h elf64/elf64new.o: elf64/elf64.h diff --git a/src/libmach/elf64/elf64.c b/src/libmach/elf64/elf64.c @@ -15,8 +15,7 @@ struct objops elf64 = { .strip = NULL, .del = elf64del, .write = NULL, - .getsym = NULL, - .getsec = NULL, + .getsec = elf64getsec, .loadmap = NULL, }; diff --git a/src/libmach/elf64/elf64getsec.c b/src/libmach/elf64/elf64getsec.c @@ -0,0 +1,59 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "elf64.h" + +Section * +elf64getsec(Obj *obj, int *idx, Section *sec) +{ + int stype, n = *idx; + unsigned long flags, type; + unsigned sflags; + Elf64 *elf = obj->data; + Elf_Ehdr *hdr = &elf->hdr; + Elf_Shdr *shdr; + + if (n >= elf->nsec) + return NULL; + + shdr = &elf->shdr[n]; + flags = shdr->sh_flags; + type = shdr->sh_type; + + if (flags & SHF_ALLOC) { + if (type == SHT_NOBITS) + stype = 'B'; + else if (flags & SHF_WRITE) + stype = 'D'; + else + stype = 'T'; + } else { + stype = 'N'; + } + + sflags = 0; + if (flags & SHF_WRITE) + sflags |= SWRITE; + if (flags & SHF_EXECINSTR) + sflags |= SEXEC; + if (flags & SHF_ALLOC) + sflags |= SALLOC|SREAD; + if (type != SHT_NOBITS) + sflags |= SLOAD; + if (flags & SHF_MERGE) + sflags |= SSHARED; /* TODO: Check SSHARED in coff */ + if (stype == 'T' || stype == 'D') + sflags |= SRELOC; /* TODO: Check SRELOC in coff */ + + sec->name = elf64str(obj, SEC_STRTBL, shdr->sh_name); + sec->index = n; + sec->size = shdr->sh_size; + sec->base = shdr->sh_addr; + sec->type = stype; + sec->flags = sflags; + sec->align = shdr->sh_addralign; + + return sec; +} diff --git a/src/libmach/elf64/rules.mk b/src/libmach/elf64/rules.mk @@ -3,4 +3,5 @@ ELF64_OBJS =\ elf64/elf64new.o\ elf64/elf64probe.o\ elf64/elf64read.o\ + elf64/elf64getsec.o\ elf64/elf64del.o\