Skip to content

Commit

Permalink
Merge pull request #232 from dosemu2/rel2
Browse files Browse the repository at this point in the history
Rel2
  • Loading branch information
stsp authored Oct 29, 2023
2 parents bdd4293 + f574931 commit 01699a8
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 68 deletions.
5 changes: 3 additions & 2 deletions ci_prereq.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#!/bin/sh

sudo add-apt-repository ppa:stsp-0/nasm-segelf
sudo apt update -q
sudo apt install -y \
bison \
flex \
sed \
bash \
clang \
nasm \
lld \
nasm-segelf \
binutils \
pkgconf \
autoconf \
libelf-dev \
Expand Down
4 changes: 2 additions & 2 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Build-Depends:
sed,
bash,
clang,
nasm,
lld (>= 13~),
nasm-segelf,
binutils,
coreutils,
libelf-dev,
autoconf,
Expand Down
6 changes: 3 additions & 3 deletions fdpp/clang.mak
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# CLANG.MAK - kernel copiler options for clang
#

LD ?= ld
LLD ?= $(shell which ld.lld 2>/dev/null)
CCACHE ?= $(shell which ccache 2>/dev/null)
CC = $(CCACHE) clang++
Expand All @@ -23,12 +24,11 @@ endif
CC_FOR_BUILD = $(CCACHE) clang
CPP = $(CC_FOR_BUILD) -E
CC_LD = $(CL)
ifneq ($(LLD),)
ifeq ($(LD),)
# ld.lld can cross-compile while gnu ld not
CROSS_LD ?= $(LLD)
else
$(warning lld not installed)
CROSS_LD ?= ld
CROSS_LD ?= $(LD)
endif
NASM ?= nasm
PKG_CONFIG ?= pkg-config
Expand Down
121 changes: 96 additions & 25 deletions fdpp/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,99 @@ struct elfstate {
uint32_t load_offs;
};

static void elf_dl(char *addr, uint16_t seg)
static int do_getsym(struct elfstate *state, const char *name, GElf_Sym *r_sym)
{
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->symtab_scn, NULL);
count = state->symtab_shdr.sh_size / state->symtab_shdr.sh_entsize;

for (i = 0; i < count; i++) {
GElf_Sym sym;
gelf_getsym(data, i, &sym);
if (strcmp(elf_strptr(state->elf, state->symtab_shdr.sh_link,
sym.st_name), name) == 0) {
*r_sym = sym;
return 0;
}
}

return -1;
}

static void do_elf_dl(struct elfstate *state, uint16_t seg, Elf_Scn *rel_scn,
GElf_Shdr *rel_shdr)
{
Elf_Data *rel_data;
Elf_Data *st_data;
int rel_count, st_count, i;

rel_data = elf_getdata(rel_scn, NULL);
rel_count = rel_shdr->sh_size / rel_shdr->sh_entsize;
st_data = elf_getdata(state->symtab_scn, NULL);
st_count = state->symtab_shdr.sh_size / state->symtab_shdr.sh_entsize;

for (i = 0; i < rel_count; i++) {
uint16_t *val;
GElf_Rel rel;
GElf_Sym sym;
char *name, *name2, *p;
int rc;

gelf_getrel(rel_data, i, &rel);
/* look for R_386_SEG16 */
if (GELF_R_TYPE(rel.r_info) != R_386_16)
continue;
if (GELF_R_SYM(rel.r_info) >= st_count) {
fprintf(stderr, "bad reloc %lx %i %li off=%lx\n",
GELF_R_TYPE(rel.r_info), st_count,
GELF_R_SYM(rel.r_info), rel.r_offset);
return;
}
gelf_getsym(st_data, GELF_R_SYM(rel.r_info), &sym);
#ifndef STT_RELC
#define STT_RELC 8
#endif
if (GELF_ST_TYPE(sym.st_info) != STT_RELC)
continue;

name = elf_strptr(state->elf, state->symtab_shdr.sh_link, sym.st_name);
/* make sure its a SEG16 reloc symbol */
if (strncmp(name, ">>:", 3) != 0 || !strstr(name, "04"))
continue;
p = strstr(name, ":s");
if (!p)
continue;
p = strchr(p + 1, ':');
if (!p)
continue;
name2 = strdup(p + 1);
p = strchr(name2, ':');
if (p)
*p = '\0';
rc = do_getsym(state, name2, &sym);
free(name2);
if (rc)
continue;

/* not relocating against abs symbol */
if (sym.st_shndx == SHN_ABS)
continue;
val = (uint16_t *)(state->addr + state->load_offs + rel.r_offset);
*val += seg;
}
}

static void elf_dl(struct elfstate *state, uint16_t seg)
{
Elf_Scn *rel_scn = NULL;
while ((rel_scn = elf_nextscn(state->elf, rel_scn)) != NULL) {
GElf_Shdr rel_shdr;
gelf_getshdr(rel_scn, &rel_shdr);
if (rel_shdr.sh_type == SHT_REL)
do_elf_dl(state, seg, rel_scn, &rel_shdr);
}
}

void *elf_open(const char *name)
Expand Down Expand Up @@ -130,7 +213,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 All @@ -144,21 +227,9 @@ void elf_close(void *arg)

static int do_getsymoff(struct elfstate *state, const char *name)
{
Elf_Data *data;
int count, i;

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

for (i = 0; i < count; i++) {
GElf_Sym sym;
gelf_getsym(data, i, &sym);
if (strcmp(elf_strptr(state->elf, state->symtab_shdr.sh_link,
sym.st_name), name) == 0)
return sym.st_value;
}

return -1;
GElf_Sym sym;
int err = do_getsym(state, name, &sym);
return (err ? -1 : sym.st_value);
}

