mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
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:
parent
0e3fe30c67
commit
e681b3dc4b
10 changed files with 189 additions and 68 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue