VirtualBox

Changeset 59932 in vbox


Ignore:
Timestamp:
Mar 4, 2016 4:01:18 PM (9 years ago)
Author:
vboxsync
Message:

bs3kit: Eliminate BS3_MSC64_FIXUP_HACK and the associated /TP (compile as C++) option as these aren't durable workarounds for the problem. Instead do quick COFF -> OMF conversion so we can better control what WLINK will do during link. This addresses a few other issues too, like dot-prefixed segment names and incorrect fixups (not using FLAT but, symbol segment as the reference frame).

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
8 edited

Legend:

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

    r59863 r59932  
    118118TOOL_Bs3Gcc64Elf64_COMPILE_C_DEPEND = $(VBoxBs3ObjConverter_1_TARGET)
    119119TOOL_Bs3Gcc64Elf64_COMPILE_C_DEPORD =
    120 TOOL_Bs3Gcc64Elf64_COMPILE_C_OUTPUT =
     120TOOL_Bs3Gcc64Elf64_COMPILE_C_OUTPUT = $(obj).orignal
    121121define TOOL_Bs3Gcc64Elf64_COMPILE_C_CMDS
    122122        $(QUIET)$(TOOL_Bs3Gcc64Elf64_CC) -c\
     
    139139TOOL_Bs3Gcc64Elf64_COMPILE_CXX_DEPEND = $(VBoxBs3ObjConverter_1_TARGET)
    140140TOOL_Bs3Gcc64Elf64_COMPILE_CXX_DEPORD =
    141 TOOL_Bs3Gcc64Elf64_COMPILE_CXX_OUTPUT =
     141TOOL_Bs3Gcc64Elf64_COMPILE_CXX_OUTPUT = $(obj).orignal
    142142define TOOL_Bs3Gcc64Elf64_COMPILE_CXX_CMDS
    143143        $(QUIET)$(TOOL_Bs3Gcc64Elf64_CXX) -c\
     
    157157TOOL_Bs3Vcc64_CXX = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_CXX)
    158158TOOL_Bs3Vcc64_COBJSUFF                 = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COBJSUFF)
    159 TOOL_Bs3Vcc64_CFLAGS                   = $(filter-out -TC,$(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_CFLAGS)) -TP # compile as C++
     159TOOL_Bs3Vcc64_CFLAGS                   = $(filter-out -TC,$(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_CFLAGS))
    160160TOOL_Bs3Vcc64_CFLAGS.debug             =
    161161TOOL_Bs3Vcc64_CFLAGS.dbgopt            = -O1
     
    166166TOOL_Bs3Vcc64_COMPILE_C_DEPEND         = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_C_DEPEND) $(VBoxBs3ObjConverter_1_TARGET)
    167167TOOL_Bs3Vcc64_COMPILE_C_DEPORD         = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_C_DEPORD)
    168 TOOL_Bs3Vcc64_COMPILE_C_OUTPUT         = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_C_OUTPUT)
     168TOOL_Bs3Vcc64_COMPILE_C_OUTPUT         = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_C_OUTPUT) $(obj).orignal
    169169TOOL_Bs3Vcc64_COMPILE_C_OUTPUT_MAYBE   = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_C_OUTPUT_MAYBE)
    170170define TOOL_Bs3Vcc64_COMPILE_C_CMDS
     
    183183TOOL_Bs3Vcc64_COMPILE_CXX_DEPEND       = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_CXX_DEPEND) $(VBoxBs3ObjConverter_1_TARGET)
    184184TOOL_Bs3Vcc64_COMPILE_CXX_DEPORD       = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_CXX_DEPORD)
    185 TOOL_Bs3Vcc64_COMPILE_CXX_OUTPUT       = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_CXX_OUTPUT)
     185TOOL_Bs3Vcc64_COMPILE_CXX_OUTPUT       = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_CXX_OUTPUT) $(obj).orignal
    186186TOOL_Bs3Vcc64_COMPILE_CXX_OUTPUT_MAYBE = $(TOOL_$(VBOX_VCC_TOOL_STEM)AMD64_COMPILE_CXX_OUTPUT_MAYBE)
    187187define TOOL_Bs3Vcc64_COMPILE_CXX_CMDS
     
    212212TOOL_Bs3Ow32_COMPILE_C_DEPEND         = $(TOOL_OPENWATCOM_COMPILE_C_DEPEND) $(VBoxBs3ObjConverter_1_TARGET)
    213213TOOL_Bs3Ow32_COMPILE_C_DEPORD         = $(TOOL_OPENWATCOM_COMPILE_C_DEPORD)
    214 TOOL_Bs3Ow32_COMPILE_C_OUTPUT         = $(TOOL_OPENWATCOM_COMPILE_C_OUTPUT)
     214TOOL_Bs3Ow32_COMPILE_C_OUTPUT         = $(TOOL_OPENWATCOM_COMPILE_C_OUTPUT) $(obj).orignal
    215215TOOL_Bs3Ow32_COMPILE_C_OUTPUT_MAYBE   = $(TOOL_OPENWATCOM_COMPILE_C_OUTPUT_MAYBE)
    216216define TOOL_Bs3Ow32_COMPILE_C_CMDS
     
    230230TOOL_Bs3Ow32_COMPILE_CXX_DEPEND       = $(TOOL_OPENWATCOM_COMPILE_CXX_DEPEND) $(VBoxBs3ObjConverter_1_TARGET)
    231231TOOL_Bs3Ow32_COMPILE_CXX_DEPORD       = $(TOOL_OPENWATCOM_COMPILE_CXX_DEPORD)
    232 TOOL_Bs3Ow32_COMPILE_CXX_OUTPUT       = $(TOOL_OPENWATCOM_COMPILE_CXX_OUTPUT)
     232TOOL_Bs3Ow32_COMPILE_CXX_OUTPUT       = $(TOOL_OPENWATCOM_COMPILE_CXX_OUTPUT) $(obj).orignal
    233233TOOL_Bs3Ow32_COMPILE_CXX_OUTPUT_MAYBE = $(TOOL_OPENWATCOM_COMPILE_CXX_OUTPUT_MAYBE)
    234234define TOOL_Bs3Ow32_COMPILE_CXX_CMDS
     
    390390          segment BS3DATA32_DATA \
    391391          segment DATA32 \
     392          segment BS3DATA64 \
     393          segment DATA64 \
     394          segment .data \
     395          segment DATA64_END \
    392396        clname BS3CODE32 \
    393397          segment BS3TEXT32 \
    394398          segment TEXT32 \
    395         clname CODE \
     399        clname BS3CODE64 \
    396400          segment BS3TEXT64 \
    397401          segment TEXT64 \
    398402          segment .text \
    399403          segment .rdata \
    400         clname DATA \
    401           segment BS3DATA64 \
    402           segment DATA64 \
    403           segment .data \
    404           segment .pdata \
    405           segment .xdata \
    406404
    407405TEMPLATE_VBoxBS3KitImg_DEPS = \
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp

    r59902 r59932  
    3434#include <errno.h>
    3535#include <iprt/types.h>
     36#include <iprt/ctype.h>
    3637#include <iprt/assert.h>
    3738#include <iprt/x86.h>
     
    4041#include <iprt/formats/elf-amd64.h>
    4142#include <iprt/formats/pecoff.h>
     43#include <iprt/formats/omf.h>
    4244
    4345
     
    176178static bool error(const char *pszFile, const char *pszFormat, ...)
    177179{
     180    fflush(stdout);
    178181    fprintf(stderr, "error: %s: ", pszFile);
    179182    va_list va;
     
    184187}
    185188
     189
     190
     191/*********************************************************************************************************************************
     192*   Common OMF Writer                                                                                                            *
     193*********************************************************************************************************************************/
     194
     195/** Entry for each segment/section in the source format for mapping it to a
     196 *  segment defintion. */
     197typedef struct OMFTOSEGDEF
     198{
     199    /** The segment defintion index of the section, UINT16_MAX if not translated. */
     200    uint16_t    iSegDef;
     201    /** The group index for this segment, UINT16_MAX if not applicable. */
     202    uint16_t    iGrpDef;
     203    /** The class name table entry, UINT16_MAX if not applicable. */
     204    uint16_t    iClassNm;
     205    /** The group name for this segment, UINT16_MAX if not applicable. */
     206    uint16_t    iGrpNm;
     207    /** The group name for this segment, UINT16_MAX if not applicable. */
     208    uint16_t    iSegNm;
     209    /** The number of public definitions for this segment. */
     210    uint32_t    cPubDefs;
     211    /** The segment name (OMF). */
     212    char       *pszName;
     213} OMFTOSEGDEF;
     214/** Pointer to a segment/section to segdef mapping. */
     215typedef OMFTOSEGDEF *POMFTOSEGDEF;
     216
     217/** Symbol table translation type. */
     218typedef enum OMFSYMTYPE
     219{
     220    /** Invalid symbol table entry (aux sym). */
     221    OMFSYMTYPE_INVALID = 0,
     222    /** Ignored. */
     223    OMFSYMTYPE_IGNORED,
     224    /** A public defintion.  */
     225    OMFSYMTYPE_PUBDEF,
     226    /** An external definition. */
     227    OMFSYMTYPE_EXTDEF,
     228    /** A segment reference for fixups. */
     229    OMFSYMTYPE_SEGDEF,
     230    /** Internal symbol that may be used for fixups. */
     231    OMFSYMTYPE_INTERNAL
     232} OMFSYMTYPE;
     233
     234/** Symbol table translation. */
     235typedef struct OMFSYMBOL
     236{
     237    /** What this source symbol table entry should be translated into. */
     238    OMFSYMTYPE      enmType;
     239    /** The OMF table index. UINT16_MAX if not applicable. */
     240    uint16_t        idx;
     241    /** The OMF segment definition index. */
     242    uint16_t        idxSegDef;
     243    /** The OMF group definition index. */
     244    uint16_t        idxGrpDef;
     245} OMFSYMBOL;
     246/** Pointer to an source symbol table translation entry. */
     247typedef OMFSYMBOL *POMFSYMBOL;
     248
     249/**
     250 * OMF converter & writer instance.
     251 */
     252typedef struct OMFWRITER
     253{
     254    /** The source file name (for bitching). */
     255    const char     *pszSrc;
     256    /** The destination output file. */
     257    FILE           *pDst;
     258
     259    /** Number of source segments/sections. */
     260    uint32_t        cSegments;
     261    /** Pointer to the table mapping from source segments/section to segdefs. */
     262    POMFTOSEGDEF    paSegments;
     263
     264    /** Number of entries in the source symbol table. */
     265    uint32_t        cSymbols;
     266    /** Pointer to the table mapping from source symbols to OMF stuff. */
     267    POMFSYMBOL      paSymbols;
     268
     269    /** The index of the next list of names entry. */
     270    uint16_t        idxNextName;
     271
     272    /** The current record size.  */
     273    uint16_t        cbRec;
     274    /** The current record type */
     275    uint8_t         bType;
     276    /** The record data buffer (too large, but whatever).  */
     277    uint8_t         abData[_1K + 64];
     278    /** Alignment padding. */
     279    uint8_t         abAlign[2];
     280
     281    /** Current FIXUPP entry. */
     282    uint8_t         iFixupp;
     283    /** FIXUPP records being prepared for LEDATA currently stashed in abData.
     284     * We may have to adjust addend values in the LEDATA when converting to OMF
     285     * fixups. */
     286    struct
     287    {
     288        uint16_t    cbRec;
     289        uint8_t     abData[_1K + 64];
     290        uint8_t     abAlign[2]; /**< Alignment padding. */
     291    } aFixupps[3];
     292
     293    /** The index of the FLAT group. */
     294    uint16_t        idxGrpFlat;
     295    /** The EXTDEF index of the __ImageBase symbol. */
     296    uint16_t        idxExtImageBase;
     297} OMFWRITE;
     298/** Pointer to an OMF writer. */
     299typedef OMFWRITE *POMFWRITER;
     300
     301
     302/**
     303 * Creates an OMF writer instance.
     304 */
     305static POMFWRITER omfWriter_Create(const char *pszSrc, uint32_t cSegments, uint32_t cSymbols, FILE *pDst)
     306{
     307    POMFWRITER pThis = (POMFWRITER)calloc(sizeof(OMFWRITER), 1);
     308    if (pThis)
     309    {
     310        pThis->pszSrc        = pszSrc;
     311        pThis->idxNextName   = 1;       /* We start counting at 1. */
     312        pThis->cSegments     = cSegments;
     313        pThis->paSegments    = (POMFTOSEGDEF)calloc(sizeof(OMFTOSEGDEF), cSegments);
     314        if (pThis->paSegments)
     315        {
     316            pThis->cSymbols  = cSymbols;
     317            pThis->paSymbols = (POMFSYMBOL)calloc(sizeof(OMFSYMBOL), cSymbols);
     318            if (pThis->paSymbols)
     319            {
     320                pThis->pDst  = pDst;
     321                return pThis;
     322            }
     323            free(pThis->paSegments);
     324        }
     325        free(pThis);
     326    }
     327    error(pszSrc, "Out of memory!\n");
     328    return NULL;
     329}
     330
     331/**
     332 * Destroys the given OMF writer instance.
     333 * @param   pThis           OMF writer instance.
     334 */
     335static void omfWriter_Destroy(POMFWRITER pThis)
     336{
     337    free(pThis->paSymbols);
     338    for (uint32_t i = 0; i < pThis->cSegments; i++)
     339        if (pThis->paSegments[i].pszName)
     340            free(pThis->paSegments[i].pszName);
     341    free(pThis->paSegments);
     342    free(pThis);
     343}
     344
     345static bool omfWriter_RecBegin(POMFWRITER pThis, uint8_t bType)
     346{
     347    pThis->bType = bType;
     348    pThis->cbRec = 0;
     349    return true;
     350}
     351
     352static bool omfWriter_RecAddU8(POMFWRITER pThis, uint8_t b)
     353{
     354    if (pThis->cbRec < OMF_MAX_RECORD_PAYLOAD)
     355    {
     356        pThis->abData[pThis->cbRec++] = b;
     357        return true;
     358    }
     359    return error(pThis->pszSrc, "Exceeded max OMF record length (bType=%#x)!\n", pThis->bType);
     360}
     361
     362static bool omfWriter_RecAddU16(POMFWRITER pThis, uint16_t u16)
     363{
     364    if (pThis->cbRec + 2 <= OMF_MAX_RECORD_PAYLOAD)
     365    {
     366        pThis->abData[pThis->cbRec++] = (uint8_t)u16;
     367        pThis->abData[pThis->cbRec++] = (uint8_t)(u16 >> 8);
     368        return true;
     369    }
     370    return error(pThis->pszSrc, "Exceeded max OMF record length (bType=%#x)!\n", pThis->bType);
     371}
     372
     373static bool omfWriter_RecAddU32(POMFWRITER pThis, uint32_t u32)
     374{
     375    if (pThis->cbRec + 4 <= OMF_MAX_RECORD_PAYLOAD)
     376    {
     377        pThis->abData[pThis->cbRec++] = (uint8_t)u32;
     378        pThis->abData[pThis->cbRec++] = (uint8_t)(u32 >> 8);
     379        pThis->abData[pThis->cbRec++] = (uint8_t)(u32 >> 16);
     380        pThis->abData[pThis->cbRec++] = (uint8_t)(u32 >> 24);
     381        return true;
     382    }
     383    return error(pThis->pszSrc, "Exceeded max OMF record length (bType=%#x)!\n", pThis->bType);
     384}
     385
     386static bool omfWriter_RecAddIdx(POMFWRITER pThis, uint16_t idx)
     387{
     388    if (idx < 128)
     389        return omfWriter_RecAddU8(pThis, (uint8_t)idx);
     390    if (idx < _32K)
     391        return omfWriter_RecAddU8(pThis, (uint8_t)(idx >> 7) | 0x80)
     392            && omfWriter_RecAddU8(pThis, (uint8_t)idx);
     393    return error(pThis->pszSrc, "Index out of range %#x\n", idx);
     394}
     395
     396static bool omfWriter_RecAddBytes(POMFWRITER pThis, const void *pvData, size_t cbData)
     397{
     398    if (cbData + pThis->cbRec <= OMF_MAX_RECORD_PAYLOAD)
     399    {
     400        memcpy(&pThis->abData[pThis->cbRec], pvData, cbData);
     401        pThis->cbRec += (uint16_t)cbData;
     402        return true;
     403    }
     404    return error(pThis->pszSrc, "Exceeded max OMF record length (bType=%#x, cbData=%#x)!\n", pThis->bType, (unsigned)cbData);
     405}
     406
     407static bool omfWriter_RecAddStringN(POMFWRITER pThis, const char *pchString, size_t cchString)
     408{
     409    if (cchString < 256)
     410    {
     411        return omfWriter_RecAddU8(pThis, (uint8_t)cchString)
     412            && omfWriter_RecAddBytes(pThis, pchString, cchString);
     413    }
     414    return error(pThis->pszSrc, "String too long (%u bytes): '%*.*s'\n",
     415                 (unsigned)cchString, (int)cchString, (int)cchString, pchString);
     416}
     417
     418static bool omfWriter_RecAddString(POMFWRITER pThis, const char *pszString)
     419{
     420    return omfWriter_RecAddStringN(pThis, pszString, strlen(pszString));
     421}
     422
     423static bool omfWriter_RecEnd(POMFWRITER pThis, bool fAddCrc)
     424{
     425    if (   !fAddCrc
     426        || omfWriter_RecAddU8(pThis, 0))
     427    {
     428        OMFRECHDR RecHdr = { pThis->bType, RT_H2LE_U16(pThis->cbRec) };
     429        if (   fwrite(&RecHdr, sizeof(RecHdr), 1, pThis->pDst) == 1
     430            && fwrite(pThis->abData, pThis->cbRec, 1, pThis->pDst) == 1)
     431        {
     432            pThis->bType = 0;
     433            pThis->cbRec = 0;
     434            return true;
     435        }
     436        return error(pThis->pszSrc, "Write error\n");
     437    }
     438    return false;
     439}
     440
     441static bool omfWriter_RecEndWithCrc(POMFWRITER pThis)
     442{
     443    return omfWriter_RecEnd(pThis, true /*fAddCrc*/);
     444}
     445
     446
     447static bool omfWriter_BeginModule(POMFWRITER pThis, const char *pszFile)
     448{
     449    return omfWriter_RecBegin(pThis, OMF_THEADR)
     450        && omfWriter_RecAddString(pThis, pszFile)
     451        && omfWriter_RecEndWithCrc(pThis);
     452}
     453
     454static bool omfWriter_LNamesAddN(POMFWRITER pThis, const char *pchName, size_t cchName, uint16_t *pidxName)
     455{
     456    /* split? */
     457    if (pThis->cbRec + 1 /*len*/ + cchName + 1 /*crc*/ > OMF_MAX_RECORD_PAYLOAD)
     458    {
     459        if (pThis->cbRec == 0)
     460            return error(pThis->pszSrc, "Too long LNAME '%*.*s'\n", (int)cchName, (int)cchName, pchName);
     461        if (   !omfWriter_RecEndWithCrc(pThis)
     462            || !omfWriter_RecBegin(pThis, OMF_LNAMES))
     463            return false;
     464    }
     465
     466    if (pidxName)
     467        *pidxName = pThis->idxNextName;
     468    pThis->idxNextName++;
     469    return omfWriter_RecAddStringN(pThis, pchName, cchName);
     470}
     471
     472static bool omfWriter_LNamesAdd(POMFWRITER pThis, const char *pszName, uint16_t *pidxName)
     473{
     474    return omfWriter_LNamesAddN(pThis, pszName, strlen(pszName), pidxName);
     475}
     476
     477static bool omfWriter_LNamesBegin(POMFWRITER pThis)
     478{
     479    /* First entry is an empty string. */
     480    return omfWriter_RecBegin(pThis, OMF_LNAMES)
     481        && (   pThis->idxNextName > 1
     482            || omfWriter_LNamesAddN(pThis, "", 0, NULL));
     483}
     484
     485static bool omfWriter_LNamesEnd(POMFWRITER pThis)
     486{
     487    return omfWriter_RecEndWithCrc(pThis);
     488}
     489
     490
     491static bool omfWriter_SegDef(POMFWRITER pThis, uint8_t bSegAttr, uint32_t cbSeg, uint16_t idxSegName, uint16_t idxSegClass)
     492{
     493    return omfWriter_RecBegin(pThis, OMF_SEGDEF32)
     494        && omfWriter_RecAddU8(pThis, bSegAttr)
     495        && omfWriter_RecAddU32(pThis, cbSeg)
     496        && omfWriter_RecAddIdx(pThis, idxSegName)
     497        && omfWriter_RecAddIdx(pThis, idxSegClass)
     498        && omfWriter_RecAddIdx(pThis, 1) /* overlay name index = NULL entry */
     499        && omfWriter_RecEndWithCrc(pThis);
     500}
     501
     502static bool omfWriter_GrpDefBegin(POMFWRITER pThis, uint16_t idxGrpName)
     503{
     504    return omfWriter_RecBegin(pThis, OMF_GRPDEF)
     505        && omfWriter_RecAddIdx(pThis, idxGrpName);
     506}
     507
     508static bool omfWriter_GrpDefAddSegDef(POMFWRITER pThis, uint16_t idxSegDef)
     509{
     510    return omfWriter_RecAddU8(pThis, 0xff)
     511        && omfWriter_RecAddIdx(pThis, idxSegDef);
     512}
     513
     514static bool omfWriter_GrpDefEnd(POMFWRITER pThis)
     515{
     516    return omfWriter_RecEndWithCrc(pThis);
     517}
     518
     519
     520static bool omfWriter_PubDefBegin(POMFWRITER pThis, uint16_t idxGrpDef, uint16_t idxSegDef)
     521{
     522    return omfWriter_RecBegin(pThis, OMF_PUBDEF32)
     523        && omfWriter_RecAddIdx(pThis, idxGrpDef)
     524        && omfWriter_RecAddIdx(pThis, idxSegDef)
     525        && (   idxSegDef != 0
     526            || omfWriter_RecAddU16(pThis, 0));
     527
     528}
     529
     530static bool omfWriter_PubDefAddN(POMFWRITER pThis, uint32_t uValue, const char *pchString, size_t cchString)
     531{
     532    /* Split? */
     533    if (pThis->cbRec + 1 + cchString + 4 + 1 + 1 > OMF_MAX_RECORD_PAYLOAD)
     534    {
     535        if (cchString >= 256)
     536            return error(pThis->pszSrc, "PUBDEF string too long %u ('%s')\n",
     537                         (unsigned)cchString, (int)cchString, (int)cchString, pchString);
     538        if (!omfWriter_RecEndWithCrc(pThis))
     539            return false;
     540
     541        /* Figure out the initial data length. */
     542        pThis->cbRec      = 1 + ((pThis->abData[0] & 0x80) != 0);
     543        if (pThis->abData[pThis->cbRec] != 0)
     544            pThis->cbRec += 1 + ((pThis->abData[pThis->cbRec] & 0x80) != 0);
     545        else
     546            pThis->cbRec += 3;
     547        pThis->bType = OMF_PUBDEF32;
     548    }
     549
     550    return omfWriter_RecAddStringN(pThis, pchString, cchString)
     551        && omfWriter_RecAddU32(pThis, uValue)
     552        && omfWriter_RecAddIdx(pThis, 0); /* type */
     553}
     554
     555static bool omfWriter_PubDefAdd(POMFWRITER pThis, uint32_t uValue, const char *pszString)
     556{
     557    return omfWriter_PubDefAddN(pThis, uValue, pszString, strlen(pszString));
     558}
     559
     560static bool omfWriter_PubDefEnd(POMFWRITER pThis)
     561{
     562    return omfWriter_RecEndWithCrc(pThis);
     563}
     564
     565/**
     566 * EXTDEF - Begin record.
     567 */
     568static bool omfWriter_ExtDefBegin(POMFWRITER pThis)
     569{
     570    return omfWriter_RecBegin(pThis, OMF_EXTDEF);
     571
     572}
     573
     574/**
     575 * EXTDEF - Add an entry, split record if necessary.
     576 */
     577static bool omfWriter_ExtDefAddN(POMFWRITER pThis, const char *pchString, size_t cchString)
     578{
     579    /* Split? */
     580    if (pThis->cbRec + 1 + cchString + 1 + 1 > OMF_MAX_RECORD_PAYLOAD)
     581    {
     582        if (cchString >= 256)
     583            return error(pThis->pszSrc, "EXTDEF string too long %u ('%s')\n",
     584                         (unsigned)cchString, (int)cchString, (int)cchString, pchString);
     585        if (   !omfWriter_RecEndWithCrc(pThis)
     586            || !omfWriter_RecBegin(pThis, OMF_EXTDEF))
     587            return false;
     588    }
     589
     590    return omfWriter_RecAddStringN(pThis, pchString, cchString)
     591        && omfWriter_RecAddIdx(pThis, 0); /* type */
     592}
     593
     594/**
     595 * EXTDEF - Add an entry, split record if necessary.
     596 */
     597static bool omfWriter_ExtDefAdd(POMFWRITER pThis, const char *pszString)
     598{
     599    return omfWriter_ExtDefAddN(pThis, pszString, strlen(pszString));
     600}
     601
     602/**
     603 * EXTDEF - End of record.
     604 */
     605static bool omfWriter_ExtDefEnd(POMFWRITER pThis)
     606{
     607    return omfWriter_RecEndWithCrc(pThis);
     608}
     609
     610/**
     611 * COMENT/LINK_PASS_SEP - Add a link pass separator comment.
     612 */
     613static bool omfWriter_LinkPassSeparator(POMFWRITER pThis)
     614{
     615    return omfWriter_RecBegin(pThis, OMF_COMENT)
     616        && omfWriter_RecAddU8(pThis, OMF_CTYP_NO_LIST)
     617        && omfWriter_RecAddU8(pThis, OMF_CCLS_LINK_PASS_SEP)
     618        && omfWriter_RecAddU8(pThis, 1)
     619        && omfWriter_RecEndWithCrc(pThis);
     620}
     621
     622/**
     623 * LEDATA + FIXUPP - Begin records.
     624 */
     625static bool omfWriter_LEDataBegin(POMFWRITER pThis, uint16_t idxSeg, uint32_t offSeg,
     626                                  uint32_t cbData, uint32_t cbRawData, void const *pbRawData, uint8_t **ppbData)
     627{
     628    if (   omfWriter_RecBegin(pThis, OMF_LEDATA32)
     629        && omfWriter_RecAddIdx(pThis, idxSeg)
     630        && omfWriter_RecAddU32(pThis, offSeg))
     631    {
     632        if (   cbData <= _1K
     633            && pThis->cbRec + cbData + 1 <= OMF_MAX_RECORD_PAYLOAD)
     634        {
     635            uint8_t *pbDst = &pThis->abData[pThis->cbRec];
     636            if (ppbData)
     637                *ppbData = pbDst;
     638
     639            if (cbRawData)
     640                memcpy(pbDst, pbRawData, RT_MIN(cbData, cbRawData));
     641            if (cbData > cbRawData)
     642                memset(&pbDst[cbRawData], 0, cbData - cbRawData);
     643
     644            pThis->cbRec += cbData;
     645
     646            /* Reset the associated FIXUPP records. */
     647            pThis->iFixupp = 0;
     648            for (unsigned i = 0; i < RT_ELEMENTS(pThis->aFixupps); i++)
     649                pThis->aFixupps[i].cbRec = 0;
     650            return true;
     651        }
     652        error(pThis->pszSrc, "Too much data for LEDATA record! (%#x)\n", (unsigned)cbData);
     653    }
     654    return false;
     655}
     656
     657/**
     658 * LEDATA + FIXUPP - Add FIXUPP subrecord bytes, split if necessary.
     659 */
     660static bool omfWriter_LEDataAddFixuppBytes(POMFWRITER pThis, void *pvSubRec, size_t cbSubRec)
     661{
     662    /* Split? */
     663    unsigned iFixupp = pThis->iFixupp;
     664    if (pThis->aFixupps[iFixupp].cbRec + cbSubRec >= OMF_MAX_RECORD_PAYLOAD)
     665    {
     666        iFixupp++;
     667        if (iFixupp >= RT_ELEMENTS(pThis->aFixupps))
     668            return error(pThis->pszSrc, "Out of FIXUPP records\n");
     669        pThis->iFixupp = iFixupp;
     670        pThis->aFixupps[iFixupp].cbRec = 0; /* paranoia */
     671    }
     672
     673    /* Append the sub-record data. */
     674    memcpy(&pThis->aFixupps[iFixupp].abData[pThis->aFixupps[iFixupp].cbRec], pvSubRec, cbSubRec);
     675    pThis->aFixupps[iFixupp].cbRec += (uint16_t)cbSubRec;
     676    return true;
     677}
     678
     679/**
     680 * LEDATA + FIXUPP - Add fixup, split if necessary.
     681 */
     682static bool omfWriter_LEDataAddFixup(POMFWRITER pThis, uint16_t offDataRec, bool fSelfRel, uint8_t bLocation,
     683                                     uint8_t bFrame, uint16_t idxFrame,
     684                                     uint8_t bTarget, uint16_t idxTarget, bool fTargetDisp, uint32_t offTargetDisp)
     685{
     686    if (g_cVerbose >= 2)
     687        printf("debug: FIXUP[%#x]: off=%#x frame=%u:%#x target=%u:%#x disp=%d:%#x\n", pThis->aFixupps[pThis->iFixupp].cbRec,
     688               offDataRec, bFrame, idxFrame, bTarget, idxTarget, fTargetDisp, offTargetDisp);
     689
     690    if (   offDataRec >= _1K
     691        || bFrame >= 6
     692        || bTarget > 6
     693        || idxFrame >= _32K
     694        || idxTarget >= _32K
     695        || fTargetDisp != (bTarget <= 4) )
     696        /*return*/ error(pThis->pszSrc,  "Internal error: off=%#x frame=%u:%#x target=%u:%#x disp=%d:%#x\n",
     697                     offDataRec, bFrame, idxFrame, bTarget, idxTarget, fTargetDisp, offTargetDisp);
     698
     699    /*
     700     * Encode the FIXUP subrecord.
     701     */
     702    uint8_t abFixup[16];
     703    uint8_t off = 0;
     704    /* Location */
     705    abFixup[off++] = (offDataRec >> 8) | (bLocation << 2) | ((uint8_t)!fSelfRel << 6) | 0x80;
     706    abFixup[off++] = (uint8_t)offDataRec;
     707    /* Fix Data */
     708    abFixup[off++] = 0x00 /*F=0*/ | (bFrame << 4) | 0x00 /*T=0*/ | bTarget;
     709    /* Frame Datum */
     710    if (bFrame <= OMF_FIX_F_FRAME_NO)
     711    {
     712        if (idxFrame >= 128)
     713            abFixup[off++] = (uint8_t)(idxFrame >> 8);
     714        abFixup[off++] = (uint8_t)idxFrame;
     715    }
     716    /* Target Datum */
     717    if (idxTarget >= 128)
     718        abFixup[off++] = (uint8_t)(idxTarget >> 8);
     719    abFixup[off++] = (uint8_t)idxTarget;
     720    /* Target Displacement */
     721    if (fTargetDisp)
     722    {
     723        abFixup[off++] = RT_BYTE1(offTargetDisp);
     724        abFixup[off++] = RT_BYTE2(offTargetDisp);
     725        abFixup[off++] = RT_BYTE3(offTargetDisp);
     726        abFixup[off++] = RT_BYTE4(offTargetDisp);
     727    }
     728
     729    return omfWriter_LEDataAddFixuppBytes(pThis, abFixup, off);
     730}
     731
     732/**
     733 * LEDATA + FIXUPP - End of records.
     734 */
     735static bool omfWriter_LEDataEnd(POMFWRITER pThis)
     736{
     737    if (omfWriter_RecEndWithCrc(pThis))
     738    {
     739        for (unsigned iFixupp = 0; iFixupp <= pThis->iFixupp; iFixupp++)
     740        {
     741            uint8_t const cbRec = pThis->aFixupps[iFixupp].cbRec;
     742            if (!cbRec)
     743                break;
     744            if (   !omfWriter_RecBegin(pThis, OMF_FIXUPP32)
     745                || !omfWriter_RecAddBytes(pThis, pThis->aFixupps[iFixupp].abData, cbRec)
     746                || !omfWriter_RecEndWithCrc(pThis))
     747                return false;
     748        }
     749        pThis->iFixupp = 0;
     750        return true;
     751    }
     752    return false;
     753}
     754
     755/**
     756 * MODEND - End of module, simple variant.
     757 */
     758static bool omfWriter_EndModule(POMFWRITER pThis)
     759{
     760    return omfWriter_RecBegin(pThis, OMF_MODEND32)
     761        && omfWriter_RecAddU8(pThis, 0)
     762        && omfWriter_RecEndWithCrc(pThis);
     763}
     764
     765
     766
     767
     768/*********************************************************************************************************************************
     769*   ELF64/AMD64 -> ELF64/i386 Converter                                                                                          *
     770*********************************************************************************************************************************/
    186771
    187772/** AMD64 relocation type names for ELF. */
     
    298883
    299884
     885
     886
     887
     888/*********************************************************************************************************************************
     889*   COFF -> OMF Converter                                                                                                        *
     890*********************************************************************************************************************************/
     891
    300892/** AMD64 relocation type names for (Microsoft) COFF. */
    301893static const char * const g_apszCoffAmd64RelTypes[] =
     
    320912};
    321913
    322 
    323 static const char *coffGetSymbolName(PCIMAGE_SYMBOL pSym, const char *pchStrTab, char pszShortName[16])
     914/** AMD64 relocation type sizes for (Microsoft) COFF. */
     915static uint8_t const g_acbCoffAmd64RelTypes[] =
     916{
     917    8, /* ABSOLUTE */
     918    8, /* ADDR64   */
     919    4, /* ADDR32   */
     920    4, /* ADDR32NB */
     921    4, /* REL32    */
     922    4, /* REL32_1  */
     923    4, /* REL32_2  */
     924    4, /* REL32_3  */
     925    4, /* REL32_4  */
     926    4, /* REL32_5  */
     927    2, /* SECTION  */
     928    4, /* SECREL   */
     929    1, /* SECREL7  */
     930    0, /* TOKEN    */
     931    4, /* SREL32   */
     932    0, /* PAIR     */
     933    4, /* SSPAN32  */
     934};
     935
     936/** Macro for getting the size of a AMD64 COFF relocation. */
     937#define COFF_AMD64_RELOC_SIZE(a_Type) ( (a_Type) < RT_ELEMENTS(g_acbCoffAmd64RelTypes) ? g_acbCoffAmd64RelTypes[(a_Type)] : 1)
     938
     939
     940static const char *coffGetSymbolName(PCIMAGE_SYMBOL pSym, const char *pchStrTab, uint32_t cbStrTab, char pszShortName[16])
    324941{
    325942    if (pSym->N.Name.Short != 0)
     
    329946        return pszShortName;
    330947    }
    331     return pchStrTab + pSym->N.Name.Long;
    332 }
    333 
    334 static bool convertcoff(const char *pszFile, uint8_t *pbFile, size_t cbFile)
     948    if (pSym->N.Name.Long < cbStrTab)
     949    {
     950        uint32_t const cbLeft = cbStrTab - pSym->N.Name.Long;
     951        const char    *pszRet = pchStrTab + pSym->N.Name.Long;
     952        if (memchr(pszRet, '\0', cbLeft) != NULL)
     953            return pszRet;
     954    }
     955    error("<null>",  "Invalid string table index %#x!\n", pSym->N.Name.Long);
     956    return "Invalid Symbol Table Entry";
     957}
     958
     959static bool validateCoff(const char *pszFile, uint8_t const *pbFile, size_t cbFile)
    335960{
    336961    /*
     
    355980    }
    356981
    357     /* Dump the symbol table if verbose mode. */
    358     PIMAGE_SYMBOL paSymTab  = (PIMAGE_SYMBOL)&pbFile[pHdr->PointerToSymbolTable];
    359     const char   *pchStrTab = (const char *)&paSymTab[pHdr->NumberOfSymbols];
    360     char          szShortName[16];
    361     if (g_cVerbose > 2)
    362         for (uint32_t i = 0; i < pHdr->NumberOfSymbols; i++)
     982    return true;
     983}
     984
     985
     986static bool convertCoffSectionsToSegDefsAndGrpDefs(POMFWRITER pThis, PCIMAGE_SECTION_HEADER paShdrs, uint16_t cSections)
     987{
     988    /*
     989     * Do the list of names pass.
     990     */
     991    uint16_t idxGrpFlat, idxGrpData;
     992    uint16_t idxClassCode, idxClassData, idxClassDebugSymbols, idxClassDebugTypes;
     993    if (   !omfWriter_LNamesBegin(pThis)
     994        || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("FLAT"), &idxGrpFlat)
     995        || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("BS3DATA64_GROUP"), &idxGrpData)
     996        || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("BS3CODE64"), &idxClassCode)
     997        || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("FAR_DATA"), &idxClassData)
     998        || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("DEBSYM"), &idxClassDebugSymbols)
     999        || !omfWriter_LNamesAddN(pThis, RT_STR_TUPLE("DEBTYP"), &idxClassDebugTypes)
     1000       )
     1001        return false;
     1002
     1003    bool fHaveData = false;
     1004    for (uint16_t i = 0; i < cSections; i++)
     1005    {
     1006        /* Copy the name and terminate it. */
     1007        char szName[32];
     1008        memcpy(szName, paShdrs[i].Name, sizeof(paShdrs[i].Name));
     1009        unsigned cchName = sizeof(paShdrs[i].Name);
     1010        while (cchName > 0 && RT_C_IS_SPACE(szName[cchName - 1]))
     1011            cchName--;
     1012        if (cchName == 0)
     1013            return error(pThis->pszSrc, "Section #%u has an empty name!\n", i);
     1014        szName[cchName] = '\0';
     1015
     1016        if (   (paShdrs[i].Characteristics & (IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_LNK_INFO))
     1017            || strcmp(szName, ".pdata") == 0 /* Exception stuff, I think, so discard it. */
     1018            || strcmp(szName, ".xdata") == 0 /* Ditto. */ )
    3631019        {
    364             printf("sym[0x%02x]: sect=0x%04x value=0x%08x storageclass=0x%x name=%s\n",
    365                    i, paSymTab[i].SectionNumber, paSymTab[i].Value, paSymTab[i].StorageClass,
    366                    coffGetSymbolName(&paSymTab[i], pchStrTab, szShortName));
    367             i += paSymTab[i].NumberOfAuxSymbols;
     1020            pThis->paSegments[i].iSegDef  = UINT16_MAX;
     1021            pThis->paSegments[i].iGrpDef  = UINT16_MAX;
     1022            pThis->paSegments[i].iSegNm   = UINT16_MAX;
     1023            pThis->paSegments[i].iGrpNm   = UINT16_MAX;
     1024            pThis->paSegments[i].iClassNm = UINT16_MAX;
     1025            pThis->paSegments[i].pszName  = NULL;
    3681026        }
    369 
    370     /* Switch it to a x86 machine. */
    371     pHdr->Machine = IMAGE_FILE_MACHINE_I386;
     1027        else
     1028        {
     1029            /* Translate the name, group and class. */
     1030            if (strcmp(szName, ".text") == 0)
     1031            {
     1032                strcpy(szName, "BS3TEXT64");
     1033                pThis->paSegments[i].iGrpNm   = idxGrpFlat;
     1034                pThis->paSegments[i].iClassNm = idxClassCode;
     1035            }
     1036            else if (strcmp(szName, ".data") == 0)
     1037            {
     1038                strcpy(szName, "BS3DATA64");
     1039                pThis->paSegments[i].iGrpNm   = idxGrpData;
     1040                pThis->paSegments[i].iClassNm = idxClassData;
     1041            }
     1042            else if (strcmp(szName, ".bss") == 0)
     1043            {
     1044                strcpy(szName, "BS3BSS64");
     1045                pThis->paSegments[i].iGrpNm   = idxGrpData;
     1046                pThis->paSegments[i].iClassNm = idxClassData;
     1047            }
     1048            else if (strcmp(szName, ".rdata") == 0)
     1049            {
     1050                strcpy(szName, "BS3DATA64CONST");
     1051                pThis->paSegments[i].iGrpNm   = idxGrpData;
     1052                pThis->paSegments[i].iClassNm = idxClassData;
     1053            }
     1054            else if (strcmp(szName, ".debug$S") == 0)
     1055            {
     1056                strcpy(szName, "$$SYMBOLS");
     1057                pThis->paSegments[i].iGrpNm   = UINT16_MAX;
     1058                pThis->paSegments[i].iClassNm = idxClassDebugSymbols;
     1059            }
     1060            else if (strcmp(szName, ".debug$T") == 0)
     1061            {
     1062                strcpy(szName, "$$TYPES");
     1063                pThis->paSegments[i].iGrpNm   = UINT16_MAX;
     1064                pThis->paSegments[i].iClassNm = idxClassDebugTypes;
     1065            }
     1066            else if (paShdrs[i].Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))
     1067            {
     1068                pThis->paSegments[i].iGrpNm   = idxGrpFlat;
     1069                pThis->paSegments[i].iClassNm = idxClassCode;
     1070                error(pThis->pszSrc, "Unknown code segment: '%s'\n", szName);
     1071            }
     1072            else
     1073            {
     1074                pThis->paSegments[i].iGrpNm = idxGrpData;
     1075                pThis->paSegments[i].iClassNm = idxClassData;
     1076                error(pThis->pszSrc, "Unknown data (?) segment: '%s'\n", szName);
     1077            }
     1078
     1079            /* Save the name. */
     1080            pThis->paSegments[i].pszName = strdup(szName);
     1081            if (!pThis->paSegments[i].pszName)
     1082                return error(pThis->pszSrc, "Out of memory!\n");
     1083
     1084            /* Add the section name. */
     1085            if (!omfWriter_LNamesAdd(pThis, pThis->paSegments[i].pszName, &pThis->paSegments[i].iSegNm))
     1086                return false;
     1087
     1088            fHaveData |= pThis->paSegments[i].iGrpDef == idxGrpData;
     1089        }
     1090    }
     1091
     1092    if (!omfWriter_LNamesEnd(pThis))
     1093        return false;
    3721094
    3731095    /*
    374      * Work the section table.
     1096     * Emit segment definitions.
    3751097     */
    376     bool fRet = true;
    377     PIMAGE_SECTION_HEADER paShdrs = (PIMAGE_SECTION_HEADER)(pHdr + 1);
    378     for (uint32_t i = 0; i < pHdr->NumberOfSections; i++)
    379     {
    380         if (g_cVerbose)
    381             printf("shdr[%2u]:       rva=%#010x  cbVirt=%#010x '%-8.8s'\n"
    382                    "            offFile=%#010x  cbFile=%#010x\n"
    383                    "          offRelocs=%#010x cRelocs=%#010x\n"
    384                    "           offLines=%#010x  cLines=%#010x Characteristics=%#010x\n",
    385                    i, paShdrs[i].VirtualAddress, paShdrs[i].Misc.VirtualSize, paShdrs[i].Name,
    386                    paShdrs[i].PointerToRawData, paShdrs[i].SizeOfRawData,
    387                    paShdrs[i].PointerToRelocations, paShdrs[i].NumberOfRelocations,
    388                    paShdrs[i].PointerToLinenumbers, paShdrs[i].NumberOfLinenumbers, paShdrs[i].Characteristics);
    389         uint32_t cRelocs = paShdrs[i].NumberOfRelocations;
    390         if (cRelocs > 0)
     1098    uint16_t iSegDef = 1; /* Start counting at 1. */
     1099    for (uint16_t i = 0; i < cSections; i++)
     1100    {
     1101        if (pThis->paSegments[i].iSegDef == UINT16_MAX)
     1102            continue;
     1103
     1104        uint8_t bSegAttr = 0;
     1105
     1106        /* The A field. */
     1107        switch (paShdrs[i].Characteristics & IMAGE_SCN_ALIGN_MASK)
    3911108        {
    392             if (   paShdrs[i].PointerToRelocations < cbHeaders
    393                 || paShdrs[i].PointerToRelocations >= cbFile
    394                 || paShdrs[i].PointerToRelocations + cRelocs * sizeof(IMAGE_RELOCATION) > cbFile)
    395                 return error(pszFile, "Relocation beyond the end of the file or overlapping the headers (section #%u)\n", i);
    396 
    397             uint32_t const cbRawData = paShdrs[i].SizeOfRawData;
    398             if (   paShdrs[i].PointerToRawData < cbHeaders
    399                 || paShdrs[i].PointerToRawData >= cbFile
    400                 || paShdrs[i].PointerToRawData + cbRawData > cbFile)
    401                 return error(pszFile, "Raw data beyond the end of the file or overlapping the headers (section #%u)\n", i);
    402             uint8_t *pbRawData = &pbFile[paShdrs[i].PointerToRawData];
    403 
    404             /* Is this a section which ends up in the binary? */
    405             bool const fInBinary = !(paShdrs[i].Characteristics & (IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_LNK_INFO));
    406             bool const fIsPData  = fInBinary
    407                                 && memcmp(paShdrs[i].Name, RT_STR_TUPLE(".pdata\0")) == 0;
    408             bool const fIsText   = fInBinary
    409                                 && (paShdrs[i].Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE));
    410 
    411             /* Whether we've seen any __ImageBase REL32 relocation that may later
    412                be used with array access using the SIB encoding and ADDR32NB. */
    413             bool fSeenImageBase = false;
     1109            default:
     1110            case IMAGE_SCN_ALIGN_1BYTES:
     1111                bSegAttr |= 1 << 5;
     1112                break;
     1113            case IMAGE_SCN_ALIGN_2BYTES:
     1114                bSegAttr |= 2 << 5;
     1115                break;
     1116            case IMAGE_SCN_ALIGN_4BYTES:
     1117                bSegAttr |= 5 << 5;
     1118                break;
     1119            case IMAGE_SCN_ALIGN_8BYTES:
     1120            case IMAGE_SCN_ALIGN_16BYTES:
     1121                bSegAttr |= 3 << 5;
     1122                break;
     1123            case IMAGE_SCN_ALIGN_32BYTES:
     1124            case IMAGE_SCN_ALIGN_64BYTES:
     1125            case IMAGE_SCN_ALIGN_128BYTES:
     1126            case IMAGE_SCN_ALIGN_256BYTES:
     1127                bSegAttr |= 4 << 5;
     1128                break;
     1129            case IMAGE_SCN_ALIGN_512BYTES:
     1130            case IMAGE_SCN_ALIGN_1024BYTES:
     1131            case IMAGE_SCN_ALIGN_2048BYTES:
     1132            case IMAGE_SCN_ALIGN_4096BYTES:
     1133            case IMAGE_SCN_ALIGN_8192BYTES:
     1134                bSegAttr |= 6 << 5; /* page aligned, pharlabs extension. */
     1135                break;
     1136        }
     1137
     1138        /* The C field. */
     1139        bSegAttr |= 2 << 2; /* public */
     1140
     1141        /* The B field. We don't have 4GB segments, so leave it as zero. */
     1142
     1143        /* The D field shall be set as we're doing USE32.  */
     1144        bSegAttr |= 1;
     1145
     1146
     1147        /* Done. */
     1148        if (!omfWriter_SegDef(pThis, bSegAttr, paShdrs[i].SizeOfRawData,
     1149                              pThis->paSegments[i].iSegNm,
     1150                              pThis->paSegments[i].iClassNm))
     1151            return false;
     1152        pThis->paSegments[i].iSegDef = iSegDef++;
     1153    }
     1154
     1155    /*
     1156     * Flat group definition (#1) - special, no members.
     1157     */
     1158    uint16_t iGrpDef = 1;
     1159    if (   !omfWriter_GrpDefBegin(pThis, idxGrpFlat)
     1160        || !omfWriter_GrpDefEnd(pThis))
     1161        return false;
     1162    for (uint16_t i = 0; i < cSections; i++)
     1163        if (pThis->paSegments[i].iGrpNm == idxGrpFlat)
     1164            pThis->paSegments[i].iGrpDef = iGrpDef;
     1165    pThis->idxGrpFlat = iGrpDef++;
     1166
     1167    /*
     1168     * Data group definition (#2).
     1169     */
     1170    /** @todo do we need to consider missing segments and ordering? */
     1171    uint16_t cGrpNms = 0;
     1172    uint16_t aiGrpNms[2];
     1173    if (fHaveData)
     1174        aiGrpNms[cGrpNms++] = idxGrpData;
     1175    for (uint32_t iGrpNm = 0; iGrpNm < cGrpNms; iGrpNm++)
     1176    {
     1177        if (!omfWriter_GrpDefBegin(pThis, aiGrpNms[iGrpNm]))
     1178            return false;
     1179        for (uint16_t i = 0; i < cSections; i++)
     1180            if (pThis->paSegments[i].iGrpNm == aiGrpNms[iGrpNm])
     1181            {
     1182                pThis->paSegments[i].iGrpDef = iGrpDef;
     1183                if (!omfWriter_GrpDefAddSegDef(pThis, pThis->paSegments[i].iSegDef))
     1184                    return false;
     1185            }
     1186        if (!omfWriter_GrpDefEnd(pThis))
     1187            return false;
     1188        iGrpDef++;
     1189    }
     1190
     1191    return true;
     1192}
     1193
     1194/**
     1195 * This is for matching STATIC symbols with value 0 against the section name,
     1196 * to see if it's a section reference or symbol at offset 0 reference.
     1197 *
     1198 * @returns true / false.
     1199 * @param   pszSymbol       The symbol name.
     1200 * @param   pachSectName8   The section name (8-bytes).
     1201 */
     1202static bool isCoffSymbolMatchingSectionName(const char *pszSymbol, uint8_t const pachSectName8[8])
     1203{
     1204    uint32_t off = 0;
     1205    char ch;
     1206    while (off < 8 && (ch = pszSymbol[off]) != '\0')
     1207    {
     1208        if (ch != pachSectName8[off])
     1209            return false;
     1210        off++;
     1211    }
     1212    while (off < 8)
     1213    {
     1214        if (!RT_C_IS_SPACE((ch = pachSectName8[off])))
     1215            return ch == '\0';
     1216        off++;
     1217    }
     1218    return true;
     1219}
     1220
     1221static bool convertCoffSymbolsToPubDefsAndExtDefs(POMFWRITER pThis, PCIMAGE_SYMBOL paSymbols, uint16_t cSymbols,
     1222                                                  const char *pchStrTab, PCIMAGE_SECTION_HEADER paShdrs)
     1223{
     1224
     1225    if (!cSymbols)
     1226        return true;
     1227    uint32_t const  cbStrTab = *(uint32_t const *)pchStrTab;
     1228    char            szShort[16];
     1229
     1230    /*
     1231     * Process the symbols the first.
     1232     */
     1233    uint32_t iSymImageBase = UINT32_MAX;
     1234    uint32_t cAbsSyms = 0;
     1235    uint32_t cExtSyms = 0;
     1236    uint32_t cPubSyms = 0;
     1237    for (uint32_t iSeg = 0; iSeg < pThis->cSegments; iSeg++)
     1238        pThis->paSegments[iSeg].cPubDefs = 0;
     1239
     1240    for (uint16_t iSym = 0; iSym < cSymbols; iSym++)
     1241    {
     1242        const char *pszSymName = coffGetSymbolName(&paSymbols[iSym], pchStrTab, cbStrTab, szShort);
     1243
     1244        pThis->paSymbols[iSym].enmType   = OMFSYMTYPE_IGNORED;
     1245        pThis->paSymbols[iSym].idx       = UINT16_MAX;
     1246        pThis->paSymbols[iSym].idxSegDef = UINT16_MAX;
     1247        pThis->paSymbols[iSym].idxGrpDef = UINT16_MAX;
     1248
     1249        int16_t const idxSection = paSymbols[iSym].SectionNumber;
     1250        if (   (idxSection >= 1 && idxSection <= (int32_t)pThis->cSegments)
     1251            || idxSection == IMAGE_SYM_ABSOLUTE)
     1252        {
     1253            switch (paSymbols[iSym].StorageClass)
     1254            {
     1255                case IMAGE_SYM_CLASS_EXTERNAL:
     1256                    if (idxSection != IMAGE_SYM_ABSOLUTE)
     1257                    {
     1258                        if (pThis->paSegments[idxSection - 1].iSegDef != UINT16_MAX)
     1259                        {
     1260                            pThis->paSymbols[iSym].enmType   = OMFSYMTYPE_PUBDEF;
     1261                            pThis->paSymbols[iSym].idxSegDef = pThis->paSegments[idxSection - 1].iSegDef;
     1262                            pThis->paSymbols[iSym].idxGrpDef = pThis->paSegments[idxSection - 1].iGrpDef;
     1263                            pThis->paSegments[idxSection - 1].cPubDefs++;
     1264                            cPubSyms++;
     1265                        }
     1266                    }
     1267                    else
     1268                    {
     1269                        pThis->paSymbols[iSym].enmType   = OMFSYMTYPE_PUBDEF;
     1270                        pThis->paSymbols[iSym].idxSegDef = 0;
     1271                        pThis->paSymbols[iSym].idxGrpDef = 0;
     1272                        cAbsSyms++;
     1273                    }
     1274                    break;
     1275
     1276                case IMAGE_SYM_CLASS_STATIC:
     1277                    if (   paSymbols[iSym].Value == 0
     1278                        && idxSection != IMAGE_SYM_ABSOLUTE
     1279                        && isCoffSymbolMatchingSectionName(pszSymName, paShdrs[idxSection - 1].Name) )
     1280                    {
     1281                        pThis->paSymbols[iSym].enmType   = OMFSYMTYPE_SEGDEF;
     1282                        pThis->paSymbols[iSym].idxSegDef = pThis->paSegments[idxSection - 1].iSegDef;
     1283                        pThis->paSymbols[iSym].idxGrpDef = pThis->paSegments[idxSection - 1].iGrpDef;
     1284                        break;
     1285                    }
     1286                    /* fall thru */
     1287
     1288                case IMAGE_SYM_CLASS_END_OF_FUNCTION:
     1289                case IMAGE_SYM_CLASS_AUTOMATIC:
     1290                case IMAGE_SYM_CLASS_REGISTER:
     1291                case IMAGE_SYM_CLASS_LABEL:
     1292                case IMAGE_SYM_CLASS_MEMBER_OF_STRUCT:
     1293                case IMAGE_SYM_CLASS_ARGUMENT:
     1294                case IMAGE_SYM_CLASS_STRUCT_TAG:
     1295                case IMAGE_SYM_CLASS_MEMBER_OF_UNION:
     1296                case IMAGE_SYM_CLASS_UNION_TAG:
     1297                case IMAGE_SYM_CLASS_TYPE_DEFINITION:
     1298                case IMAGE_SYM_CLASS_ENUM_TAG:
     1299                case IMAGE_SYM_CLASS_MEMBER_OF_ENUM:
     1300                case IMAGE_SYM_CLASS_REGISTER_PARAM:
     1301                case IMAGE_SYM_CLASS_BIT_FIELD:
     1302                case IMAGE_SYM_CLASS_BLOCK:
     1303                case IMAGE_SYM_CLASS_FUNCTION:
     1304                case IMAGE_SYM_CLASS_END_OF_STRUCT:
     1305                case IMAGE_SYM_CLASS_FILE:
     1306                    pThis->paSymbols[iSym].enmType = OMFSYMTYPE_INTERNAL;
     1307                    if (idxSection != IMAGE_SYM_ABSOLUTE)
     1308                    {
     1309                        pThis->paSymbols[iSym].idxSegDef = pThis->paSegments[idxSection - 1].iSegDef;
     1310                        pThis->paSymbols[iSym].idxGrpDef = pThis->paSegments[idxSection - 1].iGrpDef;
     1311                    }
     1312                    else
     1313                    {
     1314                        pThis->paSymbols[iSym].idxSegDef = 0;
     1315                        pThis->paSymbols[iSym].idxGrpDef = 0;
     1316                    }
     1317                    break;
     1318
     1319                case IMAGE_SYM_CLASS_SECTION:
     1320                case IMAGE_SYM_CLASS_EXTERNAL_DEF:
     1321                case IMAGE_SYM_CLASS_NULL:
     1322                case IMAGE_SYM_CLASS_UNDEFINED_LABEL:
     1323                case IMAGE_SYM_CLASS_UNDEFINED_STATIC:
     1324                case IMAGE_SYM_CLASS_CLR_TOKEN:
     1325                case IMAGE_SYM_CLASS_FAR_EXTERNAL:
     1326                case IMAGE_SYM_CLASS_WEAK_EXTERNAL:
     1327                    return error(pThis->pszSrc, "Unsupported storage class value %#x for symbol #%u (%s)\n",
     1328                                 paSymbols[iSym].StorageClass, iSym, pszSymName);
     1329
     1330                default:
     1331                    return error(pThis->pszSrc, "Unknown storage class value %#x for symbol #%u (%s)\n",
     1332                                 paSymbols[iSym].StorageClass, iSym, pszSymName);
     1333            }
     1334        }
     1335        else if (idxSection == IMAGE_SYM_UNDEFINED)
     1336        {
     1337            if (   paSymbols[iSym].StorageClass == IMAGE_SYM_CLASS_EXTERNAL
     1338                || paSymbols[iSym].StorageClass == IMAGE_SYM_CLASS_EXTERNAL_DEF)
     1339            {
     1340                pThis->paSymbols[iSym].enmType = OMFSYMTYPE_EXTDEF;
     1341                cExtSyms++;
     1342                if (iSymImageBase == UINT32_MAX && strcmp(pszSymName, "__ImageBase") == 0)
     1343                    iSymImageBase = iSym;
     1344            }
     1345            else
     1346                return error(pThis->pszSrc, "Unknown/unknown storage class value %#x for undefined symbol #%u (%s)\n",
     1347                             paSymbols[iSym].StorageClass, iSym, pszSymName);
     1348        }
     1349        else if (idxSection != IMAGE_SYM_DEBUG)
     1350            return error(pThis->pszSrc, "Invalid section number %#x for symbol #%u (%s)\n", idxSection, iSym, pszSymName);
     1351
     1352        /* Skip AUX symbols. */
     1353        uint8_t cAuxSyms = paSymbols[iSym].NumberOfAuxSymbols;
     1354        while (cAuxSyms-- > 0)
     1355        {
     1356            iSym++;
     1357            pThis->paSymbols[iSym].enmType = OMFSYMTYPE_INVALID;
     1358            pThis->paSymbols[iSym].idx     = UINT16_MAX;
     1359        }
     1360    }
     1361
     1362    /*
     1363     * Emit the PUBDEFs the first time around (see order of records in TIS spec).
     1364     */
     1365    uint16_t idxPubDef = 1;
     1366    if (cPubSyms)
     1367    {
     1368        for (uint32_t iSeg = 0; iSeg < pThis->cSegments; iSeg++)
     1369            if (pThis->paSegments[iSeg].cPubDefs > 0)
     1370            {
     1371                uint16_t const idxSegDef = pThis->paSegments[iSeg].iSegDef;
     1372                if (!omfWriter_PubDefBegin(pThis, pThis->paSegments[iSeg].iGrpDef, idxSegDef))
     1373                    return false;
     1374                for (uint16_t iSym = 0; iSym < cSymbols; iSym++)
     1375                    if (   pThis->paSymbols[iSym].idxSegDef == idxSegDef
     1376                        && pThis->paSymbols[iSym].enmType   == OMFSYMTYPE_PUBDEF)
     1377                    {
     1378                        if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].Value,
     1379                                                 coffGetSymbolName(&paSymbols[iSym], pchStrTab, cbStrTab, szShort)) )
     1380                            return false;
     1381                        pThis->paSymbols[iSym].idx = idxPubDef++;
     1382                    }
     1383                if (!omfWriter_PubDefEnd(pThis))
     1384                    return false;
     1385            }
     1386    }
     1387
     1388    if (cAbsSyms > 0)
     1389    {
     1390        if (!omfWriter_PubDefBegin(pThis, 0, 0))
     1391            return false;
     1392        for (uint16_t iSym = 0; iSym < cSymbols; iSym++)
     1393            if (   pThis->paSymbols[iSym].idxSegDef == 0
     1394                && pThis->paSymbols[iSym].enmType   == OMFSYMTYPE_PUBDEF)
     1395            {
     1396                if (!omfWriter_PubDefAdd(pThis, paSymbols[iSym].Value,
     1397                                         coffGetSymbolName(&paSymbols[iSym], pchStrTab, cbStrTab, szShort)) )
     1398                    return false;
     1399                pThis->paSymbols[iSym].idx = idxPubDef++;
     1400            }
     1401        if (!omfWriter_PubDefEnd(pThis))
     1402            return false;
     1403    }
     1404
     1405    /*
     1406     * Go over the symbol table and emit external definition records.
     1407     */
     1408    if (!omfWriter_ExtDefBegin(pThis))
     1409        return false;
     1410    uint16_t idxExtDef = 1;
     1411    for (uint16_t iSym = 0; iSym < cSymbols; iSym++)
     1412        if (pThis->paSymbols[iSym].enmType == OMFSYMTYPE_EXTDEF)
     1413        {
     1414            if (!omfWriter_ExtDefAdd(pThis, coffGetSymbolName(&paSymbols[iSym], pchStrTab, cbStrTab, szShort)))
     1415                return false;
     1416            pThis->paSymbols[iSym].idx = idxExtDef++;
     1417        }
     1418
     1419    /* Always add an __ImageBase reference, in case we need it to deal with ADDR32NB fixups. */
     1420    /** @todo maybe we don't actually need this and could use FLAT instead? */
     1421    if (iSymImageBase != UINT32_MAX)
     1422        pThis->idxExtImageBase = pThis->paSymbols[iSymImageBase].idx;
     1423    else if (omfWriter_ExtDefAdd(pThis, "__ImageBase"))
     1424        pThis->idxExtImageBase = idxExtDef;
     1425    else
     1426        return false;
     1427
     1428    if (!omfWriter_ExtDefEnd(pThis))
     1429        return false;
     1430
     1431    return true;
     1432}
     1433
     1434
     1435static bool convertCoffSectionsToLeDataAndFixupps(POMFWRITER pThis, uint8_t const *pbFile, size_t cbFile,
     1436                                                  PCIMAGE_SECTION_HEADER paShdrs, uint16_t cSections,
     1437                                                  PCIMAGE_SYMBOL paSymbols, uint16_t cSymbols, const char *pchStrTab)
     1438{
     1439    uint32_t const  cbStrTab = *(uint32_t const *)pchStrTab;
     1440    bool            fRet     = true;
     1441    for (uint32_t i = 0; i < pThis->cSegments; i++)
     1442    {
     1443        if (pThis->paSegments[i].iSegDef == UINT16_MAX)
     1444            continue;
     1445
     1446        char                szShortName[16];
     1447        const char         *pszSegNm   = pThis->paSegments[i].pszName;
     1448        uint16_t            cRelocs    = paShdrs[i].NumberOfRelocations;
     1449        PCIMAGE_RELOCATION  paRelocs   = (PCIMAGE_RELOCATION)&pbFile[paShdrs[i].PointerToRelocations];
     1450        uint32_t            cbVirtData = paShdrs[i].SizeOfRawData;
     1451        uint32_t            cbData     = paShdrs[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ? 0 : cbVirtData;
     1452        uint8_t const      *pbData     = &pbFile[paShdrs[i].PointerToRawData];
     1453        uint32_t            off        = 0;
     1454
     1455        /* Check that the relocations are sorted and within the section. */
     1456        for (uint32_t iReloc = 1; iReloc < cRelocs; iReloc++)
     1457            if (paRelocs[iReloc - 1].u.VirtualAddress >= paRelocs[iReloc].u.VirtualAddress)
     1458                return error(pThis->pszSrc, "Section #%u (%s) relocations aren't sorted\n", i, pszSegNm);
     1459        if (   cRelocs > 0
     1460            &&    paRelocs[cRelocs - 1].u.VirtualAddress - paShdrs[i].VirtualAddress
     1461               +  COFF_AMD64_RELOC_SIZE(paRelocs[cRelocs - 1].Type) > cbVirtData)
     1462            return error(pThis->pszSrc,
     1463                         "Section #%u (%s) relocations beyond section data! cbVirtData=%#x RvaFix=%#x RVASeg=%#x type=%#x\n",
     1464                         i, pszSegNm, cbVirtData, paRelocs[cRelocs - 1].u.VirtualAddress, paShdrs[i].VirtualAddress,
     1465                         paRelocs[cRelocs - 1].Type);
     1466
     1467        /* The OMF record size requires us to split larger sections up.  To make
     1468           life simple, we fill zeros for unitialized (BSS) stuff. */
     1469        const uint32_t cbMaxData = RT_MIN(OMF_MAX_RECORD_PAYLOAD - 1 - (pThis->paSegments[i].iSegDef >= 128) - 4 - 1, _1K);
     1470        while (cbVirtData > 0)
     1471        {
     1472            /* Figure out how many bytes to put out in this chunk.  Must make sure
     1473               fixups doesn't cross chunk boundraries.  ASSUMES sorted relocs. */
     1474            uint32_t       cChunkRelocs = cRelocs;
     1475            uint32_t       cbChunk      = cbVirtData;
     1476            uint32_t       uRvaEnd      = paShdrs[i].VirtualAddress + off + cbChunk;
     1477            if (cbChunk > cbMaxData)
     1478            {
     1479                cbChunk      = cbMaxData;
     1480                uRvaEnd      = paShdrs[i].VirtualAddress + off + cbChunk;
     1481                cChunkRelocs = 0;
     1482
     1483                /* Quickly determin the reloc range. */
     1484                while (   cChunkRelocs < cRelocs
     1485                       && paRelocs[cChunkRelocs].u.VirtualAddress < uRvaEnd)
     1486                    cChunkRelocs++;
     1487
     1488                /* Ensure final reloc doesn't go beyond chunk. */
     1489                while (   cChunkRelocs > 0
     1490                       &&   paRelocs[cChunkRelocs - 1].u.VirtualAddress + COFF_AMD64_RELOC_SIZE(paRelocs[cChunkRelocs - 1].Type)
     1491                          > uRvaEnd)
     1492                {
     1493                    uint32_t cbDrop = uRvaEnd - paRelocs[cChunkRelocs - 1].u.VirtualAddress;
     1494                    cbChunk -= cbDrop;
     1495                    uRvaEnd -= cbDrop;
     1496                    cChunkRelocs--;
     1497                }
     1498
     1499                if (!cbVirtData)
     1500                    return error(pThis->pszSrc, "Wtf? cbVirtData is zero!\n");
     1501            }
    4141502
    4151503            /*
    416              * Convert from AMD64 fixups to I386 ones, assuming 64-bit addresses
    417              * being fixed up doesn't need the high dword and that it's
    418              * appropriately initialized already.
     1504             * We stash the bytes into the OMF writer record buffer, receiving a
     1505             * pointer to the start of it so we can make adjustments if necessary.
    4191506             */
    420             PIMAGE_RELOCATION paRelocs = (PIMAGE_RELOCATION)&pbFile[paShdrs[i].PointerToRelocations];
    421             for (uint32_t j = 0; j < cRelocs; j++)
    422             {
     1507            uint8_t *pbCopy;
     1508            if (!omfWriter_LEDataBegin(pThis, pThis->paSegments[i].iSegDef, off, cbChunk, cbData, pbData, &pbCopy))
     1509                return false;
     1510
     1511            /*
     1512             * Convert fiuxps.
     1513             */
     1514            uint32_t const uRvaChunk = paShdrs[i].VirtualAddress + off;
     1515            for (uint32_t iReloc = 0; iReloc < cChunkRelocs; iReloc++)
     1516            {
     1517                /* Get the OMF and COFF data for the symbol the reloc references. */
     1518                if (paRelocs[iReloc].SymbolTableIndex >= pThis->cSymbols)
     1519                    return error(pThis->pszSrc, "Relocation symtab index (%#x) is out of range in segment #%u '%s'\n",
     1520                                 paRelocs[iReloc].SymbolTableIndex, i, pszSegNm);
     1521                PCIMAGE_SYMBOL pCoffSym =        &paSymbols[paRelocs[iReloc].SymbolTableIndex];
     1522                POMFSYMBOL     pOmfSym  = &pThis->paSymbols[paRelocs[iReloc].SymbolTableIndex];
     1523
     1524                /* Calc fixup location in the pending chunk and setup a flexible pointer to it. */
     1525                uint16_t  offDataRec = (uint16_t)paRelocs[iReloc].u.VirtualAddress - uRvaChunk;
    4231526                RTPTRUNION uLoc;
    424                 uLoc.pu8 = paRelocs[j].u.VirtualAddress < cbRawData ? &pbRawData[paRelocs[j].u.VirtualAddress] : NULL;
    425 
    426                 /* Print it. */
    427                 if (g_cVerbose > 1)
     1527                uLoc.pu8 = &pbCopy[offDataRec];
     1528
     1529                /* OMF fixup data initialized with typical defaults. */
     1530                bool        fSelfRel  = true;
     1531                uint8_t     bLocation = OMF_FIX_LOC_32BIT_OFFSET;
     1532                uint8_t     bFrame    = OMF_FIX_F_GRPDEF;
     1533                uint16_t    idxFrame  = pThis->idxGrpFlat;
     1534                uint8_t     bTarget;
     1535                uint16_t    idxTarget;
     1536                bool        fTargetDisp;
     1537                uint32_t    offTargetDisp;
     1538                switch (pOmfSym->enmType)
    4281539                {
    429                     size_t off = printf("%#010x  %#010x", paRelocs[j].u.VirtualAddress, paRelocs[j].SymbolTableIndex);
    430                     switch (paRelocs[j].Type)
    431                     {
    432                         case IMAGE_REL_AMD64_ADDR64:
    433                             if (uLoc.pu64)
    434                                 off += printf("  %#018" ELF_FMT_X64 "", *uLoc.pu64);
    435                             break;
    436                         case IMAGE_REL_AMD64_ADDR32:
    437                         case IMAGE_REL_AMD64_ADDR32NB:
    438                         case IMAGE_REL_AMD64_REL32:
    439                         case IMAGE_REL_AMD64_REL32_1:
    440                         case IMAGE_REL_AMD64_REL32_2:
    441                         case IMAGE_REL_AMD64_REL32_3:
    442                         case IMAGE_REL_AMD64_REL32_4:
    443                         case IMAGE_REL_AMD64_REL32_5:
    444                         case IMAGE_REL_AMD64_SECREL:
    445                             if (uLoc.pu32)
    446                                 off += printf("  %#010x", *uLoc.pu32);
    447                             break;
    448                         case IMAGE_REL_AMD64_SECTION:
    449                             if (uLoc.pu16)
    450                                 off += printf("  %#06x", *uLoc.pu16);
    451                             break;
    452                         case IMAGE_REL_AMD64_SECREL7:
    453                             if (uLoc.pu8)
    454                                 off += printf("  %#04x", *uLoc.pu8);
    455                             break;
    456                     }
    457                     while (off < 36)
    458                         off += printf(" ");
    459                     printf(" %s %s\n",
    460                            paRelocs[j].Type < RT_ELEMENTS(g_apszCoffAmd64RelTypes)
    461                            ? g_apszCoffAmd64RelTypes[paRelocs[j].Type] : "unknown",
    462                            coffGetSymbolName(&paSymTab[paRelocs[j].SymbolTableIndex], pchStrTab, szShortName));
     1540                    case OMFSYMTYPE_INTERNAL:
     1541                    case OMFSYMTYPE_PUBDEF:
     1542                        bTarget       = OMF_FIX_T_SEGDEF;
     1543                        idxTarget     = pOmfSym->idxSegDef;
     1544                        fTargetDisp   = true;
     1545                        offTargetDisp = pCoffSym->Value;
     1546                        break;
     1547
     1548                    case OMFSYMTYPE_SEGDEF:
     1549                        bTarget       = OMF_FIX_T_SEGDEF_NO_DISP;
     1550                        idxTarget     = pOmfSym->idxSegDef;
     1551                        fTargetDisp   = false;
     1552                        offTargetDisp = 0;
     1553                        break;
     1554
     1555                    case OMFSYMTYPE_EXTDEF:
     1556                        bTarget       = OMF_FIX_T_EXTDEF_NO_DISP;
     1557                        idxTarget     = pOmfSym->idx;
     1558                        fTargetDisp   = false;
     1559                        offTargetDisp = 0;
     1560                        break;
     1561
     1562                    default:
     1563                        return error(pThis->pszSrc, "Relocation in segment #%u '%s' references ignored or invalid symbol (%s)\n",
     1564                                     i, pszSegNm, coffGetSymbolName(pCoffSym, pchStrTab, cbStrTab, szShortName));
    4631565                }
    4641566
    465                 /* Convert it. */
    466                 uint8_t uDir = IMAGE_REL_AMD64_ABSOLUTE;
    467                 switch (paRelocs[j].Type)
     1567                /* Do COFF relocation type conversion. */
     1568                switch (paRelocs[iReloc].Type)
    4681569                {
    4691570                    case IMAGE_REL_AMD64_ADDR64:
    4701571                    {
    471                         uint64_t uAddend = 0;
    472                         if (uLoc.pu64)
    473                         {
    474                             if (paRelocs[j].u.VirtualAddress + 8 > cbRawData)
    475                                 return error(pszFile, "ADDR64 at %#x in section %u '%-8.8s' not fully in raw data\n",
    476                                              paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    477                             uAddend = *uLoc.pu64;
    478                         }
     1572                        uint64_t uAddend = *uLoc.pu64;
    4791573                        if (uAddend > _1G)
    480                             return error(pszFile, "ADDR64 with large addend (%#llx) at %#x in section %u '%-8.8s'\n",
    481                                          uAddend, paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    482                         paRelocs[j].Type = IMAGE_REL_I386_DIR32;
    483                         uDir = IMAGE_REL_AMD64_ADDR64;
     1574                            fRet = error(pThis->pszSrc, "ADDR64 with large addend (%#llx) at %#x in segment #%u '%s'\n",
     1575                                         uAddend, paRelocs[iReloc].u.VirtualAddress, i, pszSegNm);
     1576                        fSelfRel = false;
    4841577                        break;
    4851578                    }
     
    4901583                    case IMAGE_REL_AMD64_REL32_4:
    4911584                    case IMAGE_REL_AMD64_REL32_5:
    492                     {
    493                         if (paRelocs[j].u.VirtualAddress + 4 > cbRawData)
    494                             return error(pszFile, "%s at %#x in section %u '%-8.8s' is not (fully) in raw data\n",
    495                                          g_apszCoffAmd64RelTypes[paRelocs[j].Type], paRelocs[j].u.VirtualAddress, i,
    496                                          paShdrs[i].Name);
    497                         *uLoc.pu32 += paRelocs[j].Type - IMAGE_REL_AMD64_REL32;
    498                         paRelocs[j].Type = IMAGE_REL_I386_REL32;
     1585                        /** @todo Check whether OMF read addends from the data or relies on the
     1586                         *        displacement. Also, check what it's relative to. */
     1587                        *uLoc.pu32 += paRelocs[iReloc].Type - IMAGE_REL_AMD64_REL32;
    4991588                        break;
    500                     }
    501 
    502                     /* These are 1:1 conversions: */
     1589
    5031590                    case IMAGE_REL_AMD64_ADDR32:
    504 #if 1   /* Turns out this is special when wlink is doing DOS/BIOS binaries. */
    505 /** @todo this still doesn't work for bs3-cmn-SelProtFar32ToFlat32.obj!! */
    506                         paRelocs[j].Type = IMAGE_REL_I386_ABSOLUTE; /* Note! Don't believe MS pecoff.doc, this works with wlink. */
    507 #else
    508                         paRelocs[j].Type = IMAGE_REL_I386_DIR32;
    509                         uDir = IMAGE_REL_AMD64_ADDR32;
    510 #endif
     1591                        fSelfRel = false;
    5111592                        break;
     1593
    5121594                    case IMAGE_REL_AMD64_ADDR32NB:
    513                         if (fSeenImageBase && fIsText) /* This is voodoo. */
    514                             paRelocs[j].Type = IMAGE_REL_I386_ABSOLUTE; /* Note! Don't believe MS pecoff.doc, this works with wlink. */
     1595                        fSelfRel = false;
     1596                        bFrame   = OMF_FIX_F_EXTDEF;
     1597                        idxFrame = pThis->idxExtImageBase;
     1598                        break;
     1599
     1600                    case IMAGE_REL_AMD64_REL32:
     1601                        /* defaults are ok. */
     1602                        break;
     1603
     1604                    case IMAGE_REL_AMD64_SECTION:
     1605                        bLocation = OMF_FIX_LOC_16BIT_SEGMENT;
     1606                        /* fall thru */
     1607
     1608                    case IMAGE_REL_AMD64_SECREL:
     1609                        fSelfRel = false;
     1610                        if (pOmfSym->enmType == OMFSYMTYPE_EXTDEF)
     1611                        {
     1612                            bFrame   = OMF_FIX_F_EXTDEF;
     1613                            idxFrame = pOmfSym->idx;
     1614                        }
    5151615                        else
    5161616                        {
    517                             paRelocs[j].Type = IMAGE_REL_I386_DIR32NB;
    518                             uDir = IMAGE_REL_AMD64_ADDR32NB;
     1617                            bFrame   = OMF_FIX_F_SEGDEF;
     1618                            idxFrame = pOmfSym->idxSegDef;
    5191619                        }
    5201620                        break;
    521                     case IMAGE_REL_AMD64_REL32:
    522                         paRelocs[j].Type = IMAGE_REL_I386_REL32;
    523 
    524                         /* This is voodoo! */
    525                         if (   fIsText
    526                             && strcmp(coffGetSymbolName(&paSymTab[paRelocs[j].SymbolTableIndex], pchStrTab, szShortName),
    527                                       "__ImageBase") == 0)
    528                         {
    529                             if (   (uLoc.pu8[-1] & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5 /* disp32 + wrt */
    530                                 && uLoc.pu8[-2] == 0x8d /* LEA */
    531                                 && (uLoc.pu8[-3] & (0xf8 | X86_OP_REX_W)) == X86_OP_REX_W /* 64-bit reg */ )
    532                             {
    533                                 if (*uLoc.pu32)
    534                                 {
    535                                     error(pszFile, "__ImageBase fixup with disp %#x at rva=%#x in section #%u '%-8.8s'!\n",
    536                                           *uLoc.pu32, paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    537                                     fRet = false;
    538                                 }
    539 
    540                                 if (fSeenImageBase)
    541                                     return error(pszFile, "More than one __ImageBase fixup! 2nd at rva=%#x in section #%u '%-8.8s'\n",
    542                                                  paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    543                                 if (g_cVerbose)
    544                                     printf("Applying __ImageBase hack at rva=%#x in section #%u '%-8.8s'\n",
    545                                            paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    546 
    547                                 /* Convert it into a mov reg, dword 0. Leave the extra rex prefix, as it will be ignored. */
    548                                 uint8_t iReg = (uLoc.pu8[-1] >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK;
    549                                 uLoc.pu8[-1] = 0xb8 | iReg;
    550                                 uLoc.pu8[-2] = X86_OP_REX_R & uLoc.pu8[-3];
    551                                 fSeenImageBase = true;
    552 
    553                                 /* Neutralize the fixup.
    554                                    Note! wlink takes the IMAGE_REL_I386_ABSOLUTE fixups seriously, so we cannot use that
    555                                          to disable it, so instead we have to actually remove it from the fixup table. */
    556                                 cRelocs--;
    557                                 if (j != cRelocs)
    558                                     memmove(&paRelocs[j], &paRelocs[j + 1], (cRelocs - j) * sizeof(paRelocs[j]));
    559                                 paShdrs[i].NumberOfRelocations = (uint16_t)cRelocs;
    560                                 j--;
    561                             }
    562                             else
    563                             {
    564                                 error(pszFile, "__ImageBase fixup that isn't a recognized LEA at rva=%#x in section #%u '%-8.8s'!\n",
    565                                       paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    566                                 fRet = false;
    567                             }
    568                         }
    569                         break;
    570                     case IMAGE_REL_AMD64_SECTION:
    571                         paRelocs[j].Type = IMAGE_REL_I386_SECTION;
    572                         break;
    573                     case IMAGE_REL_AMD64_SECREL:
    574                         paRelocs[j].Type = IMAGE_REL_I386_SECREL;
    575                         break;
     1621
     1622                    case IMAGE_REL_AMD64_ABSOLUTE:
     1623                        continue; /* Ignore it like the PECOFF.DOC says we should. */
     1624
    5761625                    case IMAGE_REL_AMD64_SECREL7:
    577                         paRelocs[j].Type = IMAGE_REL_I386_SECREL7;
    578                         break;
    579                     case IMAGE_REL_AMD64_ABSOLUTE:
    580                         paRelocs[j].Type = IMAGE_REL_I386_ABSOLUTE;
    581                         /* Turns out wlink takes this seriously, so it usage must be checked out. */
    582                         error(pszFile, "ABSOLUTE fixup at rva=%#x in section #%u '%-8.8s'\n",
    583                               paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    584                         fRet = false;
    585                         break;
    586 
    5871626                    default:
    588                         return error(pszFile, "Unsupported fixup type %#x (%s) at rva=%#x in section #%u '%-8.8s'\n",
    589                                      paRelocs[j].Type,
    590                                      paRelocs[j].Type < RT_ELEMENTS(g_apszCoffAmd64RelTypes)
    591                                      ? g_apszCoffAmd64RelTypes[paRelocs[j].Type] : "unknown",
    592                                      paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
     1627                        return error(pThis->pszSrc, "Unsupported fixup type %#x (%s) at rva=%#x in section #%u '%-8.8s'\n",
     1628                                     paRelocs[iReloc].Type,
     1629                                     paRelocs[iReloc].Type < RT_ELEMENTS(g_apszCoffAmd64RelTypes)
     1630                                     ? g_apszCoffAmd64RelTypes[paRelocs[iReloc].Type] : "unknown",
     1631                                     paRelocs[iReloc].u.VirtualAddress, i, paShdrs[i].Name);
    5931632                }
    5941633
    595                 /*
    596                  * Error no absolute fixup that we care about. We continue so
    597                  * the developer can get the full story before failing.
    598                  */
    599                 if (   fInBinary
    600                     && !fIsPData
    601                     && uDir != IMAGE_REL_AMD64_ABSOLUTE)
    602                 {
    603                     error(pszFile, "%s at %#x in section %u '%-8.8s': wlink won't get this right\n",
    604                           g_apszCoffAmd64RelTypes[uDir], paRelocs[j].u.VirtualAddress, i, paShdrs[i].Name);
    605                     fRet = false;
    606                 }
    607             }
     1634                /* Add the fixup. */
     1635                if (idxFrame == UINT16_MAX)
     1636                    error(pThis->pszSrc, "idxFrame=UINT16_MAX for %s type=%s\n",
     1637                          coffGetSymbolName(pCoffSym, pchStrTab, cbStrTab, szShortName),
     1638                          g_apszCoffAmd64RelTypes[paRelocs[iReloc].Type]);
     1639                fRet = omfWriter_LEDataAddFixup(pThis, offDataRec, fSelfRel, bLocation, bFrame, idxFrame,
     1640                                                bTarget, idxTarget, fTargetDisp, offTargetDisp) && fRet;
     1641            }
     1642
     1643            /*
     1644             * Write the LEDATA and associated FIXUPPs.
     1645             */
     1646            if (!omfWriter_LEDataEnd(pThis))
     1647                return false;
     1648
     1649            /*
     1650             * Advance.
     1651             */
     1652            paRelocs   += cChunkRelocs;
     1653            cRelocs    -= cChunkRelocs;
     1654            if (cbData > cbChunk)
     1655            {
     1656                cbData -= cbChunk;
     1657                pbData += cbChunk;
     1658            }
     1659            else
     1660                cbData  = 0;
     1661            off        += cbChunk;
     1662            cbVirtData -= cbChunk;
    6081663        }
    6091664    }
     1665
    6101666    return fRet;
    6111667}
    6121668
    6131669
    614 /** @name Selected OMF record types.
    615  * @{ */
    616 #define PUBDEF  UINT8_C(0x90)
    617 #define LPUBDEF UINT8_C(0xb6)
    618 #define THEADR  UINT8_C(0x80)
    619 #define EXTDEF  UINT8_C(0x8c)
    620 #define SEGDEF  UINT8_C(0x98)
    621 #define LNAMES  UINT8_C(0x96)
    622 #define GRPDEF  UINT8_C(0x9a)
    623 #define REC32   UINT8_C(0x01) /**< Flag indicating 32-bit record. */
    624 /** @} */
     1670static bool convertCoffToOmf(const char *pszFile, uint8_t const *pbFile, size_t cbFile, FILE *pDst)
     1671{
     1672    /*
     1673     * Validate the source file a little.
     1674     */
     1675    if (!validateCoff(pszFile, pbFile, cbFile))
     1676        return false;
     1677
     1678    /*
     1679     * Instantiate the OMF writer.
     1680     */
     1681    PIMAGE_FILE_HEADER pHdr = (PIMAGE_FILE_HEADER)pbFile;
     1682    POMFWRITER pThis = omfWriter_Create(pszFile, pHdr->NumberOfSections, pHdr->NumberOfSymbols, pDst);
     1683    if (!pThis)
     1684        return false;
     1685
     1686    /*
     1687     * Write the OMF object file.
     1688     */
     1689    if (omfWriter_BeginModule(pThis, pszFile))
     1690    {
     1691        PCIMAGE_SECTION_HEADER paShdrs   = (PCIMAGE_SECTION_HEADER)(pHdr + 1);
     1692        PCIMAGE_SYMBOL         paSymTab  = (PCIMAGE_SYMBOL)&pbFile[pHdr->PointerToSymbolTable];
     1693        const char            *pchStrTab = (const char *)&paSymTab[pHdr->NumberOfSymbols];
     1694        if (   convertCoffSectionsToSegDefsAndGrpDefs(pThis, paShdrs, pHdr->NumberOfSections)
     1695            && convertCoffSymbolsToPubDefsAndExtDefs(pThis, paSymTab, pHdr->NumberOfSymbols, pchStrTab, paShdrs)
     1696            && omfWriter_LinkPassSeparator(pThis)
     1697            && convertCoffSectionsToLeDataAndFixupps(pThis, pbFile, cbFile, paShdrs, pHdr->NumberOfSections,
     1698                                                     paSymTab, pHdr->NumberOfSymbols, pchStrTab)
     1699
     1700            && omfWriter_EndModule(pThis) )
     1701        {
     1702
     1703            omfWriter_Destroy(pThis);
     1704            return true;
     1705        }
     1706    }
     1707
     1708    omfWriter_Destroy(pThis);
     1709    return false;
     1710
     1711}
     1712
     1713
     1714
     1715/*********************************************************************************************************************************
     1716*   OMF Converter/Tweaker                                                                                                        *
     1717*********************************************************************************************************************************/
    6251718
    6261719/** Watcom intrinsics we need to modify so we can mix 32-bit and 16-bit
     
    6841777            return error(pszFile, "Invalid record length at %#x: %#x (cbFile=%#lx)\n", off, cbRec, (unsigned long)cbFile);
    6851778
    686         if (bRecType & REC32)
     1779        if (bRecType & OMF_REC32)
    6871780            fProbably32bit = true;
    6881781
     
    6981791             * Scan external definitions for intrinsics needing mangling.
    6991792             */
    700             case EXTDEF:
     1793            case OMF_EXTDEF:
    7011794            {
    7021795                while (offRec + 1 < cbRec)
     
    7491842             * Record LNAME records, scanning for FLAT.
    7501843             */
    751             case LNAMES:
     1844            case OMF_LNAMES:
    7521845            {
    7531846                while (offRec + 1 < cbRec)
     
    7751868             * Display public names if -v is specified.
    7761869             */
    777             case PUBDEF:
    778             case PUBDEF | REC32:
    779             case LPUBDEF:
    780             case LPUBDEF | REC32:
     1870            case OMF_PUBDEF16:
     1871            case OMF_PUBDEF32:
     1872            case OMF_LPUBDEF16:
     1873            case OMF_LPUBDEF32:
    7811874            {
    7821875                if (g_cVerbose > 0)
    7831876                {
    784                     char const  chType  = bRecType == PUBDEF || bRecType == (PUBDEF | REC32) ? 'T' : 't';
     1877                    char const  chType  = bRecType == OMF_PUBDEF16 || bRecType == OMF_PUBDEF32 ? 'T' : 't';
    7851878                    const char *pszRec = "LPUBDEF";
    7861879                    if (chType == 'T')
     
    8161909
    8171910                        uint32_t offSeg;
    818                         if (bRecType & REC32)
     1911                        if (bRecType & OMF_REC32)
    8191912                        {
    8201913                            OMF_CHECK_RET(4, [L]PUBDEF);
     
    8611954static int convertit(const char *pszFile)
    8621955{
     1956    /* Construct the filename for saving the unmodified file. */
     1957    char szOrgFile[_4K];
     1958    size_t cchFile = strlen(pszFile);
     1959    if (cchFile + sizeof(".original") > sizeof(szOrgFile))
     1960    {
     1961        error(pszFile, "Filename too long!\n");
     1962        return RTEXITCODE_FAILURE;
     1963    }
     1964    memcpy(szOrgFile, pszFile, cchFile);
     1965    memcpy(&szOrgFile[cchFile], ".original", sizeof(".original"));
     1966
     1967    /* Read the whole file. */
    8631968    void  *pvFile;
    8641969    size_t cbFile;
    8651970    if (readfile(pszFile, &pvFile, &cbFile))
    8661971    {
     1972        /*
     1973         * Do format conversions / adjustments.
     1974         */
    8671975        bool fRc = false;
    8681976        uint8_t *pbFile = (uint8_t *)pvFile;
     
    8721980            && pbFile[2] == ELFMAG2
    8731981            && pbFile[3] == ELFMAG3)
    874             fRc = convertelf(pszFile, pbFile, cbFile);
     1982            /** @todo convertElfToOmf(). */
     1983            fRc = writefile(szOrgFile, pvFile, cbFile)
     1984               && convertelf(pszFile, pbFile, cbFile)
     1985               && writefile(pszFile, pvFile, cbFile);
    8751986        else if (   cbFile > sizeof(IMAGE_FILE_HEADER)
    8761987                 && RT_MAKE_U16(pbFile[0], pbFile[1]) == IMAGE_FILE_MACHINE_AMD64
     
    8781989                    < cbFile
    8791990                 && RT_MAKE_U16(pbFile[2], pbFile[3]) > 0)
    880             fRc = convertcoff(pszFile, pbFile, cbFile);
     1991        {
     1992            if (writefile(szOrgFile, pvFile, cbFile))
     1993            {
     1994                FILE *pDst = openfile(pszFile, true /*fWrite*/);
     1995                if (pDst)
     1996                {
     1997                    fRc = convertCoffToOmf(pszFile, pbFile, cbFile, pDst);
     1998                    fRc = fclose(pDst) == 0 && fRc;
     1999                }
     2000            }
     2001        }
    8812002        else if (   cbFile >= 8
    882                  && pbFile[0] == THEADR
     2003                 && pbFile[0] == OMF_THEADR
    8832004                 && RT_MAKE_U16(pbFile[1], pbFile[2]) < cbFile)
    8842005        {
    8852006            const char **papchLNames = (const char **)calloc(sizeof(*papchLNames), _32K);
    886             fRc = convertomf(pszFile, pbFile, cbFile, papchLNames, _32K);
     2007            fRc = writefile(szOrgFile, pvFile, cbFile)
     2008               && convertomf(pszFile, pbFile, cbFile, papchLNames, _32K)
     2009               && writefile(pszFile, pvFile, cbFile);
    8872010            free(papchLNames);
    8882011        }
     
    8902013            fprintf(stderr, "error: Don't recognize format of '%s' (%#x %#x %#x %#x, cbFile=%lu)\n",
    8912014                    pszFile, pbFile[0], pbFile[1], pbFile[2], pbFile[3], (unsigned long)cbFile);
    892         if (fRc)
    893             fRc = writefile(pszFile, pvFile, cbFile);
    8942015        free(pvFile);
    8952016        if (fRc)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-MemAlloc.c

    r58814 r59932  
    4343         */
    4444        PBS3SLABHEAD pHead = enmKind == BS3MEMKIND_REAL
    45                            ? &BS3_MSC64_FIXUP_HACK(BS3SLABHEAD, BS3_DATA_NM(g_aBs3LowSlabLists))[idxSlabList]
    46                            : &BS3_MSC64_FIXUP_HACK(BS3SLABHEAD, BS3_DATA_NM(g_aBs3UpperTiledSlabLists))[idxSlabList];
     45                           ? &BS3_DATA_NM(g_aBs3LowSlabLists)[idxSlabList]
     46                           : &BS3_DATA_NM(g_aBs3UpperTiledSlabLists)[idxSlabList];
    4747
    48         BS3_ASSERT(BS3_MSC64_FIXUP_HACK(BS3SLABHEAD, BS3_DATA_NM(g_aBs3LowSlabLists))[idxSlabList].cbChunk >= cb);
     48        BS3_ASSERT(BS3_DATA_NM(g_aBs3LowSlabLists)[idxSlabList].cbChunk >= cb);
    4949        pvRet = Bs3SlabListAlloc(pHead);
    5050        if (pvRet)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-memory.h

    r58814 r59932  
    7272    {
    7373        unsigned idx = cbRequest ? ASMBitLastSetU16((uint16_t)(cbRequest - 1)) : 0;
    74         return BS3_MSC64_FIXUP_HACK(uint8_t const, BS3_DATA_NM(g_aiBs3SlabListsByPowerOfTwo))[idx];
     74        return BS3_DATA_NM(g_aiBs3SlabListsByPowerOfTwo)[idx];
    7575    }
    7676    return UINT8_MAX;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-common.mac

    r59900 r59932  
    123123
    124124%ifdef ASM_FORMAT_OMF
    125 section TEXT64 align=4 CLASS=CODE PUBLIC USE32
     125;section TEXT64 align=4 CLASS=CODE PUBLIC USE32
    126126;section .text  align=4 CLASS=CODE PUBLIC USE32 - nasm doesn't do '.' at the start of segments in OMF mode. Not that this helps anyways...
    127127;section .rdata align=4 CLASS=CODE PUBLIC USE32
     
    132132section BS3TEXT64_END   align=1 progbits alloc exec nowrite
    133133%else
    134 section BS3TEXT64_END   align=1 CLASS=CODE PUBLIC USE32 FLAT
     134section BS3TEXT64_END   align=1 CLASS=BS3CODE64 PUBLIC USE32 FLAT
    135135%endif
    136136BS3_GLOBAL_DATA Bs3Text64_EndOfSegment, 0
     
    171171;section .pdata          align=8    CLASS=DATA PUBLIC USE32
    172172;section .bss            align=8    CLASS=DATA PUBLIC USE32
    173 section BS3DATA64_END   align=16   CLASS=DATA PUBLIC USE32
     173section BS3DATA64_END   align=16   CLASS=FAR_DATA PUBLIC USE32
    174174%endif
    175175BS3_GLOBAL_DATA Bs3Data64_EndOfSegment, 0
     
    177177%ifndef ASM_FORMAT_ELF
    178178;GROUP BS3DATA64_GROUP BS3DATA64 .data .rdata .xdata .pdata .bss BS3DATA64_END
    179 GROUP DGROUP BS3DATA64 BS3DATA64_END
     179GROUP BS3DATA64_GROUP BS3DATA64 BS3DATA64_END
    180180%endif
    181181
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-pe16.asm

    r59287 r59932  
    4444BS3_EXTERN_SYSTEM16 Bs3Lidt_Idt16
    4545
     46extern Bs3SelProtFar32ToFlat32_c64
     47extern Bs3PrintChr_c64
     48extern Bs3Printf_c64
     49extern Bs3TestTerm_c64
     50extern Bs3TestSub_c64
     51extern Bs3TestInit_c64
     52
    4653BS3_BEGIN_TEXT16
     54EXTERN Bs3InitMemory_rm
     55
     56%if 0
    4757EXTERN Main_pe16
    4858EXTERN Bs3SwitchToPE16_rm
     
    6474EXTERN Bs3SwitchToRM_pae32
    6575extern Bs3SwitchToRM_lm64
    66 EXTERN Bs3InitMemory_rm
     76extern _Bs3PrintChr_c16
     77extern _Bs3PrintChr_c32
     78extern Bs3PrintChr_c64
     79%endif
     80
    6781BS3_EXTERN_CMN Bs3Shutdown
    6882BS3_EXTERN_CMN Bs3Trap32Init
    6983
    70 extern _Bs3PrintChr_c16
    71 extern _Bs3PrintChr_c32
    72 extern Bs3PrintChr_c64
    7384
    7485BS3_BEGIN_TEXT16
     
    7990    call    Bs3Trap32Init
    8091    sub     xSP, 20h                    ; for 64-bit calls.
     92%if 0
    8193    call    NAME(Bs3SwitchToPE16_rm)
    8294    push    '1'
     
    154166    push    'g'
    155167    call    NAME(Bs3PrintChr_c16)
     168%endif
    156169
    157170    ;
     
    161174hlt
    162175jmp .halt
    163     call    NAME(Main_pe16)
     176;    call    NAME(Main_pe16)
    164177    call    Bs3Shutdown
    165178
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h

    r59895 r59932  
    455455# define BS3_DATA_NM(a_Name)  a_Name
    456456#endif
    457 
    458 /** @def BS3_MSC64_FIXUP_HACK
    459  * Used to avoid IMAGE_REL_AMD64_ADDR32NB fixups where the compiler tries to
    460  * make use of __ImageBase as a base pointer instead of emitting rip relative
    461  * accesses.  Happens when there are a bunch of global data accesses in the same
    462  * function, probably to save space.
    463  *
    464  * The volatile variable in the lambda fixes it.
    465  */
    466 #if _MSC_VER && ARCH_BITS == 64
    467 # define BS3_MSC64_FIXUP_HACK(a_BaseType, a_Data) \
    468     ([]() -> a_BaseType * \
    469      { \
    470         a_BaseType * volatile x = a_Data; \
    471         return x; \
    472      }())
    473 
    474 #else
    475 # define BS3_MSC64_FIXUP_HACK(a_BaseType, a_Data) (a_Data)
    476 #endif
    477 
    478457
    479458/**
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac

    r59878 r59932  
    379379        section BS3TEXT64 align=1 progbits alloc exec nowrite
    380380  %else
    381         section BS3TEXT64 align=1 CLASS=CODE PUBLIC USE32 FLAT  ; class=CODE here because of 64-bit cl and/or wlink.exe
     381        section BS3TEXT64 align=1 CLASS=BS3CODE64 PUBLIC USE32 FLAT
    382382  %endif
    383383 %else
     
    393393        section BS3DATA64 align=16 progbits alloc noexec write
    394394  %else
    395         section BS3DATA64 align=16 CLASS=DATA PUBLIC USE32 ;FLAT (see DATA32) ; class=DATA here because of 64-bit cl and/or wlink.exe
     395        section BS3DATA64 align=16 CLASS=FAR_DATA PUBLIC USE32 ;FLAT (see DATA32)
    396396  %endif
    397397 %else
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