VirtualBox

Changeset 102157 in vbox for trunk


Ignore:
Timestamp:
Nov 20, 2023 4:16:55 PM (15 months ago)
Author:
vboxsync
Message:

ValKit/bs3kit,bs3-cpu-basic-3: Experimental support for loading a 2nd test image above 1MB (at 8MB by default). This should allow for larger testcases, esp. for 32-bit and 64-bit code. bugref:10371

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
5 added
17 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/Config.kmk

    r102131 r102157  
    117117 $1_SOURCES += $$($1_0_OUTDIR)/stub$2.asm
    118118 $1_CLEAN  += $$($1_0_OUTDIR)/stub$2.asm
    119  $$$$($1_0_OUTDIR)/stub$2.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@)
     119 #$$$$($1_0_OUTDIR)/stub$2.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@)
     120 $$$$($1_0_OUTDIR)/stub$2.asm: | $$$$(dir $$$$@)
    120121        $(QUIET)$(APPEND) -tn $$@ \
    121122                '%include "bs3kit.mac"' \
     
    168169 $1_SOURCES += $$($1_0_OUTDIR)/stub_$2$3.asm
    169170 $1_CLEAN  += $$($1_0_OUTDIR)/stub_$2$3.asm
    170  $$$$($1_0_OUTDIR)/stub_$2$3.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@)
     171 #$$$$($1_0_OUTDIR)/stub_$2$3.asm: $$(VBOX_PATH_BOOTSECTORS_SRC)/Config.kmk | $$$$(dir $$$$@)
     172 $$$$($1_0_OUTDIR)/stub_$2$3.asm: | $$$$(dir $$$$@)
    171173        $(QUIET)$(APPEND) -tn $$@ \
    172174                '%include "bs3kit.mac"' \
     
    407409# to rename intrinsic functions so they don't clash with the 16-bit compiler.
    408410#
    409 TOOL_Bs3Ow32 := OpenWatcom C/C++ 32-bit with object convertsion
    410 TOOL_Bs3Ow32_CC  = $(TOOL_OPENWATCOM_CC)
    411 TOOL_Bs3Ow32_CXX = $(TOOL_OPENWATCOM_CXX)
     411TOOL_Bs3Ow32                         := OpenWatcom C/C++ 32-bit with object conversion and import library creation
     412TOOL_Bs3Ow32_EXTENDS                  = OPENWATCOM
     413TOOL_Bs3Ow32_CC                       = $(TOOL_OPENWATCOM_CC)
     414TOOL_Bs3Ow32_CXX                      = $(TOOL_OPENWATCOM_CXX)
    412415TOOL_Bs3Ow32_COBJSUFF                 = .o32
    413416TOOL_Bs3Ow32_CFLAGS                   = $(TOOL_OPENWATCOM_CFLAGS)
     
    470473# to rename intrinsic functions so they don't clash with the 16-bit compiler.
    471474#
    472 TOOL_Bs3Ow16 := OpenWatcom C/C++ 16-bit with object convertsion
    473 TOOL_Bs3Ow16_CC  = $(TOOL_OPENWATCOM-16_CC)
    474 TOOL_Bs3Ow16_CXX = $(TOOL_OPENWATCOM-16_CXX)
     475TOOL_Bs3Ow16                         := OpenWatcom C/C++ 16-bit with object convertsion
     476TOOL_Bs3Ow16_EXTENDS                 := OPENWATCOM-16
     477TOOL_Bs3Ow16_CC                       = $(TOOL_OPENWATCOM-16_CC)
     478TOOL_Bs3Ow16_CXX                      = $(TOOL_OPENWATCOM-16_CXX)
    475479TOOL_Bs3Ow16_COBJSUFF                 = .o16
    476480TOOL_Bs3Ow16_CFLAGS                   = $(TOOL_OPENWATCOM-16_CFLAGS)
     
    523527endef
    524528
     529TOOL_Bs3Ow16_AR                                 = $(TOOL_OPENWATCOM_AR)
     530TOOL_Bs3Ow16_ARFLAGS                            = $(TOOL_OPENWATCOM_ARFLAGS) @@replace-me-with-list-option@@
     531TOOL_Bs3Ow16_ARLIBSUFF                          = $(TOOL_OPENWATCOM_ARLIBSUFF)
     532TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT                = $(outbase)-implib.lib $(outbase)-implib.rsp $(outbase).lst
     533TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT_MAYBE_PRECIOUS = $(TOOL_OPENWATCOM_LINK_LIBRARY_OUTPUT_MAYBE_PRECIOUS)
     534TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT_DEPEND         = $(TOOL_OPENWATCOM_LINK_LIBRARY_OUTPUT_DEPEND)
     535TOOL_Bs3Ow16_LINK_LIBRARY_OUTPUT_DEPORD         = $(TOOL_OPENWATCOM_LINK_LIBRARY_OUTPUT_DEPORD)
     536define TOOL_Bs3Ow16_LINK_LIBRARY_CMDS
     537$(subst @@replace-me-with-list-option@@,-l=$(call TOOL_OPENWATCOM_FIX_SLASHES,$(outbase).lst),$(TOOL_OPENWATCOM_LINK_LIBRARY_CMDS))
     538        $(TOOL_Bs3Ow16_AR) -m "$(out)" \
     539        | $(SED) \
     540                -e '/^    _Bs3[_a-zA-Z0-9]*$$(DOLLAR)/!d' \
     541                -e '/_EndProc/d' \
     542                -e '/\./d' \
     543                -e 's/^ *\(_Bs3[_a-zA-Z0-9]*\)$$(DOLLAR)/++\1.bs3kit/' \
     544                --output $(outbase)-implib.rsp
     545        $(TOOL_Bs3Ow16_AR) -q -n -io -inn $(call TOOL_OPENWATCOM_FIX_SLASHES,$(outbase)-implib.lib) @$(outbase)-implib.rsp
     546endef
     547
    525548# Debug info format depends on what we use for 64-bit.
    526549if 1 #1of ($(KBUILD_HOST), win) - wlink dwarf .sym files are useless for binary blobs
     
    550573 local type := C64
    551574 $(kb-src-one 2)
     575endef
     576
     577define VBoxBs3KitImgSrcHandler_high_dll
     578 local genasm := $($(target)_0_OUTDIR)/high-dll-$(notdir $(basename $(source))).asm
     579 $(eval $(target)_CLEAN        += $(genasm))
     580 $(eval $(target)_GEN_SOURCES_ += $(genasm))
     581 $(target)_2_VBOX_BS3KIT_HIGH_DLLS := $($(target)_2_VBOX_BS3KIT_HIGH_DLLS) $(source)
     582
     583 $(genasm): $(source) | $(VBoxBs3Linker_1_TARGET) $$(dir $$@)
     584        $(VBoxBs3Linker_1_TARGET) --generate-high-dll-import-table "$<" --output "$@"
    552585endef
    553586
     
    609642        .c16:VBoxBs3KitImgSrcHandler_16bit_c \
    610643        .c32:VBoxBs3KitImgSrcHandler_32bit_c \
    611         .c64:VBoxBs3KitImgSrcHandler_64bit_c
     644        .c64:VBoxBs3KitImgSrcHandler_64bit_c \
     645        .high-dll:VBoxBs3KitImgSrcHandler_high_dll
    612646TEMPLATE_VBoxBS3KitImg_ASOBJSUFF    = .o16
    613647TEMPLATE_VBoxBS3KitImg_ASTOOL       = VBoxNasm
     
    620654TEMPLATE_VBoxBS3KitImg_DEFS.debug   = BS3_STRICT
    621655
    622 TEMPLATE_VBoxBS3KitImg_ARTOOL       = OPENWATCOM-16
     656TEMPLATE_VBoxBS3KitImg_ARTOOL       = Bs3Ow16
    623657
    624658TEMPLATE_VBoxBS3KitImg_CTOOL        = Bs3Ow16
     
    738772        segment BS3TEXT64_START \
    739773        segment BS3TEXT64 \
    740         segment BS3TEXT64_END
     774        segment BS3TEXT64_END \
     775        clname BS3HIGHDLLCLASS \
     776        segment BS3HIGHDLLEXPORTS \
     777        segment BS3HIGHDLLIMPORTS \
     778        segment BS3HIGHDLLSTRINGS \
     779        segment BS3HIGHDLLTABLE \
     780        segment BS3HIGHDLLTABLE_END
    741781
    742782TEMPLATE_VBoxBS3KitImg_LNK_DEPS = \
     
    745785TEMPLATE_VBoxBS3KitImg_POST_CMDS = $(if $(eq $(tool_do),LINK_LIBRARY) \
    746786                ,,$(QUIET)$(MV_EXT) -f -- "$(out)" "$(out).tmp" \
    747                 $$(NLTAB)$(QUIET)$(VBoxBs3Linker_1_TARGET) -o $(out) $(bs3-bootsector_1_TARGET) $(out).tmp \
     787                $$(NLTAB)$(QUIET)$(VBoxBs3Linker_1_TARGET) -o $(out) $(bs3-bootsector_1_TARGET) $(out).tmp $($(target)_2_VBOX_BS3KIT_HIGH_DLLS) \
    748788        $$(NLTAB)$(QUIET)$(RM_EXT) -f -- "$(out).tmp") \
    749789        $(eval .PRECIOUS: $(outbase).map) # ugly hack!
    750 
    751790
    752791TEMPLATE_VBoxBS3KitImg_LIBS = \
     
    778817        $(PATH_OBJ)/bs3kit-lm64/bs3kit-lm64.lib
    779818
     819# Variant of VBoxBS3KitImg that's for images needing large 32-bit and 64-bit
     820# code segments.
     821TEMPLATE_VBoxBS3KitImgBig = Template for building BS3Kit test images with high 32-bit & 64-bit code
     822TEMPLATE_VBoxBS3KitImgBig_EXTENDS     = VBoxBS3KitImg
     823TEMPLATE_VBoxBS3KitImgBig_DEFS        = $(TEMPLATE_VBoxBS3KitImg_DEFS) BS3_BIG_IMAGE  BS3_TEXT32_ABOVE_1M BS3_TEXT64_ABOVE_1M
     824#TEMPLATE_VBoxBS3KitImgBig_LDFLAGS     = \
     825#       $(subst BS3CLASS32CODE, BS3CLASS32CODE segaddr=0xa000$(SP), $(TEMPLATE_VBoxBS3KitImg_LDFLAGS))
     826#TEMPLATE_VBoxBS3KitImgBig_POST_CMDS = $(NO_SUCH_VARIABLE)
     827
     828# BS3Kit template for a high image.
     829TEMPLATE_VBoxBS3KitHighImg = Template for building BS3Kit test images, the high DLL.
     830TEMPLATE_VBoxBS3KitHighImg_EXTENDS   := VBoxBS3KitImg
     831TEMPLATE_VBoxBS3KitHighImg_DEFS       = $(TEMPLATE_VBoxBS3KitImg_DEFS) BS3_IS_HIGH_IMAGE
     832TEMPLATE_VBoxBS3KitHighImg_ASFLAGS    = $(filter-out -g,$(TEMPLATE_VBoxBS3KitImg_ASFLAGS)) # trouble with bs3-cpu-basic-3, nasm produce garbage comment/something.
     833TEMPLATE_VBoxBS3KitHighImg_BINSUFF   := .high-dll
     834TEMPLATE_VBoxBS3KitHighImg_LDTOOL    := OPENWATCOM-WL
     835TEMPLATE_VBoxBS3KitHighImg_LDFLAGS   := system os2v2 flat dll \
     836        \
     837        segment BS3TEXT16           executeread \
     838        segment BS3TEXT16_NEARSTUBS executeread \
     839        segment BS3TEXT16_FARSTUBS  executeread \
     840        segment BS3TEXT16_END       executeread \
     841        \
     842        $(if-expr "$(BS3KIT_SEGNM_DATA16)" == "", \
     843                segment BS3DATA16       readwrite \
     844                segment BS3DATA16_DATA  readwrite \
     845                segment DATA            readwrite \
     846                segment _DATA           readwrite \
     847                segment BS3DATA16CONST  readwrite \
     848                segment CONST           readwrite \
     849                segment BS3DATA16CONST2 readwrite \
     850                segment CONST2          readwrite \
     851                segment STRINGS         readwrite \
     852                segment BSS             readwrite \
     853                segment _BSS            readwrite \
     854                segment BS3DATA16_END   readwrite \
     855                , \
     856                segment BS3DATA16       readwrite \
     857                segment BS3DATA16CONST  readwrite \
     858                segment BS3DATA16CONST2 readwrite \
     859                segment BS3DATA16_DATA  readwrite \
     860                segment BS3DATA16_END   readwrite \
     861                ) \
     862        \
     863        segment BS3TEXT32           executeonly \
     864        segment BS3TEXT32_END       executeonly \
     865        \
     866        segment BS3DATA32           readwrite \
     867        segment BS3DATA32CONST      readwrite \
     868        segment BS3DATA32CONST2     readwrite \
     869        segment BS3DATA32_DATA      readwrite \
     870        segment BS3DATA32_BSS       readwrite \
     871        segment BS3DATA32_END       readwrite \
     872        \
     873        segment BS3TEXT64           executeread \
     874        segment BS3TEXT64_END       executeread \
     875        \
     876        segment BS3DATA64           readwrite \
     877        segment BS3DATA64CONST      readwrite \
     878        segment BS3DATA64_BSS       readwrite \
     879        segment BS3DATA64_END       readwrite \
     880        \
     881        debug $(BS3_OW_DBG_LDOPT) all \
     882        \
     883        option quiet, map, statics, verbose, symfile, objalign=4096, offset=0x800000 \
     884        disable 1014, 1080
     885
     886TEMPLATE_VBoxBS3KitHighImg_LIBS = \
     887        $(PATH_OBJ)/bs3kit-common-16/bs3kit-common-16-implib.lib \
     888        $(PATH_OBJ)/bs3kit-common-32/bs3kit-common-32-implib.lib \
     889        $(PATH_OBJ)/bs3kit-common-64/bs3kit-common-64-implib.lib \
     890        \
     891        $(PATH_OBJ)/bs3kit-pe16/bs3kit-pe16-implib.lib \
     892        $(PATH_OBJ)/bs3kit-pe16_32/bs3kit-pe16_32-implib.lib \
     893        $(PATH_OBJ)/bs3kit-pe32/bs3kit-pe32-implib.lib \
     894        $(PATH_OBJ)/bs3kit-pe32_16/bs3kit-pe32_16-implib.lib \
     895        $(PATH_OBJ)/bs3kit-pev86/bs3kit-pev86-implib.lib \
     896        $(PATH_OBJ)/bs3kit-pp16/bs3kit-pp16-implib.lib \
     897        $(PATH_OBJ)/bs3kit-pp16_32/bs3kit-pp16_32-implib.lib \
     898        $(PATH_OBJ)/bs3kit-pp32/bs3kit-pp32-implib.lib \
     899        $(PATH_OBJ)/bs3kit-pp32_16/bs3kit-pp32_16-implib.lib \
     900        $(PATH_OBJ)/bs3kit-pae16/bs3kit-pae16-implib.lib \
     901        $(PATH_OBJ)/bs3kit-pae16_32/bs3kit-pae16_32-implib.lib \
     902        $(PATH_OBJ)/bs3kit-pae32/bs3kit-pae32-implib.lib \
     903        $(PATH_OBJ)/bs3kit-pae32_16/bs3kit-pae32_16-implib.lib \
     904        $(PATH_OBJ)/bs3kit-lm16/bs3kit-lm16-implib.lib \
     905        $(PATH_OBJ)/bs3kit-lm32/bs3kit-lm32-implib.lib \
     906        $(PATH_OBJ)/bs3kit-lm64/bs3kit-lm64-implib.lib
     907
     908TEMPLATE_VBoxBS3KitHighImg_POST_CMDS  = $(NO_SUCH_VARIABLE)
     909
    780910# BS3Kit template for 32-bit code.
    781911TEMPLATE_VBoxBS3KitImg32 = Template for building BS3Kit test images.
     
    791921TEMPLATE_VBoxBS3KitImg32_DEFS         = ARCH_BITS=32 IN_BS3KIT
    792922TEMPLATE_VBoxBS3KitImg32_DEFS.debug   = BS3_STRICT
    793 TEMPLATE_VBoxBS3KitImg32_ARTOOL       = OPENWATCOM
     923TEMPLATE_VBoxBS3KitImg32_ARTOOL       = Bs3Ow16
    794924TEMPLATE_VBoxBS3KitImg32_CTOOL        = Bs3Ow32
    795925TEMPLATE_VBoxBS3KitImg32_CXXTOOL      = Bs3Ow32
     
    814944TEMPLATE_VBoxBS3KitImg64_DEFS         = IN_BS3KIT ARCH_BITS=64
    815945TEMPLATE_VBoxBS3KitImg64_DEFS.debug   = BS3_STRICT
    816 TEMPLATE_VBoxBS3KitImg64_ARTOOL       = OPENWATCOM
     946TEMPLATE_VBoxBS3KitImg64_ARTOOL       = Bs3Ow16
    817947TEMPLATE_VBoxBS3KitImg64_INCS         = $(VBOX_PATH_BS3KIT_SRC) .
    818948if1of ($(KBUILD_HOST), win)
  • trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk

    r102134 r102157  
    276276 # CPU basics #3 (first being bootsector2-cpu-basic-1).
    277277 MISCBINS += bs3-cpu-basic-3
    278  bs3-cpu-basic-3_TEMPLATE = VBoxBS3KitImg
     278 bs3-cpu-basic-3_TEMPLATE = VBoxBS3KitImgBig
    279279 bs3-cpu-basic-3_INCS = .
    280280 bs3-cpu-basic-3_DEFS = BS3_CMN_INSTANTIATE_FILE1=bs3-cpu-basic-3-cmn-template.c
     
    286286        bs3kit/bs3-cmn-instantiate.c32 \
    287287        bs3kit/bs3-cmn-instantiate.c64 \
    288         bs3-cpu-basic-3-asm.asm
     288        bs3-cpu-basic-3-asm.asm \
     289        $(bs3-cpu-basic-3-high_1_TARGET)
    289290 bs3-cpu-basic-3-cmn-template.o:: \
    290291                $$(bs3-cpu-basic-3_0_OUTDIR)/bs3kit/bs3-cmn-instantiate-x0.o16 \
     
    292293                $$(bs3-cpu-basic-3_0_OUTDIR)/bs3kit/bs3-cmn-instantiate.o64 \
    293294                $$(bs3-cpu-basic-3_0_OUTDIR)/bs3-cpu-basic-3-asm.o16
     295
     296 MISCBINS += bs3-cpu-basic-3-high
     297 bs3-cpu-basic-3-high_TEMPLATE = VBoxBS3KitHighImg
     298 bs3-cpu-basic-3-high_INCS     = .
     299 bs3-cpu-basic-3-high_SOURCES  = \
     300        bs3kit/bs3-first-high-image.asm \
     301        bs3-cpu-basic-3-high-asm.asm
    294302
    295303 #
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-asm.asm

    r102134 r102157  
    11; $Id$
    22;; @file
    3 ; BS3Kit - bs3-cpu-basic-2
     3; BS3Kit - bs3-cpu-basic-3
    44;
    55
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-cmn-template.c

    r102134 r102157  
    6565            pfnWorker32();
    6666    }
     67#else
     68    for (i = 0; i < 64; i++)
     69        BS3_CMN_FAR_NM(bs3CpuBasic3_lea_64)();
     70#endif
    6771    return 0;
    68 #else
    69     //for (i = 0; i < 64; i++)
    70     //    BS3_CMN_FAR_NM(bs3CpuBasic3_lea_64)
    71     RT_NOREF(i);
    72     return BS3TESTDOMODE_SKIPPED;
    73 #endif
    7472}
    7573
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-cmn-template.mac

    r102134 r102157  
    4444TMPL_BEGIN_TEXT
    4545
     46
     47;*********************************************************************************************************************************
     48;*  External Symbols                                                                                                             *
     49;*********************************************************************************************************************************
     50extern _Bs3Text16_StartOfSegment
    4651
    4752
     
    5964%define LEA_EDI 077777177h
    6065
     66%define LEA_RAX 01111111111111110h
     67%define LEA_RCX 02222222222222202h
     68%define LEA_RDX 03333333333333033h
     69%define LEA_RBX 04444444444440444h
     70%define LEA_RSP 058595a5d51525356h
     71%define LEA_RBP 05555555555555551h
     72%define LEA_RSI 06666666666666616h
     73%define LEA_RDI 07777777777777177h
     74%define LEA_R8  08888888888881888h
     75%define LEA_R9  09999999999999992h
     76%define LEA_R10 0aaaaaaaaaaaaaa2ah
     77%define LEA_R11 0bbbbbbbbbbbbb2bbh
     78%define LEA_R12 0cccccccccccc2ccch
     79%define LEA_R13 0ddddddddddddddd3h
     80%define LEA_R14 0eeeeeeeeeeeeee3eh
     81%define LEA_R15 0fffffffffffff3ffh
     82
     83
     84
    6185;
    6286; Switching segment for the 16-bit stuff, this may need some space.
     
    6791TMPL_BEGIN_TEXT
    6892%endif
    69 
    70 
    71 ;;
    72 ; Loads known values into all registers but xSP.
    73 BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_load_regs, BS3_PBC_NEAR
    74 %if TMPL_BITS == 64
    75         mov     rax, 01111111111111110h
    76         mov     rcx, 02222222222222202h
    77         mov     rdx, 03333333333333033h
    78         mov     rbx, 04444444444440444h
    79         mov     rbp, 05555555555555551h
    80         mov     rsi, 06666666666666616h
    81         mov     rdi, 07777777777777177h
    82         mov     r8,  08888888888881888h
    83         mov     r9,  09999999999999992h
    84         mov     r10, 0aaaaaaaaaaaaaa2ah
    85         mov     r11, 0bbbbbbbbbbbbb2bbh
    86         mov     r12, 0cccccccccccc2ccch
    87         mov     r13, 0ddddddddddddddd3h
    88         mov     r14, 0eeeeeeeeeeeeee3eh
    89         mov     r15, 0fffffffffffff3ffh
    90 %else
    91         mov     eax, LEA_EAX
    92         mov     ecx, LEA_ECX
    93         mov     edx, LEA_EDX
    94         mov     ebx, LEA_EBX
    95         mov     ebp, LEA_EBP
    96         mov     esi, LEA_ESI
    97         mov     edi, LEA_EDI
    98 %endif
    99         BS3_HYBRID_RET
    100 BS3_PROC_END_CMN   bs3CpuBasic3_lea_16_load_regs
    10193
    10294
     
    108100  %define BS3CPUBASIC3_LEA_16_MACROS
    109101  %macro test_lea_16_one 3
    110         call    BS3_CMN_NM(bs3CpuBasic3_lea_load_regs)
     102        call    .load_regs
    111103        lea     strict %1, strict %2
    112104        cmp     %1, %3 & 0ffffh
     
    162154        popad
    163155        BS3_HYBRID_RET
     156
     157.load_regs:
     158        mov     eax, LEA_EAX
     159        mov     ecx, LEA_ECX
     160        mov     edx, LEA_EDX
     161        mov     ebx, LEA_EBX
     162        mov     ebp, LEA_EBP
     163        mov     esi, LEA_ESI
     164        mov     edi, LEA_EDI
     165        ret
    164166BS3_PROC_END_CMN   bs3CpuBasic3_lea_16
    165167
     
    452454BS3_PROC_END_CMN   bs3CpuBasic3_lea_32
    453455
    454 %endif ; TMPL_BITS != 64
     456
     457%else  ; TMPL_BITS == 64
     458
     459
     460;;
     461; Tests 64-bit addressing using the LEA instruction.
     462;
     463BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_64, BS3_PBC_FAR
     464        push    rax
     465        push    rcx
     466        push    rdx
     467        push    rbx
     468        push    rbp
     469        push    rsi
     470        push    rdi
     471        push    r8
     472        push    r9
     473        push    r10
     474        push    r11
     475        push    r12
     476        push    r13
     477        push    r14
     478        push    r15
     479.test_label:
     480        mov     [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], rsp
     481
     482        ;
     483        ; Loop thru all the modr/m memory encodings.
     484        ;
     485 %assign iMod          0
     486 %assign iDstReg       0    ; We don't test all destination registers
     487 %rep   3
     488  %rep   16                 ; Destination registers per encoding. Testing all takes too much space.
     489   %assign iMemReg     0
     490   %rep   16
     491     %assign iDstReg_Value %sel(iDstReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
     492                                           LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
     493
     494    %if (iMemReg & 7) == 4
     495        ;
     496        ; SIB.
     497        ;
     498       %assign iBase       0
     499       %rep 16
     500        %if (iBase & 7) == 5 && iMod == 0
     501         %assign iBase_Value 0
     502        %else
     503         %assign iBase_Value %sel(iBase+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
     504                                           LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
     505        %endif
     506
     507        %assign iIndex     0
     508        %assign cShift     0 ; we don't have enough room for checking all the shifts.
     509        %rep 16
     510         %assign iBase_Value %sel(iIndex+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, 0, LEA_RBP, LEA_RSI, LEA_RDI, \
     511                                            LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
     512
     513        ;
     514        ; We don't test all shift combinations, there just isn't enough space
     515        ; in the image for that.
     516        ;
     517         %assign cShiftLoops 0 ; Disabled for now
     518         %rep cShiftLoops
     519%error asdf
     520        ;
     521        ; LEA+SIB w/ 64-bit operand size and 64-bit address size.
     522        ;
     523        call    .load_regs
     524          %if iBase == 4 || iDstReg == 4
     525        mov     rsp, LEA_RSP
     526          %endif
     527
     528        ; lea
     529          %assign   iValue  iBase_Value + (iIndex_Value << cShift)
     530        db      X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg) & 8 >> 1)
     531        db      8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
     532          %if iMod == X86_MOD_MEM1
     533        db      -128
     534           %assign  iValue  iValue - 128
     535          %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
     536        dd      -07fffffffh
     537           %assign  iValue  iValue - 07fffffffh
     538          %endif
     539
     540        ; cmp iDstReg, iValue
     541          %if iValue <= 07fffffffh && iValue >= -080000000h
     542        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     543        db      81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
     544        dd      iValue & 0ffffffffh
     545          %elif iDstReg != X86_GREG_xAX
     546        mov     rax, iValue
     547        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     548        db      39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
     549          %else
     550            mov     rcx, iValue
     551            cmp     rax, rcx
     552          %endif
     553          %if iDstReg == 4
     554        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     555          %endif
     556        jz      $+3
     557        int3
     558           %assign cShift    (cShift + 1) & 3
     559
     560         %endrep
     561         %assign iIndex    iIndex + 1
     562        %endrep
     563        %assign iBase      iBase + 1
     564       %endrep
     565
     566    %else ; !SIB
     567        ;
     568        ; Plain lea reg, [reg] with disp according to iMod,
     569        ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
     570        ;
     571     %if (iMemReg & 7) == 5 && iMod == 0
     572      %assign iMemReg_Value 0
     573     %else
     574      %assign iMemReg_Value %sel(iMemReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
     575                                            LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
     576     %endif
     577
     578        ;
     579        ; 64-bit operand and address size first.
     580        ;
     581        call    .load_regs
     582     %if iDstReg == 4
     583        mov     rsp, LEA_RSP
     584     %endif
     585
     586        ; lea
     587     %assign   iValue  iMemReg_Value
     588        db      X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
     589        db      8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
     590     %if iMod == X86_MOD_MEM1
     591        db      39
     592      %assign  iValue  iValue + 39
     593     %elif iMod == 0 && (iMemReg & 7) == 5
     594        dd      .load_regs - $ - 4
     595     %elif iMod == X86_MOD_MEM4
     596        dd      058739af8h
     597      %assign  iValue  iValue + 058739af8h
     598     %endif
     599
     600        ; cmp iDstReg, iValue
     601     %if (iValue <= 07fffffffh && iValue >= -080000000h) || (iMod == 0 && (iMemReg & 7) == 5)
     602        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     603        db      81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
     604      %if iMod == 0 && (iMemReg & 7) == 5
     605        dd      .load_regs wrt BS3FLAT
     606      %else
     607        dd      iValue & 0ffffffffh
     608      %endif
     609     %else
     610      %if iDstReg != iMemReg && iValue == iMemReg_Value ; This isn't entirely safe, but it saves a bit of space.
     611        db      X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
     612        db      39h, X86_MODRM_MAKE(X86_MOD_REG, iDstReg & 7, iMemReg & 7)
     613      %elif iDstReg != X86_GREG_xAX
     614        mov     rax, iValue
     615        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     616        db      39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
     617      %else
     618        mov     rcx, iValue
     619        cmp     rax, rcx
     620      %endif
     621     %endif
     622     %if iDstReg == 4
     623        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     624     %endif
     625        jz      $+3
     626        int3
     627
     628        ;
     629        ; 64-bit operand and 32-bit address size.
     630        ;
     631        call    .load_regs
     632     %if iDstReg == 4
     633        mov     rsp, LEA_RSP
     634     %endif
     635
     636        ; lea
     637     %assign   iValue  iMemReg_Value
     638        db      X86_OP_PRF_SIZE_ADDR
     639        db      X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
     640        db      8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
     641     %if iMod == X86_MOD_MEM1
     642        db      -92
     643      %assign  iValue  iValue - 92
     644     %elif iMod == 0 && (iMemReg & 7) == 5
     645        dd      .test_label - $ - 4
     646     %elif iMod == X86_MOD_MEM4
     647        dd      -038f8acf3h
     648      %assign  iValue  iValue - 038f8acf3h
     649     %endif
     650      %assign  iValue  iValue & 0ffffffffh
     651
     652        ; cmp iDstReg, iValue
     653     %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
     654        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     655        db      81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
     656      %if iMod == 0 && (iMemReg & 7) == 5
     657        dd      .test_label wrt BS3FLAT
     658      %else
     659        dd      iValue
     660      %endif
     661     %else
     662      %if iDstReg != X86_GREG_xAX
     663        mov     eax, iValue
     664        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     665        db      39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
     666      %else
     667        mov     ecx, iValue
     668        cmp     rax, rcx
     669      %endif
     670     %endif
     671     %if iDstReg == 4
     672        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     673     %endif
     674        jz      $+3
     675        int3
     676
     677        ;
     678        ; 32-bit operand and 64-bit address size.
     679        ;
     680        call    .load_regs
     681     %if iDstReg == 4
     682        mov     rsp, LEA_RSP
     683     %endif
     684
     685        ; lea
     686     %assign   iValue  iMemReg_Value
     687      %if iDstReg >= 8 || iMemReg >= 8
     688        db      X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
     689      %endif
     690        db      8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
     691     %if iMod == X86_MOD_MEM1
     692        db      16
     693      %assign  iValue  iValue + 16
     694     %elif iMod == 0 && (iMemReg & 7) == 5
     695        dd      .load_regs - $ - 4
     696     %elif iMod == X86_MOD_MEM4
     697        dd      0596829deh
     698      %assign  iValue  iValue + 0596829deh
     699     %endif
     700      %assign  iValue  iValue & 0ffffffffh
     701
     702        ; cmp iDstReg, iValue
     703     %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
     704        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     705        db      81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
     706      %if iMod == 0 && (iMemReg & 7) == 5
     707        dd      .load_regs wrt BS3FLAT
     708      %else
     709        dd      iValue
     710      %endif
     711     %else
     712      %if iDstReg != X86_GREG_xAX
     713        mov     eax, iValue
     714        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     715        db      39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
     716      %else
     717        mov     ecx, iValue
     718        cmp     rax, rcx
     719      %endif
     720     %endif
     721     %if iDstReg == 4
     722        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     723     %endif
     724        jz      $+3
     725        int3
     726
     727        ;
     728        ; 16-bit operand and 64-bit address size.
     729        ;
     730        call    .load_regs
     731     %if iDstReg == 4
     732        mov     rsp, LEA_RSP
     733     %endif
     734
     735        ; lea
     736     %assign   iValue  iMemReg_Value
     737        db      X86_OP_PRF_SIZE_OP
     738      %if iDstReg >= 8 || iMemReg >= 8
     739        db      X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
     740      %endif
     741        db      8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
     742     %if iMod == X86_MOD_MEM1
     743        db      -16
     744      %assign  iValue  iValue - 16
     745     %elif iMod == 0 && (iMemReg & 7) == 5
     746        dd      _Bs3Text16_StartOfSegment - $ - 4 + 7 wrt BS3FLAT
     747      %assign  iValue  7
     748     %elif iMod == X86_MOD_MEM4
     749        dd      075682332h
     750      %assign  iValue  iValue + 075682332h
     751     %endif
     752      %assign  iValue  (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
     753
     754        ; cmp iDstReg, iValue
     755     %if (iValue <= 07fffffffh && iValue >= -080000000h)
     756        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     757        db      81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
     758        dd      iValue
     759     %elif iDstReg != X86_GREG_xAX
     760        mov     rax, iValue
     761        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     762        db      39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
     763     %else
     764        mov     rcx, iValue
     765        cmp     rax, rcx
     766     %endif
     767     %if iDstReg == 4
     768        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     769     %endif
     770        jz      $+3
     771        int3
     772
     773        ;
     774        ; 16-bit operand and 32-bit address size.
     775        ;
     776        call    .load_regs
     777     %if iDstReg == 4
     778        mov     rsp, LEA_RSP
     779     %endif
     780
     781        ; lea
     782     %assign   iValue  iMemReg_Value
     783        db      X86_OP_PRF_SIZE_OP
     784        db      X86_OP_PRF_SIZE_ADDR
     785      %if iDstReg >= 8 || iMemReg >= 8
     786        db      X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
     787      %endif
     788        db      8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
     789     %if iMod == X86_MOD_MEM1
     790        db      99
     791      %assign  iValue  iValue + 99
     792     %elif iMod == 0 && (iMemReg & 7) == 5
     793        dd      _Bs3Text16_StartOfSegment - $ - 4 + 3347 wrt BS3FLAT
     794      %assign  iValue  3347
     795     %elif iMod == X86_MOD_MEM4
     796        dd      -075623432h
     797      %assign  iValue  iValue - 075623432h
     798     %endif
     799      %assign  iValue  (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
     800
     801        ; cmp iDstReg, iValue
     802     %if (iValue <= 07fffffffh && iValue >= -080000000h)
     803        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     804        db      81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
     805        dd      iValue
     806     %elif iDstReg != X86_GREG_xAX
     807        mov     rax, iValue
     808        db      X86_OP_REX_W | ((iDstReg & 8) >> 3)
     809        db      39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
     810     %else
     811        mov     rcx, iValue
     812        cmp     rax, rcx
     813     %endif
     814     %if iDstReg == 4
     815        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     816     %endif
     817        jz      $+3
     818        int3
     819
     820    %endif ; !SIB
     821    %assign iMemReg    iMemReg + 1
     822   %endrep
     823   %assign iDstReg     (iDstReg + 1) & 15
     824  %endrep
     825  %assign iMod         iMod + 1
     826 %endrep
     827
     828        mov     rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
     829        pop     r15
     830        pop     r14
     831        pop     r13
     832        pop     r12
     833        pop     r11
     834        pop     r10
     835        pop     r9
     836        pop     r8
     837        pop     rdi
     838        pop     rsi
     839        pop     rbp
     840        pop     rbx
     841        pop     rdx
     842        pop     rcx
     843        pop     rax
     844        ret
     845
     846.load_regs:
     847        mov     rax, LEA_RAX
     848        mov     rcx, LEA_RCX
     849        mov     rdx, LEA_RDX
     850        mov     rbx, LEA_RBX
     851        mov     rbp, LEA_RBP
     852        mov     rsi, LEA_RSI
     853        mov     rdi, LEA_RDI
     854        mov     r8,  LEA_R8
     855        mov     r9,  LEA_R9
     856        mov     r10, LEA_R10
     857        mov     r11, LEA_R11
     858        mov     r12, LEA_R12
     859        mov     r13, LEA_R13
     860        mov     r14, LEA_R14
     861        mov     r15, LEA_R15
     862        ret
     863BS3_PROC_END_CMN   bs3CpuBasic3_lea_64
     864
     865%endif ; TMPL_BITS == 64
    455866
    456867
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3.c

    r102130 r102157  
    6464BS3_DECL(void) Main_rm()
    6565{
    66     Bs3InitAll_rm();
     66    Bs3InitAllWithHighDlls_rm();
    6767    Bs3TestInit("bs3-cpu-basic-3");
    6868    Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk

    r102127 r102157  
    4242# Boot Sector post-link tool (used via the parent Config.kmk).
    4343BLDPROGS += VBoxBs3Linker
    44 VBoxBs3Linker_TEMPLATE = VBoxBldProg
     44VBoxBs3Linker_TEMPLATE = VBoxAdvBldProg
    4545VBoxBs3Linker_SOURCES  = $(VBOX_PATH_BS3KIT_SRC)/VBoxBs3Linker.cpp
    4646
     
    204204        bs3-cmn-SlabAlloc.c \
    205205        bs3-cmn-SlabAllocEx.c \
     206        bs3-cmn-SlabAllocFixed.c \
    206207        bs3-cmn-SlabFree.c \
    207208        bs3-cmn-SlabListInit.c \
     
    299300        bs3-system-data.asm \
    300301        bs3-rm-InitAll.c \
     302        bs3-rm-InitAllWithHighDlls.c \
    301303        bs3-rm-InitMemory.c \
    302304        bs3-rm-InitGdt.c \
     305        bs3-rm-InitHighDlls.c \
    303306        bs3-cmn-hexdigits.c \
    304307        bs3-cmn-CpuDetectData.c \
     
    370373#
    371374VBOX_BS3KIT_MODE_SOURCES = \
     375        bs3-mode-MemCopyFlat.asm \
    372376        bs3-mode-Name.asm \
    373377        bs3-mode-NameShortLower.asm \
     
    408412        bs3-mode-TestDoModesByMax.c \
    409413        bs3-mode-TestDoModesHlp.asm \
    410         bs3-mode-BiosInt15hE820.asm
     414        bs3-mode-BiosInt15hE820.asm \
     415        bs3-mode-DiskQueryGeometry.asm \
     416        bs3-mode-DiskRead.asm
    411417
    412418# The 16-bit real mode BS3Kit library.
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3Linker.cpp

    r99632 r102157  
    4040*********************************************************************************************************************************/
    4141#include <stdio.h>
    42 #include <string.h>
    4342#include <stdlib.h>
    44 #include <iprt/types.h>
     43
    4544#include <iprt/assert.h>
     45#include <iprt/err.h>
     46#include <iprt/file.h>
     47#include <iprt/getopt.h>
     48#include <iprt/initterm.h>
     49#include <iprt/ldr.h>
     50#include <iprt/mem.h>
     51#include <iprt/message.h>
     52#include <iprt/path.h>
     53#include <iprt/string.h>
     54
     55#include "bs3kit-linker.h"
    4656
    4757
     
    4959*   Structures and Typedefs                                                                                                      *
    5060*********************************************************************************************************************************/
    51 #pragma pack(1)
    52 typedef struct BS3BOOTSECTOR
    53 {
    54     uint8_t     abJmp[3];
    55     char        abOemId[8];
    56     /** @name EBPB, DOS 4.0 style.
    57      * @{  */
    58     uint16_t    cBytesPerSector;        /**< 00bh */
    59     uint8_t     cSectorsPerCluster;     /**< 00dh */
    60     uint16_t    cReservedSectors;       /**< 00eh */
    61     uint8_t     cFATs;                  /**< 010h */
    62     uint16_t    cRootDirEntries;        /**< 011h */
    63     uint16_t    cTotalSectors;          /**< 013h */
    64     uint8_t     bMediaDescriptor;       /**< 015h */
    65     uint16_t    cSectorsPerFAT;         /**< 016h */
    66     uint16_t    cPhysSectorsPerTrack;   /**< 018h */
    67     uint16_t    cHeads;                 /**< 01ah */
    68     uint32_t    cHiddentSectors;        /**< 01ch */
    69     uint32_t    cLargeTotalSectors;     /**< 020h - We (ab)use this to indicate the number of sectors to load. */
    70     uint8_t     bBootDrv;               /**< 024h */
    71     uint8_t     bFlagsEtc;              /**< 025h */
    72     uint8_t     bExtendedSignature;     /**< 026h */
    73     uint32_t    dwSerialNumber;         /**< 027h */
    74     char        abLabel[11];            /**< 02bh */
    75     char        abFSType[8];            /**< 036h */
    76     /** @} */
    77 } BS3BOOTSECTOR;
    78 #pragma pack()
    79 typedef BS3BOOTSECTOR *PBS3BOOTSECTOR;
    80 
    81 AssertCompileMemberOffset(BS3BOOTSECTOR, cLargeTotalSectors, 0x20);
    82 AssertCompileMemberOffset(BS3BOOTSECTOR, abLabel, 0x2b);
    83 AssertCompileMemberOffset(BS3BOOTSECTOR, abFSType, 0x36);
    84 
    85 #define BS3_OEMID       "BS3Kit\n\n"
    86 #define BS3_FSTYPE      "RawCode\n"
    87 #define BS3_LABEL       "VirtualBox\n"
    88 #define BS3_MAX_SIZE    UINT32_C(491520) /* 480KB */
    89 
    90 
    91 int main(int argc, char **argv)
    92 {
    93     const char  *pszOutput  = NULL;
    94     struct BS3LNKINPUT
    95     {
    96         const char *pszFile;
    97         FILE       *pFile;
    98         uint32_t    cbFile;
    99     }           *paInputs   = (struct BS3LNKINPUT *)calloc(sizeof(paInputs[0]), argc);
    100     unsigned     cInputs    = 0;
    101     uint32_t     cSectors   = 0;
    102 
     61typedef struct BS3LNKINPUT
     62{
     63    const char     *pszFile;
     64    FILE           *pFile;
     65    uint32_t        cbFile;
     66    uint32_t        cbBits;
     67    uint32_t        uLoadAddr;
     68    uint32_t        offInImage;
     69    void           *pvBits;
     70    RTLDRMOD        hLdrMod;
     71} BS3LNKINPUT;
     72
     73
     74typedef struct BS3LNKIMPORTSTATE
     75{
     76    FILE           *pOutput;
     77    RTSTRSPACE      hImportNames;
     78    unsigned        cImports;
     79    unsigned        cExports;
     80    size_t          cbStrings;
     81} BS3LNKIMPORTSTATE;
     82
     83typedef struct BS3LNKIMPORTNAME
     84{
     85    RTSTRSPACECORE  Core;
     86    size_t          offString;
     87    RT_FLEXIBLE_ARRAY_EXTENSION
     88    char            szName[RT_FLEXIBLE_ARRAY];
     89} BS3LNKIMPORTNAME;
     90
     91
     92
     93/**
     94 * @callback_method_impl{FNRTLDRENUMSYMS}
     95 */
     96static DECLCALLBACK(int) GenerateHighDllAsmOutputExportTable(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol,
     97                                                             RTLDRADDR Value, void *pvUser)
     98{
     99    BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser;
     100    if (!pszSymbol || !*pszSymbol)
     101        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All exports must be by name. uSymbol=%#x Value=%RX64", uSymbol, (uint64_t)Value);
     102
     103    // BS3HIGHDLLEXPORTENTRY
     104    fprintf(pState->pOutput,
     105            "g_pfn%s:\n"
     106            "        dd      0\n"
     107            "        dd      %#08x\n",
     108            pszSymbol, (unsigned)pState->cbStrings);
     109    pState->cbStrings += strlen(pszSymbol) + 1;
     110    pState->cExports  += 1;
     111
     112    RT_NOREF(hLdrMod);
     113    return VINF_SUCCESS;
     114}
     115
     116/**
     117 * @callback_method_impl{FNRTSTRSPACECALLBACK}
     118 */
     119static DECLCALLBACK(int) GenerateHighDllAsmOutputImportTable(PRTSTRSPACECORE pStr, void *pvUser)
     120{
     121    FILE             *pOutput = (FILE *)pvUser;
     122    BS3LNKIMPORTNAME *pName   = (BS3LNKIMPORTNAME *)pStr;
     123
     124    // BS3HIGHDLLIMPORTENTRY
     125    fprintf(pOutput,
     126            "        dw      %#06x\n"
     127            "        dw      seg %s\n"
     128            "        dd      %s wrt BS3FLAT\n"
     129            , (unsigned)pName->offString, pName->szName, pName->szName);
     130
     131    return VINF_SUCCESS;
     132}
     133
     134
     135/**
     136 * @callback_method_impl{FNRTLDRENUMSYMS}
     137 */
     138static DECLCALLBACK(int) GenerateHighDllAsmOutputExportStrings(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol,
     139                                                               RTLDRADDR Value, void *pvUser)
     140{
     141    BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser;
     142    if (!pszSymbol || !*pszSymbol)
     143        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All exports must be by name. uSymbol=%#x Value=%RX64", uSymbol, (uint64_t)Value);
     144
     145    fprintf(pState->pOutput, "        db      '%s', 0\n", pszSymbol);
     146    pState->cbStrings += strlen(pszSymbol) + 1;
     147
     148    RT_NOREF(hLdrMod);
     149    return VINF_SUCCESS;
     150}
     151
     152
     153/**
     154 * @callback_method_impl{FNRTSTRSPACECALLBACK}
     155 */
     156static DECLCALLBACK(int) GenerateHighDllAsmOutputImportStrings(PRTSTRSPACECORE pStr, void *pvUser)
     157{
     158    BS3LNKIMPORTSTATE * const pState = (BS3LNKIMPORTSTATE *)pvUser;
     159    BS3LNKIMPORTNAME  * const pName   = (BS3LNKIMPORTNAME *)pStr;
     160
     161    pName->offString = pState->cbStrings;
     162    fprintf(pState->pOutput, "        db      '%s', 0\n", pName->szName);
     163    pState->cbStrings += pName->Core.cchString + 1;
     164
     165    return VINF_SUCCESS;
     166}
     167
     168
     169/**
     170 * @callback_method_impl{FNRTLDRIMPORT}
     171 */
     172static DECLCALLBACK(int) GenerateHighDllAsmImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol,
     173                                                          unsigned uSymbol, PRTLDRADDR pValue, void *pvUser)
     174{
     175    BS3LNKIMPORTSTATE *pState = (BS3LNKIMPORTSTATE *)pvUser;
     176    if (!pszSymbol)
     177        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All imports must be by name. pszModule=%s uSymbol=%#x", pszModule, uSymbol);
     178    if (!RTStrSpaceGet(&pState->hImportNames, pszSymbol))
     179    {
     180        size_t const           cchSymbol = strlen(pszSymbol);
     181        BS3LNKIMPORTNAME * const pName   = (BS3LNKIMPORTNAME *)RTMemAlloc(RT_UOFFSETOF_DYN(BS3LNKIMPORTNAME,
     182                                                                                           szName[cchSymbol + 1]));
     183        AssertReturn(pName, VERR_NO_MEMORY);
     184
     185        pName->Core.cchString = cchSymbol;
     186        pName->Core.pszString = (char *)memcpy(pName->szName, pszSymbol, cchSymbol + 1);
     187        pName->offString      = UINT16_MAX;
     188
     189        AssertReturnStmt(RTStrSpaceInsert(&pState->hImportNames, &pName->Core), RTMemFree(pName),
     190                         RTMsgErrorRc(VERR_INTERNAL_ERROR, "IPE #1"));
     191        pState->cImports++;
     192    }
     193    *pValue = 0x10042;
     194    RT_NOREF(hLdrMod);
     195    return VINF_SUCCESS;
     196}
     197
     198
     199static RTEXITCODE GenerateHighDllImportTableAssembly(FILE *pOutput, const char *pszGenAsmFor)
     200{
     201    RTERRINFOSTATIC ErrInfo;
     202    RTLDRMOD        hLdrMod;
     203    int rc = RTLdrOpenEx(pszGenAsmFor, 0, RTLDRARCH_X86_32, &hLdrMod, RTErrInfoInitStatic(&ErrInfo));
     204    if (RT_FAILURE(rc))
     205        return RTMsgErrorExitFailure("RTLdrOpenEx failed to open '%s': %Rrc%#RTeim", pszGenAsmFor, rc, &ErrInfo.Core);
     206
     207    RTEXITCODE rcExit;
     208    size_t cbImage = RTLdrSize(hLdrMod);
     209    if (cbImage != ~(size_t)0)
     210    {
     211        void *pvBits = RTMemAlloc(cbImage);
     212        if (pvBits)
     213        {
     214            BS3LNKIMPORTSTATE State = { pOutput, NULL, 0, 0, 0 };
     215            rc = RTLdrGetBits(hLdrMod, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmImportCallback, pOutput);
     216            if (RT_SUCCESS(rc))
     217            {
     218                /** @todo move more of this to bs3kit*.h?    */
     219                fprintf(pOutput,
     220                        ";\n"
     221                        "; Automatically generated - DO NOT MODIFY!\n"
     222                        ";\n"
     223                        "%%include \"bs3kit.mac\"\n"
     224                        "\n"
     225                        "section BS3HIGHDLLEXPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     226                        "section BS3HIGHDLLIMPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     227                        "section BS3HIGHDLLSTRINGS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     228                        "section BS3HIGHDLLTABLE     align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     229                        "section BS3HIGHDLLTABLE_END align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT\n"
     230                        "GROUP BS3HIGHDLLGROUP  BS3HIGHDLLIMPORTS BS3HIGHDLLEXPORTS BS3HIGHDLLSTRINGS BS3HIGHDLLTABLE BS3HIGHDLLTABLE_END\n"
     231                        "\n");
     232
     233                /* Populate the string table with imports. */
     234                const char *pszFilename = RTPathFilename(pszGenAsmFor);
     235                fprintf(pOutput,
     236                        "section BS3HIGHDLLSTRINGS\n"
     237                        "start_strings:\n"
     238                        "        db      0\n"
     239                        "        db      '%s', 0    ; module name\n"
     240                        "        ; imports\n",
     241                        pszFilename);
     242                State.cbStrings = 1 + strlen(pszFilename) + 1;
     243                rc = RTStrSpaceEnumerate(&State.hImportNames, GenerateHighDllAsmOutputImportStrings, &State);
     244                AssertRC(rc);
     245                fprintf(pOutput, "        ; exports\n");
     246
     247                /* Populate the string table with exports. */
     248                size_t const offExportStrings = State.cbStrings;
     249                rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportStrings, &State);
     250                size_t const cbStrings        = State.cbStrings;
     251                if (RT_SUCCESS(rc) && cbStrings < _64K)
     252                {
     253                    /* Output the import table. */
     254                    fprintf(pOutput,
     255                            "section BS3HIGHDLLIMPORTS\n"
     256                            "start_imports:\n");
     257                    rc = RTStrSpaceEnumerate(&State.hImportNames, GenerateHighDllAsmOutputImportTable, &State);
     258                    AssertRC(rc);
     259                    fprintf(pOutput, "\n");
     260
     261                    /* Output the export table (ASSUMES stable enumeration order). */
     262                    fprintf(pOutput,
     263                            "section BS3HIGHDLLEXPORTS\n"
     264                            "start_exports:\n");
     265                    State.cbStrings = offExportStrings;
     266                    rc = RTLdrEnumSymbols(hLdrMod, 0, pvBits, BS3HIGHDLL_LOAD_ADDRESS, GenerateHighDllAsmOutputExportTable, &State);
     267                    AssertRC(rc);
     268                    fprintf(pOutput, "\n");
     269
     270                    /* Generate the table entry. */
     271                    fprintf(pOutput,
     272                            "section BS3HIGHDLLTABLE\n"
     273                            "start_entry: ; struct BS3HIGHDLLENTRY \n"
     274                            "        db      '%s', 0    ; achMagic[8]\n"
     275                            "        dd      0               ; uLoadAddress\n"
     276                            "        dd      %#08zx        ; cbLoaded\n"
     277                            "        dd      0               ; offInImage\n"
     278                            "        dd      %#08zx        ; cbInImage\n"
     279                            "        dd      %#04x            ; cImports\n"
     280                            "        dd      start_imports - start_entry\n"
     281                            "        dd      %#04x            ; cExports\n"
     282                            "        dd      start_exports - start_entry\n"
     283                            "        dd      %#05x           ; cbStrings\n"
     284                            "        dd      start_strings - start_entry\n"
     285                            "        dd      1               ; offDllName\n"
     286                            , BS3HIGHDLLENTRY_MAGIC, cbImage, cbImage, State.cImports, State.cExports, (unsigned)cbStrings);
     287                    rcExit = RTEXITCODE_SUCCESS;
     288                }
     289                else if (RT_FAILURE(rc))
     290                    rcExit = RTMsgErrorExitFailure("RTLdrEnumSymbols failed: %Rrc", rc);
     291                else
     292                    rcExit = RTMsgErrorExitFailure("Too many import/export strings: %#x bytes, max 64KiB", cbStrings);
     293            }
     294            else
     295                rcExit = RTMsgErrorExitFailure("RTLdrGetBits failed: %Rrc", rc);
     296            RTMemFree(pvBits);
     297        }
     298        else
     299            rcExit = RTMsgErrorExitFailure("Out of memory!");
     300    }
     301    else
     302        rcExit = RTMsgErrorExitFailure("RTLdrSize failed on '%s'", pszGenAsmFor);
     303
     304    RTLdrClose(hLdrMod);
     305    return rcExit;
     306}
     307
     308
     309static BS3HIGHDLLENTRY *LocateHighDllEntry(uint8_t const *pbBits, uint32_t cbBits, const char *pszFilename)
     310{
    103311    /*
    104      * Scan the arguments.
     312     * We search backwards for up to 4 KB.
    105313     */
    106     for (int i = 1; i < argc; i++)
    107     {
    108         if (argv[i][0] == '-')
     314    size_t const offStop = cbBits > _4K ? cbBits - _4K : 0;
     315    size_t       off     = cbBits >= sizeof(BS3HIGHDLLENTRY) ? cbBits - sizeof(BS3HIGHDLLENTRY) : 0;
     316    while (off > offStop)
     317    {
     318        BS3HIGHDLLENTRY const *pEntry = (BS3HIGHDLLENTRY const *)&pbBits[off];
     319        if (   pEntry->achMagic[0] == BS3HIGHDLLENTRY_MAGIC[0]
     320            && memcmp(pEntry->achMagic, BS3HIGHDLLENTRY_MAGIC, sizeof(pEntry->achMagic)) == 0)
    109321        {
    110             const char *pszOpt = &argv[i][1];
    111             if (*pszOpt == '-')
     322            if (pEntry->cbStrings < _64K && pEntry->cbStrings >= 8)
    112323            {
    113                 /* Convert long options to short ones. */
    114                 pszOpt--;
    115                 if (!strcmp(pszOpt, "--output"))
    116                     pszOpt = "o";
    117                 else if (!strcmp(pszOpt, "--version"))
    118                     pszOpt = "V";
    119                 else if (!strcmp(pszOpt, "--help"))
    120                     pszOpt = "h";
    121                 else
     324                if (off + pEntry->offStrings > 0 && off + pEntry->offStrings + pEntry->cbStrings <= off)
    122325                {
    123                     fprintf(stderr, "syntax errro: Unknown options '%s'\n", pszOpt);
    124                     free(paInputs);
    125                     return 2;
    126                 }
    127             }
    128 
    129             /* Process the list of short options. */
    130             while (*pszOpt)
    131             {
    132                 switch (*pszOpt++)
    133                 {
    134                     case 'o':
     326                    if (off + pEntry->offExports > 0 && off + pEntry->offExports + pEntry->cExports * 8 <= off)
    135327                    {
    136                         const char *pszValue = pszOpt;
    137                         pszOpt = strchr(pszOpt, '\0');
    138                         if (*pszValue == '=')
    139                             pszValue++;
    140                         else if (!*pszValue)
     328                        if (off + pEntry->offImports > 0 && off + pEntry->offImports + pEntry->cImports * 8 <= off)
    141329                        {
    142                             if (i + 1 >= argc)
     330                            if (pEntry->offFilename > 0 && pEntry->offFilename < pEntry->cbStrings)
    143331                            {
    144                                 fprintf(stderr, "syntax error: The --output option expects a filename.\n");
    145                                 free(paInputs);
    146                                 return 12;
     332                                const char *psz = (const char *)&pbBits[off + pEntry->offStrings + pEntry->offFilename];
     333                                if (strcmp(pszFilename, psz) == 0)
     334                                    return (BS3HIGHDLLENTRY *)pEntry;
    147335                            }
    148                             pszValue = argv[++i];
    149336                        }
    150                         if (pszOutput)
    151                         {
    152                             fprintf(stderr, "Only one output file is allowed. You've specified '%s' and '%s'\n",
    153                                     pszOutput, pszValue);
    154                             free(paInputs);
    155                             return 2;
    156                         }
    157                         pszOutput = pszValue;
    158                         pszOpt = "";
    159                         break;
    160337                    }
    161 
    162                     case 'V':
    163                         printf("%s\n", "$Revision$");
    164                         free(paInputs);
    165                         return 0;
    166 
    167                     case '?':
    168                     case 'h':
    169                         printf("usage: %s [options] -o <output> <input1> [input2 ... [inputN]]\n",
    170                                argv[0]);
    171                         free(paInputs);
    172                         return 0;
    173338                }
    174339            }
    175340        }
     341        off--;
     342    }
     343    RTMsgError("Failed to find the BS3HIGHDLLENTRY structure for '%s'!", pszFilename);
     344    return NULL;
     345}
     346
     347
     348/**
     349 * @callback_method_impl{FNRTLDRIMPORT}
     350 */
     351static DECLCALLBACK(int) ResolveHighDllImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol,
     352                                                      unsigned uSymbol, PRTLDRADDR pValue, void *pvUser)
     353{
     354    BS3HIGHDLLENTRY * const pEntry = (BS3HIGHDLLENTRY *)pvUser;
     355    if (!pszSymbol)
     356        return RTMsgErrorRc(VERR_LDR_BAD_FIXUP, "All imports must be by name. pszModule=%s uSymbol=%#x", pszModule, uSymbol);
     357
     358    /* Search the import table: */
     359    BS3HIGHDLLIMPORTENTRY const *paImports   = (BS3HIGHDLLIMPORTENTRY const *)((uintptr_t)pEntry + pEntry->offImports);
     360    const char * const           pszzStrings = (const char *)((uintptr_t)pEntry + pEntry->offStrings);
     361    size_t i = pEntry->cImports;
     362    while (i-- > 0)
     363    {
     364        if (strcmp(pszSymbol, &pszzStrings[paImports[i].offName]) == 0)
     365        {
     366            *pValue = paImports[i].offFlat;
     367            return VINF_SUCCESS;
     368        }
     369    }
     370    RT_NOREF(hLdrMod);
     371    return RTMsgErrorRc(VERR_SYMBOL_NOT_FOUND, "Unable to locate import %s (in %s)!", pszSymbol, pszModule);
     372}
     373
     374
     375static RTEXITCODE DoTheLinking(FILE *pOutput, BS3LNKINPUT *paInputs, unsigned cInputs)
     376{
     377    if (cInputs < 2)
     378        return RTMsgErrorExitFailure("Require at least two input files when linking!");
     379
     380    /*
     381     * Read all the files into memory.
     382     *
     383     * The first two are binary blobs, i.e. the boot sector and the base image.
     384     * Any additional files are DLLs and we need to do linking.
     385     */
     386    uint32_t uHiLoadAddr = BS3HIGHDLL_LOAD_ADDRESS;
     387    uint32_t off         = 0;
     388    for (unsigned i = 0; i < cInputs; i++)
     389    {
     390        paInputs[i].offInImage = off;
     391        if (i < 2)
     392        {
     393            paInputs[i].cbBits = RT_ALIGN_32(paInputs[i].cbFile, 512);
     394            paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits);
     395            if (!paInputs[i].pvBits)
     396                return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits);
     397            size_t cbRead = fread(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbFile, paInputs[i].pFile);
     398            if (cbRead != paInputs[i].cbFile)
     399                return RTMsgErrorExitFailure("Error reading '%s' (got %d bytes, wanted %u).",
     400                                             paInputs[i].pszFile, (int)cbRead, (unsigned)paInputs[i].cbFile);
     401            paInputs[i].uLoadAddr = i == 90 ? 0x7c00 : 0x10000;
     402        }
    176403        else
    177404        {
    178             /*
    179              * Add to input file collection.
    180              */
    181             paInputs[cInputs].pszFile = argv[i];
    182 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
    183             FILE *pFile = fopen(paInputs[cInputs].pszFile, "rb");
    184 #else
    185             FILE *pFile = fopen(paInputs[cInputs].pszFile, "r");
    186 #endif
    187             if (pFile)
     405            RTERRINFOSTATIC ErrInfo;
     406            int rc = RTLdrOpenEx(paInputs[i].pszFile, 0, RTLDRARCH_X86_32, &paInputs[i].hLdrMod, RTErrInfoInitStatic(&ErrInfo));
     407            if (RT_FAILURE(rc))
     408                return RTMsgErrorExitFailure("RTLdrOpenEx failed to open '%s': %Rrc%#RTeim",
     409                                             paInputs[i].pszFile, rc, &ErrInfo.Core);
     410
     411            size_t const cbImage = RTLdrSize(paInputs[i].hLdrMod);
     412            if (cbImage == ~(size_t)0)
     413                return RTMsgErrorExitFailure("RTLdrSize failed on '%s'!", paInputs[i].pszFile);
     414            if (cbImage > _64M)
     415                return RTMsgErrorExitFailure("Image '%s' is definitely too large: %#zx", paInputs[i].pszFile, cbImage);
     416
     417            paInputs[i].cbBits = RT_ALIGN_32((uint32_t)cbImage, 4096); /* Bs3InitHighDlls_rm depend on the 4KiB alignment.  */
     418            paInputs[i].pvBits = RTMemAllocZ(paInputs[i].cbBits);
     419            if (!paInputs[i].pvBits)
     420                return RTMsgErrorExitFailure("Out of memory (%#x)\n", paInputs[i].cbBits);
     421
     422            /* Locate the entry for this high dll in the base image. */
     423            BS3HIGHDLLENTRY *pHighDllEntry = LocateHighDllEntry((uint8_t *)paInputs[1].pvBits, paInputs[1].cbFile,
     424                                                                RTPathFilename(paInputs[i].pszFile));
     425            AssertReturn(pHighDllEntry, RTEXITCODE_FAILURE);
     426
     427            /* Get the fixed up image bits. */
     428            rc = RTLdrGetBits(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, ResolveHighDllImportCallback, pHighDllEntry);
     429            if (RT_FAILURE(rc))
     430                return RTMsgErrorExitFailure("RTLdrGetBits failed on '%s': %Rrc", paInputs[i].pszFile, rc);
     431
     432            /* Update the export addresses. */
     433            BS3HIGHDLLEXPORTENTRY *paExports   = (BS3HIGHDLLEXPORTENTRY *)((uintptr_t)pHighDllEntry + pHighDllEntry->offExports);
     434            const char * const     pszzStrings = (const char *)((uintptr_t)pHighDllEntry + pHighDllEntry->offStrings);
     435            size_t iExport = pHighDllEntry->cExports;
     436            while (iExport-- > 0)
    188437            {
    189                 if (fseek(pFile, 0, SEEK_END) == 0)
    190                 {
    191                     paInputs[cInputs].cbFile = (uint32_t)ftell(pFile);
    192                     if (fseek(pFile, 0, SEEK_SET) == 0)
    193                     {
    194                         if (cInputs != 0 || paInputs[cInputs].cbFile == 512)
    195                         {
    196                             cSectors += RT_ALIGN_32(paInputs[cInputs].cbFile, 512) / 512;
    197                             if (cSectors <= BS3_MAX_SIZE / 512)
    198                             {
    199                                 if (cSectors > 0)
    200                                 {
    201                                     paInputs[cInputs].pFile = pFile;
    202                                     pFile = NULL;
    203                                 }
    204                                 else
    205                                     fprintf(stderr, "error: empty input file: '%s'\n", paInputs[cInputs].pszFile);
    206                             }
    207                             else
    208                                 fprintf(stderr, "error: input is too big: %u bytes, %u sectors (max %u bytes, %u sectors)\n"
    209                                         "info: detected loading '%s'\n",
    210                                         cSectors * 512, cSectors, BS3_MAX_SIZE, BS3_MAX_SIZE / 512,
    211                                         paInputs[cInputs].pszFile);
    212                         }
    213                         else
    214                             fprintf(stderr, "error: first input file (%s) must be exactly 512 bytes\n", paInputs[cInputs].pszFile);
    215                     }
    216                     else
    217                         fprintf(stderr, "error: seeking to start of '%s' failed\n", paInputs[cInputs].pszFile);
    218                 }
     438                const char * const pszSymbol = (const char *)&pszzStrings[paExports[iExport].offName];
     439                RTLDRADDR          Value     = 0;
     440                rc = RTLdrGetSymbolEx(paInputs[i].hLdrMod, paInputs[i].pvBits, uHiLoadAddr, UINT32_MAX, pszSymbol, &Value);
     441                if (RT_SUCCESS(rc))
     442                    paExports[iExport].offFlat = (uint32_t)Value;
    219443                else
    220                     fprintf(stderr, "error: seeking to end of '%s' failed\n", paInputs[cInputs].pszFile);
     444                    return RTMsgErrorExitFailure("Failed to resolve '%s' in '%s': %Rrc", pszSymbol, paInputs[i].pszFile, rc);
    221445            }
    222             else
    223                 fprintf(stderr, "error: Failed to open input file '%s' for reading\n", paInputs[cInputs].pszFile);
    224             if (pFile)
    225             {
    226                 free(paInputs);
    227                 fclose(pFile);
    228                 return 1;
    229             }
    230             cInputs++;
     446
     447            /* Update the DLL entry with the load address and file address: */
     448            pHighDllEntry->offInImage = off;
     449            pHighDllEntry->uLoadAddr  = uHiLoadAddr;
     450            paInputs[i].uLoadAddr     = uHiLoadAddr;
     451            uHiLoadAddr += paInputs[i].cbBits;
    231452        }
    232     }
    233 
    234     if (!pszOutput)
    235     {
    236         fprintf(stderr, "syntax error: No output file was specified (-o or --output).\n");
    237         free(paInputs);
    238         return 2;
    239     }
    240     if (cInputs == 0)
    241     {
    242         fprintf(stderr, "syntax error: No input files was specified.\n");
    243         free(paInputs);
    244         return 2;
    245     }
     453        Assert(!(off & 0x1ff));
     454        off += paInputs[i].cbBits;
     455        Assert(!(off & 0x1ff));
     456    }
     457
     458    /** @todo image size check.   */
    246459
    247460    /*
    248      * Do the job.
     461     * Patch the BPB with base image sector count.
    249462     */
    250     /* Open the output file. */
    251 #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
    252     FILE *pOutput = fopen(pszOutput, "wb");
    253 #else
    254     FILE *pOutput = fopen(pszOutput, "w");
    255 #endif
    256     if (!pOutput)
    257     {
    258         fprintf(stderr, "error: Failed to open output file '%s' for writing\n", pszOutput);
    259         free(paInputs);
    260         return 1;
    261     }
    262 
    263     /* Copy the input files to the output file, with sector padding applied. */
    264     int rcExit = 0;
    265     size_t off = 0;
    266     for (unsigned i = 0; i < cInputs && rcExit == 0; i++)
    267     {
    268         uint8_t  abBuf[4096]; /* Must be multiple of 512! */
    269         uint32_t cbToRead = paInputs[i].cbFile;
    270         while (cbToRead > 0)
    271         {
    272             /* Read a block from the input file. */
    273             uint32_t const cbThisRead = RT_MIN(cbToRead, sizeof(abBuf));
    274             size_t cbRead = fread(abBuf, sizeof(uint8_t), cbThisRead, paInputs[i].pFile);
    275             if (cbRead != cbThisRead)
    276             {
    277                 fprintf(stderr, "error: Error reading '%s' (got %d bytes, wanted %u).\n",
    278                         paInputs[i].pszFile, (int)cbRead, (unsigned)cbThisRead);
    279                 rcExit = 1;
    280                 break;
    281             }
    282             cbToRead -= cbThisRead;
    283 
    284             /* Padd the end of the file if necessary. */
    285             if ((cbRead & 0x1ff) != 0)
    286             {
    287                 memset(&abBuf[cbRead], 0, 4096 - cbRead);
    288                 cbRead = (cbRead + 0x1ff) & ~0x1ffU;
    289             }
    290 
    291             /* Patch the BPB of the first file. */
    292             if (off == 0)
    293             {
    294                 PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)&abBuf[0];
    295                 if (   memcmp(pBs->abLabel,  RT_STR_TUPLE(BS3_LABEL))  == 0
    296                     && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0
    297                     && memcmp(pBs->abOemId,  RT_STR_TUPLE(BS3_OEMID))  == 0)
    298                     pBs->cLargeTotalSectors = cSectors;
    299                 else
    300                 {
    301                     fprintf(stderr, "error: Didn't find magic strings in the first file (%s).\n", paInputs[i].pszFile);
    302                     rcExit = 1;
    303                 }
    304             }
    305 
    306             /* Write the block to the output file. */
    307             if (fwrite(abBuf, sizeof(uint8_t), cbRead, pOutput) == cbRead)
    308                 off += cbRead;
    309             else
    310             {
    311                 fprintf(stderr, "error: fwrite failed\n");
    312                 rcExit = 1;
    313                 break;
    314             }
    315         }
    316 
    317         if (ferror(paInputs[i].pFile))
    318         {
    319             fprintf(stderr, "error: Error reading '%s'.\n", paInputs[i].pszFile);
    320             rcExit = 1;
    321         }
    322     }
    323 
    324     /* Close the input files. */
    325     for (unsigned i = 0; i < cInputs && rcExit == 0; i++)
    326         fclose(paInputs[i].pFile);
    327     free(paInputs);
    328 
    329     /* Avoid output sizes that makes the FDC code think it's a single sided
    330        floppy.  The BIOS always report double sided floppies, and even if we
    331        the bootsector adjust it's bMaxHeads value when getting a 20h error
    332        we end up with a garbaged image (seems somewhere in the BIOS/FDC it is
    333        still treated as a double sided floppy and we get half the data we want
    334        and with gaps).
    335 
    336        Similarly, if the size is 320KB or 360KB the FDC detects it as a double
    337        sided 5.25" floppy with 40 tracks, while the BIOS keeps reporting a
    338        1.44MB 3.5" floppy. So, just avoid those sizes too. */
     463    PBS3BOOTSECTOR pBs = (PBS3BOOTSECTOR)paInputs[0].pvBits;
     464    if (   memcmp(pBs->abLabel,  RT_STR_TUPLE(BS3_LABEL))  == 0
     465        && memcmp(pBs->abFSType, RT_STR_TUPLE(BS3_FSTYPE)) == 0
     466        && memcmp(pBs->abOemId,  RT_STR_TUPLE(BS3_OEMID))  == 0)
     467        pBs->cLargeTotalSectors = (paInputs[0].cbBits + paInputs[1].cbBits) / 512;
     468    else
     469        return RTMsgErrorExitFailure("Didn't find magic strings in the first file (%s).", paInputs[0].pszFile);
     470
     471    /*
     472     * Write out the image.
     473     */
     474    for (unsigned i = 0; i < cInputs; i++)
     475    {
     476        Assert(ftell(pOutput) == (int32_t)paInputs[i].offInImage);
     477        ssize_t cbWritten = fwrite(paInputs[i].pvBits, sizeof(uint8_t), paInputs[i].cbBits, pOutput);
     478        if (cbWritten != (ssize_t)paInputs[i].cbBits)
     479            return RTMsgErrorExitFailure("fwrite failed (%zd vs %zu)", cbWritten, paInputs[i].cbBits);
     480    }
     481
     482    /*
     483     * Avoid output sizes that makes the FDC code think it's a single sided
     484     * floppy.  The BIOS always report double sided floppies, and even if we
     485     * the bootsector adjust it's bMaxHeads value when getting a 20h error
     486     * we end up with a garbaged image (seems somewhere in the BIOS/FDC it is
     487     * still treated as a double sided floppy and we get half the data we want
     488     * and with gaps).
     489     *
     490     * Similarly, if the size is 320KB or 360KB the FDC detects it as a double
     491     * sided 5.25" floppy with 40 tracks, while the BIOS keeps reporting a
     492     * 1.44MB 3.5" floppy. So, just avoid those sizes too.
     493     */
    339494    uint32_t cbOutput = ftell(pOutput);
    340495    if (   cbOutput == 512 * 8 * 40 * 1 /* 160kB 5"1/4 SS */
     
    345500        static uint8_t const s_abZeroSector[512] = { 0 };
    346501        if (fwrite(s_abZeroSector, sizeof(uint8_t), sizeof(s_abZeroSector), pOutput) != sizeof(s_abZeroSector))
     502            return RTMsgErrorExitFailure("fwrite failed (padding)");
     503    }
     504
     505    return RTEXITCODE_SUCCESS;
     506}
     507
     508int main(int argc, char **argv)
     509{
     510    int rc = RTR3InitExe(argc, &argv, 0);
     511    if (RT_FAILURE(rc))
     512        return RTMsgInitFailure(rc);
     513
     514    /*
     515     * Scan the arguments.
     516     */
     517    static const RTGETOPTDEF s_aOptions[] =
     518    {
     519        { "--output",                           'o', RTGETOPT_REQ_STRING },
     520        { "--generate-high-dll-import-table",   'g', RTGETOPT_REQ_STRING },
     521    };
     522
     523    const char  *pszOutput      = NULL;
     524    const char  *pszGenAsmFor   = NULL;
     525    BS3LNKINPUT  aInputs[3];                /* 3 = bootsector, low image, high image */
     526    unsigned     cInputs        = 0;
     527    uint32_t     cSectors       = 0;
     528
     529    RTGETOPTSTATE   GetState;
     530    rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     531    AssertRCReturn(rc, RTEXITCODE_SYNTAX);
     532    RTGETOPTUNION   ValueUnion;
     533    int             ch;
     534    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     535    {
     536        switch (ch)
    347537        {
    348             fprintf(stderr, "error: fwrite failed (padding)\n");
    349             rcExit = 1;
     538            case 'o':
     539                if (pszOutput)
     540                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one output file is allowed. You've specified '%s' and '%s'",
     541                                          pszOutput, ValueUnion.psz);
     542                pszOutput = ValueUnion.psz;
     543                break;
     544
     545            case 'g':
     546                if (pszGenAsmFor)
     547                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--generate-high-dll-import-table can only be used once (first for %s, now for %s)",
     548                                          pszGenAsmFor, ValueUnion.psz);
     549                pszGenAsmFor = ValueUnion.psz;
     550                break;
     551
     552            case VINF_GETOPT_NOT_OPTION:
     553            {
     554                if (pszGenAsmFor)
     555                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--generate-high-dll-import-table don't take any non-option arguments!");
     556
     557                /*
     558                 * Add to input file collection.
     559                 */
     560                if (cInputs >= RT_ELEMENTS(aInputs))
     561                    return RTMsgErrorExitFailure("Too many input files!");
     562                aInputs[cInputs].pszFile = ValueUnion.psz;
     563#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     564                FILE *pFile = fopen(aInputs[cInputs].pszFile, "rb");
     565#else
     566                FILE *pFile = fopen(aInputs[cInputs].pszFile, "r");
     567#endif
     568                if (pFile)
     569                {
     570                    if (fseek(pFile, 0, SEEK_END) == 0)
     571                    {
     572                        aInputs[cInputs].cbFile = (uint32_t)ftell(pFile);
     573                        if (fseek(pFile, 0, SEEK_SET) == 0)
     574                        {
     575                            if (cInputs != 0 || aInputs[cInputs].cbFile == 512)
     576                            {
     577                                cSectors += RT_ALIGN_32(aInputs[cInputs].cbFile, 512) / 512;
     578                                if (cSectors <= BS3_MAX_SIZE / 512 || cInputs > 0)
     579                                {
     580                                    if (cSectors > 0)
     581                                    {
     582                                        aInputs[cInputs].pvBits  = NULL;
     583                                        aInputs[cInputs].cbBits  = 0;
     584                                        aInputs[cInputs].hLdrMod = NIL_RTLDRMOD;
     585                                        aInputs[cInputs++].pFile = pFile;
     586                                        pFile = NULL;
     587                                        break;
     588                                    }
     589                                    RTMsgError("empty input file: '%s'", aInputs[cInputs].pszFile);
     590                                }
     591                                else
     592                                    RTMsgError("input is too big: %u bytes, %u sectors (max %u bytes, %u sectors)\n"
     593                                               "detected loading '%s'",
     594                                               cSectors * 512, cSectors, BS3_MAX_SIZE, BS3_MAX_SIZE / 512,
     595                                               aInputs[cInputs].pszFile);
     596                            }
     597                            else
     598                                RTMsgError("first input file (%s) must be exactly 512 bytes", aInputs[cInputs].pszFile);
     599                        }
     600                        else
     601                            RTMsgError("seeking to start of '%s' failed", aInputs[cInputs].pszFile);
     602                    }
     603                    else
     604                        RTMsgError("seeking to end of '%s' failed", aInputs[cInputs].pszFile);
     605                }
     606                else
     607                    RTMsgError("Failed to open input file '%s' for reading", aInputs[cInputs].pszFile);
     608                if (pFile)
     609                    fclose(pFile);
     610                return RTEXITCODE_FAILURE;
     611            }
     612
     613            case 'V':
     614                printf("%s\n", "$Revision$");
     615                return RTEXITCODE_SUCCESS;
     616
     617            case 'h':
     618                printf("usage: %s --output <output> <basemod> [high-dll1... [high-dllN]]\n"
     619                       "   or: %s --output <high-dll.asm> --generate-high-dll-import-table <some.high-dll>\n"
     620                       "   or: %s --help\n"
     621                       "   or: %s --version\n"
     622                       , argv[0], argv[0], argv[0], argv[0]);
     623                return RTEXITCODE_SUCCESS;
     624
     625            default:
     626                return RTGetOptPrintError(ch, &ValueUnion);
    350627        }
    351628    }
     629
     630    if (!pszOutput)
     631        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No output file was specified (-o or --output).");
     632
     633    if (cInputs == 0 && !pszGenAsmFor)
     634        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No input files was specified.");
     635
     636    /*
     637     * Do the job.
     638     */
     639    /* Open the output file */
     640#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
     641    FILE *pOutput = fopen(pszOutput, !pszGenAsmFor ? "wb" : "w");
     642#else
     643    FILE *pOutput = fopen(pszOutput, "w");
     644#endif
     645    if (!pOutput)
     646        RTMsgErrorExitFailure("Failed to open output file '%s' for writing!", pszOutput);
     647
     648    RTEXITCODE rcExit;
     649    if (pszGenAsmFor)
     650        rcExit = GenerateHighDllImportTableAssembly(pOutput, pszGenAsmFor);
     651    else
     652        rcExit = DoTheLinking(pOutput, aInputs, cInputs);
    352653
    353654    /* Finally, close the output file (can fail because of buffered data). */
    354655    if (fclose(pOutput) != 0)
    355     {
    356         fprintf(stderr, "error: Error closing '%s'.\n", pszOutput);
    357         rcExit = 1;
    358     }
    359 
     656        rcExit = RTMsgErrorExitFailure("Error closing '%s'!", pszOutput);
     657
     658    /* Delete the output file on failure. */
     659    if (rcExit != RTEXITCODE_SUCCESS)
     660        RTFileDelete(pszOutput);
     661
     662    /* Close the input files and free memory associated with them. */
     663    for (unsigned i = 0; i < cInputs && rcExit == 0; i++)
     664    {
     665        if (aInputs[i].pFile)
     666            fclose(aInputs[i].pFile);
     667        if (aInputs[i].hLdrMod != NIL_RTLDRMOD)
     668            RTLdrClose(aInputs[i].hLdrMod);
     669        if (aInputs[i].pvBits)
     670            RTMemFree(aInputs[i].pvBits);
     671    }
     672
     673    /* Close stderr to make sure it's flushed properly. */
    360674    fclose(stderr);
    361675    return rcExit;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-SlabAllocFixed.c

    r102144 r102157  
    4343
    4444
    45 #undef Bs3SlabAllocEx
    46 BS3_CMN_DEF(void BS3_FAR *, Bs3SlabAllocEx,(PBS3SLABCTL pSlabCtl, uint16_t cChunks, uint16_t fFlags))
     45#undef Bs3SlabAllocFixed
     46BS3_CMN_DEF(uint16_t, Bs3SlabAllocFixed,(PBS3SLABCTL pSlabCtl, uint32_t uFlatAddr, uint16_t cChunks))
    4747{
    48     BS3_ASSERT(cChunks > 0);
    49     if (pSlabCtl->cFreeChunks >= cChunks)
     48    uint32_t iBit32 = (uFlatAddr - BS3_XPTR_GET_FLAT(void, pSlabCtl->pbStart)) >> pSlabCtl->cChunkShift;
     49    if (iBit32 < pSlabCtl->cChunks)
    5050    {
    51         int32_t iBit = ASMBitFirstClear(&pSlabCtl->bmAllocated, pSlabCtl->cChunks);
    52         if (iBit >= 0)
    53         {
    54             BS3_ASSERT(!ASMBitTest(&pSlabCtl->bmAllocated, iBit));
     51        uint16_t iBit = (uint16_t)iBit32;
     52        uint16_t i;
    5553
    56             while ((uint32_t)iBit + cChunks <= pSlabCtl->cChunks)
    57             {
    58                 /* Check that we've got the requested number of free chunks here. */
    59                 uint16_t i;
    60                 for (i = 1; i < cChunks; i++)
    61                     if (ASMBitTest(&pSlabCtl->bmAllocated, iBit + i))
    62                         break;
    63                 if (i == cChunks)
    64                 {
    65                     /* Check if the chunks are all in the same tiled segment. */
    66                     BS3_XPTR_AUTO(void, pvRet);
    67                     BS3_XPTR_SET_FLAT(void, pvRet,
    68                                       BS3_XPTR_GET_FLAT(uint8_t, pSlabCtl->pbStart) + ((uint32_t)iBit << pSlabCtl->cChunkShift));
    69                     if (   !(fFlags & BS3_SLAB_ALLOC_F_SAME_TILE)
    70                         ||    (BS3_XPTR_GET_FLAT(void, pvRet) >> 16)
    71                            == ((BS3_XPTR_GET_FLAT(void, pvRet) + ((uint32_t)cChunks << pSlabCtl->cChunkShift) - 1) >> 16) )
    72                     {
    73                         /* Complete the allocation. */
    74                         void *fpRet;
    75                         for (i = 0; i < cChunks; i++)
    76                             ASMBitSet(&pSlabCtl->bmAllocated, iBit + i);
    77                         pSlabCtl->cFreeChunks  -= cChunks;
    78                         fpRet = BS3_XPTR_GET(void, pvRet);
    79 #if ARCH_BITS == 16
    80                         BS3_ASSERT(fpRet != NULL);
    81 #endif
    82                         return fpRet;
    83                     }
     54        /* If the slab doesn't cover the entire area requested, reduce it.
     55           Caller can then move on to the next slab in the list to get the rest. */
     56        if (pSlabCtl->cChunks - iBit < cChunks)
     57            cChunks = pSlabCtl->cChunks - iBit;
    8458
    85                     /*
    86                      * We're crossing a tiled segment boundrary.
    87                      * Skip to the start of the next segment and retry there.
    88                      * (We already know that the first chunk in the next tiled
    89                      * segment is free, otherwise we wouldn't have a crossing.)
    90                      */
    91                     BS3_ASSERT(((uint32_t)cChunks << pSlabCtl->cChunkShift) <= _64K);
    92                     i = BS3_XPTR_GET_FLAT_LOW(void, pvRet);
    93                     i = UINT16_C(0) - i;
    94                     i >>= pSlabCtl->cChunkShift;
    95                     iBit += i;
    96                 }
    97                 else
    98                 {
    99                     /*
    100                      * Continue searching.
    101                      */
    102                     iBit = ASMBitNextClear(&pSlabCtl->bmAllocated, pSlabCtl->cChunks, iBit + i);
    103                     if (iBit < 0)
    104                         break;
    105                 }
    106             }
    107         }
     59        /* Check that all the chunks are free. */
     60        for (i = 0; i < cChunks; i++)
     61            if (ASMBitTest(&pSlabCtl->bmAllocated, iBit + i))
     62                return UINT16_MAX;
     63
     64        /* Complete the allocation. */
     65        for (i = 0; i < cChunks; i++)
     66            ASMBitSet(&pSlabCtl->bmAllocated, iBit + i);
     67        pSlabCtl->cFreeChunks  -= cChunks;
     68        return cChunks;
    10869    }
    109     return NULL;
     70    return 0;
    11071}
    11172
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac

    r102131 r102157  
    5252;
    5353
    54 ;
    55 ; 16-bit text
     54
     55;                                                                      0x86a00
     56; 16-bit text                                                 442368 = 0x6C000 (442368)
    5657;
    5758%ifndef BS3_IS_DOS_EXE
     
    111112BS3_GLOBAL_DATA Bs3Text16_Size, 2
    112113    dw  BS3_DATA_NM(Bs3Text16_EndOfSegment) wrt CGROUP16
     114%ifndef BS3_IS_HIGH_IMAGE
    113115BS3_GLOBAL_DATA Bs3RmText16_Size, 2
    114116    dw  BS3_DATA_NM(Bs3RmText16_EndOfSegment) wrt BS3GROUPRMTEXT16
     117%endif ; !BS3_IS_HIGH_IMAGE
    115118BS3_GLOBAL_DATA Bs3X0Text16_Size, 2
    116119    dw  BS3_DATA_NM(Bs3X0Text16_EndOfSegment) wrt BS3GROUPX0TEXT16
     
    118121    dw  BS3_DATA_NM(Bs3X1Text16_EndOfSegment) wrt BS3GROUPX1TEXT16
    119122
     123%ifndef BS3_IS_HIGH_IMAGE
    120124BS3_GLOBAL_DATA Bs3RmText16_FlatAddr, 4
    121125    dd  BS3_DATA_NM(Bs3RmText16_StartOfSegment) wrt BS3FLAT
     126%endif ; !BS3_IS_HIGH_IMAGE
    122127BS3_GLOBAL_DATA Bs3X0Text16_FlatAddr, 4
    123128    dd  BS3_DATA_NM(Bs3X0Text16_StartOfSegment) wrt BS3FLAT
     
    164169%endif
    165170
     171%ifndef BS3_IS_HIGH_IMAGE
    166172;
    167173; 16-bit real-mode text
     
    174180BS3_GLOBAL_DATA Bs3RmText16_EndOfSegment, 0
    175181GROUP BS3GROUPRMTEXT16 BS3RMTEXT16_START BS3RMTEXT16 BS3RMTEXT16_END
    176 
     182%endif ; !BS3_IS_HIGH_IMAGE
    177183
    178184;
     
    199205GROUP BS3GROUPX1TEXT16 BS3X1TEXT16_START BS3X1TEXT16 BS3X1TEXT16_END
    200206
     207%ifndef BS3_IS_HIGH_IMAGE
    201208;
    202209; Separate the BS3X1TEXT16_END from BS3_BEGIN_TEXT32 to better help pinpoint
     
    208215BS3_GLOBAL_DATA BS3SEPARATE16AND32BITCODE_EndOfSegment, 0
    209216GROUP BS3SEPARATE16AND32BITCODEGROUP BS3SEPARATE16AND32BITCODE
     217%endif ; !BS3_IS_HIGH_IMAGE
    210218
    211219
     
    220228
    221229
     230%ifndef BS3_IS_HIGH_IMAGE
    222231;
    223232; This is a hack to separate the 32-bit and 64-bit text segments when linking,
     
    230239BS3_GLOBAL_DATA Bs3Separate32And64BitCode_EndOfSegment, 0
    231240GROUP BS3SEPARATE32AND64BITCODEGROUP BS3SEPARATE32AND64BITCODE
     241%endif ; !BS3_IS_HIGH_IMAGE
    232242
    233243
     
    276286
    277287
     288%ifndef BS3_IS_HIGH_IMAGE
     289;
     290; The high dll table segment.
     291;
     292section BS3HIGHDLLEXPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT ;; @todo Consider moving this to DATA16...
     293section BS3HIGHDLLIMPORTS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     294section BS3HIGHDLLSTRINGS   align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     295section BS3HIGHDLLTABLE     align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     296BS3_GLOBAL_DATA g_aBs3HighDllTable, 0
     297section BS3HIGHDLLTABLE_END align=4 CLASS=BS3HIGHDLLCLASS PUBLIC USE32 FLAT
     298BS3_GLOBAL_DATA g_Bs3HighDllTable_End, 0
     299GROUP BS3HIGHDLLGROUP  BS3HIGHDLLIMPORTS BS3HIGHDLLEXPORTS BS3HIGHDLLSTRINGS BS3HIGHDLLTABLE BS3HIGHDLLTABLE_END
     300
    278301;
    279302; 16-bit accessible system data.
     
    288311BS3_BEGIN_TEXT16
    289312BS3_GLOBAL_NAME_EX Bs3KitEntryPoint, function, 0
    290 
     313%endif ; !BS3_IS_HIGH_IMAGE
     314
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-BiosInt15hE820.asm

    r98103 r102157  
    172172        jc      .failed
    173173        cmp     eax, INT15_E820_SIGNATURE
    174         jc      .failed
     174        jne     .failed
    175175        cmp     ecx, 20
    176176        jb      .failed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskQueryGeometry.asm

    r102150 r102157  
    11; $Id$
    22;; @file
    3 ; BS3Kit - Bs3BiosInt15hE820
     3; BS3Kit - Bs3DiskQueryGeometry
    44;
    55
     
    3939;*********************************************************************************************************************************
    4040%include "bs3kit-template-header.mac"
    41 
    42 
    43 ;*********************************************************************************************************************************
    44 ;*  Defined Constants And Macros                                                                                                 *
    45 ;*********************************************************************************************************************************
    46 ;; Signature: 'SMAP'
    47 %define INT15_E820_SIGNATURE    0534d4150h
    4841
    4942
     
    118111        BS3_SET_BITS 16
    119112%endif
    120         ; Ralf Brown suggest setting es:di to NULL before the call. This is also helpful
    121         ; wrt to IVT manipulation (next step).
     113
     114        ;
     115        ; Ralf Brown suggest setting es:di to NULL before the call.
     116        ; Doubt this is really needed in our case, but whatever.
     117        ;
    122118        xor     di, di
    123119        mov     es, di
    124 
    125         ;
    126         ; Save current and restore the original IVT[13h] entry.
    127         ;
    128         mov     si, seg g_aBs3RmIvtOriginal
    129         mov     ds, si
    130         mov     si, g_aBs3RmIvtOriginal
    131 
    132         push    word [es:13h * 4]
    133         mov     ax, [si + 13h * 4]
    134         mov     [es:13h * 4], ax
    135 
    136         push    word [es:13h * 4 + 2]
    137         mov     ax, [si + 13h * 4 + 2]
    138         mov     [es:13h * 4 + 2], ax
    139120
    140121        ;
     
    145126        mov     es, di
    146127        int     13h
    147 
    148         ;
    149         ; Restore the modified IVT[13h] entry.
    150         ; Must not touch EFLAGS.CF!
    151         ;
    152         push    word 0
    153         pop     ds
    154         pop     word [ds:13h * 4 + 2]
    155         pop     word [ds:13h * 4]
    156128
    157129        ;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-DiskRead.asm

    r102150 r102157  
    11; $Id$
    22;; @file
    3 ; BS3Kit - Bs3BiosInt15hE820
     3; BS3Kit - Bs3DiskRead
    44;
    55
     
    4242
    4343;*********************************************************************************************************************************
    44 ;*  Defined Constants And Macros                                                                                                 *
    45 ;*********************************************************************************************************************************
    46 ;; Signature: 'SMAP'
    47 %define INT15_E820_SIGNATURE    0534d4150h
    48 
    49 
    50 ;*********************************************************************************************************************************
    5144;*  External symbols                                                                                                             *
    5245;*********************************************************************************************************************************
     
    5548BS3_BEGIN_TEXT16
    5649extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm)
    57 BS3_EXTERN_DATA16 g_aBs3RmIvtOriginal
     50
     51BS3_EXTERN_DATA16   g_aBs3RmIvtOriginal
     52%ifdef TMPL_16BIT
     53BS3_EXTERN_CMN      Bs3SelProtFar16DataToRealMode
     54%else
     55BS3_EXTERN_CMN      Bs3SelFlatDataToRealMode
     56%endif
     57
    5858
    5959
    6060;;
    61 ; Performs a int 13h function 8 call.
    62 ;
    63 ; @cproto   BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskQueryGeometry,(uint8_t bDrive, uint16_t *puMaxCylinder,
    64 ;                                                              uint8_t *puMaxHead, uint8_t *puMaxSector));
     61; Performs a int 13h function 2 call.
     62;
     63; @cproto   BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskRead,(uint8_t bDrive, uint16_t uCylinder, uint8_t uHead, uint8_t uSector,
     64;                                                     uint8_t cSectors, void RT_FAR *pvBuf));
    6565;
    6666; @returns  Register value (ax/eax). Zero on success, non-zero on failure.
     
    7272;
    7373TMPL_BEGIN_TEXT
    74 BS3_PROC_BEGIN_MODE Bs3DiskQueryGeometry, BS3_PBC_HYBRID
     74BS3_PROC_BEGIN_MODE Bs3DiskRead, BS3_PBC_HYBRID
    7575        push    xBP
    7676        mov     xBP, xSP
     
    9090        ; Load/Save parameters.
    9191%define a_bDrive                [xBP + xCB + cbCurRetAddr + xCB*0]
    92 %define a_puMaxCylinder         [xBP + xCB + cbCurRetAddr + xCB + sCB*0]
    93 %define a_pMaxHead              [xBP + xCB + cbCurRetAddr + xCB + sCB*1]
    94 %define a_puMaxSector           [xBP + xCB + cbCurRetAddr + xCB + sCB*2]
     92%define a_uCylinder             [xBP + xCB + cbCurRetAddr + xCB*1]
     93%define a_uCylinderHi           [xBP + xCB + cbCurRetAddr + xCB*1 + 1]
     94%define a_uHead                 [xBP + xCB + cbCurRetAddr + xCB*2]
     95%define a_uSector               [xBP + xCB + cbCurRetAddr + xCB*3]
     96%define a_cSectors              [xBP + xCB + cbCurRetAddr + xCB*4]
     97%define a_pvBuf                 [xBP + xCB + cbCurRetAddr + xCB*5]
     98%define a_pvBufSel              [xBP + xCB + cbCurRetAddr + xCB*5 + 2]
    9599
    96100%ifdef TMPL_64BIT
    97101        mov     a_bDrive, rcx           ; save bDrive
    98         mov     a_puMaxCylinder, rdx    ; save pcCylinders
    99         mov     a_pMaxHead, r8          ; save pcHeads
    100         mov     a_puMaxSector, r9       ; save pcSectors
     102        mov     a_uCylinder, rdx        ; save uCylinder
     103        mov     a_uHead, r8             ; save uHead
     104        mov     a_uSector, r9           ; save uSector
    101105        movzx   edx, cl                 ; dl = drive
    102106%else
    103107        mov     dl, a_bDrive            ; dl = drive
    104108%endif
     109
     110        ;
     111        ; Convert buffer pointer if not in real mode.
     112        ; Note! We clean the stack up in the epilogue.
     113        ;
     114%ifdef TMPL_64BIT
     115        sub     rsp, 20h
     116        mov     rcx, a_pvBuf
     117        call    Bs3SelFlatDataToRealMode
     118        mov     a_pvBuf, rax
     119%elifdef TMPL_32BIT
     120        mov     ecx, a_pvBuf
     121        push    ecx
     122        call    Bs3SelFlatDataToRealMode
     123        mov     a_pvBuf, eax
     124%elif !BS3_MODE_IS_RM_OR_V86(TMPL_MODE)
     125        push    word a_pvBufSel
     126        push    word a_pvBuf
     127        call    Bs3SelProtFar16DataToRealMode
     128        mov     a_pvBuf, ax
     129        mov     a_pvBufSel, dx
     130%endif
     131
     132        ;
     133        ; Set up the BIOS call parameters.
     134        ;
     135        mov     ah, 02h                     ; read
     136        mov     al, a_cSectors
     137        mov     cx, a_uCylinder
     138        xchg    ch, cl
     139        shl     cl, 6
     140        or      cl, a_uSector
     141        mov     dl, a_bDrive
     142        mov     dh, a_uHead
     143        mov     bx, a_pvBuf
     144        mov     di, a_pvBufSel
    105145
    106146        ;
     
    118158        BS3_SET_BITS 16
    119159%endif
    120         ; Ralf Brown suggest setting es:di to NULL before the call. This is also helpful
    121         ; wrt to IVT manipulation (next step).
    122         xor     di, di
     160
     161        ;
     162        ; Make the call.
     163        ;
    123164        mov     es, di
    124 
    125         ;
    126         ; Save current and restore the original IVT[13h] entry.
    127         ;
    128         mov     si, seg g_aBs3RmIvtOriginal
    129         mov     ds, si
    130         mov     si, g_aBs3RmIvtOriginal
    131 
    132         push    word [es:13h * 4]
    133         mov     ax, [si + 13h * 4]
    134         mov     [es:13h * 4], ax
    135 
    136         push    word [es:13h * 4 + 2]
    137         mov     ax, [si + 13h * 4 + 2]
    138         mov     [es:13h * 4 + 2], ax
    139 
    140         ;
    141         ; Make the call.
    142         ;
    143         mov     ax, 0800h                   ; ah=08h
    144         xor     di, di                      ; ralf brown suggestion to guard against bios bugs.
    145         mov     es, di
     165;        pushf
     166;        sti
    146167        int     13h
    147 
    148         ;
    149         ; Restore the modified IVT[13h] entry.
    150         ; Must not touch EFLAGS.CF!
    151         ;
    152         push    word 0
    153         pop     ds
    154         pop     word [ds:13h * 4 + 2]
    155         pop     word [ds:13h * 4]
     168;        popf
    156169
    157170        ;
     
    167180 %endif
    168181%endif
     182hlt
     183
    169184        ;
    170185        ; Check that we didn't failed.
    171186        ;
    172187        jc      .failed_return_ah
    173 
    174         ;
    175         ; Save the return values.
    176         ;   CL[7:6]:CH = max cylinders.
    177         ;   DH         = max heads
    178         ;   CL[5:0]    = max sectors
    179         ; Other stuff we don't care about:
    180         ;   AH         = 0
    181         ;   AL         = undefined/zero
    182         ;   BL         = drive type
    183         ;   DL         = max drives.
    184         ;   ES:DI      = driver parameter table for floppies.
    185         ;
    186 %ifdef TMPL_16BIT
    187         les     di, a_pMaxHead
    188         mov     [es:di], dh
    189 
    190         les     di, a_puMaxSector
    191         mov     al, 3fh
    192         and     al, cl
    193         mov     [es:di], al
    194 
    195         les     di, a_puMaxCylinder
    196         shr     cl, 6
    197         xchg    cl, ch
    198         mov     [es:di], cx
    199 %else
    200         mov     xDI, a_pMaxHead
    201         mov     [xDI], dh
    202 
    203         mov     xDI, a_puMaxSector
    204         mov     al, 3fh
    205         and     al, cl
    206         mov     [xDI], al
    207 
    208         mov     xDI, a_puMaxCylinder
    209         shr     cl, 6
    210         xchg    cl, ch
    211         mov     [xDI], cx
    212 %endif
     188        test    ah, ah
     189        jnz     .failed_return_ah
    213190
    214191        ;
     
    243220        dec     al
    244221        jmp     .return
    245 BS3_PROC_END_MODE   Bs3DiskQueryGeometry
    246 
     222BS3_PROC_END_MODE   Bs3DiskRead
     223
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-rm-InitAll.c

    r98103 r102157  
    5959    Bs3InitGdt_rm_far();
    6060
     61#ifdef BS3_INIT_ALL_WITH_HIGH_DLLS
     62    /*
     63     * Load the high DLLs (if any) now, before we bugger up the PIC and
     64     * replace the IVT.
     65     */
     66    Bs3InitHighDlls_rm_far();
     67#endif
     68
    6169    /*
    6270     * Before we disable all interrupts, try convince the BIOS to stop the
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk

    r102127 r102157  
    9797$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3ExtCtxGetFsw)
    9898$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3PicUpdateMask)
     99$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabAllocFixed)
    99100$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabFree)
    100101$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3TestSubErrorCount)
     
    194195$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3SwitchTo32BitAndCallC)
    195196$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3BiosInt15h88)
     197$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3DiskQueryGeometry)
     198$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3DiskRead)
     199$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3MemCopyFlat)
    196200$(call BS3KIT_FN_GEN_MODE_NEARSTUB,bs3kit-common-16,Bs3TrapInit)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h

    r102127 r102157  
    181181#define Bs3SlabAlloc BS3_CMN_MANGLER(Bs3SlabAlloc)
    182182#define Bs3SlabAllocEx BS3_CMN_MANGLER(Bs3SlabAllocEx)
     183#define Bs3SlabAllocFixed BS3_CMN_MANGLER(Bs3SlabAllocFixed)
    183184#define Bs3SlabFree BS3_CMN_MANGLER(Bs3SlabFree)
    184185#define Bs3SlabInit BS3_CMN_MANGLER(Bs3SlabInit)
     
    251252# define Bs3BiosInt15hE820 BS3_MODE_MANGLER(Bs3BiosInt15hE820)
    252253# define Bs3CpuDetect BS3_MODE_MANGLER(Bs3CpuDetect)
     254# define Bs3DiskQueryGeometry BS3_MODE_MANGLER(Bs3DiskQueryGeometry)
     255# define Bs3DiskRead BS3_MODE_MANGLER(Bs3DiskRead)
     256# define Bs3MemCopyFlat BS3_MODE_MANGLER(Bs3MemCopyFlat)
    253257# define Bs3SwitchTo32BitAndCallC BS3_MODE_MANGLER(Bs3SwitchTo32BitAndCallC)
    254258# define Bs3TestDoModes BS3_MODE_MANGLER(Bs3TestDoModes)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h

    r102127 r102157  
    181181#undef Bs3SlabAlloc
    182182#undef Bs3SlabAllocEx
     183#undef Bs3SlabAllocFixed
    183184#undef Bs3SlabFree
    184185#undef Bs3SlabInit
     
    251252# undef Bs3BiosInt15hE820
    252253# undef Bs3CpuDetect
     254# undef Bs3DiskQueryGeometry
     255# undef Bs3DiskRead
     256# undef Bs3MemCopyFlat
    253257# undef Bs3SwitchTo32BitAndCallC
    254258# undef Bs3TestDoModes
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h

    r102127 r102157  
    615615# define BS3_FP_OFF(a_pv)            ((uintptr_t)(a_pv))
    616616#endif
     617
     618/**
     619 * Converts a far real mode address to a 32-bit flat address.
     620 *
     621 * @returns Flat address.
     622 * @param   a_pv        The _real_ _mode_ far pointer to convert.
     623 */
     624#define BS3_FP_REAL_TO_FLAT(a_pv)   (((uint32_t)BS3_FP_SEG(a_pv) << 4) + BS3_FP_OFF(a_pv))
    617625
    618626/** @def BS3_MAKE_PROT_R0PTR_FROM_FLAT
     
    17571765 * @param   pvSrc           The source buffer.
    17581766 * @param   cbToCopy        The number of bytes to copy.
     1767 * @sa      Bs3MemCopyFlat
    17591768 */
    17601769BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3MemCpy,(void BS3_FAR *pvDst, const void BS3_FAR *pvSrc, size_t cbToCopy));
     
    21522161
    21532162/**
    2154  * Allocates one or more chunks rom a slab.
     2163 * Allocates one or more chunks from a slab.
    21552164 *
    21562165 * @returns Pointer to the request number of chunks on success, NULL if we're
     
    21612170 */
    21622171BS3_CMN_PROTO_STUB(void BS3_FAR *, Bs3SlabAllocEx,(PBS3SLABCTL pSlabCtl, uint16_t cChunks, uint16_t fFlags));
     2172
     2173/**
     2174 * Allocates a specific range of chunks from a slab.
     2175 *
     2176 * @returns Number of chunks it was possible to allocate in the slab.
     2177 * @retval  0 if the given address isn't in the slab.
     2178 * @retval  UINT16_MAX if one or more of the requested chunks are already in
     2179 *          use, so the request cannot be fulfilled.
     2180 * @param   pSlabCtl        The slab control structure to allocate from.
     2181 * @param   uFlatAddr       The flat address of the range to allocate.
     2182 * @param   cChunks         The number of contiguous chunks we want.
     2183 */
     2184BS3_CMN_PROTO_STUB(uint16_t, Bs3SlabAllocFixed,(PBS3SLABCTL pSlabCtl, uint32_t uFlatAddr, uint16_t cChunks));
    21632185
    21642186/**
     
    25422564 * Call 16-bit prot mode function from v8086 mode.
    25432565 *
    2544  * This switches from v8086 mode to 16-bit protected mode (code) and executed
     2566 * This switches from v8086 mode to 16-bit protected mode (code) and executes
    25452567 * @a fpfnCall with @a cbParams bytes of parameters pushed on the stack.
    25462568 * Afterwards it switches back to v8086 mode and returns a 16-bit status code.
     
    41314153
    41324154/**
     4155 * Initializes all of boot sector kit \#3 as well as the high DLLs.
     4156 */
     4157BS3_DECL(void) Bs3InitAllWithHighDlls_rm(void);
     4158
     4159/**
    41334160 * Initializes the REAL and TILED memory pools.
    41344161 *
     
    41414168 */
    41424169BS3_DECL_FAR(void) Bs3InitGdt_rm_far(void);
     4170
     4171/**
     4172 * Initializes (loads) any high DLLs.
     4173 *
     4174 * @note This cannot be called after the PIC or traps have been initialized!
     4175 */
     4176BS3_DECL_FAR(void) Bs3InitHighDlls_rm_far(void);
    41434177
    41444178
     
    43374371
    43384372/**
     4373 * Special version of memcpy for copying from/to real mode.
     4374 *
     4375 * @returns pvDst
     4376 * @param   uFlatDst        The flat address of the destination buffer.
     4377 * @param   uFlatSrc        The flat address of the source buffer.
     4378 * @param   cbToCopy        The number of bytes to copy.  Max 64KB.
     4379 *
     4380 * @todo    Only work on 386+ at present.   Could be made to work for 286 and
     4381 *          addresses < 16MB if we care...
     4382 */
     4383BS3_MODE_PROTO_STUB(void BS3_FAR *, Bs3MemCopyFlat,(uint32_t uFlatDst, uint32_t uFlatSrc, uint32_t cbToCopy));
     4384
     4385/**
    43394386 * Executes the array of tests in every possibly mode.
    43404387 *
     
    45464593/** @} */
    45474594
     4595/** @defgroup grp_bs3kit_disk   Disk via INT 13h
     4596 * @{
     4597 */
     4598
     4599/**
     4600 * Performs a int 13h function AL=08h call to get the driver parameters.
     4601 *
     4602 * @returns 0 on success, non-zero error BIOS code on failure.
     4603 * @param   bDrive          The drive to get parameters for.
     4604 * @param   puMaxCylinder   Where to store the max cylinder value.
     4605 *                          Range: 0 thru *pcMaxCylinder.
     4606 * @param   puMaxHead       Where to store the max head value.
     4607 *                          Range: 0 thru *pcMaxHead.
     4608 * @param   puMaxSector     Where to store the max sector value.
     4609 *                          Range: 1 thru *pcMaxSector.
     4610 */
     4611BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskQueryGeometry,(uint8_t bDrive, uint16_t *puMaxCylinder,
     4612                                                   uint8_t *puMaxHead, uint8_t *puMaxSector));
     4613
     4614/**
     4615 * Performs a int 13h function AL=08h call to get the driver parameters.
     4616 *
     4617 * @returns 0 on success, non-zero error BIOS code on failure.
     4618 * @param   bDrive          The drive to read from.
     4619 * @param   uCylinder       The cylinder to start read at (0-max).
     4620 * @param   uHead           The head to start reading at (0-max).
     4621 * @param   uSector         The sector to start reading at (1-max).
     4622 * @param   cSectors        The number of sectors to read (1+).
     4623 * @param   pvBuf           The buffer to read into.  This MUST be addressable
     4624 *                          from real mode!
     4625 */
     4626BS3_MODE_PROTO_STUB(uint8_t, Bs3DiskRead,(uint8_t bDrive, uint16_t uCylinder, uint8_t uHead, uint8_t uSector,
     4627                                          uint8_t cSectors, void RT_FAR *pvBuf));
     4628
     4629/** @} */
     4630
    45484631
    45494632/** @} */
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac

    r99443 r102157  
    333333;
    334334; !!HACK ALERT!!
     335 %ifndef BS3_IS_HIGH_IMAGE
    335336segment BS3FLAT use32 class=BS3FLAT
    336337GROUP FLAT BS3FLAT
     338 %else
     339; For HIGH DLLs the hack is WRONG, so we just declare both BS3FLAT and FLAT the way
     340; wlink wants flat groups to be defined. (See FIX_FRAME_FLAT use in omfreloc.c.)
     341GROUP BS3FLAT
     342GROUP FLAT
     343 %endif
    337344%endif
    338345
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette