15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** BEGIN LICENSE BLOCK *****
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: MPL 1.1/GPL 2.0/LGPL 2.1
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contents of this file are subject to the Mozilla Public License Version
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1.1 (the "License"); you may not use this file except in compliance with
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License. You may obtain a copy of the License at
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.mozilla.org/MPL/
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software distributed under the License is distributed on an "AS IS" basis,
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the specific language governing rights and limitations under the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Original Code is msmap2tsv.c code, released
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Oct 3, 2002.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Initial Developer of the Original Code is
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Netscape Communications Corporation.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Portions created by the Initial Developer are Copyright (C) 2002
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Initial Developer. All Rights Reserved.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contributor(s):
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   Garrett Arch Blythe, 03-October-2002
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, the contents of this file may be used under the terms of
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either the GNU General Public License Version 2 or later (the "GPL"), or
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in which case the provisions of the GPL or the LGPL are applicable instead
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of those above. If you wish to allow use of your version of this file only
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * under the terms of either the GPL or the LGPL, and not to allow others to
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * use your version of this file under the terms of the MPL, indicate your
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decision by deleting the provisions above and replace them with the notice
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and other provisions required by the GPL or the LGPL. If you do not delete
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the provisions above, a recipient may use your version of this file under
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the terms of any one of the MPL, the GPL or the LGPL.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** END LICENSE BLOCK ***** */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "msmap.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN32)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <imagehlp.h>
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define F_DEMANGLE 1
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_NORMAL 0
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_QDECODE 1
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_PROLOGUE_1 2
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_HAVE_TYPE 3
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_DEC_LENGTH 4
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_HEX_LENGTH 5
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_PROLOGUE_SECONDARY 6
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_DOLLAR_1 7
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_DOLLAR_2 8
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_START 9
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_STATE_STOP 10
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEMANGLE_SAFE_CHAR(eval)  (isprint(eval) ? eval : ' ')
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define F_DEMANGLE 0
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* WIN32 */
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR_REPORT(num, val, msg)   fprintf(stderr, "error(%d):\t\"%s\"\t%s\n", (num), (val), (msg));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CLEANUP(ptr)    do { if(NULL != ptr) { free(ptr); ptr = NULL; } } while(0)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_SymDB_Size
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The size of the symbol.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The size is nested withing a symbols structures to produce a fast
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      lookup path.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The objects are listed in case the client of the symdb needs to
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      match the object name in the scenario where multiple symbol
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      sizes are present.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSize           The size of the symbol in these objects.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mObjects        A list of objects containing said symbol.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mObjectCount    Number of objects.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned            mSize;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char**              mObjects;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned            mObjectCount;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SymDB_Size;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_SymDB_Section
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Each section for a symbol has a list of sizes.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Should there be exactly one size for the symbol, then that
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      is the size that should be accepted.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  If there is more than one size, then a match on the object
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      should be attempted, held withing each size.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mName           The section name.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSizes          The varoius sizes of the symbol in this section.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSizeCount      The number of available sizes.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char*               mName;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SymDB_Size*         mSizes;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned            mSizeCount;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SymDB_Section;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_SymDB_Symbol
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Each symbol has at least one section.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The section indicates what type of symbol a client may be looking for.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  If there is no match on the section, then the client should not trust
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      the symbdb.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mName           The mangled name of the symbol.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSections       Various sections this symbol belongs to.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSectionCount   The number of sections.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char*               mName;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SymDB_Section*      mSections;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned            mSectionCount;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SymDB_Symbol;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYMDB_SYMBOL_GROWBY 0x1000 /* how many sybols to allocate at a time */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_SymDB_Container
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The symbol DB container object.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The goal of the symbol DB is to have exactly one SymDB_Symbol for each
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      mangled name, no matter how ever many identical mangled names there
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      are in the input.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The input is already expected to be well sorted, futher this leads to
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      the ability to binary search for symbol name matches.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSymbols        The symbols.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSymbolCount    The number of symbols in the DB.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSymbolCapacity The number of symbols we can hold (before realloc).
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SymDB_Symbol*       mSymbols;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned            mSymbolCount;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned            mSymbolCapacity;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SymDB_Container;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_Options
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Options to control how we perform.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mProgramName        Used in help text.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mInput              File to read for input.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                      Default is stdin.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mInputName          Name of the file.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mOutput             Output file, append.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                      Default is stdout.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mOutputName         Name of the file.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mHelp               Whether or not help should be shown.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mMatchModules       Array of strings which the module name should match.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mMatchModuleCount   Number of items in array.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mSymDBName          Symbol DB filename.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  mBatchMode          Batch mode.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                      When in batch mode, the input file contains a list of
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                          map files to process.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**                      Normally the input file is a single map file itself.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mProgramName;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* mInput;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* mInputName;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* mOutput;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* mOutputName;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHelp;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char** mMatchModules;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned mMatchModuleCount;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* mSymDBName;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SymDB_Container* mSymDB;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mBatchMode;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Options;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_Switch
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Command line options.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mLongName;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mShortName;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasValue;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mValue;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* mDescription;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Switch;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DESC_NEWLINE "\n\t\t"
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gInputSwitch = {"--input", "-i", 1, NULL, "Specify input file." DESC_NEWLINE "stdin is default."};
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gOutputSwitch = {"--output", "-o", 1, NULL, "Specify output file." DESC_NEWLINE "Appends if file exists." DESC_NEWLINE "stdout is default."};
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gHelpSwitch = {"--help", "-h", 0, NULL, "Information on usage."};
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gMatchModuleSwitch = {"--match-module", "-mm", 1, NULL, "Specify a valid module name." DESC_NEWLINE "Multiple specifications allowed." DESC_NEWLINE "If a module name does not match one of the names specified then no output will occur."};
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gSymDBSwitch = {"--symdb", "-sdb", 1, NULL, "Specify a symbol tsv db input file." DESC_NEWLINE "Such a symdb is produced using the tool msdump2symdb." DESC_NEWLINE "This allows better symbol size approximations." DESC_NEWLINE "The symdb file must be pre-sorted."};
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch gBatchModeSwitch = {"--batch", "-b", 0, NULL, "Runs in batch mode." DESC_NEWLINE "The input file contains a list of map files." DESC_NEWLINE "Normally the input file is a map file itself." DESC_NEWLINE "This eliminates reprocessing the symdb for multiple map files."};
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Switch* gSwitches[] = {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gInputSwitch,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gOutputSwitch,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gMatchModuleSwitch,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gSymDBSwitch,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gBatchModeSwitch,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &gHelpSwitch
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct __struct_MSMap_ReadState
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Keep track of what state we are while reading input.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  This gives the input context in which we absorb the datum.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasModule;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasTimestamp;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasPreferredLoadAddress;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasSegmentData;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mSegmentDataSkippedLine;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasPublicSymbolData;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasPublicSymbolDataSkippedLines;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mHasEntryPoint;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mFoundStaticSymbols;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSMap_ReadState;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* skipWhite(char* inScan)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Skip whitespace.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* retval = inScan;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(isspace(*retval))
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval++;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void trimWhite(char* inString)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Remove any whitespace from the end of the string.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len = strlen(inString);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(len)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len--;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(isspace(*(inString + len)))
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *(inString + len) = '\0';
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* lastWord(char* inString)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Finds and returns the last word in a string.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  It is assumed no whitespace is at the end of the string.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mod = 0;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len = strlen(inString);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(len)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len--;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(isspace(*(inString + len)))
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mod = 1;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return inString + len + mod;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSMap_Segment* getSymbolSection(MSMap_Module* inModule, MSMap_Symbol* inoutSymbol)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Perform a lookup for the section of the symbol.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  The function could cache the value.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MSMap_Segment* retval = NULL;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != inoutSymbol->mSection)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Use cached value.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = inoutSymbol->mSection;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned secLoop = 0;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Go through sections in module to find the match for the symbol.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(secLoop = 0; secLoop < inModule->mSegmentCount; secLoop++)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(inoutSymbol->mPrefix == inModule->mSegments[secLoop].mPrefix)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(inoutSymbol->mOffset >= inModule->mSegments[secLoop].mOffset)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(inoutSymbol->mOffset < (inModule->mSegments[secLoop].mOffset + inModule->mSegments[secLoop].mLength))
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  We have the section.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = &inModule->mSegments[secLoop];
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Cache the value for next time.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inoutSymbol->mSection = retval;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int readSymDB(const char* inDBName, SymDB_Container** outDB)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Intialize the symbol DB.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Only call if the symbol DB should be initialized.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Initialize out arguments.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != outDB)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *outDB = NULL;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != outDB && NULL != inDBName)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FILE* symDB = NULL;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        symDB = fopen(inDBName, "r");
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL != symDB)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *outDB = (SymDB_Container*)calloc(1, sizeof(SymDB_Container));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(NULL != *outDB)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                char lineBuf[0x400];
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                char* symbol = NULL;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                char* section = NULL;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                char* object = NULL;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                char* length = NULL;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                unsigned lengthNum = 0;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                char* endLength = NULL;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /*
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                **  Read the file line by line.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                */
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                while(0 == retval && NULL != fgets(lineBuf, sizeof(lineBuf), symDB))
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    trimWhite(lineBuf);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  Each line has four arguments.  tab separated values (tsv).
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **      Symbol
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **      Section
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **      Length
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **      Object
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    symbol = skipWhite(lineBuf);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == symbol)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, inDBName, "File does not appear to be a symbol DB.");
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    section = strchr(symbol, '\t');
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == section)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, inDBName, "File does not appear to be a symbol DB.");
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    *section = '\0';
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    section++;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    length = strchr(section, '\t');
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == length)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, inDBName, "File does not appear to be a symbol DB.");
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    *length = '\0';
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    length++;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    object = strchr(length, '\t');
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == object)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, inDBName, "File does not appear to be a symbol DB.");
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    *object = '\0';
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    object++;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  Convert the length into a number.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    errno = 0;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    lengthNum = strtoul(length, &endLength, 16);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(0 == errno && endLength != length)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SymDB_Symbol* dbSymbol = NULL;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SymDB_Section* dbSection = NULL;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SymDB_Size* dbSize = NULL;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        char* dbObject = NULL;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        void* moved = NULL;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Are we looking at the same symbol as last line?
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  This assumes the symdb is pre sorted!!!
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(0 != (*outDB)->mSymbolCount)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            unsigned index = (*outDB)->mSymbolCount - 1;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(0 == strcmp((*outDB)->mSymbols[index].mName, symbol))
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSymbol = &(*outDB)->mSymbols[index];
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  May need to create symbol.
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(NULL == dbSymbol)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /*
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            **  Could be time to grow the symbol pool.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if((*outDB)->mSymbolCount >= (*outDB)->mSymbolCapacity)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                moved = realloc((*outDB)->mSymbols, sizeof(SymDB_Symbol) * ((*outDB)->mSymbolCapacity + SYMDB_SYMBOL_GROWBY));
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(NULL != moved)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    (*outDB)->mSymbols = (SymDB_Symbol*)moved;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    memset(&(*outDB)->mSymbols[(*outDB)->mSymbolCapacity], 0, sizeof(SymDB_Symbol) * SYMDB_SYMBOL_GROWBY);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    (*outDB)->mSymbolCapacity += SYMDB_SYMBOL_GROWBY;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                else
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    retval = __LINE__;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ERROR_REPORT(retval, inDBName, "Unable to grow symbol DB symbol array.");
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    break;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if((*outDB)->mSymbolCount < (*outDB)->mSymbolCapacity)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSymbol = &(*outDB)->mSymbols[(*outDB)->mSymbolCount];
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                (*outDB)->mSymbolCount++;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSymbol->mName = strdup(symbol);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(NULL == dbSymbol->mName)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    retval = __LINE__;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ERROR_REPORT(retval, symbol, "Unable to duplicate string.");
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    break;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                retval = __LINE__;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ERROR_REPORT(retval, symbol, "Unable to grow symbol DB for symbol.");
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Assume we have the symbol.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Is this the same section as the last section in the symbol?
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  This assumes the symdb was presorted!!!!
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(0 != dbSymbol->mSectionCount)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            unsigned index = dbSymbol->mSectionCount - 1;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(0 == strcmp(dbSymbol->mSections[index].mName, section))
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSection = &dbSymbol->mSections[index];
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  May need to create the section.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(NULL == dbSection)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            moved = realloc(dbSymbol->mSections, sizeof(SymDB_Section) * (dbSymbol->mSectionCount + 1));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(NULL != moved)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSymbol->mSections = (SymDB_Section*)moved;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSection = &dbSymbol->mSections[dbSymbol->mSectionCount];
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSymbol->mSectionCount++;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                memset(dbSection, 0, sizeof(SymDB_Section));
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSection->mName = strdup(section);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(NULL == dbSection->mName)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    retval = __LINE__;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ERROR_REPORT(retval, section, "Unable to duplicate string.");
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    break;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                retval = __LINE__;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ERROR_REPORT(retval, section, "Unable to grow symbol sections for symbol DB.");
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Assume we have the section.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Is this the same size as the last size?
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  This assumes the symdb was presorted!!!
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(0 != dbSection->mSizeCount)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            unsigned index = dbSection->mSizeCount - 1;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(dbSection->mSizes[index].mSize == lengthNum)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSize = &dbSection->mSizes[index];
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  May need to create the size in question.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(NULL == dbSize)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            moved = realloc(dbSection->mSizes, sizeof(SymDB_Size) * (dbSection->mSizeCount + 1));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(NULL != moved)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSection->mSizes = (SymDB_Size*)moved;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSize = &dbSection->mSizes[dbSection->mSizeCount];
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSection->mSizeCount++;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                memset(dbSize, 0, sizeof(SymDB_Size));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                dbSize->mSize = lengthNum;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                retval = __LINE__;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ERROR_REPORT(retval, length, "Unable to grow symbol section sizes for symbol DB.");
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Assume we have the size.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  We assume a one to one correllation between size and object.
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Always try to add the new object name.
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  As the symdb is assumed to be sorted, the object names should also be in order.
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        moved = realloc(dbSize->mObjects, sizeof(char*) * (dbSize->mObjectCount + 1));
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(NULL != moved)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            dbObject = strdup(object);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            dbSize->mObjects = (char**)moved;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            dbSize->mObjects[dbSize->mObjectCount] = dbObject;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            dbSize->mObjectCount++;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(NULL == dbObject)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                retval = __LINE__;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                ERROR_REPORT(retval, object, "Unable to duplicate string.");
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        else
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            retval = __LINE__;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ERROR_REPORT(retval, object, "Unable to grow symbol section size objects for symbol DB.");
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, length, "Unable to convert symbol DB length into a number.");
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(0 == retval && 0 != ferror(symDB))
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, inDBName, "Unable to read file.");
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = __LINE__;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ERROR_REPORT(retval, inDBName, "Unable to allocate symbol DB.");
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fclose(symDB);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symDB = NULL;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, inDBName, "Unable to open symbol DB.");
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = __LINE__;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR_REPORT(retval, "(NULL)", "Invalid arguments.");
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void cleanSymDB(SymDB_Container** inDB)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Free it all up.
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != inDB && NULL != *inDB)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned symLoop = 0;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned secLoop = 0;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned sizLoop = 0;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned objLoop = 0;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(symLoop = 0; symLoop < (*inDB)->mSymbolCount; symLoop++)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for(secLoop = 0; secLoop < (*inDB)->mSymbols[symLoop].mSectionCount; secLoop++)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                for(sizLoop = 0; sizLoop < (*inDB)->mSymbols[symLoop].mSections[secLoop].mSizeCount; sizLoop++)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    for(objLoop = 0; objLoop < (*inDB)->mSymbols[symLoop].mSections[secLoop].mSizes[sizLoop].mObjectCount; objLoop++)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        CLEANUP((*inDB)->mSymbols[symLoop].mSections[secLoop].mSizes[sizLoop].mObjects[objLoop]);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    CLEANUP((*inDB)->mSymbols[symLoop].mSections[secLoop].mSizes[sizLoop].mObjects);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP((*inDB)->mSymbols[symLoop].mSections[secLoop].mName);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP((*inDB)->mSymbols[symLoop].mSections[secLoop].mSizes);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            CLEANUP((*inDB)->mSymbols[symLoop].mName);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            CLEANUP((*inDB)->mSymbols[symLoop].mSections);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CLEANUP((*inDB)->mSymbols);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CLEANUP(*inDB);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int symDBLookup(const void* inKey, const void* inItem)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  bsearch utility routine to find the symbol in the symdb.
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* key = (const char*)inKey;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SymDB_Symbol* symbol = (const SymDB_Symbol*)inItem;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retval = strcmp(key, symbol->mName);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int fillSymbolSizeFromDB(Options* inOptions, MSMap_Module* inModule, MSMap_Symbol* inoutSymbol, const char* inMangledName)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  If we have a symbol DB, attempt to determine the real size of the symbol
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      up front.
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  This helps us later in the game to avoid performing size guesses by
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      offset.
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  May need to initialize symdb.
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL == inOptions->mSymDB && NULL != inOptions->mSymDBName)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = readSymDB(inOptions->mSymDBName, &inOptions->mSymDB);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Optional
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 == retval && NULL != inOptions->mSymDB)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void* match = NULL;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Find the symbol.
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        match = bsearch(inMangledName, inOptions->mSymDB->mSymbols, inOptions->mSymDB->mSymbolCount, sizeof(SymDB_Symbol), symDBLookup);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL != match)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SymDB_Symbol* symbol = (SymDB_Symbol*)match;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            unsigned symDBSize = 0;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            MSMap_Segment* mapSection = NULL;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  We found the symbol.
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  See if it has the section in question.
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mapSection = getSymbolSection(inModule, inoutSymbol);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(NULL != mapSection)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                unsigned secLoop = 0;
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                for(secLoop = 0; secLoop < symbol->mSectionCount; secLoop++)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(0 == strcmp(mapSection->mSegment, symbol->mSections[secLoop].mName))
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SymDB_Section* section = &symbol->mSections[secLoop];
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  We have a section match.
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Should there be a single size for the symbol,
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **      then we just default to that.
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  If more than one size, we have to do an
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **      object match search.
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Should there be no object match, we do nothign.
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(1 == section->mSizeCount)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            symDBSize = section->mSizes[0].mSize;
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        else
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            char* mapObject = NULL;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /*
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            **  Figure out the map object file name.
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            **  Skip any colon.
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            **  If it doesn't have a .obj in it, not worth continuing.
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            mapObject = strrchr(inoutSymbol->mObject, ':');
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(NULL == mapObject)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                mapObject = inoutSymbol->mObject;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                mapObject++; /* colon */
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(NULL != strstr(mapObject, ".obj"))
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                unsigned sizLoop = 0;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                unsigned objLoop = 0;
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SymDB_Size* size = NULL;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                for(sizLoop = 0; sizLoop < section->mSizeCount; sizLoop++)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    size = &section->mSizes[sizLoop];
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    for(objLoop = 0; objLoop < size->mObjectCount; objLoop++)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if(NULL != strstr(size->mObjects[objLoop], mapObject))
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            /*
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            **  As we matched the object, in a particular section,
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            **      we'll go with this as the number.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            */
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            symDBSize = size->mSize;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            break;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    /*
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  If the object loop broke early, we break too.
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    */
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(objLoop < size->mObjectCount)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        break;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Put the size in.
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            inoutSymbol->mSymDBSize = symDBSize;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char* symdup(const char* inSymbol)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Attempts to demangle the symbol if appropriate.
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Otherwise acts like strdup.
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* retval = NULL;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if F_DEMANGLE
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int isImport = 0;
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(0 == strncmp("__imp_", inSymbol, 6))
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            isImport = __LINE__;
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            inSymbol += 6;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if('?' == inSymbol[0])
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            char demangleBuf[0x200];
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DWORD demangleRes = 0;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            demangleRes = UnDecorateSymbolName(inSymbol, demangleBuf, sizeof(demangleBuf), UNDNAME_COMPLETE);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(0 != demangleRes)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (strcmp(demangleBuf, "`string'") == 0)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* attempt manual demangling of string prefix.. */
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* first make sure we have enough space for the
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       updated string - the demangled string will
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       always be shorter than strlen(inSymbol) and the
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       prologue will always be longer than the
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "string: " that we tack on the front of the string
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    char *curresult = retval = malloc(strlen(inSymbol) + 11);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const char *curchar = inSymbol;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int state = DEMANGLE_STATE_START;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* the hex state is for stuff like ?$EA which
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       really means hex value 0x40 */
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    char hex_state = 0;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    char string_is_unicode = 0;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* sometimes we get a null-termination before the
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       final @ sign - in that case, remember that
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       we've seen the whole string */
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int have_null_char = 0;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* stick our user-readable prefix on */
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    strcpy(curresult, "string: \"");
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    curresult += 9;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    while (*curchar) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        // process current state
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        switch (state) {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* the Prologue states are divided up so
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               that someday we can try to decode
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               the random letters in between the '@'
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               signs. Also, some strings only have 2
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               prologue '@' signs, so we have to
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               figure out how to distinguish between
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               them at some point. */
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_START:
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (*curchar == '@')
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_PROLOGUE_1;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* ignore all other states */
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_PROLOGUE_1:
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            switch (*curchar) {
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '0':
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                string_is_unicode=0;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_HAVE_TYPE;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '1':
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                string_is_unicode=1;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_HAVE_TYPE;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* ignore all other characters */
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_HAVE_TYPE:
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (*curchar >= '0' && *curchar <= '9') {
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_DEC_LENGTH;
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            } else if (*curchar >= 'A' && *curchar <= 'Z') {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_HEX_LENGTH;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_DEC_LENGTH:
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* decimal lengths don't have the 2nd
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               field
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (*curchar == '@')
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_NORMAL;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_HEX_LENGTH:
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* hex lengths have a 2nd field
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               (though I have no idea what it is for)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (*curchar == '@')
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_PROLOGUE_SECONDARY;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_PROLOGUE_SECONDARY:
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (*curchar == '@')
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_NORMAL;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_NORMAL:
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            switch (*curchar) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '?':
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_QDECODE;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '@':
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_STOP;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            default:
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = DEMANGLE_SAFE_CHAR(*curchar);
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_NORMAL;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* found a '?' */
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_QDECODE:
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            state = DEMANGLE_STATE_NORMAL;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* there are certain shortcuts, like
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               "?3" means ":"
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            switch (*curchar) {
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '1':
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = '/';
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '2':
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = '\\';
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '3':
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = ':';
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '4':
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = '.';
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '5':
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = ' ';
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '6':
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = '\\';
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = 'n';
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '8':
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = '\'';
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '9':
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = '-';
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                break;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /* any other arbitrary ASCII value can
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   be stored by prefixing it with ?$
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                */
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            case '$':
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                state = DEMANGLE_STATE_DOLLAR_1;
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_DOLLAR_1:
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* first digit of ?$ notation. All digits
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               are hex, represented starting with the
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               capital leter 'A' such that 'A' means 0x0,
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               'B' means 0x1, 'K' means 0xA
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            hex_state = (*curchar - 'A') * 0x10;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            state = DEMANGLE_STATE_DOLLAR_2;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_DOLLAR_2:
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* same mechanism as above */
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            hex_state += (*curchar - 'A');
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if (hex_state) {
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                *curresult++ = DEMANGLE_SAFE_CHAR(hex_state);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                have_null_char = 0;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else {
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                have_null_char = 1;
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            state = DEMANGLE_STATE_NORMAL;
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        case DEMANGLE_STATE_STOP:
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        curchar++;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /* add the appropriate termination depending
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       if we completed the string or not */
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (!have_null_char)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        strcpy(curresult, "...\"");
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        strcpy(curresult, "\"");
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = strdup(demangleBuf);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /*
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ** fall back to normal.
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                */
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = strdup(inSymbol);
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else if('_' == inSymbol[0])
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = strdup(inSymbol + 1);
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = strdup(inSymbol);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  May need to rewrite the symbol if an import.
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL != retval && isImport)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const char importPrefix[] = "__declspec(dllimport) ";
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            char importBuf[0x200];
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int printRes = 0;
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            printRes = _snprintf(importBuf, sizeof(importBuf), "%s%s", importPrefix, retval);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            free(retval);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = NULL;
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(printRes > 0)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = strdup(importBuf);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* F_DEMANGLE */
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retval = strdup(inSymbol);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  /* F_DEMANGLE */
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int readmap(Options* inOptions, MSMap_Module* inModule)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Read the input line by line, adding it to the module.
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char lineBuffer[0x400];
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* current = NULL;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MSMap_ReadState fsm;
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len = 0;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int forceContinue = 0;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&fsm, 0, sizeof(fsm));
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Read the map file line by line.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  We keep a simple state machine to determine what we're looking at.
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(0 == retval && NULL != fgets(lineBuffer, sizeof(lineBuffer), inOptions->mInput))
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(forceContinue)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Used to skip anticipated blank lines.
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            forceContinue--;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current = skipWhite(lineBuffer);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trimWhite(current);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len = strlen(current);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(fsm.mHasModule)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(fsm.mHasTimestamp)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(fsm.mHasPreferredLoadAddress)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(fsm.mHasSegmentData)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(fsm.mHasPublicSymbolData)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(fsm.mHasEntryPoint)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(fsm.mFoundStaticSymbols)
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    /*
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  A blank line means we've reached the end of all static symbols.
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    */
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(len)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       /*
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        **  We're adding a new symbol.
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        **  Make sure we have room for it.
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        */
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if(inModule->mSymbolCapacity == inModule->mSymbolCount)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            void* moved = NULL;
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            moved = realloc(inModule->mSymbols, sizeof(MSMap_Symbol) * (inModule->mSymbolCapacity + MSMAP_SYMBOL_GROWBY));
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            if(NULL != moved)
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                inModule->mSymbolCapacity += MSMAP_SYMBOL_GROWBY;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                inModule->mSymbols = (MSMap_Symbol*)moved;
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            else
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                retval = __LINE__;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                ERROR_REPORT(retval, inModule->mModule, "Unable to grow symbols.");
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if(0 == retval && inModule->mSymbolCapacity > inModule->mSymbolCount)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            MSMap_Symbol* theSymbol = NULL;
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            unsigned index = 0;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int scanRes = 0;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            char symbolBuf[0x200];
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            index = inModule->mSymbolCount;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            inModule->mSymbolCount++;
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            theSymbol = (inModule->mSymbols + index);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            memset(theSymbol, 0, sizeof(MSMap_Symbol));
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            theSymbol->mScope = STATIC;
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            scanRes = sscanf(current, "%x:%x %s %x", (unsigned*)&(theSymbol->mPrefix), (unsigned*)&(theSymbol->mOffset), symbolBuf, (unsigned*)&(theSymbol->mRVABase));
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            if(4 == scanRes)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                theSymbol->mSymbol = symdup(symbolBuf);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                if(0 == retval)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                {
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    if(NULL != theSymbol->mSymbol)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    {
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        char *last = lastWord(current);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        theSymbol->mObject = strdup(last);
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        if(NULL == theSymbol->mObject)
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        {
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            retval = __LINE__;
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            ERROR_REPORT(retval, last, "Unable to copy object name.");
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        }
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    }
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    else
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    {
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        retval = __LINE__;
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        ERROR_REPORT(retval, symbolBuf, "Unable to copy symbol name.");
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    }
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                }
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            else
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                retval = __LINE__;
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                ERROR_REPORT(retval, inModule->mModule, "Unable to scan static symbols.");
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    else
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        /*
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        **  All done.
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        */
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        break;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                else
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    /*
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  Static symbols are optional.
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  If no static symbols we're done.
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  Otherwise, set the flag such that it will work more.
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    */
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(0 == strcmp(current, "Static symbols"))
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        fsm.mFoundStaticSymbols = __LINE__;
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        forceContinue = 1;
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    else
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        /*
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        **  All done.
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        */
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        break;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int scanRes = 0;
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                scanRes = sscanf(current, "entry point at %x:%x", (unsigned*)&(inModule->mEntryPrefix), (unsigned*)&(inModule->mEntryOffset));
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(2 == scanRes)
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    fsm.mHasEntryPoint = __LINE__;
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    forceContinue = 1;
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                else
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    retval = __LINE__;
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ERROR_REPORT(retval, current, "Unable to obtain entry point.");
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        else
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /*
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            **  Skip the N lines of public symbol data (column headers).
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(2 <= fsm.mHasPublicSymbolDataSkippedLines)
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /*
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                **  A blank line indicates end of public symbols.
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                */
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(len)
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    /*
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  We're adding a new symbol.
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    **  Make sure we have room for it.
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    */
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(inModule->mSymbolCapacity == inModule->mSymbolCount)
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        void* moved = NULL;
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        moved = realloc(inModule->mSymbols, sizeof(MSMap_Symbol) * (inModule->mSymbolCapacity + MSMAP_SYMBOL_GROWBY));
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if(NULL != moved)
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            inModule->mSymbolCapacity += MSMAP_SYMBOL_GROWBY;
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            inModule->mSymbols = (MSMap_Symbol*)moved;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        else
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            retval = __LINE__;
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERROR_REPORT(retval, inModule->mModule, "Unable to grow symbols.");
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(0 == retval && inModule->mSymbolCapacity > inModule->mSymbolCount)
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        MSMap_Symbol* theSymbol = NULL;
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        unsigned index = 0;
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int scanRes = 0;
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        char symbolBuf[0x200];
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        index = inModule->mSymbolCount;
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        inModule->mSymbolCount++;
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        theSymbol = (inModule->mSymbols + index);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        memset(theSymbol, 0, sizeof(MSMap_Symbol));
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        theSymbol->mScope = PUBLIC;
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        scanRes = sscanf(current, "%x:%x %s %x", (unsigned*)&(theSymbol->mPrefix), (unsigned*)&(theSymbol->mOffset), symbolBuf, (unsigned *)&(theSymbol->mRVABase));
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if(4 == scanRes)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            theSymbol->mSymbol = symdup(symbolBuf);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            if(NULL != theSymbol->mSymbol)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                char *last = lastWord(current);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                theSymbol->mObject = strdup(last);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                if(NULL != theSymbol->mObject)
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                {
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    /*
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    **  Finally, attempt to lookup the actual size of the symbol
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    **      if there is a symbol DB available.
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    */
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    retval = fillSymbolSizeFromDB(inOptions, inModule, theSymbol, symbolBuf);
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                }
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                else
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                {
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    retval = __LINE__;
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    ERROR_REPORT(retval, last, "Unable to copy object name.");
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                }
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            else
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                retval = __LINE__;
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                ERROR_REPORT(retval, symbolBuf, "Unable to copy symbol name.");
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        else
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            retval = __LINE__;
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERROR_REPORT(retval, inModule->mModule, "Unable to scan public symbols.");
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                else
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    fsm.mHasPublicSymbolData = __LINE__;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                fsm.mHasPublicSymbolDataSkippedLines++;
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Skip the first line of segment data (column headers).
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  Mark that we've begun grabbing segement data.
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(fsm.mSegmentDataSkippedLine)
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /*
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            **  A blank line means end of the segment data.
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            */
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            if(len)
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                /*
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                **  We're adding a new segment.
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                **  Make sure we have room for it.
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                */
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(inModule->mSegmentCapacity == inModule->mSegmentCount)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    void* moved = NULL;
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    moved = realloc(inModule->mSegments, sizeof(MSMap_Segment) * (inModule->mSegmentCapacity + MSMAP_SEGMENT_GROWBY));
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(NULL != moved)
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        inModule->mSegmentCapacity += MSMAP_SEGMENT_GROWBY;
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        inModule->mSegments = (MSMap_Segment*)moved;
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    else
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        retval = __LINE__;
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ERROR_REPORT(retval, inModule->mModule, "Unable to grow segments.");
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                if(0 == retval && inModule->mSegmentCapacity > inModule->mSegmentCount)
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                {
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    MSMap_Segment* theSegment = NULL;
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    unsigned index = 0;
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    char classBuf[0x10];
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    char nameBuf[0x20];
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int scanRes = 0;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    index = inModule->mSegmentCount;
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    inModule->mSegmentCount++;
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    theSegment = (inModule->mSegments + index);
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    memset(theSegment, 0, sizeof(MSMap_Segment));
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    scanRes = sscanf(current, "%x:%x %xH %s %s", (unsigned*)&(theSegment->mPrefix), (unsigned*)&(theSegment->mOffset), (unsigned*)&(theSegment->mLength), nameBuf, classBuf);
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    if(5 == scanRes)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if('.' == nameBuf[0])
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            theSegment->mSegment = strdup(&nameBuf[1]);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        else
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            theSegment->mSegment = strdup(nameBuf);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        if(NULL != theSegment->mSegment)
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            if(0 == strcmp("DATA", classBuf))
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                theSegment->mClass = DATA;
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            else if(0 == strcmp("CODE", classBuf))
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                theSegment->mClass = CODE;
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            else
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            {
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                retval = __LINE__;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                ERROR_REPORT(retval, classBuf, "Unrecognized segment class.");
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            }
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        else
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        {
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            retval = __LINE__;
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            ERROR_REPORT(retval, nameBuf, "Unable to copy segment name.");
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        }
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    else
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    {
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        retval = __LINE__;
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        ERROR_REPORT(retval, inModule->mModule, "Unable to scan segments.");
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    }
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                }
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            else
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            {
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                fsm.mHasSegmentData = __LINE__;
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        else
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            fsm.mSegmentDataSkippedLine = __LINE__;
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int scanRes = 0;
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  The PLA has a particular format.
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    scanRes = sscanf(current, "Preferred load address is %x", (unsigned*)&(inModule->mPreferredLoadAddress));
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(1 == scanRes)
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        fsm.mHasPreferredLoadAddress = __LINE__;
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        forceContinue = 1;
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, current, "Unable to obtain preferred load address.");
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int scanRes = 0;
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /*
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                **  The timestamp has a particular format.
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                */
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                scanRes = sscanf(current, "Timestamp is %x", (unsigned*)&(inModule->mTimestamp));
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(1 == scanRes)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fsm.mHasTimestamp = __LINE__;
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    forceContinue = 1;
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current, "Unable to obtain timestamp.");
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  The module is on a line by itself.
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            inModule->mModule = strdup(current);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(NULL != inModule->mModule)
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                fsm.mHasModule = __LINE__;
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                forceContinue = 1;
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(0 != inOptions->mMatchModuleCount)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    unsigned matchLoop = 0;
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  If this module name doesn't match, then bail.
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  Compare in a case sensitive manner, exact match only.
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    for(matchLoop = 0; matchLoop < inOptions->mMatchModuleCount; matchLoop++)
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if(0 == strcmp(inModule->mModule, inOptions->mMatchModules[matchLoop]))
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        {
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(matchLoop == inOptions->mMatchModuleCount)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        /*
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  A match did not occur, bail out of read loop.
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        **  No error, however.
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        */
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = __LINE__;
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ERROR_REPORT(retval, current, "Unable to obtain module.");
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 == retval && 0 != ferror(inOptions->mInput))
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = __LINE__;
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR_REPORT(retval, inOptions->mInputName, "Unable to read file.");
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int qsortRVABase(const void* in1, const void* in2)
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  qsort callback to sort the symbols by their RVABase.
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MSMap_Symbol* sym1 = (MSMap_Symbol*)in1;
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MSMap_Symbol* sym2 = (MSMap_Symbol*)in2;
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(sym1->mRVABase < sym2->mRVABase)
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = -1;
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if(sym1->mRVABase > sym2->mRVABase)
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = 1;
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tsvout(Options* inOptions, unsigned inSize, MSMap_SegmentClass inClass, MSMap_SymbolScope inScope, const char* inModule, const char* inSegment, const char* inObject, const char* inSymbol)
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Output a line of map information separated by tabs.
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Some items (const char*), if not present, will receive a default value.
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  No need to output on no size.
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  This can happen with zero sized segments,
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **      or an imported symbol which has multiple names (one will count).
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 != inSize)
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        char objectBuf[0x100];
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const char* symScope = NULL;
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const char* segClass = NULL;
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const char* undefined = "UNDEF";
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Fill in unspecified values.
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL == inObject)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sprintf(objectBuf, "%s:%s:%s", undefined, inModule, inSegment);
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            inObject = objectBuf;
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL == inSymbol)
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            inSymbol = inObject;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Convert some enumerations to text.
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch(inClass)
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case CODE:
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            segClass = "CODE";
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case DATA:
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            segClass = "DATA";
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, "", "Unable to determine class for output.");
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch(inScope)
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case PUBLIC:
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symScope = "PUBLIC";
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case STATIC:
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symScope = "STATIC";
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case UNDEFINED:
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symScope = undefined;
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, "", "Unable to determine scope for symbol.");
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(0 == retval)
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int printRes = 0;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            printRes = fprintf(inOptions->mOutput,
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "%.8X\t%s\t%s\t%s\t%s\t%s\t%s\n",
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                inSize,
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                segClass,
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                symScope,
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                inModule,
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                inSegment,
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                inObject,
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                inSymbol
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                );
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(0 > printRes)
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = __LINE__;
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ERROR_REPORT(retval, inOptions->mOutputName, "Unable to output tsv data.");
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void cleanModule(MSMap_Module* inModule)
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned loop = 0;
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(loop = 0; loop < inModule->mSymbolCount; loop++)
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CLEANUP(inModule->mSymbols[loop].mObject);
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CLEANUP(inModule->mSymbols[loop].mSymbol);
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inModule->mSymbols);
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(loop = 0; loop < inModule->mSegmentCount; loop++)
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CLEANUP(inModule->mSegments[loop].mSegment);
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inModule->mSegments);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inModule->mModule);
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(inModule, 0, sizeof(MSMap_Module));
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int map2tsv(Options* inOptions)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Read all input.
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Output tab separated value data.
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MSMap_Module module;
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&module, 0, sizeof(module));
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Read in the map file.
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retval = readmap(inOptions, &module);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 == retval)
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned symLoop = 0;
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MSMap_Symbol* symbol = NULL;
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned secLoop = 0;
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MSMap_Segment* section = NULL;
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned size = 0;
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned dbSize = 0;
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned offsetSize = 0;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned endOffset = 0;
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Quick sort the symbols via RVABase.
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        qsort(module.mSymbols, module.mSymbolCount, sizeof(MSMap_Symbol), qsortRVABase);
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Go through all the symbols (in order by sort).
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Output their sizes.
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(symLoop = 0; 0 == retval && symLoop < module.mSymbolCount; symLoop++)
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            symbol = &module.mSymbols[symLoop];
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            section = getSymbolSection(&module, symbol);
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!section)
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                continue;
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Use the symbol DB size if available.
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            dbSize = symbol->mSymDBSize;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Guess using offsets.
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Is there a next symbol available?  If so, its start offset is the end of this symbol.
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Otherwise, our section offset + length is the end of this symbol.
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  The trick is, the DB size can not go beyond the offset size, for sanity.
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Try next symbol, but only if in same section.
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  If still not, use the end of the segment.
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  This implies we were the last symbol in the segment.
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if((symLoop + 1) < module.mSymbolCount)
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                MSMap_Symbol* nextSymbol = NULL;
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                MSMap_Segment* nextSection = NULL;
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nextSymbol = &module.mSymbols[symLoop + 1];
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nextSection = getSymbolSection(&module, nextSymbol);
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(section == nextSection)
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    endOffset = nextSymbol->mOffset;
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    endOffset = section->mOffset + section->mLength;
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                endOffset = section->mOffset + section->mLength;
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Can now guess at size.
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            offsetSize = endOffset - symbol->mOffset;
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Now, determine which size to use.
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  This is really a sanity check as well.
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            size = offsetSize;
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(0 != dbSize)
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(dbSize < offsetSize)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    size = dbSize;
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Output the symbol with the size.
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = tsvout(inOptions,
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                size,
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                section->mClass,
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                symbol->mScope,
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                module.mModule,
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                section->mSegment,
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                symbol->mObject,
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                symbol->mSymbol
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                );
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Make sure we mark this amount of space as used in the section.
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            section->mUsed += size;
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Go through the sections, and those whose length is longer than the
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **      amount of space used, output dummy filler values.
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(secLoop = 0; 0 == retval && secLoop < module.mSegmentCount; secLoop++)
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            section = &module.mSegments[secLoop];
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(section && section->mUsed < section->mLength)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = tsvout(inOptions,
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    section->mLength - section->mUsed,
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    section->mClass,
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    UNDEFINED,
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    module.mModule,
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    section->mSegment,
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    NULL,
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    NULL
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    );
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Cleanup.
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cleanModule(&module);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int initOptions(Options* outOptions, int inArgc, char** inArgv)
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  returns int     0 if successful.
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int loop = 0;
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int switchLoop = 0;
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int match = 0;
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]);
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Switch* current = NULL;
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Set any defaults.
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(outOptions, 0, sizeof(Options));
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mProgramName = inArgv[0];
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mInput = stdin;
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mInputName = strdup("stdin");
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mOutput = stdout;
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    outOptions->mOutputName = strdup("stdout");
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL == outOptions->mOutputName || NULL == outOptions->mInputName)
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = __LINE__;
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR_REPORT(retval, "stdin/stdout", "Unable to strdup.");
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Go through and attempt to do the right thing.
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(loop = 1; loop < inArgc && 0 == retval; loop++)
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        match = 0;
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current = NULL;
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for(switchLoop = 0; switchLoop < switchCount && 0 == retval; switchLoop++)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(0 == strcmp(gSwitches[switchLoop]->mLongName, inArgv[loop]))
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                match = __LINE__;
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(0 == strcmp(gSwitches[switchLoop]->mShortName, inArgv[loop]))
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                match = __LINE__;
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(match)
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(gSwitches[switchLoop]->mHasValue)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    /*
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    **  Attempt to absorb next option to fullfill value.
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    */
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(loop + 1 < inArgc)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        loop++;
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        current = gSwitches[switchLoop];
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        current->mValue = inArgv[loop];
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    current = gSwitches[switchLoop];
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(0 == match)
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            outOptions->mHelp = __LINE__;
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, inArgv[loop], "Unknown command line switch.");
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else if(NULL == current)
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            outOptions->mHelp = __LINE__;
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, inArgv[loop], "Command line switch requires a value.");
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ** Do something based on address/swtich.
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(current == &gInputSwitch)
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP(outOptions->mInputName);
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL != outOptions->mInput && stdin != outOptions->mInput)
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fclose(outOptions->mInput);
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mInput = NULL;
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mInput = fopen(current->mValue, "r");
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL == outOptions->mInput)
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current->mValue, "Unable to open input file.");
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mInputName = strdup(current->mValue);
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == outOptions->mInputName)
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, current->mValue, "Unable to strdup.");
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gOutputSwitch)
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP(outOptions->mOutputName);
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL != outOptions->mOutput && stdout != outOptions->mOutput)
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    fclose(outOptions->mOutput);
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mOutput = NULL;
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mOutput = fopen(current->mValue, "a");
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL == outOptions->mOutput)
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current->mValue, "Unable to open output file.");
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mOutputName = strdup(current->mValue);
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL == outOptions->mOutputName)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, current->mValue, "Unable to strdup.");
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gHelpSwitch)
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mHelp = __LINE__;
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gMatchModuleSwitch)
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                void* moved = NULL;
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /*
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                **  Add the value to the list of allowed module names.
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                */
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                moved = realloc(outOptions->mMatchModules, sizeof(char*) * (outOptions->mMatchModuleCount + 1));
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL != moved)
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mMatchModules = (char**)moved;
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    outOptions->mMatchModules[outOptions->mMatchModuleCount] = strdup(current->mValue);
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if(NULL != outOptions->mMatchModules[outOptions->mMatchModuleCount])
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        outOptions->mMatchModuleCount++;
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        retval = __LINE__;
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ERROR_REPORT(retval, current->mValue, "Unable to duplicate string.");
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current->mValue, "Unable to allocate space for string.");
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gSymDBSwitch)
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CLEANUP(outOptions->mSymDBName);
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mSymDBName = strdup(current->mValue);
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(NULL == outOptions->mSymDBName)
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    retval = __LINE__;
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    ERROR_REPORT(retval, current->mValue, "Unable to duplicate symbol db name.");
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else if(current == &gBatchModeSwitch)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                outOptions->mBatchMode = __LINE__;
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                retval = __LINE__;
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ERROR_REPORT(retval, current->mLongName, "No handler for command line switch.");
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void cleanOptions(Options* inOptions)
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Clean up any open handles, et. al.
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inOptions->mInputName);
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != inOptions->mInput && stdin != inOptions->mInput)
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fclose(inOptions->mInput);
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inOptions->mOutputName);
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(NULL != inOptions->mOutput && stdout != inOptions->mOutput)
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fclose(inOptions->mOutput);
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(0 != inOptions->mMatchModuleCount)
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inOptions->mMatchModuleCount--;
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CLEANUP(inOptions->mMatchModules[inOptions->mMatchModuleCount]);
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CLEANUP(inOptions->mMatchModules);
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cleanSymDB(&inOptions->mSymDB);
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(inOptions, 0, sizeof(Options));
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void showHelp(Options* inOptions)
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Show some simple help text on usage.
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int loop = 0;
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]);
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* valueText = NULL;
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("usage:\t%s [arguments]\n", inOptions->mProgramName);
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("\n");
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("arguments:\n");
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(loop = 0; loop < switchCount; loop++)
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(gSwitches[loop]->mHasValue)
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            valueText = " <value>";
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            valueText = "";
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("\t%s%s\n", gSwitches[loop]->mLongName, valueText);
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf("\t %s%s", gSwitches[loop]->mShortName, valueText);
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf(DESC_NEWLINE "%s\n\n", gSwitches[loop]->mDescription);
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf("This tool normalizes MS linker .map files for use by other tools.\n");
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int batchMode(Options* inOptions)
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  Batch mode means that the input file is actually a list of map files.
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  We simply swap out our input file names while we do this.
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char lineBuf[0x400];
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* realInput = NULL;
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* realInputName = NULL;
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE* mapFile = NULL;
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int finalRes = 0;
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    realInput = inOptions->mInput;
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    realInputName = inOptions->mInputName;
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while(0 == retval && NULL != fgets(lineBuf, sizeof(lineBuf), realInput))
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trimWhite(lineBuf);
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Skip/allow blank lines.
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if('\0' == lineBuf[0])
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue;
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /*
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **  Override what we believe to be the input for this line.
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inOptions->mInputName = lineBuf;
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inOptions->mInput = fopen(lineBuf, "r");
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(NULL != inOptions->mInput)
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int mapRes = 0;
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Do it.
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mapRes = map2tsv(inOptions);
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  We report the first error that we encounter, but we continue.
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  This is batch mode after all.
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(0 == finalRes)
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                finalRes = mapRes;
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /*
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            **  Close the input file.
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            */
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fclose(inOptions->mInput);
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = __LINE__;
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ERROR_REPORT(retval, lineBuf, "Unable to open map file.");
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 == retval && 0 != ferror(realInput))
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = __LINE__;
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ERROR_REPORT(retval, realInputName, "Unable to read file.");
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Restore what we've swapped.
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inOptions->mInput = realInput;
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inOptions->mInputName = realInputName;
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **  Report first map file error if there were no other operational
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **      problems.
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(0 == retval)
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retval = finalRes;
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int inArgc, char** inArgv)
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retval = 0;
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Options options;
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    retval = initOptions(&options, inArgc, inArgv);
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(options.mHelp)
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        showHelp(&options);
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if(0 == retval)
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(options.mBatchMode)
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = batchMode(&options);
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        {
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            retval = map2tsv(&options);
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cleanOptions(&options);
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return retval;
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2238