shithub: scc

Download patch

ref: 129b80feb976b22ba4eacaed59bd1c1f54804e1a
parent: 893983575da0f76075ffd8f3d60cb23d6c3475e6
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Oct 30 07:21:08 EDT 2021

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.

--- a/src/libmach/deps.mk
+++ b/src/libmach/deps.mk
@@ -56,6 +56,9 @@
 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
--- a/src/libmach/elf64/elf64.c
+++ b/src/libmach/elf64/elf64.c
@@ -15,8 +15,7 @@
 	.strip = NULL,
 	.del = elf64del,
 	.write = NULL,
-	.getsym = NULL,
-	.getsec = NULL,
+	.getsec = elf64getsec,
 	.loadmap = NULL,
 };
 
--- /dev/null
+++ b/src/libmach/elf64/elf64getsec.c
@@ -1,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;
+}
--- a/src/libmach/elf64/rules.mk
+++ b/src/libmach/elf64/rules.mk
@@ -3,4 +3,5 @@
 	elf64/elf64new.o\
 	elf64/elf64probe.o\
 	elf64/elf64read.o\
+	elf64/elf64getsec.o\
 	elf64/elf64del.o\