GP-2198 correct ELF Loader issues which failed to some non-loaded memory blocks. Improve use of task monitor during ELF import and cancellation. Also corrected bug in memory map table sort for Byte Source column.

This commit is contained in:
ghidra1 2022-06-21 12:07:57 -04:00
parent 0e3fe30c67
commit e681b3dc4b
10 changed files with 189 additions and 68 deletions

View file

@ -20,6 +20,8 @@ import java.io.InputStream;
import java.util.List;
import db.*;
import ghidra.util.MonitoredInputStream;
import ghidra.util.exception.IOCancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
@ -75,8 +77,21 @@ abstract class FileBytesAdapter {
return new FileBytesAdapterV0(handle, true);
}
abstract FileBytes createFileBytes(String filename, long offset, long size, InputStream is)
throws IOException;
/**
* Create {@link FileBytes} from specified input stream
* @param filename name of original file
* @param offset position of input stream within original file or 0 if no file
* @param size number of bytes to be read from input stream for stored file bytes
* @param is input stream
* @param monitor task monitor for progress and to allow cancellation. This will be ignored if
* input stream is a {@link MonitoredInputStream}. Monitor may be reinitialized and progress
* updated while reading from input stream.
* @return new file bytes
* @throws IOException if error occurs reading input stream or writing file bytes to database
* @throws IOCancelledException if operation was cancelled
*/
abstract FileBytes createFileBytes(String filename, long offset, long size, InputStream is,
TaskMonitor monitor) throws IOException;
/**
* Returns a DBBuffer object for the given database buffer id

View file

@ -21,6 +21,7 @@ import java.util.List;
import db.DBBuffer;
import db.DBHandle;
import ghidra.util.task.TaskMonitor;
/**
* Version of the FileBytesAdapter used to access older databases for read-only and upgrade purposes.
@ -32,7 +33,8 @@ class FileBytesAdapterNoTable extends FileBytesAdapter {
}
@Override
FileBytes createFileBytes(String filename, long offset, long size, InputStream is) {
FileBytes createFileBytes(String filename, long offset, long size, InputStream is,
TaskMonitor monitor) {
throw new UnsupportedOperationException();
}

View file

@ -20,8 +20,10 @@ import java.io.InputStream;
import java.util.*;
import db.*;
import ghidra.util.MonitoredInputStream;
import ghidra.util.exception.IOCancelledException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
/**
* Initial version of the FileBytesAdapter
@ -71,9 +73,9 @@ class FileBytesAdapterV0 extends FileBytesAdapter {
}
@Override
FileBytes createFileBytes(String filename, long offset, long size, InputStream is)
throws IOException {
DBBuffer[] buffers = createBuffers(size, is);
FileBytes createFileBytes(String filename, long offset, long size, InputStream is,
TaskMonitor monitor) throws IOException {
DBBuffer[] buffers = createBuffers(size, is, monitor);
DBBuffer[] layeredBuffers = createLayeredBuffers(buffers);
int[] bufIds = getIds(buffers);
int[] layeredBufIds = getIds(layeredBuffers);
@ -152,7 +154,24 @@ class FileBytesAdapterV0 extends FileBytesAdapter {
return layeredBuffers;
}
private DBBuffer[] createBuffers(long size, InputStream is) throws IOException {
@SuppressWarnings("resource")
private DBBuffer[] createBuffers(long size, InputStream is, TaskMonitor monitor)
throws IOException {
if (monitor == null) {
monitor = TaskMonitor.DUMMY;
}
MonitoredInputStream mis;
if (is instanceof MonitoredInputStream) {
mis = (MonitoredInputStream) is;
mis.getTaskMonitor().initialize(size);
}
else {
// caller responsible for closing input stream provided
mis = new MonitoredInputStream(is, monitor).setCleanupOnCancel(true);
monitor.initialize(size);
}
int maxBufSize = getMaxBufferSize();
int bufCount = (int) (size / maxBufSize);
int sizeLastBuf = (int) (size % maxBufSize);
@ -174,12 +193,21 @@ class FileBytesAdapterV0 extends FileBytesAdapter {
try {
for (DBBuffer buffer : buffers) {
buffer.fill(is);
buffer.fill(mis);
}
}
catch (IOCancelledException e) {
for (DBBuffer buffer : buffers) {
buffer.delete();
if (mis.cleanupOnCancel()) {
// Optional cleanup which can be avoided during import where entire program
// will get removed on cancel.
monitor.initialize(buffers.length);
monitor.setMessage("Cancelling...");
monitor.setCancelEnabled(false);
for (DBBuffer buffer : buffers) {
buffer.delete();
monitor.incrementProgress(1);
}
monitor.setIndeterminate(true);
}
throw e;
}

View file

@ -2196,11 +2196,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
}
lock.acquire();
try {
if (monitor != null && is != null) {
is = new MonitoredInputStream(is, monitor);
monitor.initialize(size);
}
return fileBytesAdapter.createFileBytes(filename, offset, size, is);
return fileBytesAdapter.createFileBytes(filename, offset, size, is, monitor);
}
catch (IOCancelledException e) {
throw new CancelledException();

View file

@ -140,8 +140,7 @@ public interface Memory extends AddressSetView {
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryConflictException if the new block overlaps with a
* previous block
* @throws AddressOverflowException if the start is beyond the
* address space
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws CancelledException user cancelled operation
* @throws IllegalArgumentException if invalid block name specified
*/
@ -165,8 +164,7 @@ public interface Memory extends AddressSetView {
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryConflictException if the new block overlaps with a
* previous block
* @throws AddressOverflowException if the start is beyond the
* address space
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name specified
* @throws CancelledException user cancelled operation
*/
@ -191,7 +189,7 @@ public interface Memory extends AddressSetView {
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryConflictException if the new block overlaps with a
* previous block
* @throws AddressOverflowException if the start is beyond the address space
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IndexOutOfBoundsException if file bytes range specified by offset and size
* is out of bounds for the specified fileBytes.
* @throws IllegalArgumentException if invalid block name specified
@ -213,8 +211,7 @@ public interface Memory extends AddressSetView {
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryConflictException if the new block overlaps with a
* previous block
* @throws AddressOverflowException if the start is beyond the
* address space
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name specified
*/
public MemoryBlock createUninitializedBlock(String name, Address start, long size,
@ -305,8 +302,7 @@ public interface Memory extends AddressSetView {
* @return new block
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryConflictException if block specification conflicts with an existing block
* @throws AddressOverflowException if the new memory block would extend
* beyond the end of the address space.
* @throws AddressOverflowException if block specification exceeds bounds of address space
* @throws IllegalArgumentException if invalid block name specifiede
*/
public MemoryBlock createBlock(MemoryBlock block, String name, Address start, long length)
@ -357,8 +353,7 @@ public interface Memory extends AddressSetView {
* @throws MemoryConflictException if move would cause
* blocks to overlap.
* @throws MemoryBlockException if block movement is not permitted
* @throws AddressOverflowException if new start address +
* block.getSize() would cause the Address to wrap around.
* @throws AddressOverflowException if block movement would violate bounds of address space
* @throws NotFoundException if memoryBlock does not exist in
* this memory.
*/
@ -376,8 +371,7 @@ public interface Memory extends AddressSetView {
* @throws NotFoundException thrown if block does not exist
* in memory
* @throws MemoryBlockException memory split not permitted
* @throws AddressOutOfBoundsException thrown if address is
* not in the block
* @throws AddressOutOfBoundsException thrown if address is not in the block
*/
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException;
@ -790,7 +784,8 @@ public interface Memory extends AddressSetView {
* @param offset the offset into the file for the first byte in the input stream.
* @param size the number of bytes to store from the input stream.
* @param is the input stream that will supply the bytes to store in the program.
* @param monitor
* Caller is responsible for closing input stream upon return.
* @param monitor task monitor
* @return a FileBytes that was created to access the bytes.
* @throws IOException if there was an IOException saving the bytes to the program database.
* @throws CancelledException if the user cancelled this operation. Note: the database will