/*
 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.debugger.win32.coff;

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;

import sun.jvm.hotspot.utilities.memo.*;
import sun.jvm.hotspot.utilities.Assert;
import sun.jvm.hotspot.debugger.DataSource;
import sun.jvm.hotspot.debugger.MappedByteBufferDataSource;

/** Top-level factory which parses COFF files, including object files,
    Portable Executables and DLLs. Returns {@link
    sun.jvm.hotspot.debugger.win32.coff.COFFFile} objects. This class is a
    singleton. */

public class COFFFileParser {
  private static COFFFileParser soleInstance;

  // Constants from the file format documentation
  private static final int COFF_HEADER_SIZE = 20;
  private static final int SECTION_HEADER_SIZE = 40;
  private static final int SYMBOL_SIZE = 18;
  private static final int RELOCATION_SIZE = 10;
  private static final int LINE_NUMBER_SIZE = 6;

  private static final String US_ASCII = "US-ASCII";

  private COFFFileParser() {}

  /** This class is a singleton; returns the sole instance. */
  public static COFFFileParser getParser() {
    if (soleInstance == null) {
      soleInstance = new COFFFileParser();
    }
    return soleInstance;
  }

  public COFFFile parse(String filename) throws COFFException {
    try {
      File file = new File(filename);
      FileInputStream stream = new FileInputStream(file);
      MappedByteBuffer buf = stream.getChannel().map(FileChannel.MapMode.READ_ONLY,
                                                     0,
                                                     file.length());

      // This is pretty confusing. The file format is little-endian
      // and so is the CPU. In order for the multi-byte accessors to
      // work properly we must NOT change the endianness of the
      // MappedByteBuffer. Need to think about this some more and file
      // a bug if there is one. (FIXME)
      //   buf.order(ByteOrder.nativeOrder());
      return parse(new MappedByteBufferDataSource(buf));
    } catch (FileNotFoundException e) {
      throw new COFFException(e);
    } catch (IOException e) {
      throw new COFFException(e);
    }
  }

  public COFFFile parse(DataSource source) throws COFFException {
    return new COFFFileImpl(source);
  }

  class COFFFileImpl implements COFFFile {
    private DataSource file;
    private long       filePos;
    private boolean isImage;
    private long    imageHeaderOffset;
    private MemoizedObject header = new MemoizedObject() {
        public Object computeValue() {
          return new COFFHeaderImpl();
        }
      };

    COFFFileImpl(DataSource file) throws COFFException {
      this.file = file;
      initialize();
    }

    public boolean isImage() {
      return isImage;
    }

    public COFFHeader getHeader() {
      return (COFFHeaderImpl) header.getValue();
    }

    class COFFHeaderImpl implements COFFHeader {
      private short machine;
      private short numberOfSections;
      private int   timeDateStamp;
      private int   pointerToSymbolTable;
      private int   numberOfSymbols;
      private short sizeOfOptionalHeader;
      private short characteristics;
      private MemoizedObject[] sectionHeaders;
      private MemoizedObject[] symbols;

      // Init stringTable at decl time since other fields init'ed in the
      // constructor need the String Table.
      private MemoizedObject stringTable = new MemoizedObject() {
          public Object computeValue() {
            // the String Table follows the Symbol Table
            int ptr = getPointerToSymbolTable();
            if (ptr == 0) {
              // no Symbol Table so no String Table
              return new StringTable(0);
            } else {
              return new StringTable(ptr + SYMBOL_SIZE * getNumberOfSymbols());
            }
          }
        };

      COFFHeaderImpl() {
        seek(imageHeaderOffset);
        machine = readShort();
        numberOfSections = readShort();
        timeDateStamp = readInt();
        pointerToSymbolTable = readInt();
        numberOfSymbols = readInt();
        // String Table can be accessed at this point because
        // pointerToSymbolTable and numberOfSymbols fields are set.
        sizeOfOptionalHeader = readShort();
        characteristics = readShort();

        // Set up section headers
        sectionHeaders = new MemoizedObject[numberOfSections];
        for (int i = 0; i < numberOfSections; i++) {
          final int secHdrOffset = (int)
            (imageHeaderOffset + COFF_HEADER_SIZE + sizeOfOptionalHeader + i * SECTION_HEADER_SIZE);
          sectionHeaders[i] = new MemoizedObject() {
              public Object computeValue() {
                return new SectionHeaderImpl(secHdrOffset);
              }
            };
        }

        // Set up symbols
        symbols = new MemoizedObject[numberOfSymbols];
        for (int i = 0; i < numberOfSymbols; i++) {
          final int symbolOffset = pointerToSymbolTable + i * SYMBOL_SIZE;
          symbols[i] = new MemoizedObject() {
              public Object computeValue() {
                return new COFFSymbolImpl(symbolOffset);
              }
            };
        }
      }

      public short          getMachineType()          { return machine; }
      public short          getNumberOfSections()     { return numberOfSections; }
      public int            getTimeDateStamp()        { return timeDateStamp; }
      public int            getPointerToSymbolTable() { return pointerToSymbolTable; }
      public int            getNumberOfSymbols()      { return numberOfSymbols; }
      public short          getSizeOfOptionalHeader() { return sizeOfOptionalHeader; }
      public OptionalHeader getOptionalHeader() throws COFFException {
        if (getSizeOfOptionalHeader() == 0) {
          return null;
        }
        return new OptionalHeaderImpl((int) (imageHeaderOffset + COFF_HEADER_SIZE));
      }
      public short          getCharacteristics()      { return characteristics; }
      public boolean hasCharacteristic(short characteristic) {
        return ((characteristics & characteristic) != 0);
      }
      public SectionHeader getSectionHeader(int index) {
        // NOTE zero-basing of index
        return (SectionHeader) sectionHeaders[index - 1].getValue();
      }
      public COFFSymbol    getCOFFSymbol(int index)    {
        return (COFFSymbol) symbols[index].getValue();
      }
      public int getNumberOfStrings() {
        return getStringTable().getNum();
      }
      public String getString(int i) {
        return getStringTable().get(i);
      }

      StringTable          getStringTable() { return (StringTable) stringTable.getValue(); }

      // NOTE: can destroy current seek() position!
      int rvaToFileOffset(int rva) {
        if (rva == 0) return 0;
        // Search for section containing RVA
        for (int i = 1; i <= getNumberOfSections(); i++) {
          SectionHeader sec = getSectionHeader(i);
          int va = sec.getVirtualAddress();
          int sz = sec.getSize();
          if ((va <= rva) && (rva < (va + sz))) {
            return sec.getPointerToRawData() + (rva - va);
          }
        }
        throw new COFFException("Unable to find RVA 0x" +
                                Integer.toHexString(rva) +
                                " in any section");
      }

      class OptionalHeaderImpl implements OptionalHeader {
        private short magic;
        private MemoizedObject standardFields;
        private MemoizedObject windowsSpecificFields;
        private MemoizedObject dataDirectories;

        // We use an offset of 2 because OptionalHeaderStandardFieldsImpl doesn't
        // include the 'magic' field.
        private static final int STANDARD_FIELDS_OFFSET = 2;
        private static final int PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET = 28;
        private static final int PE32_DATA_DIRECTORIES_OFFSET = 96;
        private static final int PE32_PLUS_WINDOWS_SPECIFIC_FIELDS_OFFSET = 24;
        private static final int PE32_PLUS_DATA_DIRECTORIES_OFFSET = 112;

        OptionalHeaderImpl(final int offset) {
          seek(offset);
          magic = readShort();

          final boolean isPE32Plus = (magic == MAGIC_PE32_PLUS);
          final int standardFieldsOffset = offset + STANDARD_FIELDS_OFFSET;
          final int windowsSpecificFieldsOffset = offset +
            (isPE32Plus
             ? PE32_PLUS_WINDOWS_SPECIFIC_FIELDS_OFFSET
             : PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET);
          final int dataDirectoriesOffset = offset +
            (isPE32Plus
             ? PE32_PLUS_DATA_DIRECTORIES_OFFSET
             : PE32_DATA_DIRECTORIES_OFFSET);

          standardFields = new MemoizedObject() {
              public Object computeValue() {
                return new OptionalHeaderStandardFieldsImpl(standardFieldsOffset,
                                                            isPE32Plus);
              }
            };
          windowsSpecificFields = new MemoizedObject() {
              public Object computeValue() {
                return new OptionalHeaderWindowsSpecificFieldsImpl(windowsSpecificFieldsOffset,
                                                                   isPE32Plus);
              }
            };
          dataDirectories = new MemoizedObject() {
              public Object computeValue() {
                return new OptionalHeaderDataDirectoriesImpl(dataDirectoriesOffset,
                                                             getWindowsSpecificFields().getNumberOfRvaAndSizes());
              }
            };
        }

        public short getMagicNumber() {
          return magic;
        }

        public OptionalHeaderStandardFields getStandardFields() {
          return (OptionalHeaderStandardFields) standardFields.getValue();
        }

        public OptionalHeaderWindowsSpecificFields getWindowsSpecificFields() {
          return (OptionalHeaderWindowsSpecificFields) windowsSpecificFields.getValue();
        }
        public OptionalHeaderDataDirectories getDataDirectories() {
          return (OptionalHeaderDataDirectories) dataDirectories.getValue();
        }
      }

      class OptionalHeaderStandardFieldsImpl implements OptionalHeaderStandardFields {
        private boolean isPE32Plus;
        private byte majorLinkerVersion;
        private byte minorLinkerVersion;
        private int sizeOfCode;
        private int sizeOfInitializedData;
        private int sizeOfUninitializedData;
        private int addressOfEntryPoint;
        private int baseOfCode;
        private int baseOfData;  // only set in PE32

        OptionalHeaderStandardFieldsImpl(int offset,
                                         boolean isPE32Plus) {
          this.isPE32Plus = isPE32Plus;
          seek(offset);
          majorLinkerVersion = readByte();
          minorLinkerVersion = readByte();
          sizeOfCode = readInt();
          sizeOfInitializedData = readInt();
          sizeOfUninitializedData = readInt();
          addressOfEntryPoint = readInt();
          baseOfCode = readInt();
          if (!isPE32Plus) {
            // only available in PE32
            baseOfData = readInt();
          }
        }

        public byte getMajorLinkerVersion() { return majorLinkerVersion; }
        public byte getMinorLinkerVersion() { return minorLinkerVersion; }
        public int getSizeOfCode()              { return sizeOfCode; }
        public int getSizeOfInitializedData()   { return sizeOfInitializedData; }
        public int getSizeOfUninitializedData() { return sizeOfUninitializedData; }
        public int getAddressOfEntryPoint()     { return addressOfEntryPoint; }
        public int getBaseOfCode()              { return baseOfCode; }
        public int getBaseOfData() throws COFFException {
          if (isPE32Plus) {
            throw new COFFException("Not present in PE32+ files");
          }
          return baseOfData;
        }
      }

      class OptionalHeaderWindowsSpecificFieldsImpl implements OptionalHeaderWindowsSpecificFields {
        private long imageBase;
        private int sectionAlignment;
        private int fileAlignment;
        private short majorOperatingSystemVersion;
        private short minorOperatingSystemVersion;
        private short majorImageVersion;
        private short minorImageVersion;
        private short majorSubsystemVersion;
        private short minorSubsystemVersion;
        private int sizeOfImage;
        private int sizeOfHeaders;
        private int checkSum;
        private short subsystem;
        private short dllCharacteristics;
        private long sizeOfStackReserve;
        private long sizeOfStackCommit;
        private long sizeOfHeapReserve;
        private long sizeOfHeapCommit;
        private int loaderFlags;
        private int numberOfRvaAndSizes;

        OptionalHeaderWindowsSpecificFieldsImpl(int offset, boolean isPE32Plus) {
          seek(offset);

          if (!isPE32Plus) {
            imageBase = maskInt(readInt());
          } else {
            imageBase = readLong();
          }
          sectionAlignment = readInt();
          fileAlignment = readInt();
          majorOperatingSystemVersion = readShort();
          minorOperatingSystemVersion = readShort();
          majorImageVersion = readShort();
          minorImageVersion = readShort();
          majorSubsystemVersion = readShort();
          minorSubsystemVersion = readShort();
          readInt(); // Reserved
          sizeOfImage = readInt();
          sizeOfHeaders = readInt();
          checkSum = readInt();
          subsystem = readShort();
          dllCharacteristics = readShort();
          if (!isPE32Plus) {
            sizeOfStackReserve = maskInt(readInt());
            sizeOfStackCommit  = maskInt(readInt());
            sizeOfHeapReserve  = maskInt(readInt());
            sizeOfHeapCommit   = maskInt(readInt());
          } else {
            sizeOfStackReserve = readLong();
            sizeOfStackCommit  = readLong();
            sizeOfHeapReserve  = readLong();
            sizeOfHeapCommit   = readLong();
          }
          loaderFlags = readInt();
          numberOfRvaAndSizes = readInt();
        }

        public long getImageBase()              { return imageBase; }
        public int getSectionAlignment()        { return sectionAlignment; }
        public int getFileAlignment()           { return fileAlignment; }
        public short getMajorOperatingSystemVersion() { return majorOperatingSystemVersion; }
        public short getMinorOperatingSystemVersion() { return minorOperatingSystemVersion; }
        public short getMajorImageVersion()     { return majorImageVersion; }
        public short getMinorImageVersion()     { return minorImageVersion; }
        public short getMajorSubsystemVersion() { return majorSubsystemVersion; }
        public short getMinorSubsystemVersion() { return minorSubsystemVersion; }
        public int getSizeOfImage()             { return sizeOfImage; }
        public int getSizeOfHeaders()           { return sizeOfHeaders; }
        public int getCheckSum()                { return checkSum; }
        public short getSubsystem()             { return subsystem; }
        public short getDLLCharacteristics()    { return dllCharacteristics; }
        public long getSizeOfStackReserve()     { return sizeOfStackReserve; }
        public long getSizeOfStackCommit()      { return sizeOfStackCommit; }
        public long getSizeOfHeapReserve()      { return sizeOfHeapReserve; }
        public long getSizeOfHeapCommit()       { return sizeOfHeapCommit; }
        public int getLoaderFlags()             { return loaderFlags; }
        public int getNumberOfRvaAndSizes()     { return numberOfRvaAndSizes; }

