Search in sources :

Example 1 with CorruptCoreException

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;
}
Also used : CorruptCoreException(com.ibm.j9ddr.corereaders.CorruptCoreException) ISymbol(com.ibm.j9ddr.corereaders.memory.ISymbol) ISymbol(com.ibm.j9ddr.corereaders.memory.ISymbol) Symbol(com.ibm.j9ddr.corereaders.memory.Symbol) ArrayList(java.util.ArrayList) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 2 with CorruptCoreException

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;
}
Also used : CorruptCoreException(com.ibm.j9ddr.corereaders.CorruptCoreException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) RuntimeFunction(com.ibm.j9ddr.corereaders.minidump.unwind.RuntimeFunction) LinkedList(java.util.LinkedList)

Example 3 with CorruptCoreException

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());
    }
}
Also used : CorruptCoreException(com.ibm.j9ddr.corereaders.CorruptCoreException) IOException(java.io.IOException)

Aggregations

CorruptCoreException (com.ibm.j9ddr.corereaders.CorruptCoreException)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ISymbol (com.ibm.j9ddr.corereaders.memory.ISymbol)1 Symbol (com.ibm.j9ddr.corereaders.memory.Symbol)1 RuntimeFunction (com.ibm.j9ddr.corereaders.minidump.unwind.RuntimeFunction)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1