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 + ")");