        private long maskInt(long arg) {
          return (arg & 0x00000000FFFFFFFFL);
        }
      }

      class OptionalHeaderDataDirectoriesImpl implements OptionalHeaderDataDirectories {
        private int numberOfRvaAndSizes;
        private MemoizedObject[] dataDirectories;
        private MemoizedObject   exportDirectoryTable;
        private MemoizedObject   debugDirectory;

        private static final int DATA_DIRECTORY_SIZE = 8;

        OptionalHeaderDataDirectoriesImpl(int offset,
                                          int numberOfRvaAndSizes) {
          this.numberOfRvaAndSizes = numberOfRvaAndSizes;
          dataDirectories = new MemoizedObject[numberOfRvaAndSizes];
          for (int i = 0; i < numberOfRvaAndSizes; i++) {
            final int dirOffset = offset + (i * DATA_DIRECTORY_SIZE);
            dataDirectories[i] = new MemoizedObject() {
                public Object computeValue() {
                  return new DataDirectoryImpl(dirOffset);
                }
              };
          }

          exportDirectoryTable = new MemoizedObject() {
              public Object computeValue() {
                DataDirectory dir = getExportTable();
                if (dir.getRVA() == 0 || dir.getSize() == 0) {
                  return null;
                }
                // ExportDirectoryTableImpl needs both the RVA and the
                // RVA converted to a file offset.
                return new
                    ExportDirectoryTableImpl(dir.getRVA(), dir.getSize());
              }
            };

          debugDirectory = new MemoizedObject() {
              public Object computeValue() {
                DataDirectory dir = getDebug();
                if (dir.getRVA() == 0 || dir.getSize() == 0) {
                  return null;
                }
                return new DebugDirectoryImpl(rvaToFileOffset(dir.getRVA()), dir.getSize());
              }
            };
        }