void *elf_getsym(void *arg, const char *name)
Expand Down
27 changes: 17 additions & 10 deletions fdpp/kernel.ld
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
/* linker script for fdpp project */

/* 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;

SECTIONS
{
_LOADADDR = DEFINED(loadaddr) ? loadaddr : .;
/* these GROUPs play the same role as GROUPS (segments) in OMF */
/* TINY model, all segments are equal */
_LGROUP = ABSOLUTE(.);
_DGROUP = ABSOLUTE(.);
_IGROUP = ABSOLUTE(.);
_LGROUP~ = . + _LOADADDR;
_DGROUP~ = . + _LOADADDR;
_IGROUP~ = . + _LOADADDR;

. = SIZEOF_HEADERS;
. = ALIGN(0x100);
/* Target PSP section. */
.ptext SIZEOF_HEADERS : {
.ptext : {
_PGROUP = ABSOLUTE(.);
_PGROUP~ = . + _LOADADDR;
*(PSP)
. = ALIGN(0x100);
}

/* Target low data+text sections. */
.ltext 0x200 : {
.ltext : {
*(_IRQTEXT)
*(_LOWTEXT)
*(_IO_TEXT)
Expand Down
25 changes: 12 additions & 13 deletions fdpp/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@ ALL = $(FDPPLIB) $(FDPPDEVL) $(TARGET).elf $(TARGET).map $(GEN_EXT)

all: $(ALL)

elf.o: rel.h
want_loadaddr = 0
ifeq ($(want_loadaddr),1)
LA = --defsym=loadaddr=0xfa100
else
LA = --emit-relocs
endif
want_pie = 0
ifeq ($(want_pie),1)
PF = -pie
endif

# 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
Expand All @@ -74,19 +83,9 @@ else
%.elf %.map : $(DEPS_OF_ELF)
endif
$(CROSS_LD) -melf_i386 -static -Map=$(TARGET).map -o $@ \
$(^:%.ld=-T%.ld) --defsym=DOS_PSP=0x60
$(LA) $(PF) $(^:%.ld=-T%.ld)
chmod -x $@

$(TARGET).elf.tmp: $(srcdir)/kernel.ld $(OBJS) $(PPOBJS) $(DOBJS)
$(CROSS_LD) -melf_i386 -static -o $@ \
$(^:%.ld=-T%.ld) --defsym=DOS_PSP=0
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 +116,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
9 changes: 5 additions & 4 deletions fdpp/thunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ const char *FdppKernelMapName(void)
struct krnl_hndl {
void *elf;
const void *start;
unsigned load_off;
};

void *FdppKernelLoad(const char *dname, int *len, struct fdpp_bss_list **bss,
Expand All @@ -663,7 +664,7 @@ void *FdppKernelLoad(const char *dname, int *len, struct fdpp_bss_list **bss,
return NULL;
}
free(kname);
start = elf_getloadaddr(handle);
start = elf_getsym(handle, "_start");
s = elf_getsymoff(handle, "_start");
if (s == -1)
goto err_close;
Expand Down Expand Up @@ -704,6 +705,7 @@ void *FdppKernelLoad(const char *dname, int *len, struct fdpp_bss_list **bss,
h = (struct krnl_hndl *)malloc(sizeof(*h));
h->elf = handle;
h->start = start;
h->load_off = s;
return h;

err_close:
Expand All @@ -716,10 +718,9 @@ const void *FdppKernelReloc(void *handle, uint16_t seg, uint16_t *r_seg)
int i;
far_s f;
struct krnl_hndl *h = (struct krnl_hndl *)handle;
unsigned load_off = elf_getloadoff(h->elf);

assert(!(load_off & 0xf));
seg -= load_off >> 4;
assert(!(h->load_off & 0xf));
seg -= h->load_off >> 4;
elf_reloc(h->elf, seg);

farhlp_init(&sym_tab);
Expand Down
1 change: 1 addition & 0 deletions kernel/glob_asm.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* grep "ASM " globals.h | grep "extern" | grep ";" | sed 's/extern \(.\+\) ASM \(.\+\);/__ASM(\1, \2) SEMIC/' */

__ASM(UWORD, DOS_PSP) SEMIC
__ASM(UWORD, NetBios) SEMIC
__ASM(BYTE *, net_name) SEMIC
__ASM(BYTE, net_set_count) SEMIC
Expand Down
2 changes: 2 additions & 0 deletions kernel/kernel.asm
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,8 @@ begin_hma:
; to minimize relocations
global _DGROUP_
_DGROUP_ dw DGROUP
global _DOS_PSP
_DOS_PSP dw PGROUP

%ifdef WATCOM
; 32 bit multiplication + division
Expand Down
3 changes: 0 additions & 3 deletions kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ __segment DosTextSeg = 0;

#endif

UWORD DOS_PSP;

ASMREF(struct lol) LoL = __ASMADDR(DATASTART);
struct _bprm bprm;
#define TEXT_SIZE (_InitTextEnd - _HMATextStart)
Expand All @@ -91,7 +89,6 @@ VOID ASMCFUNC FreeDOSmain(void)
DosDataSeg = (__segment) & DATASTART;
DosTextSeg = (__segment) & prn_dev;
#endif
DOS_PSP = _CS;
/* back up kernel code to the top of ram */
lpTop = MK_FP(_SS - (TEXT_SIZE + 15) / 16, 0);
fmemcpy(lpTop, _HMATextStart, TEXT_SIZE);
Expand Down
14 changes: 8 additions & 6 deletions kernel/segs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ 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 _PGROUP~
extern _DGROUP~
extern _LGROUP~
extern _IGROUP~
%define PGROUP seg _PGROUP~
%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 01699a8

Please sign in to comment.