MakeAlternativeSource.cpp revision 7306565f20289efa418aa6d90ebaa82fd54f3958
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * MakeAlternative - Generate an Alternative BIOS Source that requires less tools.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2012 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*******************************************************************************
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync* Header Files *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync*******************************************************************************/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/asm.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/buildconfig.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/ctype.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/dbg.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/file.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/getopt.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/initterm.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/list.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/mem.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/message.h>
e63301e141f1070f42410a0687a4853c16e03205vboxsync#include <iprt/string.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/stream.h>
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync#include <iprt/x86.h>
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
11f8b3da5f2ead2461e7998b3b091bb0f7bd14d9vboxsync#include <VBox/dis.h>
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
384478d3896257fbce9ceb8c01e74040b969e6d7vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync/*******************************************************************************
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync* Structures and Typedefs *
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync*******************************************************************************/
384478d3896257fbce9ceb8c01e74040b969e6d7vboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * A BIOS segment.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct BIOSSEG
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szName[32];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szClass[32];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szGroup[32];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTFAR16 Address;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t uFlatAddr;
3ab1cd69595235a9f15ce27945574123b0f38b46vboxsync uint32_t cb;
3ab1cd69595235a9f15ce27945574123b0f38b46vboxsync} BIOSSEG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** Pointer to a BIOS segment. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef BIOSSEG *PBIOSSEG;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * A BIOS object file.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct BIOSOBJFILE
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync RTLISTNODE Node;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync char *pszSource;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync char *pszObject;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync} BIOSOBJFILE;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync/** A BIOS object file. */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsynctypedef BIOSOBJFILE *PBIOSOBJFILE;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync/**
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync * Pointer to a BIOS map parser handle.
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsynctypedef struct BIOSMAP
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync /** The stream pointer. */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync PRTSTREAM hStrm;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync /** The file name. */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync const char *pszMapFile;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync /** Set when EOF has been reached. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync bool fEof;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /** The current line number (0 based).*/
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync uint32_t iLine;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /** The length of the current line. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync uint32_t cch;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /** The offset of the first non-white character on the line. */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync uint32_t offNW;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync /** The line buffer. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync char szLine[16384];
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync} BIOSMAP;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** Pointer to a BIOS map parser handle. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsynctypedef BIOSMAP *PBIOSMAP;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/*******************************************************************************
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync* Global Variables *
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync*******************************************************************************/
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** The verbosity level.*/
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic unsigned g_cVerbose = 1 /*0*/;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** Pointer to the BIOS image. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic uint8_t const *g_pbImg;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** The size of the BIOS image. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic size_t g_cbImg;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** Debug module for the map file. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic RTDBGMOD g_hMapMod = NIL_RTDBGMOD;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** The number of BIOS segments found in the map file. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic uint32_t g_cSegs = 0;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** Array of BIOS segments from the map file. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic BIOSSEG g_aSegs[32];
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** List of BIOSOBJFILE. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic RTLISTANCHOR g_ObjList;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** The output stream. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic PRTSTREAM g_hStrmOutput = NULL;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** The type of BIOS we're working on. */
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsyncstatic enum BIOSTYPE
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync{
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync kBiosType_System = 0,
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync kBiosType_Vga
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync} g_enmBiosType = kBiosType_System;
4a9af9a8062589b741444d717d2dd1ed22b0f583vboxsync/** The flat ROM base address. */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncstatic uint32_t g_uBiosFlatBase = 0xf0000;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncstatic bool outputPrintfV(const char *pszFormat, va_list va)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync int rc = RTStrmPrintfV(g_hStrmOutput, pszFormat, va);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync if (RT_FAILURE(rc))
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync {
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync RTMsgError("Output error: %Rrc\n", rc);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return false;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync }
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return true;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync}
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncstatic bool outputPrintf(const char *pszFormat, ...)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync va_list va;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync va_start(va, pszFormat);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync bool fRc = outputPrintfV(pszFormat, va);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync va_end(va);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return fRc;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync}
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync/**
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync * Opens the output file for writing.
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync *
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync * @param pszOutput Path to the output file.
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync */
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsyncstatic RTEXITCODE OpenOutputFile(const char *pszOutput)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync{
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync if (!pszOutput)
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync g_hStrmOutput = g_pStdOut;
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync else
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync {
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync int rc = RTStrmOpen(pszOutput, "w", &g_hStrmOutput);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync if (RT_FAILURE(rc))
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open output file '%s': %Rrc", pszOutput, rc);
1c0d3d017f9a45748b4839bf6622b53e83a4f1f8vboxsync }
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync return RTEXITCODE_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Displays a disassembly error and returns @c false.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c false.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pszFormat The error format string.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ... Format argument.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsyncstatic bool disError(const char *pszFormat, ...)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_list va;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_start(va, pszFormat);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTMsgErrorV(pszFormat, va);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_end(va);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Output the disassembly file header.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true on success,
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disFileHeader(void)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf("; $Id$ \n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ";; @file\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync "; Auto Generated source file. Do not edit.\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ";\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync );
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return fRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * List the header of each source file, up to and including the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * copyright notice.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync PBIOSOBJFILE pObjFile;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTListForEach(&g_ObjList, pObjFile, BIOSOBJFILE, Node)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PRTSTREAM hStrm;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTStrmOpen(pObjFile->pszSource, "r", &hStrm);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf("\n"
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync ";\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync "; Source file: %Rbn\n"
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync ";\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync , pObjFile->pszSource);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t iLine = 0;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync bool fSeenCopyright = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szLine[4096];
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync while ((rc = RTStrmGetLine(hStrm, szLine, sizeof(szLine))) == VINF_SUCCESS)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync iLine++;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
7b4ea63789001468ec3662bdfcd6432bf89095dfvboxsync /* Check if we're done. */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync char *psz = RTStrStrip(szLine);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if ( fSeenCopyright
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync && ( (psz[0] == '*' && psz[1] == '/')
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync || psz[0] == '\0') )
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync break;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync /* Strip comment suffix. */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync size_t cch = strlen(psz);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cch >= 2 && psz[cch - 1] == '/' && psz[cch - 2] == '*')
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync psz[cch - 2] = '\0';
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync RTStrStripR(psz);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync /* Skip line prefix. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (psz[0] == '/' && psz[1] == '*')
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync psz += 2;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync else if (psz[0] == '*')
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync psz += 1;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (*psz == ';')
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync psz++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_C_IS_SPACE(*psz))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync psz++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Skip the doxygen file tag line. */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if (!strcmp(psz, "* @file") || !strcmp(psz, "@file"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync continue;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync /* Detect copyright section. */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if ( !fSeenCopyright
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync && ( strstr(psz, "Copyright")
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync || strstr(psz, "copyright")) )
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync fSeenCopyright = true;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync fRc = outputPrintf("; %s\n", psz) && fRc;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync }
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync RTStrmClose(hStrm);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if (rc != VINF_SUCCESS)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync return disError("Error reading '%s': rc=%Rrc iLine=%u", pObjFile->pszSource, rc, iLine);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync }
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Set the org.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync fRc = outputPrintf("\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync "\n"
359416647a711739d1b14addbf399178949a1a60vboxsync "\n"
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync ) && fRc;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync return fRc;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync}
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync/**
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * Checks if a byte sequence could be a string litteral.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync *
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @returns @c true if it is, @c false if it isn't.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @param uFlatAddr The address of the byte sequence.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync * @param cb The length of the sequence.
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync */
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsyncstatic bool disIsString(uint32_t uFlatAddr, uint32_t cb)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync{
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync if (cb < 6)
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync return false;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (cb > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( !RT_C_IS_PRINT(*pb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && *pb != '\r'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && *pb != '\n'
359416647a711739d1b14addbf399178949a1a60vboxsync && *pb != '\t')
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (*pb == '\0')
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync do
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync pb++;
359416647a711739d1b14addbf399178949a1a60vboxsync cb--;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync } while (cb > 0 && *pb == '\0');
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync return cb == 0;
6902a98267d5180fb081cb5273751d0a628bf04dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync }
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync pb++;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync cb--;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync }
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync return true;
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync}
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Checks if a dword could be a far 16:16 BIOS address.
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync *
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync * @returns @c true if it is, @c false if it isn't.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param uFlatAddr The address of the dword.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disIsFarBiosAddr(uint32_t uFlatAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint16_t const *pu16 = (uint16_t const *)&g_pbImg[uFlatAddr - g_uBiosFlatBase];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pu16[1] < 0xf000)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pu16[1] > 0xfff0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t uFlatAddr2 = (uint32_t)(pu16[1] << 4) | pu16[0];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (uFlatAddr2 >= g_uBiosFlatBase + g_cbImg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disByteData(uint32_t uFlatAddr, uint32_t cb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
359416647a711739d1b14addbf399178949a1a60vboxsync size_t cbOnLine = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (cb-- > 0)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync bool fRc;
359416647a711739d1b14addbf399178949a1a60vboxsync if (cbOnLine >= 16)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf("\n"
359416647a711739d1b14addbf399178949a1a60vboxsync " db 0%02xh", *pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cbOnLine = 1;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else if (!cbOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf(" db 0%02xh", *pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cbOnLine = 1;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf(", 0%02xh", *pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cbOnLine++;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync if (!fRc)
359416647a711739d1b14addbf399178949a1a60vboxsync return false;
359416647a711739d1b14addbf399178949a1a60vboxsync pb++;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync return outputPrintf("\n");
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic bool disWordData(uint32_t uFlatAddr, uint32_t cb)
359416647a711739d1b14addbf399178949a1a60vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync if (cb & 1)
359416647a711739d1b14addbf399178949a1a60vboxsync return disError("disWordData expects word aligned size: cb=%#x uFlatAddr=%#x", uFlatAddr, cb);
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync uint16_t const *pu16 = (uint16_t const *)&g_pbImg[uFlatAddr - g_uBiosFlatBase];
359416647a711739d1b14addbf399178949a1a60vboxsync size_t cbOnLine = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync while (cb > 0)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync bool fRc;
359416647a711739d1b14addbf399178949a1a60vboxsync if (cbOnLine >= 16)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf("\n"
359416647a711739d1b14addbf399178949a1a60vboxsync " dw 0%04xh", *pu16);
359416647a711739d1b14addbf399178949a1a60vboxsync cbOnLine = 2;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else if (!cbOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf(" dw 0%04xh", *pu16);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbOnLine = 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf(", 0%04xh", *pu16);
359416647a711739d1b14addbf399178949a1a60vboxsync cbOnLine += 2;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync if (!fRc)
359416647a711739d1b14addbf399178949a1a60vboxsync return false;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pu16++;
359416647a711739d1b14addbf399178949a1a60vboxsync cb -= 2;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync return outputPrintf("\n");
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic bool disDWordData(uint32_t uFlatAddr, uint32_t cb)
359416647a711739d1b14addbf399178949a1a60vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync if (cb & 3)
ad290511521ce8388a9926b165241ecf83c330a7vboxsync return disError("disWordData expects dword aligned size: cb=%#x uFlatAddr=%#x", uFlatAddr, cb);
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync uint32_t const *pu32 = (uint32_t const *)&g_pbImg[uFlatAddr - g_uBiosFlatBase];
359416647a711739d1b14addbf399178949a1a60vboxsync size_t cbOnLine = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync while (cb > 0)
359416647a711739d1b14addbf399178949a1a60vboxsync {
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync bool fRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbOnLine >= 16)
359416647a711739d1b14addbf399178949a1a60vboxsync {
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync fRc = outputPrintf("\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync " dd 0%08xh", *pu32);
ad290511521ce8388a9926b165241ecf83c330a7vboxsync cbOnLine = 4;
359416647a711739d1b14addbf399178949a1a60vboxsync }
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync else if (!cbOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync fRc = outputPrintf(" dd 0%08xh", *pu32);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync cbOnLine = 4;
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync }
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync else
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync {
ad290511521ce8388a9926b165241ecf83c330a7vboxsync fRc = outputPrintf(", 0%08xh", *pu32);
bdbed0b8e7fb553d01417fdc976a76f3b287dbe2vboxsync cbOnLine += 4;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
359416647a711739d1b14addbf399178949a1a60vboxsync pu32++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb -= 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
41fcf8465b641c7083d3b440451f17c1210fce33vboxsync return outputPrintf("\n");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disStringData(uint32_t uFlatAddr, uint32_t cb)
359416647a711739d1b14addbf399178949a1a60vboxsync{
329df9696e709dc71611f504a4774f323545be0avboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
359416647a711739d1b14addbf399178949a1a60vboxsync uint32_t cchOnLine = 0;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync while (cb > 0)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync /* Line endings and beginnings. */
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchOnLine >= 72)
359416647a711739d1b14addbf399178949a1a60vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!outputPrintf("\n"))
329df9696e709dc71611f504a4774f323545be0avboxsync return false;
d9677fea1378fca6695c8f8fd3dbb21ac4607280vboxsync cchOnLine = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync }
abac45bdfa95437daba28dd2d94bf7e0a25f75cdvboxsync if ( !cchOnLine
359416647a711739d1b14addbf399178949a1a60vboxsync && !outputPrintf(" db "))
359416647a711739d1b14addbf399178949a1a60vboxsync return false;
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /* See how many printable character we've got. */
359416647a711739d1b14addbf399178949a1a60vboxsync uint32_t cchPrintable = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync while ( cchPrintable < cb
359416647a711739d1b14addbf399178949a1a60vboxsync && RT_C_IS_PRINT(pb[cchPrintable])
359416647a711739d1b14addbf399178949a1a60vboxsync && pb[cchPrintable] != '\'')
359416647a711739d1b14addbf399178949a1a60vboxsync cchPrintable++;
4ecd4ad59281328476ad14f2baa51716b6f5f804vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync bool fRc = true;
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchPrintable)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchPrintable + cchOnLine > 72)
4ecd4ad59281328476ad14f2baa51716b6f5f804vboxsync cchPrintable = 72 - cchOnLine;
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
329df9696e709dc71611f504a4774f323545be0avboxsync fRc = outputPrintf(", '%.*s'", cchPrintable, pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cchOnLine += 4 + cchPrintable;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf("'%.*s'", cchPrintable, pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cchOnLine += 2 + cchPrintable;
359416647a711739d1b14addbf399178949a1a60vboxsync }
329df9696e709dc71611f504a4774f323545be0avboxsync pb += cchPrintable;
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync cb -= cchPrintable;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (cchOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf(", 0%02xh", *pb);
329df9696e709dc71611f504a4774f323545be0avboxsync cchOnLine += 6;
329df9696e709dc71611f504a4774f323545be0avboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf("0%02xh", *pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cchOnLine += 4;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
46737b2c6b2da473108a7670c3682d88474bd8b9vboxsync pb++;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cb--;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync if (!fRc)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync return outputPrintf("\n");
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * For dumping a portion of a string table.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @returns @c true on success, @c false on failure.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param uFlatAddr The start address.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param cb The size of the string table.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic bool disStringsData(uint32_t uFlatAddr, uint32_t cb)
359416647a711739d1b14addbf399178949a1a60vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
359416647a711739d1b14addbf399178949a1a60vboxsync uint32_t cchOnLine = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync uint8_t bPrev = 255;
359416647a711739d1b14addbf399178949a1a60vboxsync while (cb > 0)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync /* Line endings and beginnings. */
359416647a711739d1b14addbf399178949a1a60vboxsync if ( cchOnLine >= 72
359416647a711739d1b14addbf399178949a1a60vboxsync || (bPrev == '\0' && *pb != '\0'))
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (!outputPrintf("\n"))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync cchOnLine = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync }
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if ( !cchOnLine
359416647a711739d1b14addbf399178949a1a60vboxsync && !outputPrintf(" db "))
359416647a711739d1b14addbf399178949a1a60vboxsync return false;
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync /* See how many printable character we've got. */
359416647a711739d1b14addbf399178949a1a60vboxsync uint32_t cchPrintable = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync while ( cchPrintable < cb
359416647a711739d1b14addbf399178949a1a60vboxsync && RT_C_IS_PRINT(pb[cchPrintable])
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync && pb[cchPrintable] != '\'')
359416647a711739d1b14addbf399178949a1a60vboxsync cchPrintable++;
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync bool fRc = true;
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchPrintable)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchPrintable + cchOnLine > 72)
359416647a711739d1b14addbf399178949a1a60vboxsync cchPrintable = 72 - cchOnLine;
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf(", '%.*s'", cchPrintable, pb);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync cchOnLine += 4 + cchPrintable;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf("'%.*s'", cchPrintable, pb);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync cchOnLine += 2 + cchPrintable;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync pb += cchPrintable;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync cb -= cchPrintable;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync if (cchOnLine)
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf(", 0%02xh", *pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cchOnLine += 6;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync fRc = outputPrintf("0%02xh", *pb);
359416647a711739d1b14addbf399178949a1a60vboxsync cchOnLine += 4;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync pb++;
359416647a711739d1b14addbf399178949a1a60vboxsync cb--;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync if (!fRc)
359416647a711739d1b14addbf399178949a1a60vboxsync return false;
359416647a711739d1b14addbf399178949a1a60vboxsync bPrev = pb[-1];
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync return outputPrintf("\n");
359416647a711739d1b14addbf399178949a1a60vboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * Minds the gap between two segments.
359416647a711739d1b14addbf399178949a1a60vboxsync *
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * Gaps should generally be zero filled.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @returns @c true on success, @c false on failure.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * @param uFlatAddr The address of the gap.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param cbPadding The size of the gap.
359416647a711739d1b14addbf399178949a1a60vboxsync */
09f4b412099acda62997fd82c8608075c453b3ebvboxsyncstatic bool disCopySegmentGap(uint32_t uFlatAddr, uint32_t cbPadding)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync if (g_cVerbose > 0)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync outputPrintf("\n"
359416647a711739d1b14addbf399178949a1a60vboxsync " ; Padding %#x bytes at %#x\n", cbPadding, uFlatAddr);
359416647a711739d1b14addbf399178949a1a60vboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
359416647a711739d1b14addbf399178949a1a60vboxsync if (!ASMMemIsAll8(pb, cbPadding, 0))
359416647a711739d1b14addbf399178949a1a60vboxsync return outputPrintf(" times %u db 0\n", cbPadding);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync return disByteData(uFlatAddr, cbPadding);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync}
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * Worker for disGetNextSymbol that only does the looking up, no RTDBSYMBOL::cb
359416647a711739d1b14addbf399178949a1a60vboxsync * calc.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @param uFlatAddr The address to start searching at.
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * @param cbMax The size of the search range.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param poff Where to return the offset between the symbol
359416647a711739d1b14addbf399178949a1a60vboxsync * and @a uFlatAddr.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param pSym Where to return the symbol data.
359416647a711739d1b14addbf399178949a1a60vboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic void disGetNextSymbolWorker(uint32_t uFlatAddr, uint32_t cbMax, uint32_t *poff, PRTDBGSYMBOL pSym)
359416647a711739d1b14addbf399178949a1a60vboxsync{
359416647a711739d1b14addbf399178949a1a60vboxsync RTINTPTR off = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync int rc = RTDbgModSymbolByAddr(g_hMapMod, RTDBGSEGIDX_RVA, uFlatAddr, RTDBGSYMADDR_FLAGS_GREATER_OR_EQUAL, &off, pSym);
359416647a711739d1b14addbf399178949a1a60vboxsync if (RT_SUCCESS(rc))
359416647a711739d1b14addbf399178949a1a60vboxsync {
359416647a711739d1b14addbf399178949a1a60vboxsync /* negative offset, indicates beyond. */
09f4b412099acda62997fd82c8608075c453b3ebvboxsync if (off <= 0)
359416647a711739d1b14addbf399178949a1a60vboxsync {
09f4b412099acda62997fd82c8608075c453b3ebvboxsync *poff = (uint32_t)-off;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync return;
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync outputPrintf(" ; !! RTDbgModSymbolByAddr(,,%#x,,) -> off=%RTptr cb=%RTptr uValue=%RTptr '%s'\n",
359416647a711739d1b14addbf399178949a1a60vboxsync uFlatAddr, off, pSym->cb, pSym->Value, pSym->szName);
359416647a711739d1b14addbf399178949a1a60vboxsync }
359416647a711739d1b14addbf399178949a1a60vboxsync else if (rc != VERR_SYMBOL_NOT_FOUND)
359416647a711739d1b14addbf399178949a1a60vboxsync outputPrintf(" ; !! RTDbgModSymbolByAddr(,,%#x,,) -> %Rrc\n", uFlatAddr, rc);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync RTStrPrintf(pSym->szName, sizeof(pSym->szName), "_dummy_addr_%#x", uFlatAddr + cbMax);
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pSym->Value = uFlatAddr + cbMax;
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync pSym->cb = 0;
359416647a711739d1b14addbf399178949a1a60vboxsync pSym->offSeg = uFlatAddr + cbMax;
359416647a711739d1b14addbf399178949a1a60vboxsync pSym->iSeg = RTDBGSEGIDX_RVA;
359416647a711739d1b14addbf399178949a1a60vboxsync pSym->iOrdinal = 0;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync pSym->fFlags = 0;
09f4b412099acda62997fd82c8608075c453b3ebvboxsync *poff = cbMax;
359416647a711739d1b14addbf399178949a1a60vboxsync}
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync
359416647a711739d1b14addbf399178949a1a60vboxsync/**
359416647a711739d1b14addbf399178949a1a60vboxsync * Gets the symbol at or after the given address.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * If there are no symbols in the specified range, @a pSym and @a poff will be
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * set up to indicate a symbol at the first byte after the range.
359416647a711739d1b14addbf399178949a1a60vboxsync *
359416647a711739d1b14addbf399178949a1a60vboxsync * @param uFlatAddr The address to start searching at.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param cbMax The size of the search range.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param poff Where to return the offset between the symbol
359416647a711739d1b14addbf399178949a1a60vboxsync * and @a uFlatAddr.
359416647a711739d1b14addbf399178949a1a60vboxsync * @param pSym Where to return the symbol data.
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync */
359416647a711739d1b14addbf399178949a1a60vboxsyncstatic void disGetNextSymbol(uint32_t uFlatAddr, uint32_t cbMax, uint32_t *poff, PRTDBGSYMBOL pSym)
09f4b412099acda62997fd82c8608075c453b3ebvboxsync{
09f4b412099acda62997fd82c8608075c453b3ebvboxsync disGetNextSymbolWorker(uFlatAddr, cbMax, poff, pSym);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync if ( *poff < cbMax
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pSym->cb == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync if (*poff + 1 < cbMax)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t off2;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync RTDBGSYMBOL Sym2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disGetNextSymbolWorker(uFlatAddr + *poff + 1, cbMax - *poff - 1, &off2, &Sym2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSym->cb = off2 + 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSym->cb = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSym->cb > cbMax - *poff)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSym->cb = cbMax - *poff;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_cVerbose > 1)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync outputPrintf(" ; disGetNextSymbol %#x LB %#x -> off=%#x cb=%RTptr uValue=%RTptr '%s'\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr, cbMax, *poff, pSym->cb, pSym->Value, pSym->szName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * For dealing with the const segment (string constants).
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync * @returns @c true on success, @c false on failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param iSeg The segment.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disConstSegment(uint32_t iSeg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync uint32_t uFlatAddr = g_aSegs[iSeg].uFlatAddr;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync uint32_t cb = g_aSegs[iSeg].cb;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync while (cb > 0)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync uint32_t off;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync RTDBGSYMBOL Sym;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync disGetNextSymbol(uFlatAddr, cb, &off, &Sym);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (!disStringsData(uFlatAddr, off))
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb -= off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchName = strlen(Sym.szName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf("%s: %*s; %#x LB %#x\n", Sym.szName, cchName < 41 - 2 ? cchName - 41 - 2 : 0, "", uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disStringsData(uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += Sym.cb;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync cb -= Sym.cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disStringsData(uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disDataSegment(uint32_t iSeg)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync{
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync uint32_t uFlatAddr = g_aSegs[iSeg].uFlatAddr;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync uint32_t cb = g_aSegs[iSeg].cb;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync while (cb > 0)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTDBGSYMBOL Sym;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disGetNextSymbol(uFlatAddr, cb, &off, &Sym);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!disByteData(uFlatAddr, off))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb -= off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchName = strlen(Sym.szName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf("%s: %*s; %#x LB %#x\n", Sym.szName, cchName < 41 - 2 ? cchName - 41 - 2 : 0, "", uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Sym.cb == 2)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disWordData(uFlatAddr, 2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync //else if (Sym.cb == 4 && disIsFarBiosAddr(uFlatAddr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync // fRc = disDWordData(uFlatAddr, 4);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (Sym.cb == 4)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disDWordData(uFlatAddr, 4);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (disIsString(uFlatAddr, Sym.cb))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disStringData(uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disByteData(uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += Sym.cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb -= Sym.cb;
359416647a711739d1b14addbf399178949a1a60vboxsync }
ac0289f10f2d2a73377ef9572871c48631973f80vboxsync else
359416647a711739d1b14addbf399178949a1a60vboxsync {
ac0289f10f2d2a73377ef9572871c48631973f80vboxsync fRc = disByteData(uFlatAddr, cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb = 0;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disIsCodeAndAdjustSize(uint32_t uFlatAddr, PRTDBGSYMBOL pSym, PBIOSSEG pSeg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (g_enmBiosType)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This is for the PC BIOS.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case kBiosType_System:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!strcmp(pSeg->szName, "BIOSSEG"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( !strcmp(pSym->szName, "rom_fdpt")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "pmbios_gdt")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "pmbios_gdt_desc")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "_pmode_IDT")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "_rmode_IDT")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strncmp(pSym->szName, RT_STR_TUPLE("font"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "bios_string")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "vector_table")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "pci_routing_table_structure")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !strcmp(pSym->szName, "_pci_routing_table")
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!strcmp(pSym->szName, "cpu_reset"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSym->cb = RT_MIN(pSym->cb, 5);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync else if (!strcmp(pSym->szName, "pci_init_end"))
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pSym->cb = RT_MIN(pSym->cb, 3);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This is for the VGA BIOS.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case kBiosType_Vga:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool disIs16BitCode(const char *pszSymbol)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Deals with instructions that YASM will assemble differently than WASM/WCC.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic size_t disHandleYasmDifferences(PDISCPUSTATE pCpuState, uint32_t uFlatAddr, uint32_t cbInstr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char *pszBuf, size_t cbBuf, size_t cchUsed)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fDifferent = DISFormatYasmIsOddEncoding(pCpuState);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Disassembler bugs.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /** @todo Group 1a and 11 seems to be disassembled incorrectly when
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * modrm.reg != 0. Those encodings should be invalid AFAICT. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( ( pCpuState->bOpCode == 0x8f /* group 1a */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || pCpuState->bOpCode == 0xc7 /* group 11 */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || pCpuState->bOpCode == 0xc6 /* group 11 - not verified */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pCpuState->ModRM.Bits.Reg != 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fDifferent = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Check these out and consider adding them to DISFormatYasmIsOddEncoding.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if ( pb[0] == 0xf3
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pb[1] == 0x66
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pb[2] == 0x6d)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fDifferent = true; /* rep insd - prefix switched. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if ( pb[0] == 0xc6
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pb[1] == 0xc5
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && pb[2] == 0xba)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fDifferent = true; /* mov ch, 0bah - yasm uses a short sequence: 0xb5 0xba. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Handle different stuff.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (fDifferent)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disByteData(uFlatAddr, cbInstr); /* lazy bird. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cchUsed + 2 < cbBuf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memmove(pszBuf + 2, pszBuf, cchUsed + 2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cchUsed += 2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pszBuf[0] = ';';
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pszBuf[1] = ' ';
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return cchUsed;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
ad290511521ce8388a9926b165241ecf83c330a7vboxsync/**
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @callback_method_impl{FNDISREADBYTES}
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync *
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @remarks @a uSrcAddr is the flat address.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsyncstatic DECLCALLBACK(int) disReadOpcodeBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync{
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTUINTPTR offBios = pDis->uInstrAddr + offInstr - g_uBiosFlatBase;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync size_t cbToRead = cbMaxRead;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (offBios + cbToRead > g_cbImg)
f117ea164d0c252b17348042ff616dfd8ff20cb8vboxsync {
f117ea164d0c252b17348042ff616dfd8ff20cb8vboxsync if (offBios >= g_cbImg)
f117ea164d0c252b17348042ff616dfd8ff20cb8vboxsync cbToRead = 0;
f117ea164d0c252b17348042ff616dfd8ff20cb8vboxsync else
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync cbToRead = g_cbImg - offBios;
f117ea164d0c252b17348042ff616dfd8ff20cb8vboxsync }
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync memcpy(&pDis->abInstr[offInstr], &g_pbImg[offBios], cbToRead);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pDis->cbCachedInstr = offInstr + cbToRead;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return VINF_SUCCESS;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync}
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync/**
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * Disassembles code.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync *
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @returns @c true on success, @c false on failure.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @param uFlatAddr The address where the code starts.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @param cb The amount of code to disassemble.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @param fIs16Bit Is is 16-bit (@c true) or 32-bit (@c false).
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsyncstatic bool disCode(uint32_t uFlatAddr, uint32_t cb, bool fIs16Bit)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync{
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync uint8_t const *pb = &g_pbImg[uFlatAddr - g_uBiosFlatBase];
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync while (cb > 0)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /* Trailing zero padding detection. */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if ( *pb == '\0'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync && ASMMemIsAll8(pb, RT_MIN(cb, 8), 0) == NULL)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync void *pv = ASMMemIsAll8(pb, cb, 0);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync uint32_t cbZeros = pv ? (uint32_t)((uint8_t const *)pv - pb) : cb;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (!outputPrintf(" times %#x db 0\n", cbZeros))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync cb -= cbZeros;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync pb += cbZeros;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync uFlatAddr += cbZeros;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if ( cb == 2
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync && pb[0] == 'X'
ad290511521ce8388a9926b165241ecf83c330a7vboxsync && pb[1] == 'M')
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return disStringData(uFlatAddr, cb);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync }
ad290511521ce8388a9926b165241ecf83c330a7vboxsync /* Work arounds for switch tables and such (disas assertions). */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else if ( ( pb[0] == 0x11 /* int13_cdemu switch */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync && pb[1] == 0xda
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync && pb[2] == 0x05
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync && pb[3] == 0xff
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync && pb[4] == 0xff
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync )
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || 0
ad290511521ce8388a9926b165241ecf83c330a7vboxsync )
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return disByteData(uFlatAddr, cb);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync unsigned cbInstr;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync DISCPUSTATE CpuState;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync int rc = DISInstrWithReader(uFlatAddr, fIs16Bit ? DISCPUMODE_16BIT : DISCPUMODE_32BIT,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disReadOpcodeBytes, NULL, &CpuState, &cbInstr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( RT_SUCCESS(rc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && cbInstr <= cb
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CpuState.pCurInstr
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && CpuState.pCurInstr->uOpcode != OP_INVALID)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szTmp[4096];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cch = DISFormatYasmEx(&CpuState, szTmp, sizeof(szTmp),
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync DIS_FMT_FLAGS_STRICT
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync | DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_COMMENT | DIS_FMT_FLAGS_BYTES_SPACED,
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync NULL, NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cch = disHandleYasmDifferences(&CpuState, uFlatAddr, cbInstr, szTmp, sizeof(szTmp), cch);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cch < sizeof(szTmp));
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_cVerbose > 1)
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync {
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync while (cch < 72)
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync szTmp[cch++] = ' ';
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync RTStrPrintf(&szTmp[cch], sizeof(szTmp) - cch, "; %#x", uFlatAddr);
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync }
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync if (!outputPrintf(" %s\n", szTmp))
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync return false;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync cb -= cbInstr;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync pb += cbInstr;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync uFlatAddr += cbInstr;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync }
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync if (!disByteData(uFlatAddr, 1))
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync return false;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync cb--;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync pb++;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync uFlatAddr++;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsyncstatic bool disCodeSegment(uint32_t iSeg)
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync{
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync uint32_t uFlatAddr = g_aSegs[iSeg].uFlatAddr;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync uint32_t cb = g_aSegs[iSeg].cb;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync while (cb > 0)
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync {
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync uint32_t off;
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync RTDBGSYMBOL Sym;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync disGetNextSymbol(uFlatAddr, cb, &off, &Sym);
00ef464add2ac67ce0d698c9d02f720ef9e9a372vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!disByteData(uFlatAddr, off))
2721dfb0e330d57ba888311520f5a343c64e7cefvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb -= off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync off = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fRc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (off == 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchName = strlen(Sym.szName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf("%s: %*s; %#x LB %#x\n", Sym.szName, cchName < 41 - 2 ? cchName - 41 - 2 : 0, "", uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (disIsCodeAndAdjustSize(uFlatAddr, &Sym, &g_aSegs[iSeg]))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disCode(uFlatAddr, Sym.cb, disIs16BitCode(Sym.szName));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disByteData(uFlatAddr, Sym.cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += Sym.cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb -= Sym.cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disByteData(uFlatAddr, cb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += cb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cb = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic RTEXITCODE DisassembleBiosImage(void)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!disFileHeader())
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Work the image segment by segment.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool fRc = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t uFlatAddr = g_uBiosFlatBase;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (uint32_t iSeg = 0; iSeg < g_cSegs && fRc; iSeg++)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Is there a gap between the segments? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (uFlatAddr < g_aSegs[iSeg].uFlatAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disCopySegmentGap(uFlatAddr, g_aSegs[iSeg].uFlatAddr - uFlatAddr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr = g_aSegs[iSeg].uFlatAddr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (uFlatAddr > g_aSegs[iSeg].uFlatAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Overlapping segments: %u and %u; uFlatAddr=%#x\n", iSeg - 1, iSeg, uFlatAddr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Disassemble the segment. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = outputPrintf("\n"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync "section %s progbits vstart=%#x align=1 ; size=%#x class=%s group=%s\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].szName, g_aSegs[iSeg].uFlatAddr - g_uBiosFlatBase,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].cb, g_aSegs[iSeg].szClass, g_aSegs[iSeg].szGroup);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!fRc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!strcmp(g_aSegs[iSeg].szName, "CONST"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disConstSegment(iSeg);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (!strcmp(g_aSegs[iSeg].szClass, "DATA"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disDataSegment(iSeg);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disCodeSegment(iSeg);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Advance. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uFlatAddr += g_aSegs[iSeg].cb;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Final gap. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (uFlatAddr < g_uBiosFlatBase + g_cbImg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fRc = disCopySegmentGap(uFlatAddr, g_uBiosFlatBase + g_cbImg - uFlatAddr);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync else if (uFlatAddr > g_uBiosFlatBase + g_cbImg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Last segment spills beyond 1MB; uFlatAddr=%#x\n", uFlatAddr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync if (!fRc)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
ad290511521ce8388a9926b165241ecf83c330a7vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync/**
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * Parses the symbol file for the BIOS.
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync *
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * This is in ELF/DWARF format.
4ae5315434291f40e413118cd24a212532bbe572vboxsync *
f068575233c08526611dbe29684bee5f2cbe7144vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
f068575233c08526611dbe29684bee5f2cbe7144vboxsync * @param pszBiosSym Path to the sym file.
f068575233c08526611dbe29684bee5f2cbe7144vboxsync */
f068575233c08526611dbe29684bee5f2cbe7144vboxsyncstatic RTEXITCODE ParseSymFile(const char *pszBiosSym)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync{
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync#if 1
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /** @todo use RTDbg* later. (Just checking for existance currently.) */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync PRTSTREAM hStrm;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync int rc = RTStrmOpen(pszBiosSym, "rb", &hStrm);
f068575233c08526611dbe29684bee5f2cbe7144vboxsync if (RT_FAILURE(rc))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening '%s': %Rrc", pszBiosSym, rc);
ad290511521ce8388a9926b165241ecf83c330a7vboxsync RTStrmClose(hStrm);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync#else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTDBGMOD hDbgMod;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTDbgModCreateFromImage(&hDbgMod, pszBiosSym, "VBoxBios", 0 /*fFlags*/);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTMsgInfo("RTDbgModCreateFromImage -> %Rrc\n", rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync return RTEXITCODE_SUCCESS;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync * Display an error with the mapfile name and current line, return false.
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync *
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync * @returns @c false.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pMap The map file handle.
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync * @param pszFormat The format string.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ... Format arguments.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsyncstatic bool mapError(PBIOSMAP pMap, const char *pszFormat, ...)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_list va;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync va_start(va, pszFormat);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync RTMsgError("%s:%d: %N", pMap->pszMapFile, pMap->iLine, pszFormat, va);
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync va_end(va);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return false;
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync}
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync
09f4b412099acda62997fd82c8608075c453b3ebvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync/**
09f4b412099acda62997fd82c8608075c453b3ebvboxsync * Reads a line from the file.
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync *
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync * @param pMap The map file handle.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
5295c362853081eaa3944247171746a3aad9a826vboxsyncstatic bool mapReadLine(PBIOSMAP pMap)
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync{
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync int rc = RTStrmGetLine(pMap->hStrm, pMap->szLine, sizeof(pMap->szLine));
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rc == VERR_EOF)
4c98b8b05f3783351cf256cc90cd4478fb28b62bvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pMap->fEof = true;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pMap->cch = 0;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pMap->offNW = 0;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync pMap->szLine[0] = '\0';
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync }
ad290511521ce8388a9926b165241ecf83c330a7vboxsync else
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync RTMsgError("%s:%d: Read error %Rrc", pMap->pszMapFile, pMap->iLine + 1, rc);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return false;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pMap->iLine++;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pMap->cch = (uint32_t)strlen(pMap->szLine);
ad290511521ce8388a9926b165241ecf83c330a7vboxsync
7b6926b2bf44f326f40e1d9d1ce33a4dff0a2c67vboxsync /* Check out leading white space. */
ad290511521ce8388a9926b165241ecf83c330a7vboxsync if (!RT_C_IS_SPACE(pMap->szLine[0]))
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync pMap->offNW = 0;
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync else
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync uint32_t off = 1;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync while (RT_C_IS_SPACE(pMap->szLine[off]))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync off++;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pMap->offNW = off;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync/**
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * Checks if it is an empty line.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @returns @c true if empty, @c false if not.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @param pMap The map file handle.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncstatic bool mapIsEmptyLine(PBIOSMAP pMap)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(pMap->offNW <= pMap->cch);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return pMap->offNW == pMap->cch;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync/**
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * Reads ahead in the map file until a non-empty line or EOF is encountered.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync *
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @param pMap The map file handle.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncstatic bool mapSkipEmptyLines(PBIOSMAP pMap)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync for (;;)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!mapReadLine(pMap))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (pMap->offNW < pMap->cch)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync/**
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * Reads ahead in the map file until an empty line or EOF is encountered.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync *
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync * @param pMap The map file handle.
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncstatic bool mapSkipNonEmptyLines(PBIOSMAP pMap)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync for (;;)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!mapReadLine(pMap))
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (pMap->offNW == pMap->cch)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync/**
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync * Strips the current line.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync *
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * The string length may change.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync *
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * @returns Pointer to the first non-space character.
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * @param pMap The map file handle.
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * @param pcch Where to return the length of the unstripped
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * part. Optional.
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync */
5159c4c6485473c77871b515c15b59c3caa60b46vboxsyncstatic char *mapStripCurrentLine(PBIOSMAP pMap, size_t *pcch)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync{
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync char *psz = &pMap->szLine[pMap->offNW];
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync char *pszEnd = &pMap->szLine[pMap->cch];
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync while ( (uintptr_t)pszEnd > (uintptr_t)psz
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync && RT_C_IS_SPACE(pszEnd[-1]))
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync {
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync *--pszEnd = '\0';
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync pMap->cch--;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync }
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync if (pcch)
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync *pcch = pszEnd - psz;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync return psz;
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync}
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync/**
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * Reads a line from the file and right strips it.
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync *
5159c4c6485473c77871b515c15b59c3caa60b46vboxsync * @returns Pointer to szLine on success, @c NULL + msg on failure, @c NULL on
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * EOF.
73ba84f95f918cc170be38908ad240fbb2f8f354vboxsync * @param pMap The map file handle.
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync * @param pcch Where to return the length of the unstripped
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync * part. Optional.
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsync */
6b2a50fc09aa4f7ce2082284f082d97a2c738321vboxsyncstatic char *mapReadLineStripRight(PBIOSMAP pMap, size_t *pcch)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync if (!mapReadLine(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync mapStripCurrentLine(pMap, NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pcch)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *pcch = pMap->cch;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pMap->szLine;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * mapReadLine() + mapStripCurrentLine().
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns Pointer to the first non-space character in the new line. NULL on
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * read error (bitched already) or end of file.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pMap The map file handle.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcch Where to return the length of the unstripped
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * part. Optional.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic char *mapReadLineStrip(PBIOSMAP pMap, size_t *pcch)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapReadLine(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return mapStripCurrentLine(pMap, pcch);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses a word, copying it into the supplied buffer, and skipping any spaces
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * following it.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true on success, @c false on failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ppszCursor Pointer to the cursor variable.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pszBuf The output buffer.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param cbBuf The size of the output buffer.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool mapParseWord(char **ppszCursor, char *pszBuf, size_t cbBuf)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Check that we start on a non-blank. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char *pszStart = *ppszCursor;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!*pszStart || RT_C_IS_SPACE(*pszStart))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Find the end of the word. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char *psz = pszStart + 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (*psz && !RT_C_IS_SPACE(*psz))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync psz++;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync /* Copy it. */
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync size_t cchWord = (uintptr_t)psz - (uintptr_t)pszStart;
dfa8f8fe70f68c12b11d4b15354571131dc75becvboxsync if (cchWord >= cbBuf)
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync return false;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync memcpy(pszBuf, pszStart, cchWord);
67b8a5a52c43a79ea7e159dbbeec99687fb9cd3bvboxsync pszBuf[cchWord] = '\0';
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync /* Skip blanks following it. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (RT_C_IS_SPACE(*psz))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync psz++;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync *ppszCursor = psz;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync * Parses an 16:16 address.
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync *
3a343ca21a267ec3c54e2317e2ed18fe99b8ebbbvboxsync * @returns @c true on success, @c false on failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ppszCursor Pointer to the cursor variable.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pAddr Where to return the address.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool mapParseAddress(char **ppszCursor, PRTFAR16 pAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szWord[32];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapParseWord(ppszCursor, szWord, sizeof(szWord)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchWord = strlen(szWord);
4f6450f96eae5ca3698ce0b7174fe8539adf838avboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* An address is at least 16:16 format. It may be 16:32. It may also be flagged. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchAddr = 4 + 1 + 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cchWord < cchAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( !RT_C_IS_XDIGIT(szWord[0])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[1])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[2])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[3])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || szWord[4] != ':'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[5])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[6])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[7])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !RT_C_IS_XDIGIT(szWord[8])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( cchWord > cchAddr
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && RT_C_IS_XDIGIT(szWord[9])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && RT_C_IS_XDIGIT(szWord[10])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && RT_C_IS_XDIGIT(szWord[11])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && RT_C_IS_XDIGIT(szWord[12]))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cchAddr += 4;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Drop flag if present. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cchWord > cchAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_C_IS_XDIGIT(szWord[cchAddr]))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync szWord[cchAddr] = '\0';
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cchWord = cchAddr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Convert it. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync szWord[4] = '\0';
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc1 = RTStrToUInt16Full(szWord, 16, &pAddr->sel);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rc1 != VINF_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc2 = RTStrToUInt16Full(szWord + 5, 16, &pAddr->off);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rc2 != VINF_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses a size.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true on success, @c false on failure.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ppszCursor Pointer to the cursor variable.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pcb Where to return the size.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool mapParseSize(char **ppszCursor, uint32_t *pcb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szWord[32];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapParseWord(ppszCursor, szWord, sizeof(szWord)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchWord = strlen(szWord);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cchWord != 8)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTStrToUInt32Full(szWord, 16, pcb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rc != VINF_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses a section box and the following column header.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pMap Map file handle.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pszSectionNm The expected section name.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param cColumns The number of columns.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param ... The column names.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool mapSkipThruColumnHeadings(PBIOSMAP pMap, const char *pszSectionNm, uint32_t cColumns, ...)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( mapIsEmptyLine(pMap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync && !mapSkipEmptyLines(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* +------------+ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cch;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char *psz = mapStripCurrentLine(pMap, &cch);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!psz)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( psz[0] != '+'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[1] != '-'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[2] != '-'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[3] != '-'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[cch - 4] != '-'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[cch - 3] != '-'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[cch - 2] != '-'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || psz[cch - 1] != '+'
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTMsgError("%s:%d: Expected section box: +-----...", pMap->pszMapFile, pMap->iLine);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
ad290511521ce8388a9926b165241ecf83c330a7vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync /* | pszSectionNm | */
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync psz = mapReadLineStrip(pMap, &cch);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (!psz)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync size_t cchSectionNm = strlen(pszSectionNm);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if ( psz[0] != '|'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[1] != ' '
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[2] != ' '
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[3] != ' '
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 4] != ' '
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 3] != ' '
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 2] != ' '
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 1] != '|'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || cch != 1 + 3 + cchSectionNm + 3 + 1
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || strncmp(&psz[4], pszSectionNm, cchSectionNm)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync )
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTMsgError("%s:%d: Expected section box: | %s |", pMap->pszMapFile, pMap->iLine, pszSectionNm);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /* +------------+ */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync psz = mapReadLineStrip(pMap, &cch);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!psz)
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return false;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if ( psz[0] != '+'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[1] != '-'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[2] != '-'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[3] != '-'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 4] != '-'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 3] != '-'
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync || psz[cch - 2] != '-'
fdb57e5580007400346665b64c0e14ca1d149019vboxsync || psz[cch - 1] != '+'
29e87957eab05faee4ca07215447062bd927ce67vboxsync )
29e87957eab05faee4ca07215447062bd927ce67vboxsync {
29e87957eab05faee4ca07215447062bd927ce67vboxsync RTMsgError("%s:%d: Expected section box: +-----...", pMap->pszMapFile, pMap->iLine);
29e87957eab05faee4ca07215447062bd927ce67vboxsync return false;
29e87957eab05faee4ca07215447062bd927ce67vboxsync }
29e87957eab05faee4ca07215447062bd927ce67vboxsync
29e87957eab05faee4ca07215447062bd927ce67vboxsync /* There may be a few lines describing the table notation now, surrounded by blank lines. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync do
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync psz = mapReadLineStripRight(pMap, &cch);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!psz)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync } while ( *psz == '\0'
fdb57e5580007400346665b64c0e14ca1d149019vboxsync || ( !RT_C_IS_SPACE(psz[0])
fdb57e5580007400346665b64c0e14ca1d149019vboxsync && RT_C_IS_SPACE(psz[1])
fdb57e5580007400346665b64c0e14ca1d149019vboxsync && psz[2] == '='
fdb57e5580007400346665b64c0e14ca1d149019vboxsync && RT_C_IS_SPACE(psz[3]))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync );
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /* Should have the column heading now. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync va_list va;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync va_start(va, cColumns);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync for (uint32_t i = 0; i < cColumns; i++)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync const char *pszColumn = va_arg(va, const char *);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync size_t cchColumn = strlen(pszColumn);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if ( strncmp(psz, pszColumn, cchColumn)
7ea49b4765b66fc68d2e6c1cb2a647b53a4aea24vboxsync || ( psz[cchColumn] != '\0'
fdb57e5580007400346665b64c0e14ca1d149019vboxsync && !RT_C_IS_SPACE(psz[cchColumn])))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync va_end(va);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTMsgError("%s:%d: Expected column '%s' found '%s'", pMap->pszMapFile, pMap->iLine, pszColumn, psz);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync psz += cchColumn;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync while (RT_C_IS_SPACE(*psz))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync psz++;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync va_end(va);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /* The next line is the underlining. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync psz = mapReadLineStripRight(pMap, &cch);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!psz)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (*psz != '=' || psz[cch - 1] != '=')
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTMsgError("%s:%d: Expected column header underlining", pMap->pszMapFile, pMap->iLine);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /* Skip one blank line. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync psz = mapReadLineStripRight(pMap, &cch);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!psz)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (*psz)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTMsgError("%s:%d: Expected blank line beneath the column headers", pMap->pszMapFile, pMap->iLine);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return true;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync}
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync/**
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * Parses a segment list.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync *
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * @param pMap The map file handle.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
fdb57e5580007400346665b64c0e14ca1d149019vboxsyncstatic bool mapParseSegments(PBIOSMAP pMap)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync{
fdb57e5580007400346665b64c0e14ca1d149019vboxsync for (;;)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!mapReadLineStripRight(pMap, NULL))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /* The end? The line should be empty. Expectes segment name to not
fdb57e5580007400346665b64c0e14ca1d149019vboxsync start with a space. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!pMap->szLine[0] || RT_C_IS_SPACE(pMap->szLine[0]))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!pMap->szLine[0])
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return true;
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync RTMsgError("%s:%u: Malformed segment line", pMap->pszMapFile, pMap->iLine);
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync /* Parse the segment line. */
fdb57e5580007400346665b64c0e14ca1d149019vboxsync uint32_t iSeg = g_cSegs;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (iSeg >= RT_ELEMENTS(g_aSegs))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTMsgError("%s:%u: Too many segments", pMap->pszMapFile, pMap->iLine);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return false;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync char *psz = pMap->szLine;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (!mapParseWord(&psz, g_aSegs[iSeg].szName, sizeof(g_aSegs[iSeg].szName)))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTMsgError("%s:%u: Segment name parser error", pMap->pszMapFile, pMap->iLine);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync else if (!mapParseWord(&psz, g_aSegs[iSeg].szClass, sizeof(g_aSegs[iSeg].szClass)))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTMsgError("%s:%u: Segment class parser error", pMap->pszMapFile, pMap->iLine);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else if (!mapParseWord(&psz, g_aSegs[iSeg].szGroup, sizeof(g_aSegs[iSeg].szGroup)))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTMsgError("%s:%u: Segment group parser error", pMap->pszMapFile, pMap->iLine);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else if (!mapParseAddress(&psz, &g_aSegs[iSeg].Address))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTMsgError("%s:%u: Segment address parser error", pMap->pszMapFile, pMap->iLine);
ad290511521ce8388a9926b165241ecf83c330a7vboxsync else if (!mapParseSize(&psz, &g_aSegs[iSeg].cb))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTMsgError("%s:%u: Segment size parser error", pMap->pszMapFile, pMap->iLine);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].uFlatAddr = ((uint32_t)g_aSegs[iSeg].Address.sel << 4) + g_aSegs[iSeg].Address.off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_cSegs++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_cVerbose > 2)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTStrmPrintf(g_pStdErr, "read segment at %08x / %04x:%04x LB %04x %s / %s / %s\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].uFlatAddr,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].Address.sel,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].Address.off,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].cb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].szName,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].szClass,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[iSeg].szGroup);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
e6ad2e18e663b076aeabfec994947514566a7accvboxsync while (RT_C_IS_SPACE(*psz))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync psz++;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (!*psz)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync continue;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync RTMsgError("%s:%u: Junk at end of line", pMap->pszMapFile, pMap->iLine);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
e6ad2e18e663b076aeabfec994947514566a7accvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Sorts the segment array by flat address and adds them to the debug module.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsyncstatic bool mapSortAndAddSegments(void)
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync{
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync for (uint32_t i = 0; i < g_cSegs; i++)
3ea1dbf096240fc221aea99352a74c17a367a9b6vboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (uint32_t j = i + 1; j < g_cSegs; j++)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_aSegs[j].uFlatAddr < g_aSegs[i].uFlatAddr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BIOSSEG Tmp = g_aSegs[i];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[i] = g_aSegs[j];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[j] = Tmp;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (g_cVerbose > 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTStrmPrintf(g_pStdErr, "segment at %08x / %04x:%04x LB %04x %s / %s / %s\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[i].uFlatAddr,
e6ad2e18e663b076aeabfec994947514566a7accvboxsync g_aSegs[i].Address.sel,
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync g_aSegs[i].Address.off,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[i].cb,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[i].szName,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[i].szClass,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_aSegs[i].szGroup);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTDBGSEGIDX idx = i;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTDbgModSegmentAdd(g_hMapMod, g_aSegs[i].uFlatAddr, g_aSegs[i].cb, g_aSegs[i].szName, 0 /*fFlags*/, &idx);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTMsgError("RTDbgModSegmentAdd failed on %s: %Rrc", g_aSegs[i].szName);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses a segment list.
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @returns @c true on success, @c false + msg on failure, @c false on eof.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pMap The map file handle.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic bool mapParseSymbols(PBIOSMAP pMap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (;;)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapReadLineStripRight(pMap, NULL))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* The end? The line should be empty. Expectes segment name to not
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync start with a space. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pMap->szLine[0] || RT_C_IS_SPACE(pMap->szLine[0]))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pMap->szLine[0])
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return mapError(pMap, "Malformed symbol line");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!strncmp(pMap->szLine, RT_STR_TUPLE("Module: ")))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Parse the module line. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t offObj = sizeof("Module: ") - 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while (RT_C_IS_SPACE(pMap->szLine[offObj]))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offObj++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t offSrc = offObj;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char ch;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while ((ch = pMap->szLine[offSrc]) != '(' && ch != '\0')
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSrc++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchObj = offSrc - offObj;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync offSrc++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync size_t cchSrc = offSrc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while ((ch = pMap->szLine[cchSrc]) != ')' && ch != '\0')
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cchSrc++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cchSrc -= offSrc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (ch != ')')
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return mapError(pMap, "Symbol/Module line parse error");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
e6ad2e18e663b076aeabfec994947514566a7accvboxsync PBIOSOBJFILE pObjFile = (PBIOSOBJFILE)RTMemAllocZ(sizeof(*pObjFile) + cchSrc + cchObj + 2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pObjFile)
e6ad2e18e663b076aeabfec994947514566a7accvboxsync return mapError(pMap, "Out of memory");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char *psz = (char *)(pObjFile + 1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pObjFile->pszObject = psz;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(psz, &pMap->szLine[offObj], cchObj);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync psz += cchObj;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *psz++ = '\0';
e6ad2e18e663b076aeabfec994947514566a7accvboxsync pObjFile->pszSource = psz;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync memcpy(psz, &pMap->szLine[offSrc], cchSrc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync psz[cchSrc] = '\0';
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTListAppend(&g_ObjList, &pObjFile->Node);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
e6ad2e18e663b076aeabfec994947514566a7accvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Parse the segment line. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTFAR16 Addr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char *psz = pMap->szLine;
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (!mapParseAddress(&psz, &Addr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return mapError(pMap, "Symbol address parser error");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync char szName[4096];
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapParseWord(&psz, szName, sizeof(szName)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return mapError(pMap, "Symbol name parser error");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t uFlatAddr = ((uint32_t)Addr.sel << 4) + Addr.off;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (uFlatAddr != 0)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync int rc = RTDbgModSymbolAdd(g_hMapMod, szName, RTDBGSEGIDX_RVA, uFlatAddr, 0 /*cb*/, 0 /*fFlags*/, NULL);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if (RT_FAILURE(rc) && rc != VERR_DBG_ADDRESS_CONFLICT)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync {
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync /* HACK ALERT! For dealing with lables at segment size. */ /** @todo fix end labels. */
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync rc = RTDbgModSymbolAdd(g_hMapMod, szName, RTDBGSEGIDX_RVA, uFlatAddr - 1, 0 /*cb*/, 0 /*fFlags*/, NULL);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if (RT_FAILURE(rc) && rc != VERR_DBG_ADDRESS_CONFLICT)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return mapError(pMap, "RTDbgModSymbolAdd failed: %Rrc", rc);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if (g_cVerbose > 2)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync RTStrmPrintf(g_pStdErr, "read symbol - %08x %s\n", uFlatAddr, szName);
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync while (RT_C_IS_SPACE(*psz))
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync psz++;
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync if (*psz)
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync return mapError(pMap, "Junk at end of line");
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync }
1389294d44ac76b0a25f5655756c9d39855a73efvboxsync }
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync}
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync/**
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * Parses the given map file.
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync *
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * @returns RTEXITCODE_SUCCESS and lots of globals, or RTEXITCODE_FAILURE and a
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * error message.
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync * @param pMap The map file handle.
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic RTEXITCODE mapParseFile(PBIOSMAP pMap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTDbgModCreate(&g_hMapMod, "VBoxBios", 0 /*cbSeg*/, 0 /*fFlags*/);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_FAILURE(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreate failed: %Rrc", rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Read the header.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapReadLine(pMap))
c58dc77ef4af214d7ae06910fa5ab18587d2ae08vboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (strncmp(pMap->szLine, RT_STR_TUPLE("Open Watcom Linker Version")))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected map-file header: '%s'", pMap->szLine);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if ( !mapSkipNonEmptyLines(pMap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync || !mapSkipEmptyLines(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Skip groups.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapSkipThruColumnHeadings(pMap, "Groups", 3, "Group", "Address", "Size", NULL))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (!mapSkipNonEmptyLines(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
e6ad2e18e663b076aeabfec994947514566a7accvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parse segments.
e6ad2e18e663b076aeabfec994947514566a7accvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapSkipThruColumnHeadings(pMap, "Segments", 5, "Segment", "Class", "Group", "Address", "Size"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapParseSegments(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapSortAndAddSegments())
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parse symbols.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapSkipThruColumnHeadings(pMap, "Memory Map", 2, "Address", "Symbol"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!mapParseSymbols(pMap))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_FAILURE;
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync /* Ignore the rest of the file. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_SUCCESS;
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Parses the linker map file for the BIOS.
ad290511521ce8388a9926b165241ecf83c330a7vboxsync *
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync * This is generated by the Watcom linker.
ad290511521ce8388a9926b165241ecf83c330a7vboxsync *
ad290511521ce8388a9926b165241ecf83c330a7vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync * @param pszBiosMap Path to the map file.
ad290511521ce8388a9926b165241ecf83c330a7vboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic RTEXITCODE ParseMapFile(const char *pszBiosMap)
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync{
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync BIOSMAP Map;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync Map.pszMapFile = pszBiosMap;
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync Map.hStrm = NULL;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync Map.iLine = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Map.fEof = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Map.cch = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Map.offNW = 0;
ad290511521ce8388a9926b165241ecf83c330a7vboxsync int rc = RTStrmOpen(pszBiosMap, "r", &Map.hStrm);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (RT_FAILURE(rc))
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening '%s': %Rrc", pszBiosMap, rc);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTEXITCODE rcExit = mapParseFile(&Map);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTStrmClose(Map.hStrm);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync return rcExit;
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync}
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync/**
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * Reads the BIOS image into memory (g_pbImg and g_cbImg).
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync *
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync * @param pszBiosImg Path to the image file.
fdb57e5580007400346665b64c0e14ca1d149019vboxsync */
fdb57e5580007400346665b64c0e14ca1d149019vboxsyncstatic RTEXITCODE ReadBiosImage(const char *pszBiosImg)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync{
fdb57e5580007400346665b64c0e14ca1d149019vboxsync void *pvImg;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync size_t cbImg;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync int rc = RTFileReadAll(pszBiosImg, &pvImg, &cbImg);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (RT_FAILURE(rc))
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error reading '%s': %Rrc", pszBiosImg, rc);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync size_t cbImgExpect;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync switch (g_enmBiosType)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case kBiosType_System: cbImgExpect = _64K; break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync case kBiosType_Vga: cbImgExpect = _32K; break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync default: cbImgExpect = 0; break;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync if (cbImg != cbImgExpect)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync {
fdb57e5580007400346665b64c0e14ca1d149019vboxsync RTFileReadAllFree(pvImg, cbImg);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The BIOS image %u bytes intead of %u bytes", cbImg, cbImgExpect);
fdb57e5580007400346665b64c0e14ca1d149019vboxsync }
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync g_pbImg = (uint8_t *)pvImg;
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsync g_cbImg = cbImg;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync return RTEXITCODE_SUCCESS;
fdb57e5580007400346665b64c0e14ca1d149019vboxsync}
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
fdb57e5580007400346665b64c0e14ca1d149019vboxsync
423b1ce7f19ff0687e825ddc42d8bc6c68a4c9cdvboxsyncint main(int argc, char **argv)
fdb57e5580007400346665b64c0e14ca1d149019vboxsync{
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync int rc = RTR3InitExe(argc, &argv, 0);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync if (RT_FAILURE(rc))
ad290511521ce8388a9926b165241ecf83c330a7vboxsync return RTMsgInitFailure(rc);
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync
cb0578a5309e1fc264e5a4acc30543bea075be43vboxsync RTListInit(&g_ObjList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Option config.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync static RTGETOPTDEF const s_aOpts[] =
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--bios-image", 'i', RTGETOPT_REQ_STRING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--bios-map", 'm', RTGETOPT_REQ_STRING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--bios-sym", 's', RTGETOPT_REQ_STRING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--bios-type", 't', RTGETOPT_REQ_STRING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--output", 'o', RTGETOPT_REQ_STRING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync { "--quiet", 'q', RTGETOPT_REQ_NOTHING },
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync };
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pszBiosMap = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pszBiosSym = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pszBiosImg = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync const char *pszOutput = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTGETOPTUNION ValueUnion;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTGETOPTSTATE GetOptState;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = RTGetOptInit(&GetOptState, argc, argv, &s_aOpts[0], RT_ELEMENTS(s_aOpts), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync AssertReleaseRCReturn(rc, RTEXITCODE_FAILURE);
105b1a31b6037dbe14acb8d09e60da540885202bvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /*
e6ad2e18e663b076aeabfec994947514566a7accvboxsync * Process the options.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync while ((rc = RTGetOpt(&GetOptState, &ValueUnion)) != 0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (rc)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
e6ad2e18e663b076aeabfec994947514566a7accvboxsync case 'i':
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pszBiosImg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--bios-image is given more than once");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pszBiosImg = ValueUnion.psz;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 'm':
e6ad2e18e663b076aeabfec994947514566a7accvboxsync if (pszBiosMap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--bios-map is given more than once");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pszBiosMap = ValueUnion.psz;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 's':
9cdd4d805ecb43126372f7cf12e4032836cb738avboxsync if (pszBiosSym)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--bios-sym is given more than once");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pszBiosSym = ValueUnion.psz;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 'o':
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pszOutput)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--output is given more than once");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pszOutput = ValueUnion.psz;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 't':
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!strcmp(ValueUnion.psz, "system"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_enmBiosType = kBiosType_System;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_uBiosFlatBase = 0xf0000;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else if (!strcmp(ValueUnion.psz, "vga"))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_enmBiosType = kBiosType_Vga;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_uBiosFlatBase = 0xc0000;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown bios type '%s'", ValueUnion.psz);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync case 'v':
5793d23a719d4902824a3649b6fef3822ddd5fc7vboxsync g_cVerbose++;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 'q':
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync g_cVerbose = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 'H':
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf("usage: %Rbn --bios-image <file.img> --bios-map <file.map> [--output <file.asm>]\n",
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync argv[0]);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case 'V':
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* The following is assuming that svn does it's job here. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTPrintf("r%u\n", RTBldCfgRevision());
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTEXITCODE_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return RTGetOptPrintError(rc, &ValueUnion);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync }
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync /*
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync * Got it all?
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync */
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync if (!pszBiosImg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--bios-image is required");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pszBiosMap)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--bios-map is required");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pszBiosSym)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "--bios-sym is required");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync /*
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync * Do the job.
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync */
635c83753ed04cf3637e019af0e15ba40e07f2fevboxsync RTEXITCODE rcExit;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync rcExit = ReadBiosImage(pszBiosImg);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rcExit == RTEXITCODE_SUCCESS)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync rcExit = ParseMapFile(pszBiosMap);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rcExit == RTEXITCODE_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rcExit = ParseSymFile(pszBiosSym);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (rcExit == RTEXITCODE_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rcExit = OpenOutputFile(pszOutput);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (rcExit == RTEXITCODE_SUCCESS)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync rcExit = DisassembleBiosImage();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return rcExit;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync