use of com.ibm.j9ddr.corereaders.CorruptCoreException in project openj9 by eclipse.
the class ModuleStream method buildSymbols.
/**
* Looks at the module loaded at imageBase in the given dump and produces
* a symbol table for which it returns the iterator.
* @param dump
* @param builder
* @param imageBase
* @param moduleLoadAddress
* @return
* @throws CorruptCoreException
*/
private List<ISymbol> buildSymbols(MiniDumpReader dump, IAddressSpace as, long imageBase) throws CorruptDataException, CorruptCoreException {
long moduleLoadAddress = imageBase;
byte[] magic = new byte[2];
as.getBytesAt(imageBase, magic);
String magicStr = null;
try {
magicStr = new String(magic, "ASCII");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (!magicStr.equals("MZ")) {
throw new CorruptCoreException("Invalid image magic number: \"" + magicStr + "\" @ " + Long.toHexString(imageBase));
}
// look up the PE offset: it is base+3c
int peInt = as.getIntAt(imageBase + 0x3cL);
long peBase = (peInt & 0xFFFFFFFFL) + imageBase;
// * typedef struct _IMAGE_NT_HEADERS {
// DWORD Signature;
as.getBytesAt(peBase, magic);
try {
magicStr = new String(magic, "UTF-8");
} catch (UnsupportedEncodingException e) {
// UTF-8 will be supported.
}
if (!magicStr.equals("PE")) {
throw new CorruptCoreException("Invalid PE magic number: \"" + magicStr + "\" @ " + Long.toHexString(peBase));
}
long nextRead = peBase + 4;
// IMAGE_FILE_HEADER FileHeader;
// IMAGE_OPTIONAL_HEADER32 OptionalHeader;
// cue us up to the optional header
// typedef struct _IMAGE_FILE_HEADER {
// short machine = dump.readShort(); // WORD Machine;
nextRead += 2;
// dump.readShort(); // WORD NumberOfSections;
nextRead += 2;
// dump.readInt(); // DWORD TimeDateStamp;
nextRead += 4;
// dump.readInt(); // DWORD PointerToSymbolTable;
nextRead += 4;
// dump.readInt(); // DWORD NumberOfSymbols;
nextRead += 4;
long imageOptionalHeaderSizeAddress = nextRead;
// WORD SizeOfOptionalHeader;
short optionalHeaderSize = as.getShortAt(imageOptionalHeaderSizeAddress);
nextRead += 2;
// dump.readShort(); // WORD Characteristics;
nextRead += 2;
// cue us up to the first data directory
if (224 == optionalHeaderSize) {
// 32-bit optional header
// typedef struct _IMAGE_OPTIONAL_HEADER {
short magicShort = as.getShortAt(nextRead);
if (0x10b != magicShort) {
throw new CorruptCoreException("Invalid IMAGE_OPTIONAL_HEADER magic number: \"0x" + Integer.toHexString(0xFFFF & magicShort) + "\" @ " + Long.toHexString(nextRead));
}
// dump.readBytes(2); // WORD Magic;
nextRead += 2;
// dump.readByte(); // BYTE MajorLinkerVersion;
nextRead += 1;
// dump.readByte(); // BYTE MinorLinkerVersion;
nextRead += 1;
// dump.readInt(); // DWORD SizeOfCode;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfInitializedData;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfUninitializedData;
nextRead += 4;
// dump.readInt(); // DWORD AddressOfEntryPoint;
nextRead += 4;
// dump.readInt(); // DWORD BaseOfCode;
nextRead += 4;
// dump.readInt(); // DWORD BaseOfData;
nextRead += 4;
// dump.readInt(); // DWORD ImageBase;
nextRead += 4;
// dump.readInt(); // DWORD SectionAlignment;
nextRead += 4;
// dump.readInt(); // DWORD FileAlignment;
nextRead += 4;
// dump.readShort(); // WORD MajorOperatingSystemVersion;
nextRead += 2;
// dump.readShort(); // WORD MinorOperatingSystemVersion;
nextRead += 2;
// dump.readShort(); // WORD MajorImageVersion;
nextRead += 2;
// dump.readShort(); // WORD MinorImageVersion;
nextRead += 2;
// dump.readShort(); // WORD MajorSubsystemVersion;
nextRead += 2;
// dump.readShort(); // WORD MinorSubsystemVersion;
nextRead += 2;
// dump.readInt(); // DWORD Win32VersionValue;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfImage;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfHeaders;
nextRead += 4;
// dump.readInt(); // DWORD CheckSum;
nextRead += 4;
// dump.readShort(); // WORD Subsystem;
nextRead += 2;
// dump.readShort(); // WORD DllCharacteristics;
nextRead += 2;
// dump.readInt(); // DWORD SizeOfStackReserve;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfStackCommit;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfHeapReserve;
nextRead += 4;
// dump.readInt(); // DWORD SizeOfHeapCommit;
nextRead += 4;
// dump.readInt(); // DWORD LoaderFlags;
nextRead += 4;
// dump.readInt(); // DWORD NumberOfRvaAndSizes;
nextRead += 4;
// IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
// } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
} else if (240 == optionalHeaderSize) {
// 64-bit optional header
// typedef struct _IMAGE_OPTIONAL_HEADER64 {
short magicShort = as.getShortAt(nextRead);
if (0x20b != magicShort) {
throw new CorruptCoreException("Invalid IMAGE_OPTIONAL_HEADER64 magic number: \"0x" + Integer.toHexString(0xFFFF & magicShort) + "\" @ " + Long.toHexString(nextRead));
}
// WORD Magic;
nextRead += 2;
// BYTE MajorLinkerVersion;
nextRead += 1;
// BYTE MinorLinkerVersion;
nextRead += 1;
// DWORD SizeOfCode;
nextRead += 4;
// DWORD SizeOfInitializedData;
nextRead += 4;
// DWORD SizeOfUninitializedData;
nextRead += 4;
// DWORD AddressOfEntryPoint;
nextRead += 4;
// DWORD BaseOfCode;
nextRead += 4;
// ULONGLONG ImageBase;
nextRead += 8;
// DWORD SectionAlignment;
nextRead += 4;
// DWORD FileAlignment;
nextRead += 4;
// WORD MajorOperatingSystemVersion;
nextRead += 2;
// WORD MinorOperatingSystemVersion;
nextRead += 2;
// WORD MajorImageVersion;
nextRead += 2;
// WORD MinorImageVersion;
nextRead += 2;
// WORD MajorSubsystemVersion;
nextRead += 2;
// WORD MinorSubsystemVersion;
nextRead += 2;
// DWORD Win32VersionValue;
nextRead += 4;
// DWORD SizeOfImage;
nextRead += 4;
// DWORD SizeOfHeaders;
nextRead += 4;
// DWORD CheckSum;
nextRead += 4;
// WORD Subsystem;
nextRead += 2;
// WORD DllCharacteristics;
nextRead += 2;
// ULONGLONG SizeOfStackReserve;
nextRead += 8;
// ULONGLONG SizeOfStackCommit;
nextRead += 8;
// ULONGLONG SizeOfHeapReserve;
nextRead += 8;
// ULONGLONG SizeOfHeapCommit;
nextRead += 8;
// DWORD LoaderFlags;
nextRead += 4;
// DWORD NumberOfRvaAndSizes;
nextRead += 4;
// IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
// } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
} else {
// invalid size
throw new CorruptCoreException("Invalid IMAGE_OPTIONAL_HEADER size: \"" + optionalHeaderSize + "\" bytes @ " + Long.toHexString(imageOptionalHeaderSizeAddress));
}
// we should now be at the data directory
// typedef struct _IMAGE_DATA_DIRECTORY
// note that it is this first directory which we are interested in since
// it is the export dir
// read that pointer and size and calculate where to seek to to begin work
// again
// DWORD VirtualAddress;
int exportRVA = as.getIntAt(nextRead);
nextRead += 4;
if (0 == exportRVA) {
// this module has no exports so return empty
return Collections.emptyList();
}
// int exportSize = dump.readInt(); // DWORD Size;
nextRead += 4;
nextRead = moduleLoadAddress + (exportRVA & 0xFFFFFFFFL);
// typedef struct _IMAGE_EXPORT_DIRECTORY
// dump.readInt(); // ULONG Characteristics;
nextRead += 4;
// dump.readInt(); // ULONG TimeDateStamp;
nextRead += 4;
// dump.readShort(); // USHORT MajorVersion;
nextRead += 2;
// dump.readShort(); // USHORT MinorVersion;
nextRead += 2;
// dump.readInt(); // ULONG Name;
nextRead += 4;
// dump.readInt(); // ULONG Base;
nextRead += 4;
long numberOfFunctionsAddress = nextRead;
// ULONG NumberOfFunctions;
int numberOfFunctions = as.getIntAt(numberOfFunctionsAddress);
nextRead += 4;
// ULONG NumberOfNames;
int numberOfNames = as.getIntAt(nextRead);
nextRead += 4;
// corruption
if (numberOfFunctions < numberOfNames) {
throw new CorruptCoreException("IMAGE_EXPORT_DIRECTORY NumberOfFunctions (" + numberOfFunctions + ") < NumberOfNames (" + numberOfNames + ") @ " + Long.toHexString(numberOfFunctionsAddress));
}
// Note: despite the fact that these are pointers, they appear to be 4
// bytes in both 32-bit and 64-bit binaries
// PULONG *AddressOfFunctions;
long funcAddress = (as.getIntAt(nextRead) & 0xFFFFFFFFL);
nextRead += 4;
// PULONG *AddressOfNames;
long nameAddress = (as.getIntAt(nextRead) & 0xFFFFFFFFL);
nextRead += 4;
// PUSHORT *AddressOfNameOrdinals;
long ordinalAddress = (as.getIntAt(nextRead) & 0xFFFFFFFFL);
nextRead += 4;
int[] nameAddresses = new int[numberOfNames];
nextRead = nameAddress + moduleLoadAddress;
for (int x = 0; x < numberOfNames; x++) {
nameAddresses[x] = as.getIntAt(nextRead);
nextRead += 4;
}
// the function addresses after the first numberOfNames entries are not
// addressable as symbols so this array could be made smaller if this is
// ever found to be a problem (for the near-term, however, it seems more
// correct to read them all since they should all be addressable)
long[] addresses = new long[numberOfFunctions];
nextRead = funcAddress + moduleLoadAddress;
for (int x = 0; x < numberOfFunctions; x++) {
addresses[x] = as.getIntAt(nextRead);
nextRead += 4;
}
int[] ordinals = new int[numberOfNames];
nextRead = ordinalAddress + moduleLoadAddress;
for (int x = 0; x < numberOfNames; x++) {
ordinals[x] = (0x0000FFFF & (int) as.getShortAt(nextRead));
nextRead += 2;
}
String[] names = new String[numberOfNames];
// Support symbols over 1Kb long. (We have seen some.)
byte[] buffer = new byte[2048];
for (int x = 0; x < numberOfNames; x++) {
nextRead = (nameAddresses[x] & 0xFFFFFFFFL) + moduleLoadAddress;
Arrays.fill(buffer, (byte) 0);
int index = 0;
byte thisByte = 0;
do {
thisByte = as.getByteAt(nextRead);
nextRead += 1;
buffer[index] = thisByte;
index++;
} while ((0 != thisByte) && (index < buffer.length));
try {
names[x] = new String(buffer, 0, index - 1, "UTF-8");
} catch (UnsupportedEncodingException e) {
// UTF-8 will be supported.
}
}
List<ISymbol> symbols = new ArrayList<ISymbol>(numberOfNames);
for (int x = 0; x < numberOfNames; x++) {
int index = ordinals[x];
long relocatedFunctionAddress = addresses[index] + moduleLoadAddress;
String functionName = names[x];
ISymbol symbol = new Symbol(functionName, relocatedFunctionAddress);
symbols.add(symbol);
}
return symbols;
}
use of com.ibm.j9ddr.corereaders.CorruptCoreException in project openj9 by eclipse.
the class ModuleStream method buildRuntimeFunctionList.
/* Gather the runtime function list from the loaded dll/exe.
* Possibly this should be done in the unwind package but it's
* similar to the symbol gathering above so it makes sense to
* have it here.
*/
private List<RuntimeFunction> buildRuntimeFunctionList(MiniDumpReader dump, IAddressSpace as, long imageBase) throws CorruptDataException, CorruptCoreException {
long moduleLoadAddress = imageBase;
byte[] magic = new byte[2];
as.getBytesAt(imageBase, magic);
String magicStr = null;
try {
magicStr = new String(magic, "ASCII");
} catch (UnsupportedEncodingException e) {
throw new CorruptCoreException("Unable to decode magic number");
}
if (!magicStr.equals("MZ")) {
throw new CorruptCoreException("Invalid image magic number: \"" + magicStr + "\" @ " + Long.toHexString(imageBase));
}
// look up the PE offset: it is base+3c
int peInt = as.getIntAt(imageBase + 0x3cL);
long peBase = (peInt & 0xFFFFFFFFL) + imageBase;
// * typedef struct _IMAGE_NT_HEADERS {
// DWORD Signature;
as.getBytesAt(peBase, magic);
try {
magicStr = new String(magic, "UTF-8");
} catch (UnsupportedEncodingException e) {
// UTF-8 will be supported.
}
if (!magicStr.equals("PE")) {
throw new CorruptCoreException("Invalid PE magic number: \"" + magicStr + "\" @ " + Long.toHexString(peBase));
}
long nextRead = peBase + 4;
// IMAGE_FILE_HEADER FileHeader;
// IMAGE_OPTIONAL_HEADER32 OptionalHeader;
// cue us up to the optional header
// typedef struct _IMAGE_FILE_HEADER {
// short machine = dump.readShort(); // WORD Machine;
nextRead += 2;
// dump.readShort(); // WORD NumberOfSections;
nextRead += 2;
// dump.readInt(); // DWORD TimeDateStamp;
nextRead += 4;
// dump.readInt(); // DWORD PointerToSymbolTable;
nextRead += 4;
// dump.readInt(); // DWORD NumberOfSymbols;
nextRead += 4;
long imageOptionalHeaderSizeAddress = nextRead;
// WORD SizeOfOptionalHeader;
short optionalHeaderSize = as.getShortAt(imageOptionalHeaderSizeAddress);
nextRead += 2;
// dump.readShort(); // WORD Characteristics;
nextRead += 2;
if (224 == optionalHeaderSize) {
// 32 bit processes don't need unwind information.
return null;
// cue us up to the data directories
} else if (240 == optionalHeaderSize) {
// 64-bit optional header
// typedef struct _IMAGE_OPTIONAL_HEADER64 {
short magicShort = as.getShortAt(nextRead);
if (0x20b != magicShort) {
throw new CorruptCoreException("Invalid IMAGE_OPTIONAL_HEADER64 magic number: \"0x" + Integer.toHexString(0xFFFF & magicShort) + "\" @ " + Long.toHexString(nextRead));
}
// WORD Magic;
nextRead += 2;
// BYTE MajorLinkerVersion;
nextRead += 1;
// BYTE MinorLinkerVersion;
nextRead += 1;
// DWORD SizeOfCode;
nextRead += 4;
// DWORD SizeOfInitializedData;
nextRead += 4;
// DWORD SizeOfUninitializedData;
nextRead += 4;
// DWORD AddressOfEntryPoint;
nextRead += 4;
// DWORD BaseOfCode;
nextRead += 4;
// ULONGLONG ImageBase;
nextRead += 8;
// DWORD SectionAlignment;
nextRead += 4;
// DWORD FileAlignment;
nextRead += 4;
// WORD MajorOperatingSystemVersion;
nextRead += 2;
// WORD MinorOperatingSystemVersion;
nextRead += 2;
// WORD MajorImageVersion;
nextRead += 2;
// WORD MinorImageVersion;
nextRead += 2;
// WORD MajorSubsystemVersion;
nextRead += 2;
// WORD MinorSubsystemVersion;
nextRead += 2;
// DWORD Win32VersionValue;
nextRead += 4;
// DWORD SizeOfImage;
nextRead += 4;
// DWORD SizeOfHeaders;
nextRead += 4;
// DWORD CheckSum;
nextRead += 4;
// WORD Subsystem;
nextRead += 2;
// WORD DllCharacteristics;
nextRead += 2;
// ULONGLONG SizeOfStackReserve;
nextRead += 8;
// ULONGLONG SizeOfStackCommit;
nextRead += 8;
// ULONGLONG SizeOfHeapReserve;
nextRead += 8;
// ULONGLONG SizeOfHeapCommit;
nextRead += 8;
// DWORD LoaderFlags;
nextRead += 4;
// DWORD NumberOfRvaAndSizes;
nextRead += 4;
// IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
// } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
} else {
// invalid size
throw new CorruptCoreException("Invalid IMAGE_OPTIONAL_HEADER size: \"" + optionalHeaderSize + "\" bytes @ " + Long.toHexString(imageOptionalHeaderSizeAddress));
}
// The exception data is index 3 in the directories.
int IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3;
for (int i = 0; i < IMAGE_DIRECTORY_ENTRY_EXCEPTION; i++) {
nextRead += 4;
nextRead += 4;
}
// DWORD VirtualAddress;
int exceptionRVA = as.getIntAt(nextRead);
// DWORD VirtualAddress;
int exceptionSize = as.getIntAt(nextRead);
// Now walk the table of IMAGE_RUNTIME_FUNCTION_ENTRY's, each is 3 DWORDS so 3*4 12 bytes long.
int entryCount = exceptionSize / 12;
nextRead = moduleLoadAddress + (exceptionRVA & 0xFFFFFFFFL);
// In the dll's entryCount is exceptionSize / sizeOf(IMAGE_RUNTIME_FUNCTION_ENTRY's)
// In the core files that doesn't appear to be true. Though they look like they are
// null terminated.
List<RuntimeFunction> rfList = new LinkedList<RuntimeFunction>();
for (int i = 0; i < entryCount; i++) {
// Create an entry in our list for each one of these.
int start = as.getIntAt(nextRead);
nextRead += 4;
if (start == 0) {
// Null entries appear to end the exception data.
break;
}
int end = as.getIntAt(nextRead);
nextRead += 4;
int unwindAddress = as.getIntAt(nextRead);
nextRead += 4;
RuntimeFunction rf = new RuntimeFunction(start, end, unwindAddress);
rfList.add(rf);
}
return rfList;
}
use of com.ibm.j9ddr.corereaders.CorruptCoreException in project openj9 by eclipse.
the class MiniDumpReader method setReader.
@Override
public void setReader(ImageInputStream reader) throws IOException {
// make sure that the
reader.setByteOrder(ByteOrder.LITTLE_ENDIAN);
// reader is set to the
// correct bte order for
// this dump
// set the reader on the super class
super.setReader(reader);
try {
// read in some preliminary data from the core file
readCore();
} catch (CorruptCoreException e) {
// TODO add in logging of the original method
throw new IOException("Failed to read the core : " + e.getMessage());
}
}
Aggregations