Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plt #231

Merged
merged 3 commits into from
Oct 9, 2023
Merged

Plt #231

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fdpp/clang.mak
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ PKG_CONFIG ?= pkg-config

TARGETOPT = -std=c++11 -c -fno-threadsafe-statics -fpic
# _XTRA should go at the end of cmd line
TARGETOPT_XTRA = -Wno-format-invalid-specifier
TARGETOPT_XTRA = -Wno-format-invalid-specifier -Wno-c99-designator

DEBUG_MODE ?= 1
EXTRA_DEBUG ?= 0
Expand Down
22 changes: 18 additions & 4 deletions fdpp/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ void elf_close(void *arg)
free(state);
}

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

Expand All @@ -156,8 +155,23 @@ void *elf_getsym(void *arg, const char *name)
gelf_getsym(data, i, &sym);
if (strcmp(elf_strptr(state->elf, state->symtab_shdr.sh_link,
sym.st_name), name) == 0)
return state->addr + state->load_offs + sym.st_value;
return sym.st_value;
}

return NULL;
return -1;
}

void *elf_getsym(void *arg, const char *name)
{
struct elfstate *state = (struct elfstate *)arg;
int off = do_getsymoff(state, name);
if (off == -1)
return NULL;
return state->addr + state->load_offs + off;
}

int elf_getsymoff(void *arg, const char *name)
{
struct elfstate *state = (struct elfstate *)arg;
return do_getsymoff(state, name);
}
1 change: 1 addition & 0 deletions fdpp/elf_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ void *elf_open(const char *name);
void elf_reloc(void *arg, uint16_t seg);
void elf_close(void *arg);
void *elf_getsym(void *arg, const char *name);
int elf_getsymoff(void *arg, const char *name);
8 changes: 4 additions & 4 deletions fdpp/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ GEN_HEADERS = thunk_calls.h thunk_asms.h rel.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
GEN_TMP = thunk_calls.tmp thunk_asms.tmp plt.inc plt_asmc.inc plt_asmp.inc
GEN_TMP = thunk_calls.tmp thunk_asms.tmp plt.inc plt_asmc.h plt_asmp.h
GEN_CC = $(CFILES:.c=.cc)
INITHEADERS = $(SRC)/init-mod.h $(SRC)/init-dat.h
HEADERS=$(HDRS) $(SRC)/globals.h $(SRC)/proto.h $(INITHEADERS) $(PPHDRS)
Expand Down Expand Up @@ -179,7 +179,7 @@ $(FDPP_COBJS): %.o: $(srcdir)/%.c $(PPHDRS) $(srcdir)/makefile
$(CC) $(CLCFLAGS) -I . -o $@ $<

thunks.o: $(EXT_H) $(GIT_REV)
thunks_a.o: $(SRC)/glob_asm.h $(srcdir)/glob_tmpl.h
thunks_a.o: $(SRC)/glob_asm.h $(srcdir)/glob_tmpl.h plt_asmc.h plt_asmp.h
$(FDPP_CCOBJS): %.o: $(srcdir)/%.cc $(GEN_HEADERS) $(PPHDRS) $(srcdir)/makefile
$(CC) $(CFLAGS) -o $@ $<

Expand All @@ -205,7 +205,7 @@ $(FDPPLIB): $(OBJECTS) $(FDPP_COBJS) $(FDPP_CCOBJS) $(FDPP_CPPOBJS)
$(FDPPDEVL): $(FDPPLIB)
ln -sf $< $@

plt.o: plt.asm plt.inc plt_asmc.inc plt_asmp.inc $(SRC)/segs.inc
plt.o: plt.asm plt.inc $(SRC)/segs.inc

