Skip to content

Commit

Permalink
elf: switch to HPA segelf scheme [closes #172][skip CI]
Browse files Browse the repository at this point in the history
  • Loading branch information
stsp committed Oct 12, 2023
1 parent 95432f8 commit b0fb241
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 38 deletions.
4 changes: 2 additions & 2 deletions fdpp/clang.mak
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# CLANG.MAK - kernel copiler options for clang
#

LLD ?= $(shell which ld.lld 2>/dev/null)
LLD ?= ~/src/binutils-segelf/ld/ld-new
CCACHE ?= $(shell which ccache 2>/dev/null)
CC = $(CCACHE) clang++
CLANG_VER := $(shell $(CC) -v 2>&1 | head -n 1 | \
Expand All @@ -26,7 +26,7 @@ else
$(warning lld not installed)
CROSS_LD ?= ld
endif
NASM ?= nasm
NASM ?= ~/src/nasm/nasm
PKG_CONFIG ?= pkg-config

TARGETOPT = -std=c++11 -c -fno-threadsafe-statics -fpic
Expand Down
47 changes: 37 additions & 10 deletions fdpp/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,41 @@ struct elfstate {
Elf *elf;
Elf_Scn *symtab_scn;
GElf_Shdr symtab_shdr;
Elf_Scn *rel_scn;
GElf_Shdr rel_shdr;
uint32_t load_offs;
};

static void elf_dl(char *addr, uint16_t seg)
static void elf_dl(struct elfstate *state, uint16_t seg)
{
const int reloc_tab[] = {
#include "rel.h"
};
size_t i;
#define _countof(array) (sizeof(array) / sizeof(array[0]))

for (i = 0; i < _countof(reloc_tab); i++)
memcpy(&addr[reloc_tab[i]-1], &seg, sizeof(seg));
Elf_Data *data;
int count, i;

data = elf_getdata(state->rel_scn, NULL);
count = state->rel_shdr.sh_size / state->rel_shdr.sh_entsize;

for (i = 0; i < count; i++) {
uint16_t *val;
GElf_Rel rel;
gelf_getrel(data, i, &rel);
if (ELF32_R_TYPE(rel.r_info) != 48 || ELF32_R_SYM(rel.r_info) != 0) {
fprintf(stderr, "unsupported reloc %lx %li off=%lx\n",
ELF32_R_TYPE(rel.r_info),
ELF32_R_SYM(rel.r_info), rel.r_offset);
return;
}
val = (uint16_t *)(state->addr + state->load_offs + rel.r_offset);
*val += seg;
}
}

void *elf_open(const char *name)
{
Elf *elf;
Elf_Scn *scn = NULL;
GElf_Shdr shdr;
Elf_Scn *rel_scn = NULL;
GElf_Shdr rel_shdr;
GElf_Phdr phdr;
int fd;
int i;
Expand Down Expand Up @@ -110,12 +125,24 @@ void *elf_open(const char *name)
goto err;
}

while ((rel_scn = elf_nextscn(elf, rel_scn)) != NULL) {
gelf_getshdr(rel_scn, &rel_shdr);
if (rel_shdr.sh_type == SHT_REL)
break;
}
if (!rel_scn) {
fprintf(stderr, "elf: not found SHT_REL\n");
goto err;
}

ret = (struct elfstate *)malloc(sizeof(*ret));
ret->addr = addr;
ret->mapsize = mapsize;
ret->elf = elf;
ret->symtab_scn = scn;
ret->symtab_shdr = shdr;
ret->rel_scn = rel_scn;
ret->rel_shdr = rel_shdr;
ret->load_offs = load_offs;
return ret;

Expand All @@ -130,7 +157,7 @@ void elf_reloc(void *arg, uint16_t seg)
{
struct elfstate *state = (struct elfstate *)arg;

elf_dl(state->addr, seg);
elf_dl(state, seg);
}

void elf_close(void *arg)
Expand Down
8 changes: 3 additions & 5 deletions fdpp/kernel.ld
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

/* these GROUPs play the same role as GROUPS (segments) in OMF */
/* TINY model, all segments are equal */
PGROUP = DOS_PSP;
LGROUP = DOS_PSP;
DGROUP = DOS_PSP;
TGROUP = DOS_PSP;
IGROUP = DOS_PSP;
_LGROUP = 0;
_DGROUP = 0;
_IGROUP = 0;

SECTIONS
{
Expand Down
18 changes: 3 additions & 15 deletions fdpp/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ ALL = $(FDPPLIB) $(FDPPDEVL) $(TARGET).elf $(TARGET).map $(GEN_EXT)

all: $(ALL)

elf.o: rel.h

# New makes have a way to avoid parallel invocation with the use of &:
# On old make you would write "%.elf %.map :" which is a bit silly
# given the names are fixed. Also $(TARGET).% won't work that way at all:
Expand All @@ -73,20 +71,10 @@ $(TARGET).elf $(TARGET).map &: $(DEPS_OF_ELF)
else
%.elf %.map : $(DEPS_OF_ELF)
endif
$(CROSS_LD) -melf_i386 -static -Map=$(TARGET).map -o $@ \
$(^:%.ld=-T%.ld) --defsym=DOS_PSP=0x60
chmod -x $@

$(TARGET).elf.tmp: $(srcdir)/kernel.ld $(OBJS) $(PPOBJS) $(DOBJS)
$(CROSS_LD) -melf_i386 -static -o $@ \
$(^:%.ld=-T%.ld) --defsym=DOS_PSP=0
$(CROSS_LD) -melf_i386 -static -pie -Map=$(TARGET).map -o $@ \
$(^:%.ld=-T%.ld)
chmod -x $@

rel.h: $(TARGET).elf $(TARGET).elf.tmp
cmp -l $^ | grep "140 0" | sed 's/^ *//' | cut -d " " -f 1 | \
sed 's/$$/,/' > $@


clean:
+cd parsers && $(MAKE) srcdir=$(abspath $(srcdir))/parsers clean
-$(RM) .tstamp *.map $(TARGET).elf *.inc \
Expand Down Expand Up @@ -117,7 +105,7 @@ PLPHDRS = farobj.hpp farptr.hpp dispatch.hpp ctors.hpp
_PPHDRS = $(PLPHDRS) dosobj.h farhlp.hpp thunks_priv.h smalloc.h \
farhlp_sta.h
PPHDRS = $(addprefix $(srcdir)/,$(_PPHDRS))
GEN_HEADERS = thunk_calls.h thunk_asms.h rel.h
GEN_HEADERS = thunk_calls.h thunk_asms.h
GEN_HEADERS_FD = glob_asmdefs.h
GEN_ASMS = plt.asm cdata.asm
# dont change file order in GEN_TMP as it matches the gen script
Expand Down
12 changes: 6 additions & 6 deletions kernel/segs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ group I_GROUP ID_B ID ID_E IC IDATA IB_B IB IB_E

BITS 16
; groups are defined in the linker script kernel.ld
extern PGROUP
extern DGROUP
extern LGROUP
extern TGROUP
extern IGROUP
extern I_GROUP
extern _DGROUP
extern _LGROUP
extern _IGROUP
%define DGROUP seg _DGROUP
%define LGROUP seg _LGROUP
%define IGROUP seg _IGROUP
%define class(x)
%define stack
%define INITSTACKSIZE 512
Expand Down

0 comments on commit b0fb241

Please sign in to comment.