use of com.ibm.j9ddr.corereaders.memory.IMemorySource in project openj9 by eclipse.
the class ELFDumpReader method createModuleFromElfReader.
/**
* Given an ELF reader, read the symbols, memory ranges and properties from the module
* and construct a Module object. The ELF reader may point to a segment within the core file
* or may point to a copy of the module on disk or appended to the core file.
*
* @param loadedBaseAddress of the module
* @param name of the module
* @param elfReader to the module
*
* @return IModule
* @throws IOException
*/
private IModule createModuleFromElfReader(final long loadedBaseAddress, String name, ELFFileReader inCoreReader, ELFFileReader diskReader) {
if (name == null) {
return null;
}
if (inCoreReader == null) {
return new MissingFileModule(_process, name, Collections.<IMemoryRange>emptyList());
}
List<? extends ISymbol> symbols = null;
Map<Long, String> sectionHeaderStringTable = null;
List<SectionHeaderEntry> sectionHeaderEntries = null;
Properties properties;
Collection<? extends IMemorySource> declaredRanges;
ProgramHeaderEntry ehFrameEntry = null;
// so don't raise an error if it isn't present.
for (ProgramHeaderEntry ph : inCoreReader.getProgramHeaderEntries()) {
if (ph.isEhFrame()) {
ehFrameEntry = ph;
}
}
try {
if (ehFrameEntry != null) {
unwinder.addCallFrameInformation(loadedBaseAddress, ehFrameEntry, name);
}
} catch (MemoryFault mf) {
// We get known memory faults for ld-linux-x86-64.so.2 in AMD64 dumps (at the first address it's loaded at)
// and linux-vdso.so.1. The first of these turns up again at a location that works, the second is
// "magic" so we don't worry about them. We want this code to be as resilient as possible.
logger.log(Level.FINER, "MemoryFault reading GNU_EH_FRAME data for module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
} catch (CorruptDataException cde) {
logger.log(Level.FINER, "CorruptDataException reading GNU_EH_FRAME data for module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
} catch (IOException e) {
logger.log(Level.FINER, "IOException reading GNU_EH_FRAME data for module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
}
try {
if (diskReader != null) {
symbols = diskReader.getSymbols(loadedBaseAddress, true);
sectionHeaderStringTable = diskReader.getSectionHeaderStringTable();
sectionHeaderEntries = diskReader.getSectionHeaderEntries();
} else {
symbols = inCoreReader.getSymbols(loadedBaseAddress, false);
sectionHeaderStringTable = inCoreReader.getSectionHeaderStringTable();
sectionHeaderEntries = inCoreReader.getSectionHeaderEntries();
}
properties = inCoreReader.getProperties();
// Only ever get memory ranges from the data loaded into the core file!
// But we can use the section headers and string table from the disk or zipped library
// to navigate. (Section headers are redundant once the library is loaded so may not
// be in memory.)
declaredRanges = inCoreReader.getMemoryRanges(loadedBaseAddress, sectionHeaderEntries, sectionHeaderStringTable);
} catch (IOException e) {
logger.log(Level.FINER, "Error generating module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
return null;
}
// Of the declared memory ranges, some will already be in core (i.e. .data) others will have been declared
// in the core, but not backed.
List<IMemoryRange> ranges = new ArrayList<IMemoryRange>(declaredRanges.size());
for (IMemorySource source : declaredRanges) {
IMemorySource coreSource = _process.getRangeForAddress(source.getBaseAddress());
/**
* The following test skips sections that originally had an address of 0
* the section header table.
*
* Explanation follows - see also the example section header table at the top
* of SectionHeaderEntry.java
*
* Some of the later sections in the section header table have an address field
* 0. That is a relative address, relative to the base address of the module.
* They are usually the sections from .comment onwards.
*
* When the entry is constructed the code that creates the entry creates it with
* address (base address of the module) + (address field in the SHT) hence those
* that had an address of 0 will have an address == base address of the module.
* These entries are precisely those that are often not in the core file so it is
* not safe to create them as sections - they were there in the on-disk version of
* the library but often not in memory. The code above that called elfReader.getMemoryRanges
* may have been reading the version of the module from disk (which is good, it means
* you get a good section header string table so you get good names for all the
* sections) but not all the sections exist in memory. The danger of adding them
* as memory ranges is that they start to overlay the segments in the core file
* that come immediately afterwards; that is, they cause jdmpview, for example, to
* believe that the contents of these later areas of memory are backed by the
* contents of the library on disk when they are not.
* See CMVC 185753
*
* So, don't add sections that originally had address 0.
*/
if (source.getBaseAddress() == loadedBaseAddress) {
// must have originally had address 0 in the section header table
continue;
}
if (null != coreSource) {
if (coreSource.isBacked()) {
// Range already exists
} else {
// from the library
if (source.getSize() > 0) {
_process.removeMemorySource(coreSource);
_process.addMemorySource(source);
}
}
} else {
if (source.getSize() > 0) {
_process.addMemorySource(source);
}
}
ranges.add(source);
}
return new Module(_process, name, symbols, ranges, loadedBaseAddress, properties);
}
use of com.ibm.j9ddr.corereaders.memory.IMemorySource in project openj9 by eclipse.
the class ProgramHeaderEntry method asMemorySource.
IMemorySource asMemorySource() {
IMemorySource source = null;
if (!isEmpty()) {
boolean isExecutable = (_flags & PF_X) != 0;
source = new ELFMemorySource(virtualAddress, memorySize, fileOffset, reader);
} else {
source = new UnbackedMemorySource(virtualAddress, memorySize, "ELF ProgramHeaderEntry storage declared but data not included");
}
Properties memoryProps = ((IDetailedMemoryRange) source).getProperties();
memoryProps.setProperty("IN_CORE", "" + (!isEmpty()));
if ((_flags & PF_W) != 0) {
memoryProps.setProperty(IDetailedMemoryRange.WRITABLE, Boolean.TRUE.toString());
}
if ((_flags & PF_X) != 0) {
memoryProps.setProperty(IDetailedMemoryRange.EXECUTABLE, Boolean.TRUE.toString());
}
if ((_flags & PF_R) != 0) {
memoryProps.setProperty(IDetailedMemoryRange.READABLE, Boolean.TRUE.toString());
}
return source;
}
use of com.ibm.j9ddr.corereaders.memory.IMemorySource in project openj9 by eclipse.
the class AIXDumpReader method loadModule.
private void loadModule(ILibraryResolver resolver, IProcess proc, long textVirtualAddress, long textSize, long dataVirtualAddress, long dataSize, String fileName, String objectName, String moduleName, boolean loadingExecutable) {
// .data range will be loaded in core. .text range will be in the module itself.
IMemoryRange data = new MemoryRange(proc.getAddressSpace(), dataVirtualAddress, dataSize, ".data");
IModule module;
IMemorySource text;
try {
LibraryDataSource library = null;
if (loadingExecutable) {
library = resolver.getLibrary(fileName, true);
} else {
library = resolver.getLibrary(fileName);
}
IModuleFile moduleFile = loadModuleFile(library, objectName);
text = moduleFile.getTextSegment(textVirtualAddress, textSize);
List<? extends ISymbol> symbols = moduleFile.getSymbols(textVirtualAddress);
List<IMemoryRange> moduleMemoryRanges = new LinkedList<IMemoryRange>();
moduleMemoryRanges.add(text);
moduleMemoryRanges.add(data);
module = new Module(proc, moduleName, symbols, moduleMemoryRanges, textVirtualAddress, moduleFile.getProperties());
} catch (Exception e) {
// Create a non-backed memory range for the text segment (so we know it exists)
text = new UnbackedMemorySource(textVirtualAddress, textSize, "Native library " + moduleName + " couldn't be found", 0, ".text");
List<IMemoryRange> moduleMemoryRanges = new LinkedList<IMemoryRange>();
moduleMemoryRanges.add(text);
moduleMemoryRanges.add(data);
// Can't find the library - put a stub in with the information we have.
module = new MissingFileModule(proc, moduleName, moduleMemoryRanges);
}
// Add .text to _memoryRanges so it becomes part of the native address space.
addMemorySource(text);
if (loadingExecutable) {
_executable = module;
_executableTextSection = text;
} else {
_modules.add(module);
}
}
use of com.ibm.j9ddr.corereaders.memory.IMemorySource in project openj9 by eclipse.
the class MemoryInfoStream method readFrom.
public void readFrom(MiniDumpReader dump, boolean is64Bit, Collection<? extends IMemorySource> ranges) throws IOException {
dump.seek(getLocation());
int sizeOfHeader = 0;
int sizeOfEntry = 0;
long numberOfEntries = 0;
HashMap<Long, Properties> memoryInfo = new HashMap<Long, Properties>();
// The header is 2 ULONGs, which are 32 bit and a ULONG64
sizeOfHeader = dump.readInt();
sizeOfEntry = dump.readInt();
numberOfEntries = dump.readLong();
// The thread info structures follow the header.
/* Each structure is:
ULONG64 BaseAddress;
ULONG64 AllocationBase;
ULONG32 AllocationProtect;
ULONG32 __alignment1;
ULONG64 RegionSize;
ULONG32 State;
ULONG32 Protect;
ULONG32 Type;
ULONG32 __alignment2;
*/
// We should be exactly here already but to be safe.
dump.seek(getLocation() + sizeOfHeader);
for (int i = 0; i < numberOfEntries; i++) {
Properties props = new Properties();
long baseAddress = dump.readLong();
long allocationBase = dump.readLong();
int allocationProtect = dump.readInt();
// alignment1
dump.readInt();
long regionSize = dump.readLong();
int state = dump.readInt();
int protect = dump.readInt();
int type = dump.readInt();
// alignment2
dump.readInt();
props.put("state", decodeStateFlags(state));
props.put("state_flags", String.format("0x%X", state));
props.put("size", String.format(is64Bit ? "0x%016X" : "0x%08X", regionSize));
if (state != STATE_MEM_FREE) {
// For free memory allocation base, allocation protect, protect and type are undefined.
props.put("allocationBase", String.format(is64Bit ? "0x%016X" : "0x%08X", allocationBase));
props.put("allocationProtect", decodeProtectFlags(allocationProtect));
props.put("allocationProtect_flags", String.format("0x%X", allocationProtect));
props.put("protect", decodeProtectFlags(protect));
setReadWriteExecProperties(protect, props);
props.put("protect_flags", String.format("0x%X", protect));
props.put("type", decodeTypeFlags(type));
props.put("type_flags", String.format("0x%X", allocationProtect));
} else {
// Free memory is not accessible.
props.setProperty(READABLE, FALSE);
props.setProperty(WRITABLE, FALSE);
props.setProperty(EXECUTABLE, FALSE);
}
memoryInfo.put(new Long(baseAddress), props);
}
/* Merge the extra properties into the memory info. */
Iterator<? extends IMemorySource> memoryIterator = ranges.iterator();
List<IMemorySource> newRanges = new ArrayList<IMemorySource>(memoryInfo.size());
while (memoryIterator.hasNext()) {
IMemorySource m = memoryIterator.next();
Properties p = memoryInfo.remove(m.getBaseAddress());
if (p != null && m instanceof DumpMemorySource) {
DetailedDumpMemorySource newSource = new DetailedDumpMemorySource((DumpMemorySource) m, p);
newSource.getProperties().putAll(p);
newRanges.add(newSource);
} else {
newRanges.add(m);
}
}
// Add sections we didn't find as unbacked memory!
// (There should be at least one huge one in the middle if this is 64 bit.)
Iterator<Entry<Long, Properties>> propsIterator = memoryInfo.entrySet().iterator();
while (propsIterator.hasNext()) {
Entry<Long, Properties> e = propsIterator.next();
long size = Long.parseLong(((String) e.getValue().get("size")).substring(2), 16);
String explanation = "Windows MINIDUMP_MEMORY_INFO entry included but data not included in dump";
if ("MEM_FREE".equals(e.getValue().get("state"))) {
explanation = "Free memory, unallocated";
}
UnbackedMemorySource m = new UnbackedMemorySource(e.getKey(), size, explanation);
m.getProperties().putAll(e.getValue());
newRanges.add(m);
}
Collections.sort(newRanges, new Comparator<IMemorySource>() {
public int compare(IMemorySource o1, IMemorySource o2) {
if (o1.getBaseAddress() > o2.getBaseAddress()) {
return 1;
} else if (o1.getBaseAddress() < o2.getBaseAddress()) {
return -1;
}
return 0;
}
});
dump.setMemorySources(newRanges);
}
use of com.ibm.j9ddr.corereaders.memory.IMemorySource in project openj9 by eclipse.
the class Memory64Stream method readFrom.
public void readFrom(MiniDumpReader dump) throws IOException {
long location = getLocation();
dump.seek(location);
long numberOfMemoryRanges = dump.readLong();
long baseAddress = dump.readLong();
List<IMemorySource> memorySources = new ArrayList<IMemorySource>();
DumpMemorySource memoryRange = null;
for (int i = 0; i < numberOfMemoryRanges; i++) {
long start = dump.is64Bit() ? dump.readLong() : dump.readLong() & 0x00000000FFFFFFFFL;
long size = dump.is64Bit() ? dump.readLong() : dump.readLong() & 0x00000000FFFFFFFFL;
if (null == memoryRange) {
// Allocate the first memory range starting at baseAddress in
// the dump file
memoryRange = new DumpMemorySource(start, size, baseAddress, dump, false, false, true);
} else if (memoryRange.getBaseAddress() + memoryRange.getSize() == start) {
// Combine contiguous regions
memoryRange = new DumpMemorySource(memoryRange.getBaseAddress(), memoryRange.getSize() + size, memoryRange.getFileOffset(), dump, false, false, true);
} else {
// Add the previous MemoryRange and start the next one
memorySources.add(memoryRange);
memoryRange = new DumpMemorySource(start, size, memoryRange.getFileOffset() + memoryRange.getSize(), dump, false, false, true);
}
// public DumpMemoryRange(long baseAddress, long size, long
// fileOffset, AbstractCoreReader reader)
}
if (null != memoryRange) {
memorySources.add(memoryRange);
}
dump.setMemorySources(memorySources);
}
Aggregations