diff --git a/fdpp/clang.mak b/fdpp/clang.mak index ee9801cc..71692554 100644 --- a/fdpp/clang.mak +++ b/fdpp/clang.mak @@ -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 diff --git a/fdpp/elf.c b/fdpp/elf.c index 0c0489dc..1ed04a7a 100644 --- a/fdpp/elf.c +++ b/fdpp/elf.c @@ -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; @@ -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); } diff --git a/fdpp/elf_priv.h b/fdpp/elf_priv.h index 9931c673..4ceb2129 100644 --- a/fdpp/elf_priv.h +++ b/fdpp/elf_priv.h @@ -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); diff --git a/fdpp/makefile b/fdpp/makefile index 5b5a6e50..47117746 100644 --- a/fdpp/makefile +++ b/fdpp/makefile @@ -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) @@ -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 $@ $< @@ -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 @@ -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 diff --git a/fdpp/parsers/parse_decls.sh b/fdpp/parsers/parse_decls.sh index d22f43f2..55d9050d 100755 --- a/fdpp/parsers/parse_decls.sh +++ b/fdpp/parsers/parse_decls.sh @@ -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 diff --git a/fdpp/plt.S b/fdpp/plt.S index 743eafe9..660ac928 100644 --- a/fdpp/plt.S +++ b/fdpp/plt.S @@ -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 @@ -20,8 +20,6 @@ #include "bprm.h" %include "segs.inc" -%define _SEG(s) TGROUP - extern _BootParamSeg segment _BSS @@ -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 @@ -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 -__asm_symtab_end: - segment HMA_TEXT near_wrp: @@ -147,9 +109,6 @@ init_near_wrp: global plt_init plt_init: - push bp - mov bp, sp - ; copy plt entry mov ax, FDPP_BS_SEG mov es, ax @@ -157,30 +116,4 @@ plt_init: 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 diff --git a/fdpp/thunks.cc b/fdpp/thunks.cc index 7f2b6c9e..e1da9218 100644 --- a/fdpp/thunks.cc +++ b/fdpp/thunks.cc @@ -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 @@ -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 }; @@ -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) { @@ -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; } @@ -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) @@ -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, @@ -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; } diff --git a/fdpp/thunks_a.cc b/fdpp/thunks_a.cc index cdf1e367..2511287d 100644 --- a/fdpp/thunks_a.cc +++ b/fdpp/thunks_a.cc @@ -25,16 +25,19 @@ #include "glob_tmpl.h" #undef _E +#define __S(x) #x +#define _S(x) __S(x) + struct athunk asm_thunks[] = { -#define _A(v) { __ASMREF(v), 0 } +#define _A(v, w) { _S(v), __ASMREF(w), 0 } #define SEMIC , -#define __ASM(t, v) _A(__##v) -#define __ASM_FAR(t, v) _A(__##v) -#define __ASM_NEAR(t, v) { __ASMREF(__##v), THUNKF_SHORT | THUNKF_DEEP } -#define __ASM_ARR(t, v, l) _A(__##v) -#define __ASM_ARRI(t, v) _A(__##v) -#define __ASM_ARRI_F(t, v) _A(__##v) -#define __ASM_FUNC(v) _A(__##v) +#define __ASM(t, v) _A(_##v, __##v) +#define __ASM_FAR(t, v) _A(_##v, __##v) +#define __ASM_NEAR(t, v) { _S(_##v), __ASMREF(__##v), THUNKF_SHORT | THUNKF_DEEP } +#define __ASM_ARR(t, v, l) _A(_##v, __##v) +#define __ASM_ARRI(t, v) _A(_##v, __##v) +#define __ASM_ARRI_F(t, v) _A(_##v, __##v) +#define __ASM_FUNC(v) _A(_##v, __##v) #include #undef __ASM #undef __ASM_FAR @@ -47,3 +50,12 @@ struct athunk asm_thunks[] = { }; const int num_athunks = _countof(asm_thunks); + +struct athunk asm_cthunks[] = { +#define ASMCSYM(s, n) [n] = { _S(_##s), NULL, 0 }, +#include "plt_asmc.h" +#define ASMPSYM(s, n) [n] = { _S(s), NULL, 0 }, +#include "plt_asmp.h" +}; + +const int num_cthunks = _countof(asm_cthunks); diff --git a/fdpp/thunks_a.h b/fdpp/thunks_a.h index 94786bdb..3be9d620 100644 --- a/fdpp/thunks_a.h +++ b/fdpp/thunks_a.h @@ -1,4 +1,5 @@ struct athunk { + const char *name; struct far_s *ptr; #define THUNKF_SHORT 1 #define THUNKF_DEEP 2 @@ -7,3 +8,5 @@ struct athunk { extern struct athunk asm_thunks[]; extern const int num_athunks; +extern struct athunk asm_cthunks[]; +extern const int num_cthunks;