plt.asm: $(srcdir)/plt.S $(SRC)/glob_asm.h $(TOP)/include/fdpp/bprm.h \
$(srcdir)/thunks_priv.h $(srcdir)/makefile
Expand All @@ -224,7 +224,7 @@ $(filter %.tmp,$(GEN_TMP)): $(SRC)/proto.h
$(pars)
plt.inc: thunk_calls.tmp
$(pars)
plt_asmc.inc plt_asmp.inc: thunk_asms.tmp
plt_asmc.h plt_asmp.h: thunk_asms.tmp
$(pars)

thunk_calls.h: thunk_calls.tmp parsers/thunk_gen
Expand Down
4 changes: 2 additions & 2 deletions fdpp/parsers/parse_decls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ gen_asms_tmp() {

gen_plt_asmc() {
grep ASMFUNC $1 | \
sed -E 's/([0-9]+)[[:blank:]]+([^[:blank:]\(]+[[:blank:]]+)+([^ \(]+) *\(.+/asmcsym \3, \1/'
sed -E 's/([0-9]+)[[:blank:]]+([^[:blank:]\(]+[[:blank:]]+)+([^ \(]+) *\(.+/ASMCSYM\(\3, \1\)/'
}

gen_plt_asmp() {
grep ASMPASCAL $1 | tr '[:lower:]' '[:upper:]' | \
sed -E 's/([0-9]+)[[:blank:]]+([^[:blank:]\(]+[[:blank:]]+)+([^ \(]+) *\(.+/asmpsym \3, \1/'
sed -E 's/([0-9]+)[[:blank:]]+([^[:blank:]\(]+[[:blank:]]+)+([^ \(]+) *\(.+/ASMPSYM\(\3, \1\)/'
}

case "$1" in
Expand Down
69 changes: 1 addition & 68 deletions fdpp/plt.S
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* FDPP - freedos port to modern C++
* Copyright (C) 2018 Stas Sergeev (stsp)
* Copyright (C) 2018-2023 Stas Sergeev (stsp)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -20,8 +20,6 @@
#include "bprm.h"
%include "segs.inc"

%define _SEG(s) TGROUP

extern _BootParamSeg

segment _BSS
Expand Down Expand Up @@ -60,23 +58,6 @@ segment %3

%include "plt.inc"

%macro asmcsym 2
dw %2
extern _%1
dw _%1, _SEG(_%1)
%endmacro

%macro asmpsym 2
dw %2
extern %1
dw %1, _SEG(%1)
%endmacro

%macro asmsym 1
extern _%1
dw _%1, _SEG(_%1)
%endmacro

%macro nearwrp 0
push bp
mov bp, sp
Expand Down Expand Up @@ -116,25 +97,6 @@ segment %3
retf 2
%endmacro

segment INIT_TEXT

__asm_callsymtab_start:
%include "plt_asmc.inc"
%include "plt_asmp.inc"
__asm_callsymtab_end:

#define __ASM(t, n) asmsym n
#define __ASM_FAR(t, n) asmsym n
#define __ASM_NEAR(t, n) asmsym n
#define __ASM_ARR(t, n, l) asmsym n
#define __ASM_ARRI(t, n) asmsym n
#define __ASM_ARRI_F(t, n) asmsym n
#define __ASM_FUNC(n) asmsym n
#define SEMIC
__asm_symtab_start:
#include <glob_asm.h>
__asm_symtab_end:

segment HMA_TEXT

near_wrp:
Expand All @@ -147,40 +109,11 @@ init_near_wrp:

global plt_init
plt_init:
push bp
mov bp, sp

; copy plt entry
mov ax, FDPP_BS_SEG
mov es, ax
mov ax, [es:FDPP_BS_OFF+FDPP_PLT_OFFSET]
mov bx, [es:FDPP_BS_OFF+FDPP_PLT_OFFSET+2]
mov [fdpp_plt], ax
mov [fdpp_plt + 2], bx

mov al, 0 ; reserved
mov ah, FDPP_KERNEL_VERSION
mov bx, 0 ; reserved
; fill in struct fdpp_symtab
push word IGROUP
push word init_near_wrp ; near_wrp[1]
push word TGROUP
push word near_wrp ; near_wrp[0]
push word __asm_callsymtab_end - __asm_callsymtab_start ; calltab_len
push word IGROUP
push word __asm_callsymtab_start ; calltab
push word __asm_symtab_end - __asm_symtab_start ; symtab_len
push word IGROUP
push word __asm_symtab_start ; symtab
; fdpp_symtab filled
mov si, sp

push ds
mov di, DGROUP
mov ds, di
call far [es:FDPP_BS_OFF+FDPP_PLT_OFFSET+4]
pop ds

mov sp, bp
pop bp
ret
128 changes: 41 additions & 87 deletions fdpp/thunks.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* FDPP - freedos port to modern C++
* Copyright (C) 2018 Stas Sergeev (stsp)
* Copyright (C) 2018-2023 Stas Sergeev (stsp)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -36,15 +36,14 @@
static struct fdpp_api *fdpp;

struct asm_dsc_s {
UWORD num;
UWORD off;
UWORD seg;
};
struct asm_dsc_s *asm_tab;
static int asm_tab_len;
#define asm_tab_len num_cthunks
static farhlp sym_tab;
static struct far_s *near_wrp;
#define num_wrps 2
static struct far_s near_wrp[num_wrps];
static int recur_cnt;

enum { ASM_OK, ASM_NORET, ASM_ABORT, PING_ABORT };
Expand Down Expand Up @@ -132,35 +131,6 @@ int is_dos_space(const void *ptr)
return fdpp->is_dos_space(ptr);
}

static int FdppSetAsmThunks(struct far_s *ptrs, int len)
{
int i;
int exp = num_athunks;

if (len != exp) {
fdprintf("len=%i expected %i\n", len, exp);
return -1;
}

farhlp_init(&sym_tab);
for (i = 0; i < len; i++) {
*asm_thunks[i].ptr = ptrs[i];
/* there are conflicts, for example InitTextStart will collide
* with the first sym. So use _replace. */
store_far_replace(&sym_tab, resolve_segoff(ptrs[i]), ptrs[i]);
}

return 0;
}

struct fdpp_symtab {
struct far_s symtab;
uint16_t symtab_len;
struct far_s calltab;
uint16_t calltab_len;
struct far_s near_wrp[2];
};

static void do_relocs(UWORD old_seg, uint8_t *start_p, uint8_t *end_p,
uint16_t delta)
{
Expand Down Expand Up @@ -200,37 +170,9 @@ static void do_relocs(UWORD old_seg, uint8_t *start_p, uint8_t *end_p,
fdlogprintf("processed %i relocs\n", reloc);
}

static void FdppSetSymTab(struct fdpp_symtab *symtab)
{
int err;
struct far_s *thtab = (struct far_s *)resolve_segoff(symtab->symtab);
int stab_len = symtab->symtab_len / sizeof(struct far_s);

free(near_wrp);
near_wrp = (struct far_s *)malloc(sizeof(struct far_s) * num_wrps);
memcpy(near_wrp, symtab->near_wrp, sizeof(struct far_s) * num_wrps);
free(asm_tab);
asm_tab = (struct asm_dsc_s *)malloc(symtab->calltab_len);
memcpy(asm_tab, resolve_segoff(symtab->calltab), symtab->calltab_len);
asm_tab_len = symtab->calltab_len / sizeof(struct asm_dsc_s);
err = FdppSetAsmThunks(thtab, stab_len);
___assert(!err);
}

int FdppCtrl(int idx, struct vm86_regs *regs)
{
#define DL_SET_SYMTAB 0
switch (idx) {
case DL_SET_SYMTAB:
if (HI_BYTE(regs->eax) != FDPP_KERNEL_VERSION) {
fdloudprintf("\nfdpp version mismatch: expected %i, got %i\n",
FDPP_KERNEL_VERSION, HI_BYTE(regs->eax));
_fail();
}
FdppSetSymTab(
(struct fdpp_symtab *)so2lin(regs->ss, LO_WORD(regs->esi)));
return 0;
}
// so empty then???
return -1;
}

Expand Down Expand Up @@ -354,16 +296,8 @@ static void _call_wrp(FdppAsmCall_t call, struct vm86_regs *regs,
static uint32_t _do_asm_call_far(int num, uint8_t *sp, uint8_t len,
FdppAsmCall_t call)
{
int i;

for (i = 0; i < asm_tab_len; i++) {
if (asm_tab[i].num == num) {
_call_wrp(call, &s_regs, asm_tab[i].seg, asm_tab[i].off, sp, len);
return (LO_WORD(s_regs.edx) << 16) | LO_WORD(s_regs.eax);
}
}
___assert(0);
return -1;
_call_wrp(call, &s_regs, asm_tab[num].seg, asm_tab[num].off, sp, len);
return (LO_WORD(s_regs.edx) << 16) | LO_WORD(s_regs.eax);
}

static uint16_t find_wrp(int init, uint16_t seg)
Expand All @@ -375,21 +309,13 @@ static uint16_t find_wrp(int init, uint16_t seg)
static uint32_t _do_asm_call(int num, int init, uint8_t *sp, uint8_t len,
FdppAsmCall_t call)
{
int i;

for (i = 0; i < asm_tab_len; i++) {
if (asm_tab[i].num == num) {
uint16_t wrp = find_wrp(init, asm_tab[i].seg);
LO_WORD(s_regs.eax) = asm_tab[i].off;
/* argpack should be aligned */
___assert(!(len & 1));
LO_WORD(s_regs.ecx) = len >> 1;
_call_wrp(call, &s_regs, asm_tab[i].seg, wrp, sp, len);
return (LO_WORD(s_regs.edx) << 16) | LO_WORD(s_regs.eax);
}
}
___assert(0);
return -1;
uint16_t wrp = find_wrp(init, asm_tab[num].seg);
LO_WORD(s_regs.eax) = asm_tab[num].off;
/* argpack should be aligned */
___assert(!(len & 1));
LO_WORD(s_regs.ecx) = len >> 1;
_call_wrp(call, &s_regs, asm_tab[num].seg, wrp, sp, len);
return (LO_WORD(s_regs.edx) << 16) | LO_WORD(s_regs.eax);
}

static void asm_call(struct vm86_regs *regs, uint16_t seg,
Expand Down Expand Up @@ -784,8 +710,36 @@ void *FdppKernelLoad(const char *dname, int *len, struct fdpp_bss_list **bss)

const void *FdppKernelReloc(void *handle, uint16_t seg)
{
int i;
far_s f;
struct krnl_hndl *h = (struct krnl_hndl *)handle;
elf_reloc(h->elf, seg);

farhlp_init(&sym_tab);
f.seg = seg;
for (i = 0; i < num_athunks; i++) {
int off = elf_getsymoff(h->elf, asm_thunks[i].name);
assert(off != -1);
f.off = off;
*asm_thunks[i].ptr = f;
store_far_replace(&sym_tab, resolve_segoff(f), f);
}

asm_tab = (struct asm_dsc_s *)malloc(num_cthunks *
sizeof(struct asm_dsc_s *));
for (i = 0; i < num_cthunks; i++) {
int off = elf_getsymoff(h->elf, asm_cthunks[i].name);
assert(off != -1);
assert(asm_cthunks[i].name);
asm_tab[i].seg = seg;
asm_tab[i].off = off;
}

f.off = elf_getsymoff(h->elf, "near_wrp");
near_wrp[0] = f;
f.off = elf_getsymoff(h->elf, "init_near_wrp");
near_wrp[1] = f;

return h->start;
}

Expand Down
Loading
Loading