agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2000, 2004, 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. --- 1,7 ---- /* ! * 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.
*** 120,133 **** --- 120,137 ---- 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()); } }
*** 138,147 **** --- 142,153 ---- 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];
*** 220,229 **** --- 226,237 ---- 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;
*** 286,296 **** private int sizeOfCode; private int sizeOfInitializedData; private int sizeOfUninitializedData; private int addressOfEntryPoint; private int baseOfCode; ! private int baseOfData; OptionalHeaderStandardFieldsImpl(int offset, boolean isPE32Plus) { this.isPE32Plus = isPE32Plus; seek(offset); --- 294,304 ---- 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);
*** 299,309 **** sizeOfCode = readInt(); sizeOfInitializedData = readInt(); sizeOfUninitializedData = readInt(); addressOfEntryPoint = readInt(); baseOfCode = readInt(); ! if (isPE32Plus) { baseOfData = readInt(); } } public byte getMajorLinkerVersion() { return majorLinkerVersion; } --- 307,318 ---- sizeOfCode = readInt(); sizeOfInitializedData = readInt(); sizeOfUninitializedData = readInt(); addressOfEntryPoint = readInt(); baseOfCode = readInt(); ! if (!isPE32Plus) { ! // only available in PE32 baseOfData = readInt(); } } public byte getMajorLinkerVersion() { return majorLinkerVersion; }
*** 431,441 **** public Object computeValue() { DataDirectory dir = getExportTable(); if (dir.getRVA() == 0 || dir.getSize() == 0) { return null; } ! return new ExportDirectoryTableImpl(rvaToFileOffset(dir.getRVA()), dir.getSize()); } }; debugDirectory = new MemoizedObject() { public Object computeValue() { --- 440,453 ---- 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() {
*** 524,533 **** --- 536,546 ---- 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;
*** 546,557 **** private MemoizedObject exportNameTable; private MemoizedObject exportNamePointerTable; private MemoizedObject exportOrdinalTable; private MemoizedObject exportAddressTable; ! ExportDirectoryTableImpl(int offset, int size) { ! this.offset = offset; this.size = size; seek(offset); exportFlags = readInt(); timeDateStamp = readInt(); majorVersion = readShort(); --- 559,571 ---- 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();
*** 593,602 **** --- 607,617 ---- } }; 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(); }
*** 606,623 **** exportAddressTable = new MemoizedObject() { public Object computeValue() { int[] addresses = new int[getNumberOfAddressTableEntries()]; seek(rvaToFileOffset(getExportAddressTableRVA())); ! // Must make two passes to avoid rvaToFileOffset ! // destroying seek() position for (int i = 0; i < addresses.length; i++) { addresses[i] = readInt(); } - for (int i = 0; i < addresses.length; i++) { - addresses[i] = rvaToFileOffset(addresses[i]); - } return addresses; } }; } --- 621,642 ---- 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; } }; }
*** 646,660 **** return getExportOrdinalTable()[i]; } public boolean isExportAddressForwarder(short ordinal) { int addr = getExportAddress(ordinal); ! return ((offset <= addr) && (addr < (offset + size))); } public String getExportAddressForwarder(short ordinal) { ! seek(getExportAddress(ordinal)); return readCString(); } public int getExportAddress(short ordinal) { --- 665,680 ---- 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) {
*** 3369,3382 **** "at offset " + offset); } catch (UnsupportedEncodingException e) { throw new COFFException(e); } // Look up in string table name = getStringTable().get(index); } else { try { ! name = new String(tmpName, US_ASCII); } catch (UnsupportedEncodingException e) { throw new COFFException(e); } } virtualSize = readInt(); --- 3389,3409 ---- "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();
*** 3485,3494 **** --- 3512,3522 ---- // 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();
*** 3696,3711 **** COFFString[] strings; StringTable(int offset) { if (offset == 0) { strings = new COFFString[0]; return; } seek(offset); ! int length = readInt(); 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 + ")"); --- 3724,3740 ---- 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 + ")");