        public DataDirectory getExportTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(0)].getValue();
        }
        public DataDirectory getImportTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(1)].getValue();
        }
        public DataDirectory getResourceTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(2)].getValue();
        }
        public DataDirectory getExceptionTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(3)].getValue();
        }
        public DataDirectory getCertificateTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(4)].getValue();
        }
        public DataDirectory getBaseRelocationTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(5)].getValue();
        }
        public DataDirectory getDebug() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(6)].getValue();
        }
        public DataDirectory getArchitecture() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(7)].getValue();
        }
        public DataDirectory getGlobalPtr() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(8)].getValue();
        }
        public DataDirectory getTLSTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(9)].getValue();
        }
        public DataDirectory getLoadConfigTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(10)].getValue();
        }
        public DataDirectory getBoundImportTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(11)].getValue();
        }
        public DataDirectory getImportAddressTable() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(12)].getValue();
        }
        public DataDirectory getDelayImportDescriptor() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(13)].getValue();
        }
        public DataDirectory getCOMPlusRuntimeHeader() throws COFFException {
          return (DataDirectory) dataDirectories[checkIndex(14)].getValue();
        }

        public ExportDirectoryTable getExportDirectoryTable() throws COFFException {
          return (ExportDirectoryTable) exportDirectoryTable.getValue();
        }

        public DebugDirectory getDebugDirectory() throws COFFException {
          return (DebugDirectory) debugDirectory.getValue();
        }

        private int checkIndex(int index) throws COFFException {
          if ((index < 0) || (index >= dataDirectories.length)) {
            throw new COFFException("Directory " + index + " unavailable (only " +
                                    numberOfRvaAndSizes + " tables present)");
          }
          return index;
        }
      }

      class DataDirectoryImpl implements DataDirectory {
        int rva;
        int size;

        DataDirectoryImpl(int offset) {
          seek(offset);
          rva  = readInt();
          size = readInt();
        }

        public int getRVA()  { return rva; }
        public int getSize() { return size; }
      }

      class ExportDirectoryTableImpl implements ExportDirectoryTable {
        private int exportDataDirRVA;
        private int offset;
        private int size;

        private int exportFlags;
        private int timeDateStamp;
        private short majorVersion;
        private short minorVersion;
        private int nameRVA;
        private int ordinalBase;
        private int addressTableEntries;
        private int numberOfNamePointers;
        private int exportAddressTableRVA;
        private int namePointerTableRVA;
        private int ordinalTableRVA;

        private MemoizedObject dllName;

        private MemoizedObject exportNameTable;
        private MemoizedObject exportNamePointerTable;
        private MemoizedObject exportOrdinalTable;
        private MemoizedObject exportAddressTable;

        ExportDirectoryTableImpl(int exportDataDirRVA, int size) {
          this.exportDataDirRVA = exportDataDirRVA;
          offset = rvaToFileOffset(exportDataDirRVA);
          this.size   = size;
          seek(offset);
          exportFlags = readInt();
          timeDateStamp = readInt();
          majorVersion = readShort();
          minorVersion = readShort();
          nameRVA = readInt();
          ordinalBase = readInt();
          addressTableEntries = readInt();
          numberOfNamePointers = readInt();
          exportAddressTableRVA = readInt();
          namePointerTableRVA = readInt();
          ordinalTableRVA = readInt();

          dllName = new MemoizedObject() {
              public Object computeValue() {
                seek(rvaToFileOffset(getNameRVA()));
                return readCString();
              }
            };

          exportNamePointerTable = new MemoizedObject() {
              public Object computeValue() {
                int[] pointers = new int[getNumberOfNamePointers()];
                seek(rvaToFileOffset(getNamePointerTableRVA()));
                // Must make two passes to avoid rvaToFileOffset
                // destroying seek() position
                for (int i = 0; i < pointers.length; i++) {
                  pointers[i] = readInt();
                }
                for (int i = 0; i < pointers.length; i++) {
                  pointers[i] = rvaToFileOffset(pointers[i]);
                }
                return pointers;
              }
            };

          exportNameTable = new MemoizedObject() {
              public Object computeValue() {
                return new ExportNameTable(getExportNamePointerTable());
              }
            };

          exportOrdinalTable = new MemoizedObject() {
              public Object computeValue() {
                // number of ordinals is same as the number of name pointers
                short[] ordinals = new short[getNumberOfNamePointers()];
                seek(rvaToFileOffset(getOrdinalTableRVA()));
                for (int i = 0; i < ordinals.length; i++) {
                  ordinals[i] = readShort();
                }
                return ordinals;
              }
            };

          exportAddressTable = new MemoizedObject() {
              public Object computeValue() {
                int[] addresses = new int[getNumberOfAddressTableEntries()];
                seek(rvaToFileOffset(getExportAddressTableRVA()));
                // The Export Address Table values are a union of two
                // possible values:
                //   Export RVA - The address of the exported symbol when
                //       loaded into memory, relative to the image base.
                //       This value doesn't get converted into a file offset.
                //   Forwarder RVA - The pointer to a null-terminated ASCII
                //       string in the export section. This value gets
                //       converted into a file offset because we have to
                //       fetch the string.
                for (int i = 0; i < addresses.length; i++) {
                  addresses[i] = readInt();
                }
                return addresses;
              }
            };
        }

        public int   getExportFlags()   { return exportFlags; }
        public int   getTimeDateStamp() { return timeDateStamp; }
        public short getMajorVersion()  { return majorVersion; }
        public short getMinorVersion()  { return minorVersion; }
        public int   getNameRVA()       { return nameRVA; }

        public String getDLLName() {
          return (String) dllName.getValue();
        }

        public int getOrdinalBase()                 { return ordinalBase; }
        public int getNumberOfAddressTableEntries() { return addressTableEntries; }
        public int getNumberOfNamePointers()        { return numberOfNamePointers; }
        public int getExportAddressTableRVA()       { return exportAddressTableRVA; }
        public int getNamePointerTableRVA()         { return namePointerTableRVA; }
        public int getOrdinalTableRVA()             { return ordinalTableRVA; }

        public String getExportName(int i) {
          return getExportNameTable().get(i);
        }

        public short  getExportOrdinal(int i) {
          return getExportOrdinalTable()[i];
        }

        public boolean isExportAddressForwarder(short ordinal) {
          int addr = getExportAddress(ordinal);
          return ((exportDataDirRVA <= addr) &&
              (addr < (exportDataDirRVA + size)));
        }

        public String getExportAddressForwarder(short ordinal) {
          seek(rvaToFileOffset(getExportAddress(ordinal)));
          return readCString();
        }

        public int    getExportAddress(short ordinal) {

          ///////////////////////
          // FIXME: MAJOR HACK //
          ///////////////////////

          // According to the documentation, the first line here is
          // correct. However, it doesn't seem to work. The second
          // one, however, does.

          // OK, it's probably due to using negative indices in the
          // export address table in "real life"...need to rethink
          // this when I'm more awake

          //          return getExportAddressTable()[ordinal - ordinalBase];
          return getExportAddressTable()[ordinal];
        }

        private ExportNameTable getExportNameTable() {
          return (ExportNameTable) exportNameTable.getValue();
        }

        private int[] getExportNamePointerTable() {
          return (int[]) exportNamePointerTable.getValue();
        }

        private short[] getExportOrdinalTable() {
          return (short[]) exportOrdinalTable.getValue();
        }

        private int[] getExportAddressTable() {
          return (int[]) exportAddressTable.getValue();
        }
      }

      class ExportNameTable {
        private MemoizedObject[] names;

        ExportNameTable(final int[] exportNamePointerTable) {
          names = new MemoizedObject[exportNamePointerTable.length];
          for (int i = 0; i < exportNamePointerTable.length; i++) {
            final int idx = i;
            names[idx] = new MemoizedObject() {
                public Object computeValue() {
                  seek(exportNamePointerTable[idx]);
                  return readCString();
                }
              };
            };
        }

        String get(int i) {
          return (String) names[i].getValue();
        }
      }

      class DebugDirectoryImpl implements DebugDirectory {
        private int offset;
        private int size;
        private int numEntries;

        private static final int DEBUG_DIRECTORY_ENTRY_SIZE = 28;

        DebugDirectoryImpl(int offset, int size) {
          this.offset = offset;
          this.size = size;

          if ((size % DEBUG_DIRECTORY_ENTRY_SIZE) != 0) {
            throw new COFFException("Corrupt DebugDirectory at offset 0x" +
                                    Integer.toHexString(offset));
          }

          numEntries = size / DEBUG_DIRECTORY_ENTRY_SIZE;
        }

        public int getNumEntries() { return numEntries; }
        public DebugDirectoryEntry getEntry(int i) {
          if ((i < 0) || (i >= getNumEntries())) throw new IndexOutOfBoundsException();
          return new DebugDirectoryEntryImpl(offset + i * DEBUG_DIRECTORY_ENTRY_SIZE);
        }
      }

      class DebugDirectoryEntryImpl implements DebugDirectoryEntry, DebugTypes {
        private int characteristics;
        private int timeDateStamp;
        private short majorVersion;
        private short minorVersion;
        private int type;
        private int sizeOfData;
        private int addressOfRawData;
        private int pointerToRawData;

        DebugDirectoryEntryImpl(int offset) {
          seek(offset);
          characteristics = readInt();
          timeDateStamp = readInt();
          majorVersion = readShort();
          minorVersion = readShort();
          type = readInt();
          sizeOfData = readInt();
          addressOfRawData = readInt();
          pointerToRawData = readInt();
        }

        public int   getCharacteristics()  { return characteristics; }
        public int   getTimeDateStamp()    { return timeDateStamp; }
        public short getMajorVersion()     { return majorVersion; }
        public short getMinorVersion()     { return minorVersion; }
        public int   getType()             { return type; }
        public int   getSizeOfData()       { return sizeOfData; }
        public int   getAddressOfRawData() { return addressOfRawData; }
        public int   getPointerToRawData() { return pointerToRawData; }

        public DebugVC50 getDebugVC50() {
          // See whether we can recognize VC++ 5.0 debug information.
          try {
            if (getType() != IMAGE_DEBUG_TYPE_CODEVIEW) return null;

            int offset = getPointerToRawData();
            seek(offset);
            if (readByte() == 'N' &&
                readByte() == 'B' &&
                readByte() == '1' &&
                readByte() == '1') {
              return new DebugVC50Impl(offset);
            }
          } catch (COFFException e) {
            e.printStackTrace();
          }
          return null;
        }

        public byte  getRawDataByte(int i) {
          if (i < 0 || i >= getSizeOfData()) {
            throw new IndexOutOfBoundsException();
          }
          seek(getPointerToRawData() + i);
          return readByte();
        }
      }

      class DebugVC50Impl implements DebugVC50, DebugVC50TypeLeafIndices {
        private int lfaBase;

        private int subsectionDirectoryOffset;
        private MemoizedObject subsectionDirectory;

        DebugVC50Impl(int offset) {
          lfaBase = offset;
          seek(offset);
          readInt();  // Discard NB11
          subsectionDirectoryOffset = globalOffset(readInt());

          // Ensure information is complete
          verify();

          subsectionDirectory = new MemoizedObject() {
              public Object computeValue() {
                return new DebugVC50SubsectionDirectoryImpl(getSubsectionDirectoryOffset());
              }
            };
        }

        public int getSubsectionDirectoryOffset() {
          return subsectionDirectoryOffset;
        }

        public DebugVC50SubsectionDirectory getSubsectionDirectory() {
          return (DebugVC50SubsectionDirectory) subsectionDirectory.getValue();
        }

        private int globalOffset(int offset) {
          return offset + lfaBase;
        }

        private void verify() {
          // Seek to subsection directory manually and look for
          // signature following it. This finishes validating that we
          // have VC++ 5.0 debug info. Throw COFFException if not
          // found; will cause caller to return null.
          seek(subsectionDirectoryOffset);
          int headerLength = readShort();
          int entryLength  = readShort();
          int numEntries   = readInt();
          int endOffset    = subsectionDirectoryOffset + headerLength + numEntries * entryLength;
          seek(endOffset);

          if (readByte() == 'N' &&
              readByte() == 'B' &&
              readByte() == '1' &&
              readByte() == '1') {
            return;
          }

          throw new COFFException("Did not find NB11 signature at end of debug info");
        }

        class DebugVC50SubsectionDirectoryImpl
          implements DebugVC50SubsectionDirectory,
                     DebugVC50SubsectionTypes {
          private int   offset;
          private short dirHeaderLength;
          private short dirEntryLength;
          private int   numEntries;

          DebugVC50SubsectionDirectoryImpl(int offset) {
            this.offset = offset;
            // Read header
            seek(offset);
            dirHeaderLength = readShort();
            dirEntryLength  = readShort();
            numEntries      = readInt();
          }

          public short getHeaderLength() { return dirHeaderLength; }
          public short getEntryLength()  { return dirEntryLength;  }
          public int   getNumEntries()   { return numEntries;      }

          public DebugVC50Subsection getSubsection(int i) {
            // Fetch the subsection type and instantiate the correct
            // type of subsection based on it
            seek(offset + dirHeaderLength + (i * dirEntryLength));
            short ssType = readShort();
            short iMod   = readShort(); // Unneeded?
            int   lfo    = globalOffset(readInt());
            int   cb     = readInt();
            switch (ssType) {
            case SST_MODULE:
              return new DebugVC50SSModuleImpl(ssType, iMod, cb, lfo);
            case SST_TYPES:
              return new DebugVC50SSTypesImpl(ssType, iMod, cb, lfo);
            case SST_PUBLIC:
              return new DebugVC50SSPublicImpl(ssType, iMod, cb, lfo);
            case SST_PUBLIC_SYM:
              return new DebugVC50SSPublicSymImpl(ssType, iMod, cb, lfo);
            case SST_SYMBOLS:
              return new DebugVC50SSSymbolsImpl(ssType, iMod, cb, lfo);
            case SST_ALIGN_SYM:
              return new DebugVC50SSAlignSymImpl(ssType, iMod, cb, lfo);
            case SST_SRC_LN_SEG:
              return new DebugVC50SSSrcLnSegImpl(ssType, iMod, cb, lfo);
            case SST_SRC_MODULE:
              return new DebugVC50SSSrcModuleImpl(ssType, iMod, cb, lfo);
            case SST_LIBRARIES:
              return new DebugVC50SSLibrariesImpl(ssType, iMod, cb, lfo);
            case SST_GLOBAL_SYM:
              return new DebugVC50SSGlobalSymImpl(ssType, iMod, cb, lfo);
            case SST_GLOBAL_PUB:
              return new DebugVC50SSGlobalPubImpl(ssType, iMod, cb, lfo);
            case SST_GLOBAL_TYPES:
              return new DebugVC50SSGlobalTypesImpl(ssType, iMod, cb, lfo);
            case SST_MPC:
              return new DebugVC50SSMPCImpl(ssType, iMod, cb, lfo);
            case SST_SEG_MAP:
              return new DebugVC50SSSegMapImpl(ssType, iMod, cb, lfo);
            case SST_SEG_NAME:
              return new DebugVC50SSSegNameImpl(ssType, iMod, cb, lfo);
            case SST_PRE_COMP:
              return new DebugVC50SSPreCompImpl(ssType, iMod, cb, lfo);
            case SST_UNUSED:
              return null;
            case SST_OFFSET_MAP_16:
              return new DebugVC50SSOffsetMap16Impl(ssType, iMod, cb, lfo);
            case SST_OFFSET_MAP_32:
              return new DebugVC50SSOffsetMap32Impl(ssType, iMod, cb, lfo);
            case SST_FILE_INDEX:
              return new DebugVC50SSFileIndexImpl(ssType, iMod, cb, lfo);
            case SST_STATIC_SYM:
              return new DebugVC50SSStaticSymImpl(ssType, iMod, cb, lfo);
            default:
              throw new COFFException("Unknown section type " + ssType);
            }
          }
        }

        ////////////////////////////////////
        //                                //
        // Implementations of subsections //
        //                                //
        ////////////////////////////////////

        class DebugVC50SubsectionImpl implements DebugVC50Subsection {
          private short ssType;
          private short iMod;
          private int   ssSize;

          DebugVC50SubsectionImpl(short ssType, short iMod, int ssSize, int offset) {
            this.ssType = ssType;
            this.iMod   = iMod;
            this.ssSize = ssSize;
          }

          public short getSubsectionType()        { return ssType; }
          public short getSubsectionModuleIndex() { return iMod; }
          public int   getSubsectionSize()        { return ssSize; }
        }

        class DebugVC50SSModuleImpl extends DebugVC50SubsectionImpl implements DebugVC50SSModule {
          private int offset;
          private short ovlNumber;
          private short iLib;
          private short cSeg;
          private short style;
          private MemoizedObject segInfo;
          private MemoizedObject name;

          private static final int HEADER_SIZE   = 8;
          private static final int SEG_INFO_SIZE = 12;

          DebugVC50SSModuleImpl(short ssType, short iMod, int ssSize, final int offset) {
            super(ssType, iMod, ssSize, offset);
            this.offset = offset;
            seek(offset);
            ovlNumber = readShort();
            iLib      = readShort();
            cSeg      = readShort();
            style     = readShort();
            segInfo   = new MemoizedObject() {
                public Object computeValue() {
                  int base = offset + HEADER_SIZE;
                  DebugVC50SegInfo[] res = new DebugVC50SegInfo[cSeg];
                  for (int i = 0; i < cSeg; i++) {
                    res[i] = new DebugVC50SegInfoImpl(base);
                    base += SEG_INFO_SIZE;
                  }
                  return res;
                }
              };
            name      = new MemoizedObject() {
                public Object computeValue() {
                  return readLengthPrefixedStringAt(offset + (HEADER_SIZE + cSeg * SEG_INFO_SIZE));
                }
              };
          }

          public short getOverlayNumber()   { return ovlNumber; }
          public short getLibrariesIndex()  { return iLib; }
          public short getNumCodeSegments() { return cSeg; }
          public short getDebuggingStyle()  { return style; }
          public DebugVC50SegInfo getSegInfo(int i) { return ((DebugVC50SegInfo[]) segInfo.getValue())[i]; }
          public String getName()           { return (String) name.getValue(); }
        }

        class DebugVC50SegInfoImpl implements DebugVC50SegInfo {
          private short seg;
          private int   offset;
          private int   cbSeg;

          DebugVC50SegInfoImpl(int offset) {
            seek(offset);
            seg = readShort();
            readShort(); // pad
            offset = readInt();
            cbSeg = readInt();
          }

          public short getSegment() { return seg; }
          public int getOffset() { return offset; }
          public int getSegmentCodeSize() { return cbSeg; }
        }

        class DebugVC50SSTypesImpl extends DebugVC50SubsectionImpl implements DebugVC50SSTypes {
          DebugVC50SSTypesImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSPublicImpl extends DebugVC50SubsectionImpl implements DebugVC50SSPublic {
          DebugVC50SSPublicImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSPublicSymImpl extends DebugVC50SubsectionImpl implements DebugVC50SSPublicSym {
          DebugVC50SSPublicSymImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSSymbolsImpl extends DebugVC50SubsectionImpl implements DebugVC50SSSymbols {
          DebugVC50SSSymbolsImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSAlignSymImpl extends DebugVC50SubsectionImpl implements DebugVC50SSAlignSym {
          private int offset;

          DebugVC50SSAlignSymImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
            this.offset = offset;
          }

          public DebugVC50SymbolIterator getSymbolIterator() {
            return new DebugVC50SymbolIteratorImpl(offset, getSubsectionSize());
          }
        }

        class DebugVC50SSSrcLnSegImpl extends DebugVC50SubsectionImpl implements DebugVC50SSSrcLnSeg {
          DebugVC50SSSrcLnSegImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSSrcModuleImpl extends DebugVC50SubsectionImpl implements DebugVC50SSSrcModule {
          private int offset;
          private short cFile;
          private short cSeg;
          private MemoizedObject baseSrcFiles;
          private MemoizedObject segOffsets;
          private MemoizedObject segs;

          DebugVC50SSSrcModuleImpl(short ssType, short iMod, int ssSize, final int offset) {
            super(ssType, iMod, ssSize, offset);

            this.offset = offset;
            seek(offset);
            cFile = readShort();
            cSeg  = readShort();

            baseSrcFiles = new MemoizedObject() {
                public Object computeValue() {
                  int[] offsets = new int[getNumSourceFiles()];
                  seek(offset + 4);
                  for (int i = 0; i < getNumSourceFiles(); i++) {
                    offsets[i] = offset + readInt();
                  }
                  DebugVC50SrcModFileDescImpl[] res = new DebugVC50SrcModFileDescImpl[offsets.length];
                  for (int i = 0; i < res.length; i++) {
                    res[i] = new DebugVC50SrcModFileDescImpl(offsets[i], offset);
                  }
                  return res;
                }
              };

            segOffsets = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4 * (getNumSourceFiles() + 1));
                  int[] res = new int[2 * getNumCodeSegments()];
                  for (int i = 0; i < 2 * getNumCodeSegments(); i++) {
                    res[i] = readInt();
                  }
                  return res;
                }
              };

            segs = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4 * (getNumSourceFiles() + 1) + 8 * getNumCodeSegments());
                  short[] res = new short[getNumCodeSegments()];
                  for (int i = 0; i < getNumCodeSegments(); i++) {
                    res[i] = readShort();
                  }
                  return res;
                }
              };
          }

          public int getNumSourceFiles()  { return cFile & 0xFFFF; }
          public int getNumCodeSegments() { return cSeg & 0xFFFF;  }
          public DebugVC50SrcModFileDesc getSourceFileDesc(int i) {
            return ((DebugVC50SrcModFileDescImpl[]) baseSrcFiles.getValue())[i];
          }

          public int getSegmentStartOffset(int i) {
            return ((int[]) segOffsets.getValue())[2*i];
          }

          public int getSegmentEndOffset(int i) {
            return ((int[]) segOffsets.getValue())[2*i+1];
          }

          public int getSegment(int i) {
            return ((short[]) segs.getValue())[i] & 0xFFFF;
          }
        }

        class DebugVC50SrcModFileDescImpl implements DebugVC50SrcModFileDesc {
          private short cSeg;
          private MemoizedObject baseSrcLn;
          private MemoizedObject segOffsets;
          private MemoizedObject name;

          DebugVC50SrcModFileDescImpl(final int offset, final int baseOffset) {
            seek(offset);
            cSeg = readShort();

            baseSrcLn = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4);
                  int[] offsets = new int[getNumCodeSegments()];
                  for (int i = 0; i < getNumCodeSegments(); i++) {
                    offsets[i] = baseOffset + readInt();
                  }
                  DebugVC50SrcModLineNumberMapImpl[] res =
                    new DebugVC50SrcModLineNumberMapImpl[getNumCodeSegments()];
                  for (int i = 0; i < getNumCodeSegments(); i++) {
                    res[i] = new DebugVC50SrcModLineNumberMapImpl(offsets[i]);
                  }
                  return res;
                }
              };

            segOffsets = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4 * (getNumCodeSegments() + 1));
                  int[] res = new int[2 * getNumCodeSegments()];
                  for (int i = 0; i < 2 * getNumCodeSegments(); i++) {
                    res[i] = readInt();
                  }
                  return res;
                }
              };

            name = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4 + 12 * getNumCodeSegments());
                  // NOTE: spec says name length is two bytes, but it's really one
                  int cbName = readByte() & 0xFF;
                  byte[] res = new byte[cbName];
                  readBytes(res);
                  try {
                    return new String(res, US_ASCII);
                  } catch (UnsupportedEncodingException e) {
                    throw new COFFException(e);
                  }
                }
              };
          }

          public int getNumCodeSegments() { return cSeg & 0xFFFF; }

          public DebugVC50SrcModLineNumberMap getLineNumberMap(int i) {
            return ((DebugVC50SrcModLineNumberMapImpl[]) baseSrcLn.getValue())[i];
          }

          public int getSegmentStartOffset(int i) {
            return ((int[]) segOffsets.getValue())[2*i];
          }

          public int getSegmentEndOffset(int i) {
            return ((int[]) segOffsets.getValue())[2*i+1];
          }

          public String getSourceFileName() {
            return (String) name.getValue();
          }
        }

        class DebugVC50SrcModLineNumberMapImpl implements DebugVC50SrcModLineNumberMap {
          private short seg;
          private short cPair;
          private MemoizedObject offsets;
          private MemoizedObject lineNumbers;

          DebugVC50SrcModLineNumberMapImpl(final int offset) {
            seek(offset);
            seg = readShort();
            cPair = readShort();
            offsets = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4);
                  int[] res = new int[getNumSourceLinePairs()];
                  for (int i = 0; i < getNumSourceLinePairs(); i++) {
                    res[i] = readInt();
                  }
                  return res;
                }
              };

            lineNumbers = new MemoizedObject() {
                public Object computeValue() {
                  seek(offset + 4 * (getNumSourceLinePairs() + 1));
                  short[] res = new short[getNumSourceLinePairs()];
                  for (int i = 0; i < getNumSourceLinePairs(); i++) {
                    res[i] = readShort();
                  }
                  return res;
                }
              };
          }

          public int getSegment() { return seg; }
          public int getNumSourceLinePairs() { return cPair; }
          public int getCodeOffset(int i) {
            return ((int[]) offsets.getValue())[i];
          }
          public int getLineNumber(int i) {
            return ((short[]) lineNumbers.getValue())[i] & 0xFFFF;
          }
        }

        class DebugVC50SSLibrariesImpl extends DebugVC50SubsectionImpl implements DebugVC50SSLibraries {
          DebugVC50SSLibrariesImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }

          // FIXME: NOT FINISHED
        }

        class DebugVC50SSSymbolBaseImpl extends DebugVC50SubsectionImpl implements DebugVC50SSSymbolBase {
          private int   offset;
          private short symHash;
          private short addrHash;
          private int   cbSymbol;
          private int   cbSymHash;
          private int   cbAddrHash;

          private static final int HEADER_SIZE = 16;

          DebugVC50SSSymbolBaseImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
            this.offset = offset;
            seek(offset);
            symHash    = readShort();
            addrHash   = readShort();
            cbSymbol   = readInt();
            cbSymHash  = readInt();
            cbAddrHash = readInt();
          }

          public short getSymHashIndex()  { return symHash; }
          public short getAddrHashIndex() { return addrHash; }
          public int getSymTabSize()      { return cbSymbol; }
          public int getSymHashSize()     { return cbSymHash; }
          public int getAddrHashSize()    { return cbAddrHash; }

          public DebugVC50SymbolIterator getSymbolIterator() {
            return new DebugVC50SymbolIteratorImpl(offset + HEADER_SIZE, cbSymbol);
          }
        }

        class DebugVC50SSGlobalSymImpl extends DebugVC50SSSymbolBaseImpl implements DebugVC50SSGlobalSym {
          DebugVC50SSGlobalSymImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }
        class DebugVC50SSGlobalPubImpl extends DebugVC50SSSymbolBaseImpl implements DebugVC50SSGlobalPub {
          DebugVC50SSGlobalPubImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSGlobalTypesImpl extends DebugVC50SubsectionImpl implements DebugVC50SSGlobalTypes {
          private int offset;
          private int cType;

          DebugVC50SSGlobalTypesImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
            this.offset = offset;
            seek(offset);
            readInt(); // Discard "flags"
            cType = readInt();
          }

          public int getNumTypes() { return cType; }
          // FIXME: should memoize these
          public int getTypeOffset(int i) {
            seek(offset + 4 * (i + 2));
            return readInt() + offsetOfFirstType();
          }

          public DebugVC50TypeIterator getTypeIterator() {
            return new DebugVC50TypeIteratorImpl(this,
                                                 offsetOfFirstType(),
                                                 cType);
          }

          private int offsetOfFirstType() {
            return offset + 4 * (getNumTypes() + 2);
          }
        }

        class DebugVC50SSMPCImpl extends DebugVC50SubsectionImpl implements DebugVC50SSMPC {
          DebugVC50SSMPCImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSSegMapImpl extends DebugVC50SubsectionImpl implements DebugVC50SSSegMap {
          private short cSeg;
          private short cSegLog;
          private MemoizedObject segDescs;

          DebugVC50SSSegMapImpl(short ssType, short iMod, int ssSize, final int offset) {
            super(ssType, iMod, ssSize, offset);
            seek(offset);
            cSeg = readShort();
            cSegLog = readShort();
            segDescs = new MemoizedObject() {
                public Object computeValue() {
                  DebugVC50SegDesc[] descs = new DebugVC50SegDesc[cSeg];
                  for (int i = 0; i < cSeg; i++) {
                    descs[i] = new DebugVC50SegDescImpl(offset + 4 + (20 * i));
                  }
                  return descs;
                }
              };
          }

          public short getNumSegDesc() { return cSeg; }
          public short getNumLogicalSegDesc() { return cSegLog; }
          public DebugVC50SegDesc getSegDesc(int i) { return ((DebugVC50SegDesc[]) segDescs.getValue())[i]; }
        }

        class DebugVC50SegDescImpl implements DebugVC50SegDesc {
          private short flags;
          private short ovl;
          private short group;
          private short frame;
          private short iSegName;
          private short iClassName;
          private int   offset;
          private int   cbSeg;

          DebugVC50SegDescImpl(int offset) {
            seek(offset);
            flags = readShort();
            ovl = readShort();
            group = readShort();
            frame = readShort();
            iSegName = readShort();
            iClassName = readShort();
            offset = readInt();
            cbSeg = readInt();
          }

          public short getFlags() { return flags; }
          public short getOverlayNum() { return ovl; }
          public short getGroup() { return group; }
          public short getFrame() { return frame; }
          public short getName() { return iSegName; }
          public short getClassName() { return iClassName; }
          public int   getOffset() { return offset; }
          public int   getSize() { return cbSeg; }
        }


        class DebugVC50SSSegNameImpl extends DebugVC50SubsectionImpl implements DebugVC50SSSegName {
          private int offset;
          private int size;
          private MemoizedObject names;

          DebugVC50SSSegNameImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
            this.offset = offset;
            this.size   = ssSize;
            seek(offset);
            names = new MemoizedObject() {
                public Object computeValue() {
                  int i = 0;
                  List data = new ArrayList();
                  while (i < size) {
                    String s = readCString();
                    data.add(s);
                    i += s.length();
                  }
                  String[] res = new String[data.size()];
                  res = (String[]) data.toArray(res);
                  return res;
                }
              };
          }

          public String getSegName(int i) {
            return ((String[]) names.getValue())[i];
          }
        }

        class DebugVC50SSPreCompImpl extends DebugVC50SubsectionImpl implements DebugVC50SSPreComp {
          DebugVC50SSPreCompImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSOffsetMap16Impl extends DebugVC50SubsectionImpl implements DebugVC50SSOffsetMap16 {
          DebugVC50SSOffsetMap16Impl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSOffsetMap32Impl extends DebugVC50SubsectionImpl implements DebugVC50SSOffsetMap32 {
          DebugVC50SSOffsetMap32Impl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        class DebugVC50SSFileIndexImpl extends DebugVC50SubsectionImpl implements DebugVC50SSFileIndex {
          private int offset;
          private short cMod; // Number of modules in the executable
          private short cRef; // Total number of file name references
          private MemoizedObject modStart;
          private MemoizedObject cRefCnt;
          // FIXME: probably useless; needs fixup to be converted into
          // indices rather than offsets
          private MemoizedObject nameRef;
          private MemoizedObject names;

          DebugVC50SSFileIndexImpl(short ssType, short iMod, int ssSize, final int offset) {
            super(ssType, iMod, ssSize, offset);
            this.offset = offset;
            seek(offset);
            cMod = readShort();
            cRef = readShort();
            modStart = new MemoizedObject() {
                public Object computeValue() {
                  short[] vals = new short[cMod];
                  seek(4 + offset);
                  for (int i = 0; i < cMod; i++) {
                    vals[i] = readShort();
                  }
                  return vals;
                }
              };
            cRefCnt = new MemoizedObject() {
                public Object computeValue() {
                  short[] vals = new short[cMod];
                  seek(4 + offset + (2 * cMod));
                  for (int i = 0; i < cMod; i++) {
                    vals[i] = readShort();
                  }
                  return vals;
                }
              };
            nameRef = new MemoizedObject() {
                public Object computeValue() {
                  int[] vals = new int[cRef];
                  seek(4 + offset + (4 * cMod));
                  for (int i = 0; i < cMod; i++) {
                    vals[i] = readInt();
                  }
                  return vals;
                }
              };
            names = new MemoizedObject() {
                public Object computeValue() {
                  String[] vals = new String[cRef];
                  for (int i = 0; i < cRef; i++) {
                    vals[i] = readCString();
                  }
                  return vals;
                }
              };
          }

          public short getNumModules()    { return cMod; }
          public short getNumReferences() { return cRef; }
          public short[] getModStart()    { return (short[]) modStart.getValue(); }
          public short[] getRefCount()    { return (short[]) cRefCnt.getValue(); }
          public int[] getNameRef()       { return (int[]) nameRef.getValue(); }
          public String[] getNames()      { return (String[]) names.getValue(); }
        }

        class DebugVC50SSStaticSymImpl extends DebugVC50SSSymbolBaseImpl implements DebugVC50SSStaticSym {
          DebugVC50SSStaticSymImpl(short ssType, short iMod, int ssSize, int offset) {
            super(ssType, iMod, ssSize, offset);
          }
        }

        //////////////////////////////////////////////////
        //                                              //
        // Implementations of symbol and type iterators //
        //                                              //
        //////////////////////////////////////////////////

        class DebugVC50SymbolIteratorImpl implements DebugVC50SymbolIterator {
          private int base;
          private int size;
          private int pos;
          private int curSymSize;
          private int curSymType;

          private static final int HEADER_SIZE = 4;

          DebugVC50SymbolIteratorImpl(int base, int size) {
            this(base, size, base);
          }

          private DebugVC50SymbolIteratorImpl(int base, int size, int pos) {
            this.base = base;
            this.size = size;
            this.pos = pos;
            seek(pos);
            curSymSize = readShort() & 0xFFFF;
            curSymType = readShort() & 0xFFFF;
          }

          public boolean done() {
            return (pos == (base + size));
          }

          public void next() throws NoSuchElementException {
            if (done()) throw new NoSuchElementException("No more symbols");
            pos += curSymSize + 2;
            seek(pos);
            curSymSize = readShort() & 0xFFFF;
            curSymType = readShort() & 0xFFFF;
          }

          public short getLength() {
            return (short) curSymSize;
          }

          public int getType() {
            return curSymType;
          }

          public int getOffset() {
            return pos + HEADER_SIZE;
          }

          /////////////////////////
          // S_COMPILE accessors //
          /////////////////////////

          public byte getCompilerTargetProcessor() {
            symSeek(0);
            return readByte();
          }

          public int getCompilerFlags() {
            symSeek(1);
            int res = 0;
            for (int i = 0; i < 3; i++) {
              int b = readByte() & 0xFF;
              res = (res << 8) | b;
            }
            return res;
          }

          public String getComplierVersion() {
            return readLengthPrefixedStringAt(4);
          }

          //////////////////////////
          // S_REGISTER accessors //
          //////////////////////////

          public int getRegisterSymbolType() {
            symSeek(0);
            return readInt();
          }

          public short getRegisterEnum() {
            symSeek(4);
            return readShort();
          }

          public String getRegisterSymbolName() {
            return readLengthPrefixedStringAt(6);
          }

          //////////////////////////
          // S_CONSTANT accessors //
          //////////////////////////

          public int getConstantType() {
            symSeek(0);
            return readInt();
          }

          public int getConstantValueAsInt() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(4);
          }

          public long getConstantValueAsLong() throws DebugVC50WrongNumericTypeException {
            return readLongNumericLeafAt(4);
          }

          public float getConstantValueAsFloat() throws DebugVC50WrongNumericTypeException {
            return readFloatNumericLeafAt(4);
          }

          public double getConstantValueAsDouble() throws DebugVC50WrongNumericTypeException {
            return readDoubleNumericLeafAt(4);
          }

          public String getConstantName() {
            return readLengthPrefixedStringAt(4 + numericLeafLengthAt(4));
          }

          /////////////////////
          // S_UDT accessors //
          /////////////////////

          public int getUDTType() {
            symSeek(0);
            return readInt();
          }

          public String getUDTName() {
            return readLengthPrefixedStringAt(4);
          }

          /////////////////////////
          // S_SSEARCH accessors //
          /////////////////////////

          public int getSearchSymbolOffset() {
            symSeek(0);
            return readInt();
          }

          public short getSearchSegment() {
            symSeek(4);
            return readShort();
          }

          /////////////////////
          // S_END accessors //
          /////////////////////

          // (No accessors)

          //////////////////////
          // S_SKIP accessors //
          //////////////////////

          // (No accessors)

          ///////////////////////////
          // S_CVRESERVE accessors //
          ///////////////////////////

          // (No accessors)

          /////////////////////////
          // S_OBJNAME accessors //
          /////////////////////////

          public int getObjectCodeViewSignature() {
            symSeek(0);
            return readInt();
          }

          public String getObjectName() {
            return readLengthPrefixedStringAt(4);
          }

          ////////////////////////
          // S_ENDARG accessors //
          ////////////////////////

          // (No accessors)

          //////////////////////////
          // S_COBOLUDT accessors //
          //////////////////////////

          // (Elided as they are irrelevant)

          /////////////////////////
          // S_MANYREG accessors //
          /////////////////////////

          public int getManyRegType() {
            symSeek(0);
            return readInt();
          }

          public byte getManyRegCount() {
            symSeek(4);
            return readByte();
          }

          public byte getManyRegRegister(int i) {
            symSeek(5 + i);
            return readByte();
          }

          public String getManyRegName() {
            return readLengthPrefixedStringAt(5 + getManyRegCount());
          }

          ////////////////////////
          // S_RETURN accessors //
          ////////////////////////

          public short getReturnFlags() {
            symSeek(0);
            return readShort();
          }

          public byte getReturnStyle() {
            symSeek(2);
            return readByte();
          }

          public byte getReturnRegisterCount() {
            symSeek(3);
            return readByte();
          }

          public byte getReturnRegister(int i) {
            symSeek(4 + i);
            return readByte();
          }

          ///////////////////////////
          // S_ENTRYTHIS accessors //
          ///////////////////////////

          public void advanceToEntryThisSymbol() {
            seek(pos + 4);
            int tmpSymSize = readShort();
            int tmpSymType = readShort();
            if (Assert.ASSERTS_ENABLED) {
              // Make sure that ends of inner and outer symbols line
              // up, otherwise need more work
              Assert.that(pos + curSymSize + 2 == pos + 4 + tmpSymSize,
                          "advanceToEntryThisSymbol needs more work");
            }
            pos += 4;
            curSymSize = tmpSymSize;
            curSymType = tmpSymType;
          }

          ///////////////////////////////////////////////////////////////////////
          //                                                                   //
          //                                                                   //
          // Symbols for (Intel) 16:32 Segmented and 32-bit Flat Architectures //
          //                                                                   //
          //                                                                   //
          ///////////////////////////////////////////////////////////////////////

          /////////////////////////
          // S_BPREL32 accessors //
          /////////////////////////

          public int getBPRelOffset() {
            symSeek(0);
            return readInt();
          }

          public int getBPRelType() {
            symSeek(4);
            return readInt();
          }

          public String getBPRelName() {
            return readLengthPrefixedStringAt(8);
          }

          ///////////////////////////////////////
          // S_LDATA32 and S_GDATA32 accessors //
          ///////////////////////////////////////

          public int getLGDataType() {
            symSeek(0);
            return readInt();
          }

          public int getLGDataOffset() {
            symSeek(4);
            return readInt();
          }

          public short getLGDataSegment() {
            symSeek(8);
            return readShort();
          }

          public String getLGDataName() {
            return readLengthPrefixedStringAt(10);
          }

          ///////////////////////
          // S_PUB32 accessors //
          ///////////////////////

          // FIXME: has the same format as the above; consider updating
          // documentation. No separate accessors provided.

          ///////////////////////////////////////
          // S_LPROC32 and S_GPROC32 accessors //
          ///////////////////////////////////////

          public DebugVC50SymbolIterator getLGProcParent() {
            int offs = getLGProcParentOffset();
            if (offs == 0) return null;
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getLGProcParentOffset() {
            symSeek(0);
            int offs = readInt();
            if (offs == 0) return 0;
            return base + offs;
          }

          public DebugVC50SymbolIterator getLGProcEnd() {
            int offs = getLGProcEndOffset();
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getLGProcEndOffset() {
            symSeek(4);
            int offs = readInt();
            if (Assert.ASSERTS_ENABLED) {
              Assert.that(offs != 0, "should not have null end offset for procedure symbols");
            }
            return base + offs;
          }

          public DebugVC50SymbolIterator getLGProcNext() {
            int offs = getLGProcNextOffset();
            if (offs == 0) return null;
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getLGProcNextOffset() {
            symSeek(8);
            int offs = readInt();
            if (offs == 0) return 0;
            return base + offs;
          }

          public int getLGProcLength() {
            symSeek(12);
            return readInt();
          }

          public int getLGProcDebugStart() {
            symSeek(16);
            return readInt();
          }

          public int getLGProcDebugEnd() {
            symSeek(20);
            return readInt();
          }

          public int getLGProcType() {
            symSeek(24);
            return readInt();
          }

          public int getLGProcOffset() {
            symSeek(28);
            return readInt();
          }

          public short getLGProcSegment() {
            symSeek(32);
            return readShort();
          }

          public byte getLGProcFlags() {
            symSeek(34);
            return readByte();
          }

          public String getLGProcName() {
            return readLengthPrefixedStringAt(35);
          }

          /////////////////////////
          // S_THUNK32 accessors //
          /////////////////////////

          public DebugVC50SymbolIterator getThunkParent() {
            int offs = getThunkParentOffset();
            if (offs == 0) return null;
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getThunkParentOffset() {
            symSeek(0);
            int offs = readInt();
            if (offs == 0) return 0;
            return base + offs;
          }

          public DebugVC50SymbolIterator getThunkEnd() {
            symSeek(4);
            int offs = readInt();
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getThunkEndOffset() {
            symSeek(4);
            int offs = readInt();
            if (Assert.ASSERTS_ENABLED) {
              Assert.that(offs != 0, "should not have null end offset for thunk symbols");
            }
            return base + offs;
          }

          public DebugVC50SymbolIterator getThunkNext() {
            int offs = getThunkNextOffset();
            if (offs == 0) return null;
            return new DebugVC50SymbolIteratorImpl(base, size, base + offs);
          }

          public int getThunkNextOffset() {
            symSeek(8);
            int offs = readInt();
            if (offs == 0) return 0;
            return base + offs;
          }

          public int getThunkOffset() {
            symSeek(12);
            return readInt();
          }

          public short getThunkSegment() {
            symSeek(16);
            return readShort();
          }

          public short getThunkLength() {
            symSeek(18);
            return readShort();
          }

          public byte getThunkType() {
            symSeek(20);
            return readByte();
          }

          public String getThunkName() {
            return readLengthPrefixedStringAt(21);
          }

          public short getThunkAdjustorThisDelta() {
            symSeek(21 + lengthPrefixedStringLengthAt(21));
            return readShort();
          }

          public String getThunkAdjustorTargetName() {
            return readLengthPrefixedStringAt(23 + lengthPrefixedStringLengthAt(21));
          }

          public short getThunkVCallDisplacement() {
            symSeek(21 + lengthPrefixedStringLengthAt(21));
            return readShort();
          }

          public int getThunkPCodeOffset() {
            symSeek(21 + lengthPrefixedStringLengthAt(21));
            return readInt();
          }

          public short getThunkPCodeSegment() {
            symSeek(25 + lengthPrefixedStringLengthAt(21));
            return readShort();
          }

          /////////////////////////
          // S_BLOCK32 accessors //
          /////////////////////////

          public DebugVC50SymbolIterator getBlockParent() {
            int offs = getBlockParentOffset();
            if (offs == 0) return null;
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getBlockParentOffset() {
            symSeek(0);
            int offs = readInt();
            if (offs == 0) return 0;
            return base + offs;
          }

          public DebugVC50SymbolIterator getBlockEnd() {
            symSeek(4);
            int offs = readInt();
            return new DebugVC50SymbolIteratorImpl(base, size, offs);
          }

          public int getBlockEndOffset() {
            symSeek(4);
            int offs = readInt();
            if (Assert.ASSERTS_ENABLED) {
              Assert.that(offs != 0, "should not have null end offset for block symbols");
            }
            return base + offs;
          }

          public int getBlockLength() {
            symSeek(8);
            return readInt();
          }

          public int getBlockOffset() {
            symSeek(12);
            return readInt();
          }

          public short getBlockSegment() {
            symSeek(16);
            return readShort();
          }

          public String getBlockName() {
            return readLengthPrefixedStringAt(18);
          }

          ////////////////////////
          // S_WITH32 accessors //
          ////////////////////////

          // FIXME: this is a Pascal construct; ignored for now

          /////////////////////////
          // S_LABEL32 accessors //
          /////////////////////////

          public int getLabelOffset() {
            symSeek(0);
            return readInt();
          }

          public short getLabelSegment() {
            symSeek(4);
            return readShort();
          }

          public byte getLabelFlags() {
            symSeek(6);
            return readByte();
          }

          public String getLabelName() {
            return readLengthPrefixedStringAt(7);
          }

          ////////////////////////////
          // S_CEXMODEL32 accessors //
          ////////////////////////////

          public int getChangeOffset() {
            symSeek(0);
            return readInt();
          }

          public short getChangeSegment() {
            symSeek(4);
            return readShort();
          }

          public short getChangeModel() {
            symSeek(6);
            return readShort();
          }

          ////////////////////////////
          // S_VFTTABLE32 accessors //
          ////////////////////////////

          public int getVTableRoot() {
            symSeek(0);
            return readInt();
          }

          public int getVTablePath() {
            symSeek(4);
            return readInt();
          }

          public int getVTableOffset() {
            symSeek(8);
            return readInt();
          }

          public short getVTableSegment() {
            symSeek(12);
            return readShort();
          }

          //////////////////////////
          // S_REGREL32 accessors //
          //////////////////////////

          public int getRegRelOffset() {
            symSeek(0);
            return readInt();
          }

          public int getRegRelType() {
            symSeek(4);
            return readInt();
          }

          public short getRegRelRegister() {
            symSeek(8);
            return readShort();
          }

          public String getRegRelName() {
            return readLengthPrefixedStringAt(10);
          }

          ///////////////////////////////////////////
          // S_LTHREAD32 and S_GTHREAD32 accessors //
          ///////////////////////////////////////////

          public int getLThreadType() {
            symSeek(0);
            return readInt();
          }

          public int getLThreadOffset() {
            symSeek(4);
            return readInt();
          }

          public short getLThreadSegment() {
            symSeek(8);
            return readShort();
          }

          public String getLThreadName() {
            return readLengthPrefixedStringAt(10);
          }

          //----------------------------------------------------------------------
          // Internals only below this point
          //

          private void symSeek(int offsetInSym) {
            seek(pos + HEADER_SIZE + offsetInSym);
          }

          private int numericLeafLengthAt(int offsetInSym) {
            return DebugVC50Impl.this.numericLeafLengthAt(pos + HEADER_SIZE + offsetInSym);
          }

          private int readIntNumericLeafAt(int offsetInSym) {
            return DebugVC50Impl.this.readIntNumericLeafAt(pos + HEADER_SIZE + offsetInSym);
          }

          private long readLongNumericLeafAt(int offsetInSym) {
            return DebugVC50Impl.this.readLongNumericLeafAt(pos + HEADER_SIZE + offsetInSym);
          }

          private float readFloatNumericLeafAt(int offsetInSym) {
            return DebugVC50Impl.this.readFloatNumericLeafAt(pos + HEADER_SIZE + offsetInSym);
          }

          private double readDoubleNumericLeafAt(int offsetInSym) {
            return DebugVC50Impl.this.readDoubleNumericLeafAt(pos + HEADER_SIZE + offsetInSym);
          }

          private int lengthPrefixedStringLengthAt(int offsetInSym) {
            return DebugVC50Impl.this.lengthPrefixedStringLengthAt(pos + HEADER_SIZE + offsetInSym);
          }

          private String readLengthPrefixedStringAt(int offsetInSym) {
            return DebugVC50Impl.this.readLengthPrefixedStringAt(pos + HEADER_SIZE + offsetInSym);
          }
        }

        class DebugVC50TypeIteratorImpl implements DebugVC50TypeIterator,
                        DebugVC50TypeLeafIndices, DebugVC50MemberAttributes, DebugVC50TypeEnums {
          private DebugVC50SSGlobalTypes parent;
          private int   base;
          private int   numTypes;
          private int   typeIndex;
          private int   typeRecordOffset;
          private int   typeStringOffset;
          private int   typeRecordSize;
          private int   typeStringLeaf;

          DebugVC50TypeIteratorImpl(DebugVC50SSGlobalTypes parent, int base, int numTypes) {
            this(parent, base, numTypes, 0, base);
          }

          private DebugVC50TypeIteratorImpl(DebugVC50SSGlobalTypes parent, int base, int numTypes, int curType, int offset) {
            this.parent = parent;
            this.base = base;
            this.numTypes = numTypes;
            this.typeIndex = curType;
            if (!done()) {
              typeRecordOffset = offset;
              loadTypeRecord();
            }
          }

          public boolean done() {
            return (typeIndex == numTypes);
          }

          public void next() throws NoSuchElementException {
            if (done()) throw new NoSuchElementException();
            ++typeIndex;
            if (!done()) {
              typeRecordOffset = parent.getTypeOffset(typeIndex);
              loadTypeRecord();
            }
          }

          public short getLength() {
            return (short) typeRecordSize;
          }

          public int getTypeIndex() {
            return biasTypeIndex(typeIndex);
          }

          public int getNumTypes() {
            return numTypes;
          }

          public boolean typeStringDone() {
            return (typeStringOffset - typeRecordOffset - 2) >= typeRecordSize;
          }

          public void typeStringNext() throws NoSuchElementException {
            if (typeStringDone()) throw new NoSuchElementException();
            typeStringOffset += typeStringLength();
            loadTypeString();
          }

          public int typeStringLeaf() {
            return typeStringLeaf;
          }

          public int typeStringOffset() {
            return typeStringOffset;
          }

          ///////////////////////////
          // LF_MODIFIER accessors //
          ///////////////////////////

          public int getModifierIndex() {
            typeSeek(2);
            return readInt();
          }

          public short getModifierAttribute() {
            typeSeek(6);
            return readShort();
          }

          //////////////////////////
          // LF_POINTER accessors //
          //////////////////////////

          public int getPointerType() {
            typeSeek(2);
            return readInt();
          }

          public int getPointerAttributes() {
            typeSeek(6);
            return readInt();
          }

          public int getPointerBasedOnTypeIndex() {
            typeSeek(10);
            return readInt();
          }

          public String getPointerBasedOnTypeName() {
            return readLengthPrefixedStringAt(14);
          }

          public int getPointerToMemberClass() {
            typeSeek(10);
            return readInt();
          }

          public short getPointerToMemberFormat() {
            typeSeek(14);
            return readShort();
          }

          ////////////////////////
          // LF_ARRAY accessors //
          ////////////////////////

          public int getArrayElementType() {
            typeSeek(2);
            return readInt();
          }

          public int getArrayIndexType() {
            typeSeek(6);
            return readInt();
          }

          public int getArrayLength() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(10);
          }

          public String getArrayName() {
            return readLengthPrefixedStringAt(10 + numericLeafLengthAt(10));
          }

          /////////////////////////////////////////
          // LF_CLASS and LF_STRUCTURE accessors //
          /////////////////////////////////////////

          public short getClassCount() {
            typeSeek(2);
            return readShort();
          }

          public short getClassProperty() {
            typeSeek(4);
            return readShort();
          }

          public int getClassFieldList() {
            typeSeek(6);
            return readInt();
          }

          public DebugVC50TypeIterator getClassFieldListIterator() {
            int index = unbiasTypeIndex(getClassFieldList());
            int offset = parent.getTypeOffset(index);
            return new DebugVC50TypeIteratorImpl(parent, base, numTypes, index, offset);
          }

          public int getClassDerivationList() {
            typeSeek(10);
            return readInt();
          }

          public int getClassVShape() {
            typeSeek(14);
            return readInt();
          }

          public int getClassSize() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(18);
          }

          public String getClassName() {
            return readLengthPrefixedStringAt(18 + numericLeafLengthAt(18));
          }

          ////////////////////////
          // LF_UNION accessors //
          ////////////////////////

          public short getUnionCount() {
            typeSeek(2);
            return readShort();
          }

          public short getUnionProperty() {
            typeSeek(4);
            return readShort();
          }

          public int getUnionFieldList() {
            typeSeek(6);
            return readInt();
          }

          public DebugVC50TypeIterator getUnionFieldListIterator() {
            int index = unbiasTypeIndex(getUnionFieldList());
            int offset = parent.getTypeOffset(index);
            return new DebugVC50TypeIteratorImpl(parent, base, numTypes, index, offset);
          }

          public int getUnionSize() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(10);
          }

          public String getUnionName() {
            return readLengthPrefixedStringAt(10 + numericLeafLengthAt(10));
          }

          ///////////////////////
          // LF_ENUM accessors //
          ///////////////////////

          public short getEnumCount() {
            typeSeek(2);
            return readShort();
          }

          public short getEnumProperty() {
            typeSeek(4);
            return readShort();
          }

          public int getEnumType() {
            typeSeek(6);
            return readInt();
          }

          public int getEnumFieldList() {
            typeSeek(10);
            return readInt();
          }

          public DebugVC50TypeIterator getEnumFieldListIterator() {
            int index = unbiasTypeIndex(getEnumFieldList());
            int offset = parent.getTypeOffset(index);
            return new DebugVC50TypeIteratorImpl(parent, base, numTypes, index, offset);
          }

          public String getEnumName() {
            return readLengthPrefixedStringAt(14);
          }

          ////////////////////////////
          // LF_PROCEDURE accessors //
          ////////////////////////////

          public int getProcedureReturnType() {
            typeSeek(2);
            return readInt();
          }

          public byte getProcedureCallingConvention() {
            typeSeek(6);
            return readByte();
          }

          public short getProcedureNumberOfParameters() {
            typeSeek(8);
            return readShort();
          }

          public int getProcedureArgumentList() {
            typeSeek(10);
            return readInt();
          }

          public DebugVC50TypeIterator getProcedureArgumentListIterator() {
            int index = unbiasTypeIndex(getProcedureArgumentList());
            int offset = parent.getTypeOffset(index);
            return new DebugVC50TypeIteratorImpl(parent, base, numTypes, index, offset);
          }

          ////////////////////////////
          // LF_MFUNCTION accessors //
          ////////////////////////////

          public int getMFunctionReturnType() {
            typeSeek(2);
            return readInt();
          }

          public int getMFunctionContainingClass() {
            typeSeek(6);
            return readInt();
          }

          public int getMFunctionThis() {
            typeSeek(10);
            return readInt();
          }

          public byte getMFunctionCallingConvention() {
            typeSeek(14);
            return readByte();
          }

          public short getMFunctionNumberOfParameters() {
            typeSeek(16);
            return readShort();
          }

          public int getMFunctionArgumentList() {
            typeSeek(18);
            return readInt();
          }

          public DebugVC50TypeIterator getMFunctionArgumentListIterator() {
            int index = unbiasTypeIndex(getMFunctionArgumentList());
            int offset = parent.getTypeOffset(index);
            return new DebugVC50TypeIteratorImpl(parent, base, numTypes, index, offset);
          }

          public int getMFunctionThisAdjust() {
            typeSeek(22);
            return readInt();
          }

          //////////////////////////
          // LF_VTSHAPE accessors //
          //////////////////////////

          public short getVTShapeCount() {
            typeSeek(2);
            return readShort();
          }

          public int getVTShapeDescriptor(int i) {
            typeSeek(4 + (i / 2));
            int val = readByte() & 0xFF;
            if ((i % 2) != 0) {
              val = val >> 4;
            }
            return val;
          }

          /////////////////////////
          // LF_BARRAY accessors //
          /////////////////////////

          public int getBasicArrayType() {
            typeSeek(2);
            return readInt();
          }

          ////////////////////////
          // LF_LABEL accessors //
          ////////////////////////

          public short getLabelAddressMode() {
            typeSeek(2);
            return readShort();
          }

          ///////////////////////////
          // LF_DIMARRAY accessors //
          ///////////////////////////

          public int getDimArrayType() {
            typeSeek(2);
            return readInt();
          }

          public int getDimArrayDimInfo() {
            typeSeek(6);
            return readInt();
          }

          public String getDimArrayName() {
            return readLengthPrefixedStringAt(10);
          }

          //////////////////////////
          // LF_VFTPATH accessors //
          //////////////////////////

          public int getVFTPathCount() {
            typeSeek(2);
            return readInt();
          }

          public int getVFTPathBase(int i) {
            typeSeek(6 + (4 * i));
            return readInt();
          }

          ///////////////////////
          // LF_SKIP accessors //
          ///////////////////////

          public int getSkipIndex() {
            typeSeek(2);
            return readInt();
          }

          //////////////////////////
          // LF_ARGLIST accessors //
          //////////////////////////

          public int getArgListCount() {
            typeSeek(2);
            return readInt();
          }

          public int getArgListType(int i) {
            typeSeek(6 + (4 * i));
            return readInt();
          }

          /////////////////////////
          // LF_DEFARG accessors //
          /////////////////////////

          public int getDefaultArgType() {
            typeSeek(2);
            return readInt();
          }

          public String getDefaultArgExpression() {
            return readLengthPrefixedStringAt(6);
          }

          //////////////////////////
          // LF_DERIVED accessors //
          //////////////////////////

          public int getDerivedCount() {
            typeSeek(2);
            return readInt();
          }

          public int getDerivedType(int i) {
            typeSeek(6);
            return readInt();
          }

          ///////////////////////////
          // LF_BITFIELD accessors //
          ///////////////////////////

          public int getBitfieldFieldType() {
            typeSeek(2);
            return readInt();
          }

          public byte getBitfieldLength() {
            typeSeek(6);
            return readByte();
          }

          public byte getBitfieldPosition() {
            typeSeek(7);
            return readByte();
          }

          ////////////////////////
          // LF_MLIST accessors //
          ////////////////////////

          public short getMListAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getMListLength() {
            return (getLength() - 6 - (isMListIntroducingVirtual() ? 4 : 0)) / 4;
          }

          public int getMListType(int i) {
            typeSeek(6 + 4 * i);
            return readInt();
          }

          public boolean isMListIntroducingVirtual() {
            return isIntroducingVirtual(getMListAttribute());
          }

          public int getMListVtabOffset() {
            typeSeek(6 + 4 * getMListLength());
            return readInt();
          }

          /////////////////////////
          // LF_REFSYM accessors //
          /////////////////////////

          public DebugVC50SymbolIterator getRefSym() {
            typeSeek(2);
            int len = readShort() & 0xFFFF;
            return new DebugVC50SymbolIteratorImpl(typeStringOffset + 2, len);
          }

          /////////////////////////
          // LF_BCLASS accessors //
          /////////////////////////

          public short getBClassAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getBClassType() {
            typeSeek(4);
            return readInt();
          }

          public int getBClassOffset() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(8);
          }

          //////////////////////////
          // LF_VBCLASS accessors //
          //////////////////////////

          public short getVBClassAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getVBClassBaseClassType() {
            typeSeek(4);
            return readInt();
          }

          public int getVBClassVirtualBaseClassType() {
            typeSeek(8);
            return readInt();
          }

          public int getVBClassVBPOff() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(12);
          }

          public int getVBClassVBOff() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(12 + numericLeafLengthAt(12));
          }

          ///////////////////////////
          // LF_IVBCLASS accessors //
          ///////////////////////////

          public short getIVBClassAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getIVBClassBType() {
            typeSeek(4);
            return readInt();
          }

          public int getIVBClassVBPType() {
            typeSeek(8);
            return readInt();
          }

          public int getIVBClassVBPOff() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(12);
          }

          public int getIVBClassVBOff() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(12 + numericLeafLengthAt(12));
          }

          ////////////////////////////
          // LF_ENUMERATE accessors //
          ////////////////////////////

          public short getEnumerateAttribute() {
            typeSeek(2);
            return readShort();
          }

          public long getEnumerateValue() {
            return readIntNumericLeafAt(4);
          }

          public String getEnumerateName() {
            return readLengthPrefixedStringAt(4 + numericLeafLengthAt(4));
          }

          ////////////////////////////
          // LF_FRIENDFCN accessors //
          ////////////////////////////

          public int getFriendFcnType() {
            typeSeek(4);
            return readInt();
          }

          public String getFriendFcnName() {
            return readLengthPrefixedStringAt(8);
          }

          ////////////////////////
          // LF_INDEX accessors //
          ////////////////////////

          public int getIndexValue() {
            typeSeek(4);
            return readInt();
          }

          public DebugVC50TypeIterator getIndexIterator() {
            int index = unbiasTypeIndex(getIndexValue());
            int offset = parent.getTypeOffset(index);
            return new DebugVC50TypeIteratorImpl(parent, base, numTypes, index, offset);
          }

          /////////////////////////
          // LF_MEMBER accessors //
          /////////////////////////

          public short getMemberAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getMemberType() {
            typeSeek(4);
            return readInt();
          }

          public int getMemberOffset() throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(8);
          }

          public String getMemberName() {
            return readLengthPrefixedStringAt(8 + numericLeafLengthAt(8));
          }

          ///////////////////////////
          // LF_STMEMBER accessors //
          ///////////////////////////

          public short getStaticAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getStaticType() {
            typeSeek(4);
            return readInt();
          }

          public String getStaticName() {
            return readLengthPrefixedStringAt(8);
          }

          /////////////////////////
          // LF_METHOD accessors //
          /////////////////////////

          public short getMethodCount() {
            typeSeek(2);
            return readShort();
          }

          public int getMethodList() {
            typeSeek(4);
            return readInt();
          }

          public String getMethodName() {
            return readLengthPrefixedStringAt(8);
          }

          /////////////////////////////
          // LF_NESTEDTYPE accessors //
          /////////////////////////////

          public int getNestedType() {
            typeSeek(4);
            return readInt();
          }

          public String getNestedName() {
            return readLengthPrefixedStringAt(8);
          }

          ///////////////////////////
          // LF_VFUNCTAB accessors //
          ///////////////////////////

          public int getVFuncTabType() {
            typeSeek(4);
            return readInt();
          }

          ////////////////////////////
          // LF_FRIENDCLS accessors //
          ////////////////////////////

          public int getFriendClsType() {
            typeSeek(4);
            return readInt();
          }

          ////////////////////////////
          // LF_ONEMETHOD accessors //
          ////////////////////////////

          public short getOneMethodAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getOneMethodType() {
            typeSeek(4);
            return readInt();
          }

          public boolean isOneMethodIntroducingVirtual() {
            return isIntroducingVirtual(getOneMethodAttribute());
          }

          public int getOneMethodVBaseOff() {
            typeSeek(8);
            return readInt();
          }

          public String getOneMethodName() {
            int baseLen = 8 + (isOneMethodIntroducingVirtual() ? 4 : 0);
            return readLengthPrefixedStringAt(baseLen);
          }

          ///////////////////////////
          // LF_VFUNCOFF accessors //
          ///////////////////////////

          public int getVFuncOffType() {
            typeSeek(4);
            return readInt();
          }

          public int getVFuncOffOffset() {
            typeSeek(8);
            return readInt();
          }

          ///////////////////////////////
          // LF_NESTEDTYPEEX accessors //
          ///////////////////////////////

          public short getNestedExAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getNestedExType() {
            typeSeek(4);
            return readInt();
          }

          public String getNestedExName() {
            return readLengthPrefixedStringAt(8);
          }

          ///////////////////////////////
          // LF_MEMBERMODIFY accessors //
          ///////////////////////////////

          public short getMemberModifyAttribute() {
            typeSeek(2);
            return readShort();
          }

          public int getMemberModifyType() {
            typeSeek(4);
            return readInt();
          }

          public String getMemberModifyName() {
            return readLengthPrefixedStringAt(8);
          }

          ////////////////////////////
          // Numeric Leaf accessors //
          ////////////////////////////

          public short getNumericTypeAt(int byteOffset) {
            typeSeek(byteOffset);
            return readShort();
          }

          public int getNumericLengthAt(int byteOffset)
            throws DebugVC50WrongNumericTypeException {
            return numericLeafLengthAt(byteOffset);
          }

          public int getNumericIntAt(int byteOffset)
            throws DebugVC50WrongNumericTypeException {
            return readIntNumericLeafAt(byteOffset);
          }

          public long getNumericLongAt(int byteOffset)
            throws DebugVC50WrongNumericTypeException {
            // FIXME
            throw new RuntimeException("Unimplemented");
          }

          public float getNumericFloatAt(int byteOffset)
            throws DebugVC50WrongNumericTypeException {
            // FIXME
            throw new RuntimeException("Unimplemented");
          }

          public double getNumericDoubleAt(int byteOffset)
            throws DebugVC50WrongNumericTypeException {
            // FIXME
            throw new RuntimeException("Unimplemented");
          }

          public byte[] getNumericDataAt(int byteOffset)
            throws DebugVC50WrongNumericTypeException {
            // FIXME
            throw new RuntimeException("Unimplemented");
          }

          //----------------------------------------------------------------------
          // Internals only below this point
          //

          private void loadTypeRecord() {
            seek(typeRecordOffset);
            typeRecordSize = readShort() & 0xFFFF;
            typeStringOffset = typeRecordOffset + 2;
            loadTypeString();
          }

          private void loadTypeString() {
            seek(typeStringOffset);
            int lo = readByte() & 0xFF;
            // See if it is one of the single-byte leaves
            if (lo >= LF_PAD0) {
              typeStringLeaf = lo;
            } else {
              int hi = readByte() & 0xFF;
              typeStringLeaf = (hi << 8) | lo;
            }
          }

          private void typeSeek(int offset) {
            seek(typeStringOffset + offset);
          }

          private int typeStringLength() {
            // LF_PAD
            if (typeStringLeaf >= 0xF0 && typeStringLeaf <= 0xFF) {
              return (typeStringLeaf - 0xF0);
            }

            switch (typeStringLeaf) {

              // Leaf indices for type records that can be referenced
              // from symbols:
            case LF_MODIFIER: return 8;
            case LF_POINTER: {
              int extraLen = 0;
              int attr = (getPointerAttributes() & POINTER_PTRTYPE_MASK) >> POINTER_PTRTYPE_SHIFT;
              int mode = (getPointerAttributes() & POINTER_PTRMODE_MASK) >> POINTER_PTRMODE_SHIFT;
              if (attr == POINTER_PTRTYPE_BASED_ON_TYPE) {
                extraLen = 4 + numericLeafLengthAt(typeStringOffset + 14);
              } else if (mode == POINTER_PTRMODE_PTR_TO_DATA_MEMBER ||
                         mode == POINTER_PTRMODE_PTR_TO_METHOD) {
                extraLen = 6;
              }
              return 10 + extraLen;
            }
            case LF_ARRAY: {
              int temp = 10 + numericLeafLengthAt(10);
              return temp + lengthPrefixedStringLengthAt(temp);
            }
            case LF_CLASS:
            case LF_STRUCTURE: {
              int temp = 18 + numericLeafLengthAt(18);
              return temp + lengthPrefixedStringLengthAt(temp);
            }
            case LF_UNION: {
              int temp = 10 + numericLeafLengthAt(10);
              return temp + lengthPrefixedStringLengthAt(temp);
            }
            case LF_ENUM: {
              return 14 + lengthPrefixedStringLengthAt(14);
            }
            case LF_PROCEDURE: return 14;
            case LF_MFUNCTION: return 26;
            case LF_VTSHAPE:   return 4 + ((getVTShapeCount() + 1) / 2);
            case LF_COBOL0:
            case LF_COBOL1:    throw new COFFException("COBOL symbols unimplemented");
            case LF_BARRAY:    return 6;
            case LF_LABEL:     return 4;
            case LF_NULL:      return 2;
            case LF_NOTTRAN:   return 2;
            case LF_DIMARRAY:  return 10 + lengthPrefixedStringLengthAt(10);
            case LF_VFTPATH:   return 6 + 4 * getVFTPathCount();
            case LF_PRECOMP:   return 14 + lengthPrefixedStringLengthAt(14);
            case LF_ENDPRECOMP: return 6;
            case LF_OEM:       throw new COFFException("OEM symbols unimplemented");
            case LF_TYPESERVER: return 10 + lengthPrefixedStringLengthAt(10);

            case LF_SKIP:      return 6 + numericLeafLengthAt(6);
            case LF_ARGLIST:   return 6 + 4 * getArgListCount();
            case LF_DEFARG:    return 6 + lengthPrefixedStringLengthAt(6);
              // case LF_FIELDLIST: throw new COFFException("Should not see LF_FIELDLIST leaf");
            case LF_FIELDLIST: return 2;
            case LF_DERIVED:   return 6 + 4 * getDerivedCount();
            case LF_BITFIELD:  return 8;
            case LF_METHODLIST: {
              return 6 + 4 * getMListLength() + (isMListIntroducingVirtual() ? 4 : 0);
            }
            case LF_DIMCONU:
            case LF_DIMCONLU:
            case LF_DIMVARU:
            case LF_DIMVARLU:  throw new COFFException("LF_DIMCONU, LF_DIMCONLU, LF_DIMVARU, and LF_DIMVARLU unsupported");
            case LF_REFSYM: {
              seek(typeStringOffset + 2);
              return 4 + readShort();
            }

            case LF_BCLASS:  return 8 + numericLeafLengthAt(8);
            case LF_VBCLASS:
            case LF_IVBCLASS: {
              int temp = 12 + numericLeafLengthAt(12);
              return temp + numericLeafLengthAt(temp);
            }
            case LF_ENUMERATE: {
              int temp = 4 + numericLeafLengthAt(4);
              return temp + lengthPrefixedStringLengthAt(temp);
            }
            case LF_FRIENDFCN: return 8 + lengthPrefixedStringLengthAt(8);
            case LF_INDEX: return 8;
            case LF_MEMBER: {
              int temp = 8 + numericLeafLengthAt(8);
              return temp + lengthPrefixedStringLengthAt(temp);
            }
            case LF_STMEMBER: return 8 + lengthPrefixedStringLengthAt(8);
            case LF_METHOD:   return 8 + lengthPrefixedStringLengthAt(8);
            case LF_NESTTYPE: return 8 + lengthPrefixedStringLengthAt(8);
            case LF_VFUNCTAB: return 8;
            case LF_FRIENDCLS: return 8;
            case LF_ONEMETHOD: {
              int baseLen = 8 + (isOneMethodIntroducingVirtual() ? 4 : 0);
              return baseLen + lengthPrefixedStringLengthAt(baseLen);
            }
            case LF_VFUNCOFF:  return 12;
            case LF_NESTTYPEEX: return 8 + lengthPrefixedStringLengthAt(8);
            case LF_MEMBERMODIFY: return 8 + lengthPrefixedStringLengthAt(8);

            // Should not encounter numeric leaves with this routine
            case LF_CHAR:
            case LF_SHORT:
            case LF_USHORT:
            case LF_LONG:
            case LF_ULONG:
            case LF_REAL32:
            case LF_REAL64:
            case LF_REAL80:
            case LF_REAL128:
            case LF_QUADWORD:
            case LF_UQUADWORD:
            case LF_REAL48:
            case LF_COMPLEX32:
            case LF_COMPLEX64:
            case LF_COMPLEX80:
            case LF_COMPLEX128:
            case LF_VARSTRING:  throw new RuntimeException("Unexpected numeric leaf " + typeStringLeaf +
                                                           "in type string");
            default:
              throw new COFFException("Unrecognized leaf " + typeStringLeaf + " in type string at offset " +
                                      typeStringOffset);
            }
          }

          private boolean isIntroducingVirtual(int mprop) {
            int masked = mprop & MEMATTR_MPROP_MASK;
            return ((masked == MEMATTR_MPROP_INTRODUCING_VIRTUAL) ||
                    (masked == MEMATTR_MPROP_PURE_INTRODUCING_VIRTUAL));
          }

          private int numericLeafLengthAt(int offset) {
            return DebugVC50Impl.this.numericLeafLengthAt(typeStringOffset + offset);
          }

          private int readIntNumericLeafAt(int offset) {
            return DebugVC50Impl.this.readIntNumericLeafAt(typeStringOffset + offset);
          }

          private int lengthPrefixedStringLengthAt(int offset) {
            return DebugVC50Impl.this.lengthPrefixedStringLengthAt(typeStringOffset + offset);
          }

          private String readLengthPrefixedStringAt(int offset) {
            return DebugVC50Impl.this.readLengthPrefixedStringAt(typeStringOffset + offset);
          }
        }

        private int numericLeafLengthAt(int absoluteOffset) throws DebugVC50WrongNumericTypeException {
          seek(absoluteOffset);
          int leaf = readShort() & 0xFFFF;
          if (leaf < 0x8000) return 2;
          switch (leaf) {
          case LF_CHAR:       return 3;
          case LF_SHORT:
          case LF_USHORT:     return 4;
          case LF_LONG:
          case LF_ULONG:      return 6;
          case LF_REAL32:     return 6;
          case LF_REAL64:     return 10;
          case LF_REAL80:     return 12;
          case LF_REAL128:    return 18;
          case LF_QUADWORD:
          case LF_UQUADWORD:  return 18;
          case LF_REAL48:     return 8;
          case LF_COMPLEX32:  return 10;
          case LF_COMPLEX64:  return 18;
          case LF_COMPLEX80:  return 26;
          case LF_COMPLEX128: return 66;
            // FIXME: figure out format of variable-length strings
          case LF_VARSTRING:  return 4 + readIntNumericLeafAt(absoluteOffset + 2);

          default:
            throw new DebugVC50WrongNumericTypeException("Illegal numeric leaf index " + leaf +
                                                         " at offset " + absoluteOffset);
          }
        }

        private int readIntNumericLeafAt(int absoluteOffset) throws DebugVC50WrongNumericTypeException {
          seek(absoluteOffset);
          int leaf = readShort() & 0xFFFF;
          if (leaf < 0x8000) return leaf;
          switch (leaf) {
          case LF_CHAR:       return readByte() & 0xFF;
          case LF_SHORT:
          case LF_USHORT:     return readShort() & 0xFFFF;
          case LF_LONG:
          case LF_ULONG:      return readInt();

          default:
            throw new DebugVC50WrongNumericTypeException("Illegal numeric leaf index " + leaf);
          }
        }

        private long readLongNumericLeafAt(int absoluteOffset) throws DebugVC50WrongNumericTypeException {
          seek(absoluteOffset);
          int leaf = readShort() & 0xFFFF;
          if (leaf < 0x8000) return leaf;
          switch (leaf) {
          case LF_CHAR:       return readByte() & 0xFF;
          case LF_SHORT:
          case LF_USHORT:     return readShort() & 0xFFFF;
          case LF_LONG:
          case LF_ULONG:      return readInt() & 0xFFFFFFFF;
          case LF_QUADWORD:
          case LF_UQUADWORD:  return readLong();

          default:
            throw new DebugVC50WrongNumericTypeException("Illegal numeric leaf index " + leaf);
          }
        }

        private float readFloatNumericLeafAt(int absoluteOffset) throws DebugVC50WrongNumericTypeException {
          seek(absoluteOffset);
          int leaf = readShort() & 0xFFFF;
          if (leaf != LF_REAL32) {
            throw new DebugVC50WrongNumericTypeException("Illegal numeric leaf index " + leaf);
          }
          return readFloat();
        }

        private double readDoubleNumericLeafAt(int absoluteOffset) throws DebugVC50WrongNumericTypeException {
          seek(absoluteOffset);
          int leaf = readShort() & 0xFFFF;
          if (leaf != LF_REAL64) {
            throw new DebugVC50WrongNumericTypeException("Illegal numeric leaf index " + leaf);
          }
          return readDouble();
        }

        private int lengthPrefixedStringLengthAt(int absoluteOffset) {
          // NOTE: the format of length-prefixed strings is not well
          // specified. There is a LF_VARSTRING numeric leaf (the
          // format of which is also not specified), but it seems that
          // most length-prefixed strings are comprised of a single
          // byte length followed by that many bytes of data.
          seek(absoluteOffset);
          int len = readByte() & 0xFF;
          return 1 + len;
        }

        private String readLengthPrefixedStringAt(int absoluteOffset) {
          // NOTE: it isn't clear whether LF_VARSTRING numeric leaves
          // ever show up, or in general what happens when the length
          // of the string is > 255 (FIXME)
          seek(absoluteOffset);
          int len = readByte() & 0xFF;
          byte[] res = new byte[len];
          int numRead = readBytes(res);
          if (numRead != len) {
            throw new COFFException("Error reading length prefixed string in symbol at offset " +
                                    absoluteOffset);
          }
          try {
            return new String(res, US_ASCII);
          } catch (UnsupportedEncodingException e) {
            throw new COFFException(e);
          }
        }

        private int unbiasTypeIndex(int index) {
          return index - 0x1000;
        }

        private int biasTypeIndex(int index) {
          return index + 0x1000;
        }
      } // Class DebugVC50Impl

      class SectionHeaderImpl implements SectionHeader {
        private String name;
        private int    virtualSize;
        private int    virtualAddress;
        private int    sizeOfRawData;
        private int    pointerToRawData;
        private int    pointerToRelocations;
        private int    pointerToLineNumbers;
        private short  numberOfRelocations;
        private short  numberOfLineNumbers;
        private int    characteristics;
        private MemoizedObject[] relocations;
        private MemoizedObject[] lineNumbers;

        public SectionHeaderImpl(int offset) throws COFFException {
          seek(offset);

          // FIXME: compute name lazily

          // Read name
          byte[] tmpName = new byte[8];
          int numRead = readBytes(tmpName);
          if (numRead != 8) {
            throw new COFFException("Error reading name of section header at offset " + offset);
          }
          if (tmpName[0] == (byte) '/') {
            // Long name; must find real value in string table
            int index = 0;
            try {
              index = Integer.parseInt(new String(tmpName, 1, tmpName.length - 1, US_ASCII));
            } catch (NumberFormatException e) {
              throw new COFFException("Error parsing string table index of name of section header " +
                                      "at offset " + offset);
            } catch (UnsupportedEncodingException e) {
              throw new COFFException(e);
            }
            // Look up in string table
            // FIXME: this index value is assumed to be in the valid range
            name = getStringTable().get(index);
          } else {
            try {
              int length = 0;
              // find last non-NULL
              for (; length < tmpName.length && tmpName[length] != '\0';) {
                length++;
              }
              // don't include NULL chars in returned name String
              name = new String(tmpName, 0, length, US_ASCII);
            } catch (UnsupportedEncodingException e) {
              throw new COFFException(e);
            }
          }
          virtualSize          = readInt();
          virtualAddress       = readInt();
          sizeOfRawData        = readInt();
          pointerToRawData     = readInt();
          pointerToRelocations = readInt();
          pointerToLineNumbers = readInt();
          numberOfRelocations  = readShort();
          numberOfLineNumbers  = readShort();
          characteristics      = readInt();

          // Set up relocations
          relocations = new MemoizedObject[numberOfRelocations];
          for (int i = 0; i < numberOfRelocations; i++) {
            final int relocOffset = pointerToRelocations + i * RELOCATION_SIZE;
            relocations[i] = new MemoizedObject() {
                public Object computeValue() {
                  return new COFFRelocationImpl(relocOffset);
                }
              };
          }

          // Set up line numbers
          lineNumbers = new MemoizedObject[numberOfLineNumbers];
          for (int i = 0; i < numberOfLineNumbers; i++) {
            final int lineNoOffset = pointerToLineNumbers + i * LINE_NUMBER_SIZE;
            lineNumbers[i] = new MemoizedObject() {
                public Object computeValue() {
                  return new COFFLineNumberImpl(lineNoOffset);
                }
              };
          }
        }

        public String getName() { return name; }
        public int getSize() { return virtualSize; }
        public int getVirtualAddress() { return virtualAddress; }
        public int getSizeOfRawData() { return sizeOfRawData; }
        public int getPointerToRawData() { return pointerToRawData; }
        public int getPointerToRelocations() { return pointerToRelocations; }
        public int getPointerToLineNumbers() { return pointerToLineNumbers; }
        public short getNumberOfRelocations() { return numberOfRelocations; }
        public short getNumberOfLineNumbers() { return numberOfLineNumbers; }
        public int getSectionFlags() { return characteristics; }
        public boolean hasSectionFlag(int flag ) {
          return ((characteristics & flag) != 0);
        }
        public COFFRelocation getCOFFRelocation(int index) {
          return (COFFRelocation) relocations[index].getValue();
        }
        public COFFLineNumber getCOFFLineNumber(int index) {
          return (COFFLineNumber) lineNumbers[index];
        }
      }

      class COFFSymbolImpl implements COFFSymbol, COFFSymbolConstants {
        private int    offset;
        private String name;
        private int    value;
        private short  sectionNumber;
        private short  type;
        private byte   storageClass;
        private byte   numberOfAuxSymbols;
        private MemoizedObject auxFunctionDefinitionRecord = new MemoizedObject() {
            public Object computeValue() {
              return new AuxFunctionDefinitionRecordImpl(offset + SYMBOL_SIZE);
            }
          };
        private MemoizedObject auxBfEfRecord = new MemoizedObject() {
            public Object computeValue() {
              return new AuxBfEfRecordImpl(offset + SYMBOL_SIZE);
            }
          };
        private MemoizedObject auxWeakExternalRecord = new MemoizedObject() {
            public Object computeValue() {
              return new AuxWeakExternalRecordImpl(offset + SYMBOL_SIZE);
            }
          };
        private MemoizedObject auxFileRecord = new MemoizedObject() {
            public Object computeValue() {
              return new AuxFileRecordImpl(offset + SYMBOL_SIZE);
            }
          };
        private MemoizedObject auxSectionDefinitionsRecord = new MemoizedObject() {
            public Object computeValue() {
              return new AuxSectionDefinitionsRecordImpl(offset + SYMBOL_SIZE);
            }
          };

        public COFFSymbolImpl(int offset) throws COFFException {
          this.offset = offset;
          seek(offset);

          // Parse name
          byte[] tmpName = new byte[8];
          int numRead = readBytes(tmpName);
          if (numRead != 8) {
            throw new COFFException("Error reading name of symbol at offset " + offset);
          }
          if ((tmpName[0] == 0) &&
              (tmpName[1] == 0) &&
              (tmpName[2] == 0) &&
              (tmpName[3] == 0)) {
            // It's an offset into the string table.
            // FIXME: not sure about byte ordering...
            int stringOffset = (tmpName[4] << 24 |
                                tmpName[5] << 16 |
                                tmpName[6] <<  8 |
                                tmpName[7]);
            // FIXME: stringOffset is assumed to be in the valid range
            name = getStringTable().getAtOffset(stringOffset);
          }

          value = readInt();
          sectionNumber = readShort();
          type = readShort();
          storageClass = readByte();
          numberOfAuxSymbols = readByte();
        }

        public int getOffset()              { return offset; }
        public String getName()             { return name; }
        public int getValue()               { return value; }
        public short getSectionNumber()     { return sectionNumber; }
        public short getType()              { return type; }
        public byte getStorageClass()       { return storageClass; }
        public byte getNumberOfAuxSymbols() { return numberOfAuxSymbols; }
        public boolean isFunctionDefinition() {
          return ((getStorageClass() == IMAGE_SYM_CLASS_EXTERNAL) &&
                  ((getType() >>> 8) == IMAGE_SYM_DTYPE_FUNCTION) &&
                  (getSectionNumber() > 0));
        }
        public AuxFunctionDefinitionRecord getAuxFunctionDefinitionRecord() {
          return (AuxFunctionDefinitionRecord) auxFunctionDefinitionRecord.getValue();
        }
        public boolean isBfOrEfSymbol() {
          return ((getName().equals(".bf") || getName().equals(".ef")) &&
                  (getStorageClass() == IMAGE_SYM_CLASS_FUNCTION));
        }
        public AuxBfEfRecord getAuxBfEfRecord() {
          return (AuxBfEfRecord) auxBfEfRecord.getValue();
        }
        public boolean isWeakExternal() {
          return ((getStorageClass() == IMAGE_SYM_CLASS_EXTERNAL) &&
                  (getSectionNumber() == IMAGE_SYM_UNDEFINED) &&
                  (getValue() == 0));
        }
        public AuxWeakExternalRecord getAuxWeakExternalRecord() {
          return (AuxWeakExternalRecord) auxWeakExternalRecord.getValue();
        }
        public boolean isFile() {
          return ((getName().equals(".file")) &&
                  (getStorageClass() == IMAGE_SYM_CLASS_FILE));
        }
        public AuxFileRecord getAuxFileRecord() {
          return (AuxFileRecord) auxFileRecord.getValue();
        }
        public boolean isSectionDefinition() {
          // FIXME: not sure how to ensure that symbol name is the
          // name of a section.
          return ((getName().charAt(0) == '.') &&
                  (getStorageClass() == IMAGE_SYM_CLASS_STATIC));
        }
        public AuxSectionDefinitionsRecord getAuxSectionDefinitionsRecord() {
          return (AuxSectionDefinitionsRecord) auxSectionDefinitionsRecord.getValue();
        }
      }

      class AuxFunctionDefinitionRecordImpl implements AuxFunctionDefinitionRecord {
        private int tagIndex;
        private int totalSize;
        private int pointerToLineNumber;
        private int pointerToNextFunction;

        AuxFunctionDefinitionRecordImpl(int offset) {
          seek(offset);
          tagIndex              = readInt();
          totalSize             = readInt();
          // NOTE zero-basing of this index
          pointerToLineNumber   = readInt() - 1;
          pointerToNextFunction = readInt();
        }

        public int getTagIndex()              { return tagIndex; }
        public int getTotalSize()             { return totalSize; }
        public int getPointerToLineNumber()   { return pointerToLineNumber; }
        public int getPointerToNextFunction() { return pointerToNextFunction; }
        public int getType()                  { return FUNCTION_DEFINITION; }
      }

      class AuxBfEfRecordImpl implements AuxBfEfRecord {
        private short lineNumber;
        private int   pointerToNextFunction;

        AuxBfEfRecordImpl(int offset) {
          seek(offset);
          readInt();
          lineNumber = readShort();
          readInt();
          readShort();
          pointerToNextFunction = readInt();
        }

        public short getLineNumber()          { return lineNumber; }
        public int getPointerToNextFunction() { return pointerToNextFunction; }
        public int getType()                  { return BF_EF_RECORD; }
      }

      class AuxWeakExternalRecordImpl implements AuxWeakExternalRecord {
        private int tagIndex;
        private int characteristics;

        AuxWeakExternalRecordImpl(int offset) {
          seek(offset);
          tagIndex = readInt();
          characteristics = readInt();
        }

        public int getTagIndex()        { return tagIndex; }
        public int getCharacteristics() { return characteristics; }
        public int getType()            { return WEAK_EXTERNAL; }
      }

      class AuxFileRecordImpl implements AuxFileRecord {
        private String name;

        AuxFileRecordImpl(int offset) {
          seek(offset);
          byte[] tmpName = new byte[18];
          int numRead = readBytes(tmpName);
          if (numRead != 18) {
            throw new COFFException("Error reading auxiliary file record at offset " + offset);
          }
          try {
            name = new String(tmpName, US_ASCII);
          } catch (UnsupportedEncodingException e) {
            throw new COFFException(e);
          }
        }

        public String getName() { return name; }
        public int getType()    { return FILE; }
      }

      class AuxSectionDefinitionsRecordImpl implements AuxSectionDefinitionsRecord {
        private int length;
        private short numberOfRelocations;
        private short numberOfLineNumbers;
        private int checkSum;
        private short number;
        private byte selection;

        AuxSectionDefinitionsRecordImpl(int offset) {
          seek(offset);
          length = readInt();
          numberOfRelocations = readShort();
          numberOfLineNumbers = readShort();
          checkSum = readInt();
          number = readShort();
          selection = readByte();
        }

        public int   getLength()              { return length; }
        public short getNumberOfRelocations() { return numberOfRelocations; }
        public short getNumberOfLineNumbers() { return numberOfLineNumbers; }
        public int   getCheckSum()            { return checkSum; }
        public short getNumber()              { return number; }
        public byte  getSelection()           { return selection; }
        public int getType()                  { return SECTION_DEFINITION; }
      }

      class COFFRelocationImpl implements COFFRelocation {
        private int virtualAddress;
        private int symbolTableIndex;
        private short type;

        COFFRelocationImpl(int offset) {
          seek(offset);
          virtualAddress   = readInt();
          symbolTableIndex = readInt();
          type             = readShort();
        }

        public int   getVirtualAddress()     { return virtualAddress; }
        public int   getSymbolTableIndex()   { return symbolTableIndex; }
        public short getType()               { return type; }
      }

      class COFFLineNumberImpl implements COFFLineNumber {
        private int   type;
        private short lineNumber;

        COFFLineNumberImpl(int offset) {
          seek(offset);
          type       = readInt();
          lineNumber = readShort();
        }

        public int getType() {
          return type;
        }

        public short getLineNumber() {
          return lineNumber;
        }
      }

      class StringTable {
        class COFFString {
          String str;
          int    offset;

          COFFString(String str, int offset) {
            this.str = str; this.offset = offset;
          }
        }

        COFFString[] strings;

        StringTable(int offset) {
          if (offset == 0) {
            // no String Table
            strings = new COFFString[0];
            return;
          }

          seek(offset);
          int length = readInt();  // length includes itself
          byte[] data = new byte[length - 4];
          int numBytesRead = readBytes(data);
          if (numBytesRead != data.length) {
            throw new COFFException("Error reading string table (read " +
                                    numBytesRead + " bytes, expected to read " + data.length + ")");
          }
          int numStrings = 0;
          int ptr = 0;
          for (ptr = 0; ptr < data.length; ptr++) {
            if (data[ptr] == 0) {
              numStrings++;
            }
          }
          strings = new COFFString[numStrings];
          int lastPtr = 0;
          ptr = 0;
          for (int i = 0; i < numStrings; i++) {
            while (data[ptr] != 0) {
              ptr++;
            }
            try {
              strings[i] = new COFFString(new String(data, lastPtr, ptr - lastPtr, US_ASCII),
                                          offset + ptr + 4);
            } catch (UnsupportedEncodingException e) {
              throw new COFFException(e);
            }
            ptr++;
            lastPtr = ptr;
          }
        }

        int getNum() {
          return strings.length;
        }

        String get(int i) {
          return strings[i].str;
        }

        /** This version takes an absolute offset in the file */
        String getAtOffset(int offset) {
          int i = Arrays.binarySearch(strings, new COFFString(null, offset),
                                      new Comparator() {
                                          public int compare(Object o1, Object o2) {
                                            COFFString s1 = (COFFString) o1;
                                            COFFString s2 = (COFFString) o2;
                                            if (s1.offset == s2.offset) {
                                              return 0;
                                            } else if (s1.offset < s2.offset) {
                                              return -1;
                                            } else {
                                              return 1;
                                            }
                                          }
                                        });
          if (i < 0) {
            throw new COFFException("No string found at file offset " + offset);
          }
          return strings[i].str;
        }
      }
    }

    void initialize() throws COFFException {
      // Figure out whether this file is an object file or an image
      // (either executable or DLL).
      seek(0x3c); // Error here probably indicates file format error
      try {
        int peOffset = readInt();
        seek(peOffset);
        if ((readByte() == (byte) 'P') &&
            (readByte() == (byte) 'E') &&
            (readByte() == (byte) 0) &&
            (readByte() == (byte) 0)) {
          isImage = true;
          imageHeaderOffset = getFilePointer();
        }
      }
      catch (COFFException e) {
        // Expect failures here if not image file.
      }
    }

    byte readByteAt(long offset) throws COFFException {
      seek(offset);
      return readByte();
    }

    byte readByte() throws COFFException {
      try {
        return file.readByte();
      } catch (IOException e) {
        throw new COFFException(e.toString() + " at offset 0x" +
                                Long.toHexString(filePos), e);
      }
    }

    int readBytesAt(long offset, byte[] b) throws COFFException {
      seek(offset);
      return readBytes(b);
    }

    int readBytes(byte[] b) throws COFFException {
      try {
        return file.read(b);
      } catch (IOException e) {
        throw new COFFException(e.toString() + " at offset 0x" +
                                Long.toHexString(filePos), e);
      }
    }

    /** NOTE: reads little-endian short */
    short readShortAt(long offset) throws COFFException {
      seek(offset);
      return readShort();
    }

    /** NOTE: reads little-endian short */
    short readShort() throws COFFException {
      try {
        return byteSwap(file.readShort());
      } catch (IOException e) {
        throw new COFFException(e.toString() + " at offset 0x" +
                                Long.toHexString(filePos), e);
      }
    }

    /** NOTE: reads little-endian int */
    int readIntAt(long offset) throws COFFException {
      seek(offset);
      return readInt();
    }

    /** NOTE: reads little-endian int */
    int readInt() throws COFFException {
      try {
        return byteSwap(file.readInt());
      } catch (IOException e) {
        throw new COFFException(e.toString() + " at offset 0x" +
                                Long.toHexString(filePos), e);
      }
    }

    /** NOTE: reads little-endian long */
    long readLongAt(long offset) throws COFFException {
      seek(offset);
      return readLong();
    }

    /** NOTE: reads little-endian long */
    long readLong() throws COFFException {
      try {
        return byteSwap(file.readLong());
      } catch (IOException e) {
        throw new COFFException(e.toString() + " at offset 0x" +
                                Long.toHexString(filePos), e);
      }
    }

    /** NOTE: reads little-endian float */
    float readFloat() throws COFFException {
      int i = readInt();
      return Float.intBitsToFloat(i);
    }

    /** NOTE: reads little-endian double */
    double readDouble() throws COFFException {
      long l = readLong();
      return Double.longBitsToDouble(l);
    }

    String readCString() throws COFFException {
      List data = new ArrayList();
      byte b = 0;
      while ((b = readByte()) != 0) {
        data.add(new Byte(b));
      }
      byte[] bytes = new byte[data.size()];
      for (int i = 0; i < data.size(); i++) {
        bytes[i] = ((Byte) data.get(i)).byteValue();
      }
      try {
        return new String(bytes, US_ASCII);
      } catch (UnsupportedEncodingException e) {
        throw new COFFException(e);
      }
    }

    void seek(long offset) throws COFFException {
      try {
        filePos = offset;
        file.seek(offset);
      } catch (IOException e) {
        throw new COFFException(e.toString() + " at offset 0x" +
                                Long.toHexString(offset), e);
      }
    }

    long getFilePointer() throws COFFException {
      try {
        return file.getFilePointer();
      } catch (IOException e) {
        throw new COFFException(e);
      }
    }

    short byteSwap(short arg) {
      return (short) ((arg << 8) | ((arg >>> 8) & 0xFF));
    }

    int byteSwap(int arg) {
      return (((int) byteSwap((short) arg)) << 16) | (((int) (byteSwap((short) (arg >>> 16)))) & 0xFFFF);
    }

    long byteSwap(long arg) {
      return ((((long) byteSwap((int) arg)) << 32) | (((long) byteSwap((int) (arg >>> 32))) & 0xFFFFFFFF));
    }

    public void close() throws COFFException {
      try {
        file.close();
      } catch (IOException e) {
        throw new COFFException(e);
      }
    }
  }
}
