mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-4125 Added memory block artificial attribute flag
This commit is contained in:
parent
ddf4d15327
commit
ae475f743b
48 changed files with 734 additions and 465 deletions
|
@ -104,7 +104,7 @@ public class ProgramEmulationUtils {
|
||||||
*/
|
*/
|
||||||
public static Set<TraceMemoryFlag> getRegionFlags(MemoryBlock block) {
|
public static Set<TraceMemoryFlag> getRegionFlags(MemoryBlock block) {
|
||||||
Set<TraceMemoryFlag> result = EnumSet.noneOf(TraceMemoryFlag.class);
|
Set<TraceMemoryFlag> result = EnumSet.noneOf(TraceMemoryFlag.class);
|
||||||
int mask = block.getPermissions();
|
int mask = block.getFlags();
|
||||||
if ((mask & MemoryBlock.READ) != 0) {
|
if ((mask & MemoryBlock.READ) != 0) {
|
||||||
result.add(TraceMemoryFlag.READ);
|
result.add(TraceMemoryFlag.READ);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ package ghidra.trace.database.program;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import javax.help.UnsupportedOperationException;
|
||||||
|
|
||||||
import ghidra.framework.store.LockException;
|
import ghidra.framework.store.LockException;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||||
|
@ -57,7 +59,7 @@ public class DBTraceProgramViewMemoryRegionBlock extends AbstractDBTraceProgramV
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions() {
|
public int getFlags() {
|
||||||
int bits = 0;
|
int bits = 0;
|
||||||
for (TraceMemoryFlag flag : region.getFlags()) {
|
for (TraceMemoryFlag flag : region.getFlags()) {
|
||||||
bits |= flag.getBits();
|
bits |= flag.getBits();
|
||||||
|
@ -145,4 +147,15 @@ public class DBTraceProgramViewMemoryRegionBlock extends AbstractDBTraceProgramV
|
||||||
public void setVolatile(boolean v) {
|
public void setVolatile(boolean v) {
|
||||||
region.setVolatile(v);
|
region.setVolatile(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArtificial() {
|
||||||
|
// By definition, any region present on target is non-artificial
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class DBTraceProgramViewMemorySpaceBlock extends AbstractDBTraceProgramVi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions() {
|
public int getFlags() {
|
||||||
return MemoryBlock.READ | MemoryBlock.WRITE | MemoryBlock.EXECUTE;
|
return MemoryBlock.READ | MemoryBlock.WRITE | MemoryBlock.EXECUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,16 @@ public class DBTraceProgramViewMemorySpaceBlock extends AbstractDBTraceProgramVi
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArtificial() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSourceName() {
|
public String getSourceName() {
|
||||||
return "Trace"; // TODO: What does this method actually do?
|
return "Trace"; // TODO: What does this method actually do?
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class DBTraceProgramViewRegisterMemoryBlock implements MemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions() {
|
public int getFlags() {
|
||||||
return MemoryBlock.READ | MemoryBlock.WRITE;
|
return MemoryBlock.READ | MemoryBlock.WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +220,16 @@ public class DBTraceProgramViewRegisterMemoryBlock implements MemoryBlock {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArtificial() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSourceName() {
|
public String getSourceName() {
|
||||||
return "Trace"; // TODO: What does this method actually do?
|
return "Trace"; // TODO: What does this method actually do?
|
||||||
|
|
|
@ -62,26 +62,11 @@
|
||||||
|
|
||||||
<P><A name="OverlayType"></A><B>Overlay</B> - Each of the above memory block types may
|
<P><A name="OverlayType"></A><B>Overlay</B> - Each of the above memory block types may
|
||||||
optionally be created as an <I>Overlay</I> block. One or more memory blocks may be defined
|
optionally be created as an <I>Overlay</I> block. One or more memory blocks may be defined
|
||||||
within the same overlay address space.
|
within the same overlay address space where the <B>Overlayed Space</B> is reflected in the memory map table.
|
||||||
|
Overlay blocks can serve various
|
||||||
|
purposes where a memory range may contain different data/code at any given point in time
|
||||||
An overlay memory block may be created in two ways:
|
or processor state. Note that Overlay blocks
|
||||||
* <ul>
|
do not relocate with image base changes and have some limitations in conjunction with
|
||||||
* <li>Specifying a {@code start} address within an existing overlay address space
|
|
||||||
* ({@code overlay} parameter is ignored), or</li>
|
|
||||||
* <li>Specifying a {@code start} address within a physical memory address space and passing
|
|
||||||
* {@code overlay=true}. This use case will force the creation of a new unique overlay
|
|
||||||
* address space.</li>
|
|
||||||
* </ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
If this option is selected, the block is created in a new
|
|
||||||
overlay address space. Overlay blocks can serve various
|
|
||||||
purposes where a memory range may contain different data/code or map to different areas of memory
|
|
||||||
at any given point in time or processor state. Note that
|
|
||||||
overlay blocks are fixed and may not be moved, split, merged or expanded. In addition, Overlays
|
|
||||||
do not relocate with image base changes and have significant limitations in conjunction with
|
|
||||||
decompilation and analysis.</P>
|
decompilation and analysis.</P>
|
||||||
|
|
||||||
<P>To view the <I>Memory Map</I>, select <B>Window<IMG src="help/shared/arrow.gif" border="0">
|
<P>To view the <I>Memory Map</I>, select <B>Window<IMG src="help/shared/arrow.gif" border="0">
|
||||||
|
@ -124,6 +109,9 @@
|
||||||
|
|
||||||
<P><B>Volatile * </B> - Indicates a region of volatile I/O Memory.</P>
|
<P><B>Volatile * </B> - Indicates a region of volatile I/O Memory.</P>
|
||||||
|
|
||||||
|
<P><B>Artificial * </B> - Indicates an artificial memory block which has been fabricated to
|
||||||
|
facilitate analysis.</P>
|
||||||
|
|
||||||
<P><I><B>Overlayed Space -</B></I> If the block is an overlay block this column indicates the name
|
<P><I><B>Overlayed Space -</B></I> If the block is an overlay block this column indicates the name
|
||||||
of the overlayed physical memory space. This field will be empty for non-overlay blocks.</P>
|
of the overlayed physical memory space. This field will be empty for non-overlay blocks.</P>
|
||||||
|
|
||||||
|
@ -201,6 +189,13 @@
|
||||||
checkbox.</P>
|
checkbox.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<H3>Change Artificial Setting</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>The artificial setting of a memory block can be changed by left-clicking on the
|
||||||
|
checkbox.</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H3>Initialize Memory Block</H3>
|
<H3>Initialize Memory Block</H3>
|
||||||
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
|
@ -266,7 +261,11 @@
|
||||||
|
|
||||||
<P><B><I>Execute</I></B> - Sets the execute permission.</P>
|
<P><B><I>Execute</I></B> - Sets the execute permission.</P>
|
||||||
|
|
||||||
<P><B>Volatile</B> - Marks this block as volatile I/O memory.</P>
|
<P><B>Volatile</B> - Marks a block as volatile I/O memory.</P>
|
||||||
|
|
||||||
|
<P><B>Artificial</B> - Marks a memory block as artificial. This may be useful when a
|
||||||
|
block is required to facilitate analysis but does not exist in the same form within a
|
||||||
|
running/loaded process state.</P>
|
||||||
|
|
||||||
<P><B>Overlay</B> - Creates the block as an overlay block. An overlay memory block may be
|
<P><B>Overlay</B> - Creates the block as an overlay block. An overlay memory block may be
|
||||||
created in two ways:
|
created in two ways:
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 23 KiB |
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -28,7 +28,7 @@ import ghidra.util.exception.*;
|
||||||
/**
|
/**
|
||||||
* Base command class for adding memory blocks.
|
* Base command class for adding memory blocks.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractAddMemoryBlockCmd implements Command {
|
public abstract class AbstractAddMemoryBlockCmd implements Command {
|
||||||
protected String message;
|
protected String message;
|
||||||
protected final String name;
|
protected final String name;
|
||||||
protected final String comment;
|
protected final String comment;
|
||||||
|
@ -42,6 +42,8 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
|
||||||
protected final boolean isVolatile;
|
protected final boolean isVolatile;
|
||||||
protected final boolean isOverlay;
|
protected final boolean isOverlay;
|
||||||
|
|
||||||
|
private boolean isArtificial = false;
|
||||||
|
|
||||||
AbstractAddMemoryBlockCmd(String name, String comment, String source, Address start,
|
AbstractAddMemoryBlockCmd(String name, String comment, String source, Address start,
|
||||||
long length, boolean read, boolean write, boolean execute, boolean isVolatile,
|
long length, boolean read, boolean write, boolean execute, boolean isVolatile,
|
||||||
boolean isOverlay) {
|
boolean isOverlay) {
|
||||||
|
@ -57,6 +59,15 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
|
||||||
this.isOverlay = isOverlay;
|
this.isOverlay = isOverlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prior to command execution the block's artificial attribute state may be specified
|
||||||
|
* and will be applied to the new memory block.
|
||||||
|
* @param a block artificial attribute state
|
||||||
|
*/
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
isArtificial = a;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getStatusMsg() {
|
public String getStatusMsg() {
|
||||||
return message;
|
return message;
|
||||||
|
@ -67,9 +78,8 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
|
||||||
return "Add Memory Block";
|
return "Add Memory Block";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract MemoryBlock createMemoryBlock(Memory memory)
|
protected abstract MemoryBlock createMemoryBlock(Memory memory) throws LockException,
|
||||||
throws LockException, MemoryConflictException, AddressOverflowException,
|
MemoryConflictException, AddressOverflowException, CancelledException;
|
||||||
CancelledException;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applyTo(DomainObject obj) {
|
public boolean applyTo(DomainObject obj) {
|
||||||
|
@ -82,6 +92,7 @@ abstract class AbstractAddMemoryBlockCmd implements Command {
|
||||||
block.setWrite(write);
|
block.setWrite(write);
|
||||||
block.setExecute(execute);
|
block.setExecute(execute);
|
||||||
block.setVolatile(isVolatile);
|
block.setVolatile(isVolatile);
|
||||||
|
block.setArtificial(isArtificial);
|
||||||
block.setSourceName(source);
|
block.setSourceName(source);
|
||||||
renameFragment(program, block.getStart());
|
renameFragment(program, block.getStart());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -196,7 +196,7 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
if (isNameConflict(i)) {
|
if (isNameConflict(i)) {
|
||||||
conflictList.add(new ConflictInfo(i, true, false, false));
|
conflictList.add(new ConflictInfo(i, true, false, false));
|
||||||
}
|
}
|
||||||
if (isPermissionConflict(i)) {
|
if (isFlagsConflict(i)) {
|
||||||
conflictList.add(new ConflictInfo(i, false, true, false));
|
conflictList.add(new ConflictInfo(i, false, true, false));
|
||||||
}
|
}
|
||||||
if (isCommentConflict(i)) {
|
if (isCommentConflict(i)) {
|
||||||
|
@ -233,7 +233,8 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
String myName = myBlocks[index].getName();
|
String myName = myBlocks[index].getName();
|
||||||
String origName = origBlocks[index].getName();
|
String origName = origBlocks[index].getName();
|
||||||
|
|
||||||
if (!myName.equals(origName) && !latestName.equals(origName) && !myName.equals(latestName)) {
|
if (!myName.equals(origName) && !latestName.equals(origName) &&
|
||||||
|
!myName.equals(latestName)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -244,13 +245,12 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
* LATEST and MY programs.
|
* LATEST and MY programs.
|
||||||
* @param index block index
|
* @param index block index
|
||||||
*/
|
*/
|
||||||
private boolean isPermissionConflict(int index) {
|
private boolean isFlagsConflict(int index) {
|
||||||
int latestPermissions = latestBlocks[index].getPermissions();
|
int latestFlags = latestBlocks[index].getFlags();
|
||||||
int myPermissions = myBlocks[index].getPermissions();
|
int myFlags = myBlocks[index].getFlags();
|
||||||
int origPermissions = origBlocks[index].getPermissions();
|
int origFlags = origBlocks[index].getFlags();
|
||||||
|
|
||||||
if (myPermissions != origPermissions && latestPermissions != origPermissions &&
|
if (myFlags != origFlags && latestFlags != origFlags && myFlags != latestFlags) {
|
||||||
myPermissions != latestPermissions) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -363,26 +363,20 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
|
|
||||||
if (info.nameConflict) {
|
if (info.nameConflict) {
|
||||||
title = "Resolve Name Conflict";
|
title = "Resolve Name Conflict";
|
||||||
latestStr =
|
latestStr = "Use Block name '" + latestBlocks[info.index].getName() + "' (" +
|
||||||
"Use Block name '" + latestBlocks[info.index].getName() + "' (" +
|
|
||||||
MergeConstants.LATEST_TITLE + ")";
|
MergeConstants.LATEST_TITLE + ")";
|
||||||
myStr =
|
myStr = "Use Block name '" + getUniqueBlockName(myBlocks[info.index].getName()) +
|
||||||
"Use Block name '" + getUniqueBlockName(myBlocks[info.index].getName()) + "' (" +
|
"' (" + MergeConstants.MY_TITLE + ")";
|
||||||
MergeConstants.MY_TITLE + ")";
|
origStr = "Use Block name '" + origBlocks[info.index].getName() + "' (" +
|
||||||
origStr =
|
|
||||||
"Use Block name '" + origBlocks[info.index].getName() + "' (" +
|
|
||||||
MergeConstants.ORIGINAL_TITLE + ")";
|
MergeConstants.ORIGINAL_TITLE + ")";
|
||||||
}
|
}
|
||||||
else if (info.permissionConflict) {
|
else if (info.permissionConflict) {
|
||||||
title = "Resolve Permissions Conflict";
|
title = "Resolve Flags Conflict";
|
||||||
latestStr =
|
latestStr = "Use '" + getFlagsString(latestBlocks[info.index]) + "' (" +
|
||||||
"Use '" + getPermissionString(latestBlocks[info.index]) + "' (" +
|
|
||||||
MergeConstants.LATEST_TITLE + ")";
|
MergeConstants.LATEST_TITLE + ")";
|
||||||
myStr =
|
myStr = "Use '" + getFlagsString(myBlocks[info.index]) + "' (" +
|
||||||
"Use '" + getPermissionString(myBlocks[info.index]) + "' (" +
|
|
||||||
MergeConstants.MY_TITLE + ")";
|
MergeConstants.MY_TITLE + ")";
|
||||||
origStr =
|
origStr = "Use '" + getFlagsString(origBlocks[info.index]) + "' (" +
|
||||||
"Use '" + getPermissionString(origBlocks[info.index]) + "' (" +
|
|
||||||
MergeConstants.ORIGINAL_TITLE + ")";
|
MergeConstants.ORIGINAL_TITLE + ")";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -393,7 +387,8 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
myStr = myBlocks[info.index].getComment();
|
myStr = myBlocks[info.index].getComment();
|
||||||
origStr = origBlocks[info.index].getComment();
|
origStr = origBlocks[info.index].getComment();
|
||||||
}
|
}
|
||||||
if ((memoryDetailChoice == ASK_USER) && conflictOption == ASK_USER && mergeManager != null) {
|
if ((memoryDetailChoice == ASK_USER) && conflictOption == ASK_USER &&
|
||||||
|
mergeManager != null) {
|
||||||
title = title + " (Block index " + info.index + ")";
|
title = title + " (Block index " + info.index + ")";
|
||||||
showMergePanel(panelID, title, latestStr, myStr, origStr);
|
showMergePanel(panelID, title, latestStr, myStr, origStr);
|
||||||
}
|
}
|
||||||
|
@ -428,6 +423,7 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
resultBlocks[info.index].setWrite(sourceBlock.isWrite());
|
resultBlocks[info.index].setWrite(sourceBlock.isWrite());
|
||||||
resultBlocks[info.index].setExecute(sourceBlock.isExecute());
|
resultBlocks[info.index].setExecute(sourceBlock.isExecute());
|
||||||
resultBlocks[info.index].setVolatile(sourceBlock.isVolatile());
|
resultBlocks[info.index].setVolatile(sourceBlock.isVolatile());
|
||||||
|
resultBlocks[info.index].setArtificial(sourceBlock.isArtificial());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
resultBlocks[info.index].setComment(sourceBlock.getComment());
|
resultBlocks[info.index].setComment(sourceBlock.getComment());
|
||||||
|
@ -456,8 +452,8 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
mergeManager.setApplyEnabled(false);
|
mergeManager.setApplyEnabled(false);
|
||||||
mergeManager.showComponent(mergePanel, "MemoryMerge", new HelpLocation(
|
mergeManager.showComponent(mergePanel, "MemoryMerge",
|
||||||
HelpTopics.REPOSITORY, "MemoryConflict"));
|
new HelpLocation(HelpTopics.REPOSITORY, "MemoryConflict"));
|
||||||
// block until the user either cancels or hits the "Apply" button
|
// block until the user either cancels or hits the "Apply" button
|
||||||
// on the merge dialog...
|
// on the merge dialog...
|
||||||
// when the "Apply" button is hit, get the user's selection
|
// when the "Apply" button is hit, get the user's selection
|
||||||
|
@ -465,7 +461,7 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPermissionString(MemoryBlock block) {
|
private String getFlagsString(MemoryBlock block) {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("Read = ");
|
sb.append("Read = ");
|
||||||
sb.append(block.isExecute());
|
sb.append(block.isExecute());
|
||||||
|
@ -478,6 +474,9 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
sb.append("Volatile = ");
|
sb.append("Volatile = ");
|
||||||
sb.append(block.isVolatile());
|
sb.append(block.isVolatile());
|
||||||
|
sb.append(", ");
|
||||||
|
sb.append("Artificial = ");
|
||||||
|
sb.append(block.isArtificial());
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +500,7 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isPermissionConflict(index)) {
|
if (!isFlagsConflict(index)) {
|
||||||
boolean permission = myBlocks[index].isRead();
|
boolean permission = myBlocks[index].isRead();
|
||||||
if (permission != origBlocks[index].isRead()) {
|
if (permission != origBlocks[index].isRead()) {
|
||||||
resultBlocks[index].setRead(permission);
|
resultBlocks[index].setRead(permission);
|
||||||
|
@ -534,6 +533,14 @@ public class MemoryMergeManager implements MergeResolver {
|
||||||
progressUpdated = true;
|
progressUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
permission = myBlocks[index].isArtificial();
|
||||||
|
if (permission != origBlocks[index].isArtificial()) {
|
||||||
|
resultBlocks[index].setArtificial(permission);
|
||||||
|
if (!progressUpdated) {
|
||||||
|
currentMonitor.setProgress(++progressIndex);
|
||||||
|
progressUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!isCommentConflict(index)) {
|
if (!isCommentConflict(index)) {
|
||||||
String myComment = myBlocks[index].getComment();
|
String myComment = myBlocks[index].getComment();
|
||||||
|
|
|
@ -136,7 +136,8 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (analyzerOptions.propagateRtti) {
|
if (analyzerOptions.propagateRtti) {
|
||||||
Msg.info(this, "Golang symbol analyzer: scheduling RTTI propagation after reference analysis");
|
Msg.info(this,
|
||||||
|
"Golang symbol analyzer: scheduling RTTI propagation after reference analysis");
|
||||||
aam.schedule(new PropagateRttiBackgroundCommand(goBinary),
|
aam.schedule(new PropagateRttiBackgroundCommand(goBinary),
|
||||||
AnalysisPriority.REFERENCE_ANALYSIS.after().priority());
|
AnalysisPriority.REFERENCE_ANALYSIS.after().priority());
|
||||||
}
|
}
|
||||||
|
@ -408,6 +409,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
|
||||||
MemoryBlockUtils.createUninitializedBlock(program, false, "ARTIFICAL_GOLANG_CONTEXT",
|
MemoryBlockUtils.createUninitializedBlock(program, false, "ARTIFICAL_GOLANG_CONTEXT",
|
||||||
mbStart, len, "Artifical memory block created to hold golang context data types",
|
mbStart, len, "Artifical memory block created to hold golang context data types",
|
||||||
null, true, true, false, null);
|
null, true, true, false, null);
|
||||||
|
newMB.setArtificial(true);
|
||||||
return newMB.getStart();
|
return newMB.getStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,8 +569,8 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
record CallSiteInfo(Reference ref, Function callingFunc, Function calledFunc,
|
record CallSiteInfo(Reference ref, Function callingFunc, Function calledFunc,
|
||||||
Register register,
|
Register register, java.util.function.Function<GoType, DataType> returnTypeMapper) {
|
||||||
java.util.function.Function<GoType, DataType> returnTypeMapper) {}
|
}
|
||||||
|
|
||||||
private GoRttiMapper goBinary;
|
private GoRttiMapper goBinary;
|
||||||
private MarkupSession markupSession;
|
private MarkupSession markupSession;
|
||||||
|
|
|
@ -164,8 +164,9 @@ public class AddressTableAnalyzer extends AbstractAnalyzer {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bookmark bookmark = program.getBookmarkManager().getBookmark(
|
Bookmark bookmark = program.getBookmarkManager()
|
||||||
tableEntry.getTopAddress(), BookmarkType.ANALYSIS, "Address Table");
|
.getBookmark(tableEntry.getTopAddress(), BookmarkType.ANALYSIS,
|
||||||
|
"Address Table");
|
||||||
|
|
||||||
// nothing to see here, already done.
|
// nothing to see here, already done.
|
||||||
if (!ignoreBookmarks && bookmark != null) {
|
if (!ignoreBookmarks && bookmark != null) {
|
||||||
|
@ -186,9 +187,10 @@ public class AddressTableAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
// put info bookmark in
|
// put info bookmark in
|
||||||
if (createBookmarksEnabled) {
|
if (createBookmarksEnabled) {
|
||||||
program.getBookmarkManager().setBookmark(tableEntry.getTopAddress(),
|
program.getBookmarkManager()
|
||||||
BookmarkType.ANALYSIS, "Address Table",
|
.setBookmark(tableEntry.getTopAddress(), BookmarkType.ANALYSIS,
|
||||||
"Address table[" + tableEntry.getNumberAddressEntries() + "] created");
|
"Address Table", "Address table[" +
|
||||||
|
tableEntry.getNumberAddressEntries() + "] created");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if all are valid code, disassemble
|
// if all are valid code, disassemble
|
||||||
|
@ -268,8 +270,7 @@ public class AddressTableAnalyzer extends AbstractAnalyzer {
|
||||||
//
|
//
|
||||||
AddressSet badBlocks = new AddressSet();
|
AddressSet badBlocks = new AddressSet();
|
||||||
for (MemoryBlock memoryBlock : blocks) {
|
for (MemoryBlock memoryBlock : blocks) {
|
||||||
if (memoryBlock.isWrite() || memoryBlock.isRead() || memoryBlock.isExecute() ||
|
if (memoryBlock.isWrite() || memoryBlock.isRead() || memoryBlock.isExecute()) {
|
||||||
memoryBlock.isVolatile()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,14 +341,15 @@ public class AddressTableAnalyzer extends AbstractAnalyzer {
|
||||||
AddressIterator addrIter = addrSet.getAddresses(true);
|
AddressIterator addrIter = addrSet.getAddresses(true);
|
||||||
long maxBytes = addrSet.getNumAddresses();
|
long maxBytes = addrSet.getNumAddresses();
|
||||||
|
|
||||||
MemoryBufferImpl buffer = new MemoryBufferImpl(memory, addrSet.getMinAddress(), (int) (maxBytes > 1024 ? 1024 : maxBytes));
|
MemoryBufferImpl buffer = new MemoryBufferImpl(memory, addrSet.getMinAddress(),
|
||||||
|
(int) (maxBytes > 1024 ? 1024 : maxBytes));
|
||||||
|
|
||||||
while (addrIter.hasNext()) {
|
while (addrIter.hasNext()) {
|
||||||
Address start = addrIter.next();
|
Address start = addrIter.next();
|
||||||
|
|
||||||
// skip over anything that smells like a unicode string
|
// skip over anything that smells like a unicode string
|
||||||
//
|
//
|
||||||
int strLen = getWStrLen(buffer, start, (int)(maxBytes / 2));
|
int strLen = getWStrLen(buffer, start, (int) (maxBytes / 2));
|
||||||
if (strLen > 4) {
|
if (strLen > 4) {
|
||||||
int numBytes = strLen * 2;
|
int numBytes = strLen * 2;
|
||||||
addrIter = skipBytes(addrIter, addrSet, start, numBytes);
|
addrIter = skipBytes(addrIter, addrSet, start, numBytes);
|
||||||
|
|
|
@ -65,6 +65,7 @@ class AddBlockDialog extends DialogComponentProvider implements ChangeListener {
|
||||||
private JCheckBox writeCB;
|
private JCheckBox writeCB;
|
||||||
private JCheckBox executeCB;
|
private JCheckBox executeCB;
|
||||||
private JCheckBox volatileCB;
|
private JCheckBox volatileCB;
|
||||||
|
private JCheckBox artificialCB;
|
||||||
private JCheckBox overlayCB;
|
private JCheckBox overlayCB;
|
||||||
private RegisterField initialValueField;
|
private RegisterField initialValueField;
|
||||||
private JLabel initialValueLabel;
|
private JLabel initialValueLabel;
|
||||||
|
@ -108,6 +109,7 @@ class AddBlockDialog extends DialogComponentProvider implements ChangeListener {
|
||||||
writeCB.setSelected(model.isWrite());
|
writeCB.setSelected(model.isWrite());
|
||||||
executeCB.setSelected(model.isExecute());
|
executeCB.setSelected(model.isExecute());
|
||||||
volatileCB.setSelected(model.isVolatile());
|
volatileCB.setSelected(model.isVolatile());
|
||||||
|
artificialCB.setSelected(model.isArtificial());
|
||||||
overlayCB.setSelected(model.isOverlay());
|
overlayCB.setSelected(model.isOverlay());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +171,11 @@ class AddBlockDialog extends DialogComponentProvider implements ChangeListener {
|
||||||
volatileCB.setSelected(model.isVolatile());
|
volatileCB.setSelected(model.isVolatile());
|
||||||
volatileCB.addActionListener(e -> model.setVolatile(volatileCB.isSelected()));
|
volatileCB.addActionListener(e -> model.setVolatile(volatileCB.isSelected()));
|
||||||
|
|
||||||
|
artificialCB = new GCheckBox("Artificial");
|
||||||
|
artificialCB.setName("Artificial");
|
||||||
|
artificialCB.setSelected(model.isArtificial());
|
||||||
|
artificialCB.addActionListener(e -> model.setArtificial(artificialCB.isSelected()));
|
||||||
|
|
||||||
overlayCB = new GCheckBox("Overlay");
|
overlayCB = new GCheckBox("Overlay");
|
||||||
overlayCB.setName("Overlay");
|
overlayCB.setName("Overlay");
|
||||||
overlayCB.setSelected(model.isOverlay());
|
overlayCB.setSelected(model.isOverlay());
|
||||||
|
@ -180,6 +187,7 @@ class AddBlockDialog extends DialogComponentProvider implements ChangeListener {
|
||||||
panel.add(writeCB);
|
panel.add(writeCB);
|
||||||
panel.add(executeCB);
|
panel.add(executeCB);
|
||||||
panel.add(volatileCB);
|
panel.add(volatileCB);
|
||||||
|
panel.add(artificialCB);
|
||||||
panel.add(overlayCB);
|
panel.add(overlayCB);
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
|
@ -320,6 +328,7 @@ class AddBlockDialog extends DialogComponentProvider implements ChangeListener {
|
||||||
writeCB.setSelected(model.isWrite());
|
writeCB.setSelected(model.isWrite());
|
||||||
executeCB.setSelected(model.isExecute());
|
executeCB.setSelected(model.isExecute());
|
||||||
volatileCB.setSelected(model.isVolatile());
|
volatileCB.setSelected(model.isVolatile());
|
||||||
|
artificialCB.setSelected(model.isArtificial());
|
||||||
overlayCB.setSelected(model.isOverlay());
|
overlayCB.setSelected(model.isOverlay());
|
||||||
|
|
||||||
setOkEnabled(false);
|
setOkEnabled(false);
|
||||||
|
|
|
@ -18,7 +18,6 @@ package ghidra.app.plugin.core.memory;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
import ghidra.app.cmd.memory.*;
|
import ghidra.app.cmd.memory.*;
|
||||||
import ghidra.framework.cmd.Command;
|
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.database.mem.ByteMappingScheme;
|
import ghidra.program.database.mem.ByteMappingScheme;
|
||||||
import ghidra.program.database.mem.FileBytes;
|
import ghidra.program.database.mem.FileBytes;
|
||||||
|
@ -55,6 +54,7 @@ class AddBlockModel {
|
||||||
private boolean isWrite;
|
private boolean isWrite;
|
||||||
private boolean isExecute;
|
private boolean isExecute;
|
||||||
private boolean isVolatile;
|
private boolean isVolatile;
|
||||||
|
private boolean isArtificial;
|
||||||
private InitializedType initializedType;
|
private InitializedType initializedType;
|
||||||
private String comment;
|
private String comment;
|
||||||
private FileBytes fileBytes;
|
private FileBytes fileBytes;
|
||||||
|
@ -125,6 +125,7 @@ class AddBlockModel {
|
||||||
isExecute = false;
|
isExecute = false;
|
||||||
isVolatile = false;
|
isVolatile = false;
|
||||||
isOverlay = false;
|
isOverlay = false;
|
||||||
|
isArtificial = false;
|
||||||
schemeDestByteCount = blockType == MemoryBlockType.BIT_MAPPED ? 8 : 1;
|
schemeDestByteCount = blockType == MemoryBlockType.BIT_MAPPED ? 8 : 1;
|
||||||
schemeSrcByteCount = 1;
|
schemeSrcByteCount = 1;
|
||||||
initializedType = InitializedType.UNINITIALIZED;
|
initializedType = InitializedType.UNINITIALIZED;
|
||||||
|
@ -148,6 +149,10 @@ class AddBlockModel {
|
||||||
this.isVolatile = b;
|
this.isVolatile = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setArtificial(boolean b) {
|
||||||
|
this.isArtificial = b;
|
||||||
|
}
|
||||||
|
|
||||||
void setOverlay(boolean b) {
|
void setOverlay(boolean b) {
|
||||||
this.isOverlay = b;
|
this.isOverlay = b;
|
||||||
validateInfo();
|
validateInfo();
|
||||||
|
@ -226,6 +231,10 @@ class AddBlockModel {
|
||||||
return isVolatile;
|
return isVolatile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isArtificial() {
|
||||||
|
return isArtificial;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isOverlay() {
|
boolean isOverlay() {
|
||||||
return isOverlay;
|
return isOverlay;
|
||||||
}
|
}
|
||||||
|
@ -240,7 +249,8 @@ class AddBlockModel {
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Command cmd = createAddBlockCommand();
|
AbstractAddMemoryBlockCmd cmd = createAddBlockCommand();
|
||||||
|
cmd.setArtificial(isArtificial);
|
||||||
if (!tool.execute(cmd, program)) {
|
if (!tool.execute(cmd, program)) {
|
||||||
message = cmd.getStatusMsg();
|
message = cmd.getStatusMsg();
|
||||||
return false;
|
return false;
|
||||||
|
@ -248,7 +258,7 @@ class AddBlockModel {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Command createAddBlockCommand() {
|
AbstractAddMemoryBlockCmd createAddBlockCommand() {
|
||||||
String source = "";
|
String source = "";
|
||||||
switch (blockType) {
|
switch (blockType) {
|
||||||
case BIT_MAPPED:
|
case BIT_MAPPED:
|
||||||
|
@ -267,7 +277,7 @@ class AddBlockModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Command createNonMappedMemoryBlock(String source) {
|
private AbstractAddMemoryBlockCmd createNonMappedMemoryBlock(String source) {
|
||||||
switch (initializedType) {
|
switch (initializedType) {
|
||||||
case INITIALIZED_FROM_FILE_BYTES:
|
case INITIALIZED_FROM_FILE_BYTES:
|
||||||
return new AddFileBytesMemoryBlockCmd(blockName, comment, source, startAddr, length,
|
return new AddFileBytesMemoryBlockCmd(blockName, comment, source, startAddr, length,
|
||||||
|
@ -293,8 +303,8 @@ class AddBlockModel {
|
||||||
private void validateInfo() {
|
private void validateInfo() {
|
||||||
message = "";
|
message = "";
|
||||||
isValid = hasValidName() && hasValidStartAddress() && hasValidLength() &&
|
isValid = hasValidName() && hasValidStartAddress() && hasValidLength() &&
|
||||||
hasNoMemoryConflicts() && hasMappedAddressIfNeeded() &&
|
hasNoMemoryConflicts() && hasMappedAddressIfNeeded() && hasInitialValueIfNeeded() &&
|
||||||
hasInitialValueIfNeeded() && hasFileBytesInfoIfNeeded() && isOverlayIfOtherSpace();
|
hasFileBytesInfoIfNeeded() && isOverlayIfOtherSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasFileBytesInfoIfNeeded() {
|
private boolean hasFileBytesInfoIfNeeded() {
|
||||||
|
|
|
@ -363,6 +363,7 @@ class MemoryMapManager {
|
||||||
newBlock.setWrite(bigBlock.isWrite());
|
newBlock.setWrite(bigBlock.isWrite());
|
||||||
newBlock.setExecute(bigBlock.isExecute());
|
newBlock.setExecute(bigBlock.isExecute());
|
||||||
newBlock.setVolatile(bigBlock.isVolatile());
|
newBlock.setVolatile(bigBlock.isVolatile());
|
||||||
|
newBlock.setArtificial(bigBlock.isArtificial());
|
||||||
newBlock.setSourceName("Resized Memory Block");
|
newBlock.setSourceName("Resized Memory Block");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -51,12 +51,13 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
final static byte WRITE = 5;
|
final static byte WRITE = 5;
|
||||||
final static byte EXECUTE = 6;
|
final static byte EXECUTE = 6;
|
||||||
final static byte VOLATILE = 7;
|
final static byte VOLATILE = 7;
|
||||||
final static byte OVERLAY = 8;
|
final static byte ARTIFICIAL = 8;
|
||||||
final static byte BLOCK_TYPE = 9;
|
final static byte OVERLAY = 9;
|
||||||
final static byte INIT = 10;
|
final static byte BLOCK_TYPE = 10;
|
||||||
final static byte BYTE_SOURCE = 11;
|
final static byte INIT = 11;
|
||||||
final static byte SOURCE = 12;
|
final static byte BYTE_SOURCE = 12;
|
||||||
final static byte COMMENT = 13;
|
final static byte SOURCE = 13;
|
||||||
|
final static byte COMMENT = 14;
|
||||||
|
|
||||||
final static String NAME_COL = "Name";
|
final static String NAME_COL = "Name";
|
||||||
final static String START_COL = "Start";
|
final static String START_COL = "Start";
|
||||||
|
@ -66,6 +67,7 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
final static String WRITE_COL = "W";
|
final static String WRITE_COL = "W";
|
||||||
final static String EXECUTE_COL = "X";
|
final static String EXECUTE_COL = "X";
|
||||||
final static String VOLATILE_COL = "Volatile";
|
final static String VOLATILE_COL = "Volatile";
|
||||||
|
final static String ARTIFICIAL_COL = "Artificial";
|
||||||
final static String OVERLAY_COL = "Overlayed Space";
|
final static String OVERLAY_COL = "Overlayed Space";
|
||||||
final static String BLOCK_TYPE_COL = "Type";
|
final static String BLOCK_TYPE_COL = "Type";
|
||||||
final static String INIT_COL = "Initialized";
|
final static String INIT_COL = "Initialized";
|
||||||
|
@ -80,9 +82,9 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
private List<MemoryBlock> memList;
|
private List<MemoryBlock> memList;
|
||||||
private MemoryMapProvider provider;
|
private MemoryMapProvider provider;
|
||||||
|
|
||||||
private final static String COLUMN_NAMES[] =
|
private final static String COLUMN_NAMES[] = { NAME_COL, START_COL, END_COL, LENGTH_COL,
|
||||||
{ NAME_COL, START_COL, END_COL, LENGTH_COL, READ_COL, WRITE_COL, EXECUTE_COL, VOLATILE_COL,
|
READ_COL, WRITE_COL, EXECUTE_COL, VOLATILE_COL, ARTIFICIAL_COL, OVERLAY_COL, BLOCK_TYPE_COL,
|
||||||
OVERLAY_COL, BLOCK_TYPE_COL, INIT_COL, BYTE_SOURCE_COL, SOURCE_COL, COMMENT_COL };
|
INIT_COL, BYTE_SOURCE_COL, SOURCE_COL, COMMENT_COL };
|
||||||
|
|
||||||
MemoryMapModel(MemoryMapProvider provider, Program program) {
|
MemoryMapModel(MemoryMapProvider provider, Program program) {
|
||||||
super(START);
|
super(START);
|
||||||
|
@ -124,7 +126,7 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
@Override
|
@Override
|
||||||
public boolean isSortable(int columnIndex) {
|
public boolean isSortable(int columnIndex) {
|
||||||
if (columnIndex == READ || columnIndex == WRITE || columnIndex == EXECUTE ||
|
if (columnIndex == READ || columnIndex == WRITE || columnIndex == EXECUTE ||
|
||||||
columnIndex == VOLATILE || columnIndex == INIT) {
|
columnIndex == VOLATILE || columnIndex == ARTIFICIAL || columnIndex == INIT) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -163,7 +165,7 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
if (columnIndex == READ || columnIndex == WRITE || columnIndex == EXECUTE ||
|
if (columnIndex == READ || columnIndex == WRITE || columnIndex == EXECUTE ||
|
||||||
columnIndex == VOLATILE || columnIndex == INIT) {
|
columnIndex == VOLATILE || columnIndex == ARTIFICIAL || columnIndex == INIT) {
|
||||||
return Boolean.class;
|
return Boolean.class;
|
||||||
}
|
}
|
||||||
return String.class;
|
return String.class;
|
||||||
|
@ -178,6 +180,8 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
case WRITE:
|
case WRITE:
|
||||||
case EXECUTE:
|
case EXECUTE:
|
||||||
case VOLATILE:
|
case VOLATILE:
|
||||||
|
case ARTIFICIAL:
|
||||||
|
return true;
|
||||||
case COMMENT:
|
case COMMENT:
|
||||||
return true;
|
return true;
|
||||||
case INIT:
|
case INIT:
|
||||||
|
@ -267,6 +271,14 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ARTIFICIAL: {
|
||||||
|
program.withTransaction("Set Artificial State", () -> {
|
||||||
|
boolean value = ((Boolean) aValue).booleanValue();
|
||||||
|
block.setArtificial(value);
|
||||||
|
provider.setStatusText("");
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
case INIT:
|
case INIT:
|
||||||
MemoryBlockType blockType = block.getType();
|
MemoryBlockType blockType = block.getType();
|
||||||
if (blockType == MemoryBlockType.BIT_MAPPED ||
|
if (blockType == MemoryBlockType.BIT_MAPPED ||
|
||||||
|
@ -428,6 +440,8 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
return block.isExecute() ? Boolean.TRUE : Boolean.FALSE;
|
return block.isExecute() ? Boolean.TRUE : Boolean.FALSE;
|
||||||
case VOLATILE:
|
case VOLATILE:
|
||||||
return block.isVolatile() ? Boolean.TRUE : Boolean.FALSE;
|
return block.isVolatile() ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
case ARTIFICIAL:
|
||||||
|
return block.isArtificial() ? Boolean.TRUE : Boolean.FALSE;
|
||||||
case OVERLAY:
|
case OVERLAY:
|
||||||
return getOverlayBaseSpaceName(block);
|
return getOverlayBaseSpaceName(block);
|
||||||
case INIT:
|
case INIT:
|
||||||
|
@ -554,29 +568,21 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
|
||||||
case LENGTH:
|
case LENGTH:
|
||||||
return (int) (b1.getSize() - b2.getSize());
|
return (int) (b1.getSize() - b2.getSize());
|
||||||
case READ:
|
case READ:
|
||||||
int b1r = (b1.isRead() ? 1 : -1);
|
return Boolean.compare(b1.isRead(), b2.isRead());
|
||||||
int b2r = (b2.isRead() ? 1 : -1);
|
|
||||||
return (b1r - b2r);
|
|
||||||
case WRITE:
|
case WRITE:
|
||||||
int b1w = (b1.isWrite() ? 1 : -1);
|
return Boolean.compare(b1.isWrite(), b2.isWrite());
|
||||||
int b2w = (b2.isWrite() ? 1 : -1);
|
|
||||||
return (b1w - b2w);
|
|
||||||
case EXECUTE:
|
case EXECUTE:
|
||||||
int b1x = (b1.isExecute() ? 1 : -1);
|
return Boolean.compare(b1.isExecute(), b2.isExecute());
|
||||||
int b2x = (b2.isExecute() ? 1 : -1);
|
|
||||||
return (b1x - b2x);
|
|
||||||
case VOLATILE:
|
case VOLATILE:
|
||||||
int b1v = (b1.isVolatile() ? 1 : -1);
|
return Boolean.compare(b1.isVolatile(), b2.isVolatile());
|
||||||
int b2v = (b2.isVolatile() ? 1 : -1);
|
case ARTIFICIAL:
|
||||||
return (b1v - b2v);
|
return Boolean.compare(b1.isArtificial(), b2.isArtificial());
|
||||||
case OVERLAY:
|
case OVERLAY:
|
||||||
String ov1 = getOverlayBaseSpaceName(b1);
|
String ov1 = getOverlayBaseSpaceName(b1);
|
||||||
String ov2 = getOverlayBaseSpaceName(b2);
|
String ov2 = getOverlayBaseSpaceName(b2);
|
||||||
return ov1.compareTo(ov2);
|
return ov1.compareTo(ov2);
|
||||||
case INIT:
|
case INIT:
|
||||||
int b1init = (b1.isInitialized() ? 1 : -1);
|
return Boolean.compare(b1.isInitialized(), b2.isInitialized());
|
||||||
int b2init = (b2.isInitialized() ? 1 : -1);
|
|
||||||
return (b1init - b2init);
|
|
||||||
|
|
||||||
//case BYTE_SOURCE: - handled by default comparator
|
//case BYTE_SOURCE: - handled by default comparator
|
||||||
|
|
||||||
|
|
|
@ -480,6 +480,13 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||||
column.setResizable(false);
|
column.setResizable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
column = table.getColumn(MemoryMapModel.ARTIFICIAL_COL);
|
||||||
|
if (column != null) {
|
||||||
|
column.setMaxWidth(65);
|
||||||
|
column.setMinWidth(65);
|
||||||
|
column.setResizable(false);
|
||||||
|
}
|
||||||
|
|
||||||
column = table.getColumn(MemoryMapModel.BLOCK_TYPE_COL);
|
column = table.getColumn(MemoryMapModel.BLOCK_TYPE_COL);
|
||||||
if (column != null) {
|
if (column != null) {
|
||||||
column.setMinWidth(25);
|
column.setMinWidth(25);
|
||||||
|
|
|
@ -109,6 +109,7 @@ public class StringsAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
public static enum Alignment {
|
public static enum Alignment {
|
||||||
ALIGN_1(1), ALIGN_2(2), ALIGN_4(4);
|
ALIGN_1(1), ALIGN_2(2), ALIGN_4(4);
|
||||||
|
|
||||||
private int alignment;
|
private int alignment;
|
||||||
|
|
||||||
Alignment(int alignment) {
|
Alignment(int alignment) {
|
||||||
|
@ -349,7 +350,10 @@ public class StringsAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
AddressSet addresses = new AddressSet();
|
AddressSet addresses = new AddressSet();
|
||||||
for (MemoryBlock memBlock : blocks) {
|
for (MemoryBlock memBlock : blocks) {
|
||||||
if (memBlock.getPermissions() > 0) {
|
if (!memBlock.isLoaded()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (memBlock.isWrite() || memBlock.isRead() || memBlock.isExecute()) {
|
||||||
addresses = addresses.union(new AddressSet(memBlock.getStart(), memBlock.getEnd()));
|
addresses = addresses.union(new AddressSet(memBlock.getStart(), memBlock.getEnd()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,14 +585,15 @@ public class StringsAnalyzer extends AbstractAnalyzer {
|
||||||
modelName = options.getString(MODELFILE_OPTION_NAME, MODEL_DEFAULT_NAME);
|
modelName = options.getString(MODELFILE_OPTION_NAME, MODEL_DEFAULT_NAME);
|
||||||
setTrigramFileName(modelName);
|
setTrigramFileName(modelName);
|
||||||
|
|
||||||
minStringLength = options.getEnum(MINIMUM_STRING_LENGTH_OPTION_NAME,
|
minStringLength =
|
||||||
MINIMUM_STRING_LENGTH_DEFAULT_VALUE).getMinLength();
|
options.getEnum(MINIMUM_STRING_LENGTH_OPTION_NAME, MINIMUM_STRING_LENGTH_DEFAULT_VALUE)
|
||||||
|
.getMinLength();
|
||||||
|
|
||||||
requireNullEnd = options.getBoolean(REQUIRE_NULL_TERMINATION_OPTION_NAME,
|
requireNullEnd = options.getBoolean(REQUIRE_NULL_TERMINATION_OPTION_NAME,
|
||||||
REQUIRE_NULL_TERMINATION_DEFAULT_VALUE);
|
REQUIRE_NULL_TERMINATION_DEFAULT_VALUE);
|
||||||
|
|
||||||
startAlignment = options.getEnum(START_ALIGNMENT_OPTION_NAME,
|
startAlignment = options.getEnum(START_ALIGNMENT_OPTION_NAME, START_ALIGNMENT_DEFAULT_VALUE)
|
||||||
START_ALIGNMENT_DEFAULT_VALUE).getAlignment();
|
.getAlignment();
|
||||||
|
|
||||||
setStringEndAlignment(
|
setStringEndAlignment(
|
||||||
options.getInt(END_ALIGNMENT_OPTION_NAME, END_ALIGNMENT_DEFAULT_VALUE));
|
options.getInt(END_ALIGNMENT_OPTION_NAME, END_ALIGNMENT_DEFAULT_VALUE));
|
||||||
|
|
|
@ -706,9 +706,9 @@ public class ThreadEnvironmentBlock {
|
||||||
* @throws CodeUnitInsertionException for problems laying down the structure on the block
|
* @throws CodeUnitInsertionException for problems laying down the structure on the block
|
||||||
* @throws InvalidInputException for problems with the symbol name attached to the TEB
|
* @throws InvalidInputException for problems with the symbol name attached to the TEB
|
||||||
*/
|
*/
|
||||||
public void createBlockAndStructure() throws MemoryConflictException, LockException,
|
public void createBlockAndStructure()
|
||||||
IllegalArgumentException, AddressOverflowException, CodeUnitInsertionException,
|
throws MemoryConflictException, LockException, IllegalArgumentException,
|
||||||
InvalidInputException {
|
AddressOverflowException, CodeUnitInsertionException, InvalidInputException {
|
||||||
Memory memory = program.getMemory();
|
Memory memory = program.getMemory();
|
||||||
MemoryBlock block = memory.getBlock(BLOCK_NAME);
|
MemoryBlock block = memory.getBlock(BLOCK_NAME);
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
|
@ -722,6 +722,7 @@ public class ThreadEnvironmentBlock {
|
||||||
block = memory.createUninitializedBlock(BLOCK_NAME, tebAddress, blockSize, false);
|
block = memory.createUninitializedBlock(BLOCK_NAME, tebAddress, blockSize, false);
|
||||||
}
|
}
|
||||||
block.setWrite(true);
|
block.setWrite(true);
|
||||||
|
block.setArtificial(true);
|
||||||
LayDownStructure laydown = new LayDownStructure(is64Bit);
|
LayDownStructure laydown = new LayDownStructure(is64Bit);
|
||||||
create(laydown);
|
create(laydown);
|
||||||
if (is64Bit) {
|
if (is64Bit) {
|
||||||
|
@ -806,6 +807,7 @@ public class ThreadEnvironmentBlock {
|
||||||
null, false);
|
null, false);
|
||||||
}
|
}
|
||||||
block1.setWrite(true);
|
block1.setWrite(true);
|
||||||
|
block1.setArtificial(true);
|
||||||
LayDownFlat laydown = new LayDownFlat(program, tebAddress, is64Bit);
|
LayDownFlat laydown = new LayDownFlat(program, tebAddress, is64Bit);
|
||||||
create(laydown);
|
create(laydown);
|
||||||
Data data = program.getListing().getDataAt(tebAddress.add(is64Bit ? 0x30 : 0x18));
|
Data data = program.getListing().getDataAt(tebAddress.add(is64Bit ? 0x30 : 0x18));
|
||||||
|
|
|
@ -349,6 +349,9 @@ public class CoffLoader extends AbstractLibrarySupportLoader {
|
||||||
// assume any value in external is writable.
|
// assume any value in external is writable.
|
||||||
block.setWrite(true);
|
block.setWrite(true);
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
Address current = externalAddressStart;
|
Address current = externalAddressStart;
|
||||||
while (current.compareTo(externalAddress) < 0) {
|
while (current.compareTo(externalAddress) < 0) {
|
||||||
createUndefined(program.getListing(), program.getMemory(), current,
|
createUndefined(program.getListing(), program.getMemory(), current,
|
||||||
|
@ -745,8 +748,8 @@ public class CoffLoader extends AbstractLibrarySupportLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRelocationError(Program program, Address address,
|
private void handleRelocationError(Program program, Address address, Short relocationType,
|
||||||
Short relocationType, String message, Exception causeToReport) {
|
String message, Exception causeToReport) {
|
||||||
String bookmarkMessage =
|
String bookmarkMessage =
|
||||||
String.format("Failed to apply COFF Relocation type 0x%x: %s", relocationType, message);
|
String.format("Failed to apply COFF Relocation type 0x%x: %s", relocationType, message);
|
||||||
program.getBookmarkManager()
|
program.getBookmarkManager()
|
||||||
|
|
|
@ -1546,6 +1546,10 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
||||||
|
|
||||||
// assume any value in external is writable.
|
// assume any value in external is writable.
|
||||||
block.setWrite(true);
|
block.setWrite(true);
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
block.setSourceName(BLOCK_SOURCE_NAME);
|
block.setSourceName(BLOCK_SOURCE_NAME);
|
||||||
block.setComment(
|
block.setComment(
|
||||||
"NOTE: This block is artificial and allows ELF Relocations to work correctly");
|
"NOTE: This block is artificial and allows ELF Relocations to work correctly");
|
||||||
|
|
|
@ -105,8 +105,8 @@ public class MachoProgramBuilder {
|
||||||
*/
|
*/
|
||||||
public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes,
|
public static void buildProgram(Program program, ByteProvider provider, FileBytes fileBytes,
|
||||||
MessageLog log, TaskMonitor monitor) throws Exception {
|
MessageLog log, TaskMonitor monitor) throws Exception {
|
||||||
MachoProgramBuilder machoProgramBuilder = new MachoProgramBuilder(program, provider,
|
MachoProgramBuilder machoProgramBuilder =
|
||||||
fileBytes, log, monitor);
|
new MachoProgramBuilder(program, provider, fileBytes, log, monitor);
|
||||||
machoProgramBuilder.build();
|
machoProgramBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,8 +339,7 @@ public class MachoProgramBuilder {
|
||||||
* @param suffix An optional suffix that will get appended to tree segment and segment nodes
|
* @param suffix An optional suffix that will get appended to tree segment and segment nodes
|
||||||
* @throws Exception if there was a problem fixing up the Program Tree
|
* @throws Exception if there was a problem fixing up the Program Tree
|
||||||
*/
|
*/
|
||||||
protected void fixupProgramTree(String suffix)
|
protected void fixupProgramTree(String suffix) throws Exception {
|
||||||
throws Exception {
|
|
||||||
if (suffix == null) {
|
if (suffix == null) {
|
||||||
suffix = "";
|
suffix = "";
|
||||||
}
|
}
|
||||||
|
@ -680,6 +679,10 @@ public class MachoProgramBuilder {
|
||||||
start, undefinedSymbols.size() * machoHeader.getAddressSize(), false);
|
start, undefinedSymbols.size() * machoHeader.getAddressSize(), false);
|
||||||
// assume any value in external is writable.
|
// assume any value in external is writable.
|
||||||
block.setWrite(true);
|
block.setWrite(true);
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
block.setSourceName(BLOCK_SOURCE_NAME);
|
block.setSourceName(BLOCK_SOURCE_NAME);
|
||||||
block.setComment(
|
block.setComment(
|
||||||
"NOTE: This block is artificial and is used to make relocations work correctly");
|
"NOTE: This block is artificial and is used to make relocations work correctly");
|
||||||
|
@ -792,7 +795,8 @@ public class MachoProgramBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBindings(BindingTable bindingTable, List<String> libraryPaths) throws Exception {
|
private void processBindings(BindingTable bindingTable, List<String> libraryPaths)
|
||||||
|
throws Exception {
|
||||||
DataConverter converter = DataConverter.getInstance(program.getLanguage().isBigEndian());
|
DataConverter converter = DataConverter.getInstance(program.getLanguage().isBigEndian());
|
||||||
SymbolTable symbolTable = program.getSymbolTable();
|
SymbolTable symbolTable = program.getSymbolTable();
|
||||||
|
|
||||||
|
@ -1310,9 +1314,10 @@ public class MachoProgramBuilder {
|
||||||
}
|
}
|
||||||
program.getRelocationTable()
|
program.getRelocationTable()
|
||||||
.add(address, result.status(), relocationInfo.getType(),
|
.add(address, result.status(), relocationInfo.getType(),
|
||||||
new long[] { relocationInfo.getValue(),
|
new long[] { relocationInfo.getValue(), relocationInfo.getLength(),
|
||||||
relocationInfo.getLength(), relocationInfo.isPcRelocated() ? 1 : 0,
|
relocationInfo.isPcRelocated() ? 1 : 0,
|
||||||
relocationInfo.isExternal() ? 1 : 0, relocationInfo.isScattered() ? 1 : 0 },
|
relocationInfo.isExternal() ? 1 : 0,
|
||||||
|
relocationInfo.isScattered() ? 1 : 0 },
|
||||||
result.byteLength(),
|
result.byteLength(),
|
||||||
relocation != null ? relocation.getTargetDescription() : null);
|
relocation != null ? relocation.getTargetDescription() : null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,8 +256,8 @@ public class NeLoader extends AbstractOrdinalSupportLoader {
|
||||||
}
|
}
|
||||||
MemoryBlock block;
|
MemoryBlock block;
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
block = MemoryBlockUtils.createInitializedBlock(program, false,
|
block = MemoryBlockUtils.createInitializedBlock(program, false, name, addr,
|
||||||
name, addr, fileBytes, offset, length, "", "", r, w, x, log);
|
fileBytes, offset, length, "", "", r, w, x, log);
|
||||||
if (length < minalloc) {
|
if (length < minalloc) {
|
||||||
// Things actually rely on the block being padded out with real 0's, so we
|
// Things actually rely on the block being padded out with real 0's, so we
|
||||||
// must expand it
|
// must expand it
|
||||||
|
@ -354,8 +354,7 @@ public class NeLoader extends AbstractOrdinalSupportLoader {
|
||||||
int length = resource.getFileLengthShifted();
|
int length = resource.getFileLengthShifted();
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
MemoryBlockUtils.createInitializedBlock(program, false, "Rsrc" + (id++),
|
MemoryBlockUtils.createInitializedBlock(program, false, "Rsrc" + (id++),
|
||||||
addr, fileBytes, offset, length, "", "", true,
|
addr, fileBytes, offset, length, "", "", true, false, false, log);
|
||||||
false, false, log);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AddressOverflowException e) {
|
catch (AddressOverflowException e) {
|
||||||
|
@ -445,8 +444,12 @@ public class NeLoader extends AbstractOrdinalSupportLoader {
|
||||||
String comment = "";
|
String comment = "";
|
||||||
String source = "";
|
String source = "";
|
||||||
// This isn't a real block, just place holder addresses, so don't create an initialized block
|
// This isn't a real block, just place holder addresses, so don't create an initialized block
|
||||||
MemoryBlockUtils.createUninitializedBlock(program, false, MemoryBlock.EXTERNAL_BLOCK_NAME,
|
MemoryBlock block = MemoryBlockUtils.createUninitializedBlock(program, false,
|
||||||
addr, length, comment, source, true, false, false, log);
|
MemoryBlock.EXTERNAL_BLOCK_NAME, addr, length, comment, source, true, false, false,
|
||||||
|
log);
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
for (int i = 0; i < names.length; ++i) {
|
for (int i = 0; i < names.length; ++i) {
|
||||||
String moduleName = names[i].getString();
|
String moduleName = names[i].getString();
|
||||||
|
|
|
@ -204,7 +204,7 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
||||||
int method, index, locationType = -1;
|
int method, index, locationType = -1;
|
||||||
locAddress = null;
|
locAddress = null;
|
||||||
|
|
||||||
if(fixup.getDataBlock() == null) {
|
if (fixup.getDataBlock() == null) {
|
||||||
continue; // If no data block don't try to fixup
|
continue; // If no data block don't try to fixup
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -613,6 +613,9 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
|
||||||
// assume any value in external is writable.
|
// assume any value in external is writable.
|
||||||
block.setWrite(true);
|
block.setWrite(true);
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
Address current = externalAddressStart;
|
Address current = externalAddressStart;
|
||||||
while (current.compareTo(externalAddress) < 0) {
|
while (current.compareTo(externalAddress) < 0) {
|
||||||
createUndefined(program.getListing(), program.getMemory(), current,
|
createUndefined(program.getListing(), program.getMemory(), current,
|
||||||
|
|
|
@ -52,8 +52,7 @@ class MemoryMapXmlMgr {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void read(XmlPullParser parser, boolean overwriteConflicts, TaskMonitor monitor,
|
void read(XmlPullParser parser, boolean overwriteConflicts, TaskMonitor monitor,
|
||||||
String directory)
|
String directory) throws SAXParseException, FileNotFoundException, CancelledException {
|
||||||
throws SAXParseException, FileNotFoundException, CancelledException {
|
|
||||||
|
|
||||||
XmlElement element = parser.next();
|
XmlElement element = parser.next();
|
||||||
element = parser.next();
|
element = parser.next();
|
||||||
|
@ -71,8 +70,7 @@ class MemoryMapXmlMgr {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processMemoryBlock(XmlElement memorySectionElement, XmlPullParser parser,
|
private void processMemoryBlock(XmlElement memorySectionElement, XmlPullParser parser,
|
||||||
String directory, Program program, TaskMonitor monitor)
|
String directory, Program program, TaskMonitor monitor) throws FileNotFoundException {
|
||||||
throws FileNotFoundException {
|
|
||||||
|
|
||||||
String name = memorySectionElement.getAttribute("NAME");
|
String name = memorySectionElement.getAttribute("NAME");
|
||||||
String addrStr = memorySectionElement.getAttribute("START_ADDR");
|
String addrStr = memorySectionElement.getAttribute("START_ADDR");
|
||||||
|
@ -91,6 +89,9 @@ class MemoryMapXmlMgr {
|
||||||
String volatility = memorySectionElement.getAttribute("VOLATILE");
|
String volatility = memorySectionElement.getAttribute("VOLATILE");
|
||||||
boolean isVolatile = "y".equals(volatility);
|
boolean isVolatile = "y".equals(volatility);
|
||||||
|
|
||||||
|
String artificial = memorySectionElement.getAttribute("ARTIFICIAL");
|
||||||
|
boolean isArtificial = "y".equals(artificial);
|
||||||
|
|
||||||
String comment = memorySectionElement.getAttribute("COMMENT");
|
String comment = memorySectionElement.getAttribute("COMMENT");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -124,12 +125,12 @@ class MemoryMapXmlMgr {
|
||||||
element = parser.peek();//get next start of contents or end of section
|
element = parser.peek();//get next start of contents or end of section
|
||||||
}
|
}
|
||||||
if (overlayName != null) {
|
if (overlayName != null) {
|
||||||
MemoryBlock block =
|
MemoryBlock block = MemoryBlockUtils.createInitializedBlock(program, true,
|
||||||
MemoryBlockUtils.createInitializedBlock(program, true, overlayName, addr,
|
overlayName, addr, new ByteArrayInputStream(bytes), bytes.length, comment,
|
||||||
new ByteArrayInputStream(bytes),
|
null, r, w, x, log, monitor);
|
||||||
bytes.length, comment, null, r, w, x, log, monitor);
|
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
block.setVolatile(isVolatile);
|
block.setVolatile(isVolatile);
|
||||||
|
block.setArtificial(isArtificial);
|
||||||
if (!name.equals(overlayName)) {
|
if (!name.equals(overlayName)) {
|
||||||
block.setName(name);
|
block.setName(name);
|
||||||
}
|
}
|
||||||
|
@ -138,8 +139,8 @@ class MemoryMapXmlMgr {
|
||||||
else {
|
else {
|
||||||
|
|
||||||
MemoryBlock block = MemoryBlockUtils.createInitializedBlock(program, false,
|
MemoryBlock block = MemoryBlockUtils.createInitializedBlock(program, false,
|
||||||
name, addr, new ByteArrayInputStream(bytes), bytes.length, comment, null,
|
name, addr, new ByteArrayInputStream(bytes), bytes.length, comment, null, r,
|
||||||
r, w, x, log, monitor);
|
w, x, log, monitor);
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
block.setVolatile(isVolatile);
|
block.setVolatile(isVolatile);
|
||||||
}
|
}
|
||||||
|
@ -297,6 +298,10 @@ class MemoryMapXmlMgr {
|
||||||
attrs.addAttribute("VOLATILE", true);
|
attrs.addAttribute("VOLATILE", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (block.isArtificial()) {
|
||||||
|
attrs.addAttribute("ARTIFICIAL", true);
|
||||||
|
}
|
||||||
|
|
||||||
writer.startElement("MEMORY_SECTION", attrs);
|
writer.startElement("MEMORY_SECTION", attrs);
|
||||||
|
|
||||||
if (block.getType() == MemoryBlockType.BIT_MAPPED) {
|
if (block.getType() == MemoryBlockType.BIT_MAPPED) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -24,6 +23,7 @@ import ghidra.util.SystemUtilities;
|
||||||
*/
|
*/
|
||||||
public class MemoryBlockDiff {
|
public class MemoryBlockDiff {
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
public static final int NAME = 0x001;
|
public static final int NAME = 0x001;
|
||||||
public static final int START_ADDRESS = 0x002;
|
public static final int START_ADDRESS = 0x002;
|
||||||
public static final int END_ADDRESS = 0x004;
|
public static final int END_ADDRESS = 0x004;
|
||||||
|
@ -32,11 +32,13 @@ public class MemoryBlockDiff {
|
||||||
public static final int WRITE = 0x020;
|
public static final int WRITE = 0x020;
|
||||||
public static final int EXECUTE = 0x040;
|
public static final int EXECUTE = 0x040;
|
||||||
public static final int VOLATILE = 0x080;
|
public static final int VOLATILE = 0x080;
|
||||||
public static final int TYPE = 0x100;
|
public static final int ARTIFICIAL = 0x100;
|
||||||
public static final int INIT = 0x200;
|
public static final int TYPE = 0x200;
|
||||||
public static final int SOURCE = 0x400;
|
public static final int INIT = 0x400;
|
||||||
public static final int COMMENT = 0x800;
|
public static final int SOURCE = 0x800;
|
||||||
public static final int ALL = 0xFFF;
|
public static final int COMMENT = 0x1000;
|
||||||
|
public static final int ALL = 0x1FFF;
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
private MemoryBlock block1;
|
private MemoryBlock block1;
|
||||||
private MemoryBlock block2;
|
private MemoryBlock block2;
|
||||||
|
@ -118,6 +120,13 @@ public class MemoryBlockDiff {
|
||||||
return (diffFlags & VOLATILE) != 0;
|
return (diffFlags & VOLATILE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the memory blocks Artificial flags differ.
|
||||||
|
*/
|
||||||
|
public boolean isArtificialDifferent() {
|
||||||
|
return (diffFlags & ARTIFICIAL) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the type for the memory blocks differ.
|
* Returns true if the type for the memory blocks differ.
|
||||||
*/
|
*/
|
||||||
|
@ -151,40 +160,43 @@ public class MemoryBlockDiff {
|
||||||
*/
|
*/
|
||||||
public String getDifferencesAsString() {
|
public String getDifferencesAsString() {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
if((diffFlags & NAME) != 0) {
|
if ((diffFlags & NAME) != 0) {
|
||||||
buf.append("Name ");
|
buf.append("Name ");
|
||||||
}
|
}
|
||||||
if((diffFlags & START_ADDRESS) != 0) {
|
if ((diffFlags & START_ADDRESS) != 0) {
|
||||||
buf.append("StartAddress ");
|
buf.append("StartAddress ");
|
||||||
}
|
}
|
||||||
if((diffFlags & END_ADDRESS) != 0) {
|
if ((diffFlags & END_ADDRESS) != 0) {
|
||||||
buf.append("EndAddress ");
|
buf.append("EndAddress ");
|
||||||
}
|
}
|
||||||
if((diffFlags & SIZE) != 0) {
|
if ((diffFlags & SIZE) != 0) {
|
||||||
buf.append("Size ");
|
buf.append("Size ");
|
||||||
}
|
}
|
||||||
if((diffFlags & READ) != 0) {
|
if ((diffFlags & READ) != 0) {
|
||||||
buf.append("R ");
|
buf.append("R ");
|
||||||
}
|
}
|
||||||
if((diffFlags & WRITE) != 0) {
|
if ((diffFlags & WRITE) != 0) {
|
||||||
buf.append("W ");
|
buf.append("W ");
|
||||||
}
|
}
|
||||||
if((diffFlags & EXECUTE) != 0) {
|
if ((diffFlags & EXECUTE) != 0) {
|
||||||
buf.append("X ");
|
buf.append("X ");
|
||||||
}
|
}
|
||||||
if((diffFlags & VOLATILE) != 0) {
|
if ((diffFlags & VOLATILE) != 0) {
|
||||||
buf.append("Volatile ");
|
buf.append("Volatile ");
|
||||||
}
|
}
|
||||||
if((diffFlags & TYPE) != 0) {
|
if ((diffFlags & ARTIFICIAL) != 0) {
|
||||||
|
buf.append("Artificial ");
|
||||||
|
}
|
||||||
|
if ((diffFlags & TYPE) != 0) {
|
||||||
buf.append("Type ");
|
buf.append("Type ");
|
||||||
}
|
}
|
||||||
if((diffFlags & INIT) != 0) {
|
if ((diffFlags & INIT) != 0) {
|
||||||
buf.append("Initialized ");
|
buf.append("Initialized ");
|
||||||
}
|
}
|
||||||
if((diffFlags & SOURCE) != 0) {
|
if ((diffFlags & SOURCE) != 0) {
|
||||||
buf.append("Source ");
|
buf.append("Source ");
|
||||||
}
|
}
|
||||||
if((diffFlags & COMMENT) != 0) {
|
if ((diffFlags & COMMENT) != 0) {
|
||||||
buf.append("Comment ");
|
buf.append("Comment ");
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
|
@ -209,7 +221,7 @@ public class MemoryBlockDiff {
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if(!block1.getName().equals(block2.getName())) {
|
if (!block1.getName().equals(block2.getName())) {
|
||||||
flags |= NAME;
|
flags |= NAME;
|
||||||
}
|
}
|
||||||
if (!block1.getStart().equals(block2.getStart())) {
|
if (!block1.getStart().equals(block2.getStart())) {
|
||||||
|
@ -233,6 +245,9 @@ public class MemoryBlockDiff {
|
||||||
if (block1.isVolatile() != block2.isVolatile()) {
|
if (block1.isVolatile() != block2.isVolatile()) {
|
||||||
flags |= VOLATILE;
|
flags |= VOLATILE;
|
||||||
}
|
}
|
||||||
|
if (block1.isArtificial() != block2.isArtificial()) {
|
||||||
|
flags |= ARTIFICIAL;
|
||||||
|
}
|
||||||
if (!block1.getType().equals(block2.getType())) {
|
if (!block1.getType().equals(block2.getType())) {
|
||||||
flags |= TYPE;
|
flags |= TYPE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,7 @@ public class MemoryDiff {
|
||||||
* @throws ProgramConflictException if the program memory can't be compared because the programs
|
* @throws ProgramConflictException if the program memory can't be compared because the programs
|
||||||
* are based on different languages.
|
* are based on different languages.
|
||||||
*/
|
*/
|
||||||
public MemoryDiff(Program p1, Program p2)
|
public MemoryDiff(Program p1, Program p2) throws ProgramConflictException {
|
||||||
throws ProgramConflictException {
|
|
||||||
program1 = p1;
|
program1 = p1;
|
||||||
program2 = p2;
|
program2 = p2;
|
||||||
memory1 = program1.getMemory();
|
memory1 = program1.getMemory();
|
||||||
|
@ -82,7 +81,7 @@ public class MemoryDiff {
|
||||||
ProgramMemoryComparator memComp = new ProgramMemoryComparator(program1, program2);
|
ProgramMemoryComparator memComp = new ProgramMemoryComparator(program1, program2);
|
||||||
ArrayList<AddressRange> rangeList = new ArrayList<AddressRange>();
|
ArrayList<AddressRange> rangeList = new ArrayList<AddressRange>();
|
||||||
AddressRangeIterator rangeIter = memComp.getAddressRanges();
|
AddressRangeIterator rangeIter = memComp.getAddressRanges();
|
||||||
while(rangeIter.hasNext()) {
|
while (rangeIter.hasNext()) {
|
||||||
rangeList.add(rangeIter.next());
|
rangeList.add(rangeIter.next());
|
||||||
}
|
}
|
||||||
ranges = rangeList.toArray(new AddressRange[rangeList.size()]);
|
ranges = rangeList.toArray(new AddressRange[rangeList.size()]);
|
||||||
|
@ -153,7 +152,7 @@ public class MemoryDiff {
|
||||||
*/
|
*/
|
||||||
private int getAddressRangeIndex(Address address) {
|
private int getAddressRangeIndex(Address address) {
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = diffs.length-1;
|
int high = diffs.length - 1;
|
||||||
|
|
||||||
while (low <= high) {
|
while (low <= high) {
|
||||||
int mid = (low + high) >> 1;
|
int mid = (low + high) >> 1;
|
||||||
|
@ -201,7 +200,7 @@ public class MemoryDiff {
|
||||||
else if (block2 == null) {
|
else if (block2 == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!block1.getName().equals(block2.getName())) {
|
if (!block1.getName().equals(block2.getName())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!block1.getStart().equals(block2.getStart())) {
|
if (!block1.getStart().equals(block2.getStart())) {
|
||||||
|
@ -213,7 +212,7 @@ public class MemoryDiff {
|
||||||
if (block1.getSize() != block2.getSize()) {
|
if (block1.getSize() != block2.getSize()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (block1.getPermissions() != block2.getPermissions()) {
|
if (block1.getFlags() != block2.getFlags()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!block1.getType().equals(block2.getType())) {
|
if (!block1.getType().equals(block2.getType())) {
|
||||||
|
@ -234,7 +233,6 @@ public class MemoryDiff {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean merge(int row, int mergeFields, TaskMonitor monitor) {
|
public boolean merge(int row, int mergeFields, TaskMonitor monitor) {
|
||||||
if ((mergeFields & MemoryBlockDiff.ALL) == 0) {
|
if ((mergeFields & MemoryBlockDiff.ALL) == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -246,8 +244,8 @@ public class MemoryDiff {
|
||||||
MemoryBlock block1 = blockDiff.getBlock1();
|
MemoryBlock block1 = blockDiff.getBlock1();
|
||||||
MemoryBlock block2 = blockDiff.getBlock2();
|
MemoryBlock block2 = blockDiff.getBlock2();
|
||||||
AddressRange range = ranges[row];
|
AddressRange range = ranges[row];
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.START_ADDRESS)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.START_ADDRESS) &&
|
||||||
&& blockDiff.isStartAddressDifferent()) {
|
blockDiff.isStartAddressDifferent()) {
|
||||||
if (block1 == null) {
|
if (block1 == null) {
|
||||||
// Add all or part of a block.
|
// Add all or part of a block.
|
||||||
Address start2 = block2.getStart();
|
Address start2 = block2.getStart();
|
||||||
|
@ -295,64 +293,63 @@ public class MemoryDiff {
|
||||||
memory1.removeBlock(blockToRemove, monitor);
|
memory1.removeBlock(blockToRemove, monitor);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (LockException e) {
|
}
|
||||||
|
catch (LockException e) {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
} catch (NotFoundException e) {
|
}
|
||||||
|
catch (NotFoundException e) {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
} catch (AddressOutOfBoundsException e) {
|
}
|
||||||
|
catch (AddressOutOfBoundsException e) {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
} catch (MemoryBlockException e) {
|
}
|
||||||
|
catch (MemoryBlockException e) {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.END_ADDRESS)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.END_ADDRESS) &&
|
||||||
&& blockDiff.isEndAddressDifferent()) {
|
blockDiff.isEndAddressDifferent()) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.SIZE)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.SIZE) && blockDiff.isSizeDifferent()) {
|
||||||
&& blockDiff.isSizeDifferent()) {
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.TYPE)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.TYPE) && blockDiff.isTypeDifferent()) {
|
||||||
&& blockDiff.isTypeDifferent()) {
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.INIT)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.INIT) && blockDiff.isInitDifferent()) {
|
||||||
&& blockDiff.isInitDifferent()) {
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.NAME)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.NAME) && blockDiff.isNameDifferent()) {
|
||||||
&& blockDiff.isNameDifferent()) {
|
|
||||||
try {
|
try {
|
||||||
block1.setName(block2.getName());
|
block1.setName(block2.getName());
|
||||||
} catch (LockException e) {
|
}
|
||||||
|
catch (LockException e) {
|
||||||
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.READ)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.READ) && blockDiff.isReadDifferent()) {
|
||||||
&& blockDiff.isReadDifferent()) {
|
|
||||||
block1.setRead(block2.isRead());
|
block1.setRead(block2.isRead());
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.WRITE)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.WRITE) && blockDiff.isWriteDifferent()) {
|
||||||
&& blockDiff.isWriteDifferent()) {
|
|
||||||
block1.setWrite(block2.isWrite());
|
block1.setWrite(block2.isWrite());
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.EXECUTE)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.EXECUTE) && blockDiff.isExecDifferent()) {
|
||||||
&& blockDiff.isExecDifferent()) {
|
|
||||||
block1.setExecute(block2.isExecute());
|
block1.setExecute(block2.isExecute());
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.VOLATILE)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.VOLATILE) && blockDiff.isVolatileDifferent()) {
|
||||||
&& blockDiff.isVolatileDifferent()) {
|
|
||||||
block1.setVolatile(block2.isVolatile());
|
block1.setVolatile(block2.isVolatile());
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.SOURCE)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.ARTIFICIAL) &&
|
||||||
&& blockDiff.isSourceDifferent()) {
|
blockDiff.isArtificialDifferent()) {
|
||||||
|
block1.setArtificial(block2.isArtificial());
|
||||||
|
}
|
||||||
|
if (shouldMerge(mergeFields, MemoryBlockDiff.SOURCE) && blockDiff.isSourceDifferent()) {
|
||||||
block1.setSourceName(block2.getSourceName());
|
block1.setSourceName(block2.getSourceName());
|
||||||
}
|
}
|
||||||
if (shouldMerge(mergeFields, MemoryBlockDiff.COMMENT)
|
if (shouldMerge(mergeFields, MemoryBlockDiff.COMMENT) && blockDiff.isCommentDifferent()) {
|
||||||
&& blockDiff.isCommentDifferent()) {
|
|
||||||
block1.setComment(block2.getComment());
|
block1.setComment(block2.getComment());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -111,6 +111,7 @@ public class MemoryTypeProgramLocationBasedTableColumn
|
||||||
updateForWrite(block, buffy, tooltipBuffy);
|
updateForWrite(block, buffy, tooltipBuffy);
|
||||||
updateForExecute(block, buffy, tooltipBuffy);
|
updateForExecute(block, buffy, tooltipBuffy);
|
||||||
updateForVolatile(block, buffy, tooltipBuffy);
|
updateForVolatile(block, buffy, tooltipBuffy);
|
||||||
|
updateForArtificial(block, buffy, tooltipBuffy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateForVolatile(MemoryBlock block, StringBuilder buffy,
|
private void updateForVolatile(MemoryBlock block, StringBuilder buffy,
|
||||||
|
@ -128,6 +129,21 @@ public class MemoryTypeProgramLocationBasedTableColumn
|
||||||
tooltipBuffy.append(HTMLUtilities.spaces(2)).append("Volatile<br>");
|
tooltipBuffy.append(HTMLUtilities.spaces(2)).append("Volatile<br>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateForArtificial(MemoryBlock block, StringBuilder buffy,
|
||||||
|
StringBuilder tooltipBuffy) {
|
||||||
|
|
||||||
|
if (block.isArtificial()) {
|
||||||
|
buffy.append("<b>A</b>");
|
||||||
|
tooltipBuffy.append("<image src=\"" + onIcon.getUrl() + "\">");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffy.append(HTMLUtilities.colorString(disabledColor, "A"));
|
||||||
|
tooltipBuffy.append("<image src=\"" + offIcon.getUrl() + "\">");
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltipBuffy.append(HTMLUtilities.spaces(2)).append("Artificial<br>");
|
||||||
|
}
|
||||||
|
|
||||||
private void updateForExecute(MemoryBlock block, StringBuilder buffy,
|
private void updateForExecute(MemoryBlock block, StringBuilder buffy,
|
||||||
StringBuilder tooltipBuffy) {
|
StringBuilder tooltipBuffy) {
|
||||||
|
|
||||||
|
@ -186,7 +202,7 @@ public class MemoryTypeProgramLocationBasedTableColumn
|
||||||
private class MemoryTypeComparator implements Comparator<MemoryBlock> {
|
private class MemoryTypeComparator implements Comparator<MemoryBlock> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(MemoryBlock o1, MemoryBlock o2) {
|
public int compare(MemoryBlock o1, MemoryBlock o2) {
|
||||||
return o1.getPermissions() - o2.getPermissions();
|
return o1.getFlags() - o2.getFlags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
<!ATTLIST MEMORY_SECTION LENGTH CDATA #REQUIRED>
|
<!ATTLIST MEMORY_SECTION LENGTH CDATA #REQUIRED>
|
||||||
<!ATTLIST MEMORY_SECTION PERMISSIONS (r | w | x | rw | rx | wx | rwx) #IMPLIED>
|
<!ATTLIST MEMORY_SECTION PERMISSIONS (r | w | x | rw | rx | wx | rwx) #IMPLIED>
|
||||||
<!ATTLIST MEMORY_SECTION VOLATILE (y | n) #IMPLIED>
|
<!ATTLIST MEMORY_SECTION VOLATILE (y | n) #IMPLIED>
|
||||||
|
<!ATTLIST MEMORY_SECTION ARTIFICIAL (y | n) #IMPLIED>
|
||||||
<!ATTLIST MEMORY_SECTION COMMENT CDATA #IMPLIED>
|
<!ATTLIST MEMORY_SECTION COMMENT CDATA #IMPLIED>
|
||||||
|
|
||||||
<!ELEMENT MEMORY_CONTENTS EMPTY>
|
<!ELEMENT MEMORY_CONTENTS EMPTY>
|
||||||
|
|
|
@ -269,6 +269,7 @@ public class MemoryMergeManagerTest extends AbstractMergeTest {
|
||||||
assertTrue(!blocks[4].isWrite());
|
assertTrue(!blocks[4].isWrite());
|
||||||
assertTrue(!blocks[4].isExecute());
|
assertTrue(!blocks[4].isExecute());
|
||||||
assertTrue(!blocks[4].isVolatile());
|
assertTrue(!blocks[4].isVolatile());
|
||||||
|
assertTrue(!blocks[4].isArtificial());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -239,6 +239,12 @@ public class MemoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals("Hello", block1.getComment());
|
assertEquals("Hello", block1.getComment());
|
||||||
assertEquals(block1, mem.getBlock(addr(5)));
|
assertEquals(block1, mem.getBlock(addr(5)));
|
||||||
|
|
||||||
|
block1.setArtificial(false);
|
||||||
|
assertTrue(!block1.isArtificial());
|
||||||
|
|
||||||
|
block1.setArtificial(true);
|
||||||
|
assertTrue(block1.isArtificial());
|
||||||
|
|
||||||
block1.setVolatile(false);
|
block1.setVolatile(false);
|
||||||
assertTrue(!block1.isVolatile());
|
assertTrue(!block1.isVolatile());
|
||||||
|
|
||||||
|
@ -473,6 +479,7 @@ public class MemoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertNotNull(newBlock);
|
assertNotNull(newBlock);
|
||||||
assertEquals(block.getName() + ".copy", newBlock.getName());
|
assertEquals(block.getName() + ".copy", newBlock.getName());
|
||||||
assertEquals(addr(500), newBlock.getStart());
|
assertEquals(addr(500), newBlock.getStart());
|
||||||
|
assertEquals(block.isArtificial(), newBlock.isArtificial());
|
||||||
assertEquals(block.isVolatile(), newBlock.isVolatile());
|
assertEquals(block.isVolatile(), newBlock.isVolatile());
|
||||||
assertEquals(block.isExecute(), newBlock.isExecute());
|
assertEquals(block.isExecute(), newBlock.isExecute());
|
||||||
assertEquals(block.isRead(), newBlock.isRead());
|
assertEquals(block.isRead(), newBlock.isRead());
|
||||||
|
|
|
@ -32,7 +32,7 @@ class MyTestMemoryBlock implements MemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions() {
|
public int getFlags() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +136,16 @@ class MyTestMemoryBlock implements MemoryBlock {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArtificial() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSourceName() {
|
public String getSourceName() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -30,10 +30,12 @@ public class ExtMemoryMap implements IsfObject {
|
||||||
String kind;
|
String kind;
|
||||||
String comment;
|
String comment;
|
||||||
boolean isVolatile;
|
boolean isVolatile;
|
||||||
|
boolean isArtificial;
|
||||||
String type;
|
String type;
|
||||||
String location;
|
String location;
|
||||||
|
|
||||||
public ExtMemoryMap(AddressRange range, MemoryBlock block, MemoryMapBytesFile bf, boolean write) throws IOException {
|
public ExtMemoryMap(AddressRange range, MemoryBlock block, MemoryMapBytesFile bf, boolean write)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
String permissions = "";
|
String permissions = "";
|
||||||
if (block.isRead()) {
|
if (block.isRead()) {
|
||||||
|
@ -54,12 +56,17 @@ public class ExtMemoryMap implements IsfObject {
|
||||||
if (block.isVolatile()) {
|
if (block.isVolatile()) {
|
||||||
isVolatile = true;
|
isVolatile = true;
|
||||||
}
|
}
|
||||||
|
if (block.isArtificial()) {
|
||||||
|
isArtificial = true;
|
||||||
|
}
|
||||||
type = block.getType().name();
|
type = block.getType().name();
|
||||||
if (block.getType() == MemoryBlockType.BIT_MAPPED || block.getType() == MemoryBlockType.BYTE_MAPPED) {
|
if (block.getType() == MemoryBlockType.BIT_MAPPED ||
|
||||||
|
block.getType() == MemoryBlockType.BYTE_MAPPED) {
|
||||||
// bit mapped blocks can only have one sub-block
|
// bit mapped blocks can only have one sub-block
|
||||||
MemoryBlockSourceInfo info = block.getSourceInfos().get(0);
|
MemoryBlockSourceInfo info = block.getSourceInfos().get(0);
|
||||||
location = info.getMappedRange().get().getMinAddress().toString();
|
location = info.getMappedRange().get().getMinAddress().toString();
|
||||||
} else if (block.isInitialized() && write) {
|
}
|
||||||
|
else if (block.isInitialized() && write) {
|
||||||
location = bf.getFileName() + ":" + bf.getOffset();
|
location = bf.getFileName() + ":" + bf.getOffset();
|
||||||
bf.writeBytes(range);
|
bf.writeBytes(range);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,26 +68,27 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean read(Map<String, Object> result, SarifProgramOptions options, TaskMonitor monitor)
|
public boolean read(Map<String, Object> result, SarifProgramOptions options,
|
||||||
throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
try {
|
try {
|
||||||
processMemoryBlock(result, programMgr.getDirectory(), program, monitor);
|
processMemoryBlock(result, programMgr.getDirectory(), program, monitor);
|
||||||
return true;
|
return true;
|
||||||
} catch (FileNotFoundException | AddressOverflowException e) {
|
}
|
||||||
|
catch (FileNotFoundException | AddressOverflowException e) {
|
||||||
log.appendException(e);
|
log.appendException(e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processMemoryBlock(Map<String, Object> result, String directory, Program program, TaskMonitor monitor)
|
private void processMemoryBlock(Map<String, Object> result, String directory, Program program,
|
||||||
throws FileNotFoundException, AddressOverflowException {
|
TaskMonitor monitor) throws FileNotFoundException, AddressOverflowException {
|
||||||
|
|
||||||
String name = (String) result.get("name");
|
String name = (String) result.get("name");
|
||||||
AddressSet set = SarifUtils.getLocations(result, program, null);
|
AddressSet set = SarifUtils.getLocations(result, program, null);
|
||||||
Address blockAddress = set.getMinAddress();
|
Address blockAddress = set.getMinAddress();
|
||||||
if (set.getNumAddressRanges() != 1) {
|
if (set.getNumAddressRanges() != 1) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException("Unexpected number of ranges for block @ " + blockAddress +
|
||||||
"Unexpected number of ranges for block @ " + blockAddress + ": " + set.getNumAddressRanges());
|
": " + set.getNumAddressRanges());
|
||||||
}
|
}
|
||||||
int length = (int) set.getMaxAddress().subtract(blockAddress) + 1;
|
int length = (int) set.getMaxAddress().subtract(blockAddress) + 1;
|
||||||
|
|
||||||
|
@ -100,6 +101,7 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
boolean x = permissions.indexOf("x") >= 0;
|
boolean x = permissions.indexOf("x") >= 0;
|
||||||
|
|
||||||
boolean isVolatile = (boolean) result.get("isVolatile");
|
boolean isVolatile = (boolean) result.get("isVolatile");
|
||||||
|
boolean isArtificial = (boolean) result.get("isArtificial");
|
||||||
|
|
||||||
String comment = (String) result.get("comment");
|
String comment = (String) result.get("comment");
|
||||||
String type = (String) result.get("type");
|
String type = (String) result.get("type");
|
||||||
|
@ -110,33 +112,41 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
MemoryBlock block = null;
|
MemoryBlock block = null;
|
||||||
if (type.equals("DEFAULT")) {
|
if (type.equals("DEFAULT")) {
|
||||||
if (loc == null) {
|
if (loc == null) {
|
||||||
block = MemoryBlockUtils.createUninitializedBlock(program, false, name, blockAddress, length,
|
block = MemoryBlockUtils.createUninitializedBlock(program, false, name,
|
||||||
comment, null, r, w, x, log);
|
blockAddress, length, comment, null, r, w, x, log);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
String[] split = loc.split(":");
|
String[] split = loc.split(":");
|
||||||
String fileName = split[0];
|
String fileName = split[0];
|
||||||
int fileOffset = Integer.parseInt(split[1]);
|
int fileOffset = Integer.parseInt(split[1]);
|
||||||
byte[] bytes = setData(directory, fileName, fileOffset, length, log);
|
byte[] bytes = setData(directory, fileName, fileOffset, length, log);
|
||||||
block = MemoryBlockUtils.createInitializedBlock(program, false, name, blockAddress,
|
block = MemoryBlockUtils.createInitializedBlock(program, false, name,
|
||||||
new ByteArrayInputStream(bytes), bytes.length, comment, null, r, w, x, log, monitor);
|
blockAddress, new ByteArrayInputStream(bytes), bytes.length, comment, null,
|
||||||
|
r, w, x, log, monitor);
|
||||||
}
|
}
|
||||||
} else if (type.equals("BIT_MAPPED")) {
|
}
|
||||||
|
else if (type.equals("BIT_MAPPED")) {
|
||||||
Address sourceAddr = factory.getAddress(loc);
|
Address sourceAddr = factory.getAddress(loc);
|
||||||
block = MemoryBlockUtils.createBitMappedBlock(program, name, blockAddress, sourceAddr, length, comment,
|
block = MemoryBlockUtils.createBitMappedBlock(program, name, blockAddress,
|
||||||
comment, r, w, x, false, log);
|
sourceAddr, length, comment, comment, r, w, x, false, log);
|
||||||
} else if (type.equals("BYTE_MAPPED")) {
|
}
|
||||||
|
else if (type.equals("BYTE_MAPPED")) {
|
||||||
Address sourceAddr = factory.getAddress(loc);
|
Address sourceAddr = factory.getAddress(loc);
|
||||||
block = MemoryBlockUtils.createByteMappedBlock(program, name, blockAddress, sourceAddr, length, comment,
|
block = MemoryBlockUtils.createByteMappedBlock(program, name, blockAddress,
|
||||||
comment, r, w, x, false, log);
|
sourceAddr, length, comment, comment, r, w, x, false, log);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new RuntimeException("Unexpected type value - " + type);
|
throw new RuntimeException("Unexpected type value - " + type);
|
||||||
}
|
}
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
block.setVolatile(isVolatile);
|
block.setVolatile(isVolatile);
|
||||||
|
block.setArtificial(isArtificial);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e) {
|
||||||
log.appendException(e);
|
log.appendException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +170,8 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
}
|
}
|
||||||
pos += readLen;
|
pos += readLen;
|
||||||
}
|
}
|
||||||
} catch (IndexOutOfBoundsException e) {
|
}
|
||||||
|
catch (IndexOutOfBoundsException e) {
|
||||||
log.appendMsg("Read exceeded array length " + length);
|
log.appendMsg("Read exceeded array length " + length);
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
|
@ -170,8 +181,8 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
// SARIF WRITE CURRENT DTD //
|
// SARIF WRITE CURRENT DTD //
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|
||||||
void write(JsonArray results, AddressSetView addrs, TaskMonitor monitor, boolean isWriteContents, String filePath)
|
void write(JsonArray results, AddressSetView addrs, TaskMonitor monitor,
|
||||||
throws IOException, CancelledException {
|
boolean isWriteContents, String filePath) throws IOException, CancelledException {
|
||||||
monitor.setMessage("Writing MEMORY MAP ...");
|
monitor.setMessage("Writing MEMORY MAP ...");
|
||||||
|
|
||||||
List<Pair<AddressRange, MemoryBlock>> request = new ArrayList<>();
|
List<Pair<AddressRange, MemoryBlock>> request = new ArrayList<>();
|
||||||
|
@ -179,7 +190,8 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
AddressRange ranges = iter.next();
|
AddressRange ranges = iter.next();
|
||||||
RangeBlock rb = new RangeBlock(program.getAddressFactory(), program.getMemory(), ranges);
|
RangeBlock rb =
|
||||||
|
new RangeBlock(program.getAddressFactory(), program.getMemory(), ranges);
|
||||||
for (int i = 0; i < rb.getRanges().length; ++i) {
|
for (int i = 0; i < rb.getRanges().length; ++i) {
|
||||||
AddressRange range = rb.getRanges()[i];
|
AddressRange range = rb.getRanges()[i];
|
||||||
MemoryBlock block = rb.getBlocks()[i];
|
MemoryBlock block = rb.getBlocks()[i];
|
||||||
|
@ -190,16 +202,19 @@ public class MemoryMapSarifMgr extends SarifMgr {
|
||||||
try {
|
try {
|
||||||
bf = isWriteContents ? new MemoryMapBytesFile(program, filePath) : null;
|
bf = isWriteContents ? new MemoryMapBytesFile(program, filePath) : null;
|
||||||
writeAsSARIF(request, bf, isWriteContents, results);
|
writeAsSARIF(request, bf, isWriteContents, results);
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
if (isWriteContents) {
|
if (isWriteContents) {
|
||||||
bf.close();
|
bf.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeAsSARIF(List<Pair<AddressRange, MemoryBlock>> request, MemoryMapBytesFile bytes,
|
public static void writeAsSARIF(List<Pair<AddressRange, MemoryBlock>> request,
|
||||||
boolean isWriteContents, JsonArray results) throws IOException {
|
MemoryMapBytesFile bytes, boolean isWriteContents, JsonArray results)
|
||||||
SarifMemoryMapWriter writer = new SarifMemoryMapWriter(request, null, bytes, isWriteContents);
|
throws IOException {
|
||||||
|
SarifMemoryMapWriter writer =
|
||||||
|
new SarifMemoryMapWriter(request, null, bytes, isWriteContents);
|
||||||
new TaskLauncher(new SarifWriterTask(SUBKEY, writer, results), null);
|
new TaskLauncher(new SarifWriterTask(SUBKEY, writer, results), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -69,13 +68,13 @@ public class MemoryBlocksValidator extends VTPreconditionValidator {
|
||||||
sourceProgram.getMemory().getBlock(destBlocks[i].getName());
|
sourceProgram.getMemory().getBlock(destBlocks[i].getName());
|
||||||
if (matchingABlock != null) {
|
if (matchingABlock != null) {
|
||||||
numMatchingNames++;
|
numMatchingNames++;
|
||||||
int sourcePerm = matchingABlock.getPermissions();
|
int sourceFlags = matchingABlock.getFlags();
|
||||||
if (sourcePerm == destBlocks[i].getPermissions()) {
|
if (sourceFlags == destBlocks[i].getFlags()) {
|
||||||
numMatches++;
|
numMatches++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warnings.append("Block " + destProgName + ":" + blockName +
|
warnings.append("Block " + destProgName + ":" + blockName +
|
||||||
" doesn't match permissions of " + sourceProgName + ":" + blockName + "\n");
|
" has different flags than " + sourceProgName + ":" + blockName + "\n");
|
||||||
status = ConditionStatus.Warning;
|
status = ConditionStatus.Warning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,10 +101,12 @@ public class MemoryBlocksValidator extends VTPreconditionValidator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (numMatchingNames == numBlocksNeededForPerfectMatch) {
|
if (numMatchingNames == numBlocksNeededForPerfectMatch) {
|
||||||
warnings.append("\nSUMMARY: Number and names of blocks match but not all permissions match.");
|
warnings.append(
|
||||||
|
"\nSUMMARY: Number and names of blocks match but not all permissions match.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warnings.append("\nSUMMARY: Number, names, and permissions of blocks do not all match");
|
warnings.append(
|
||||||
|
"\nSUMMARY: Number, names, and permissions of blocks do not all match");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ConditionResult(status, warnings.toString());
|
return new ConditionResult(status, warnings.toString());
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class MemoryBlockDefinition {
|
||||||
private boolean readPermission = true;
|
private boolean readPermission = true;
|
||||||
private boolean writePermission = true;
|
private boolean writePermission = true;
|
||||||
private boolean executePermission = false;
|
private boolean executePermission = false;
|
||||||
private boolean volatilePermission = false;
|
private boolean isVolatile = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct <code>MemoryBlockDefinition</code> using a text-based specified.
|
* Construct <code>MemoryBlockDefinition</code> using a text-based specified.
|
||||||
|
@ -107,7 +107,7 @@ public class MemoryBlockDefinition {
|
||||||
readPermission = mode.indexOf('r') >= 0;
|
readPermission = mode.indexOf('r') >= 0;
|
||||||
writePermission = mode.indexOf('w') >= 0;
|
writePermission = mode.indexOf('w') >= 0;
|
||||||
executePermission = mode.indexOf('x') >= 0;
|
executePermission = mode.indexOf('x') >= 0;
|
||||||
volatilePermission = mode.indexOf('v') >= 0;
|
isVolatile = mode.indexOf('v') >= 0;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
length = XmlUtilities.parseInt(lengthString);
|
length = XmlUtilities.parseInt(lengthString);
|
||||||
|
@ -186,7 +186,7 @@ public class MemoryBlockDefinition {
|
||||||
block.setRead(readPermission);
|
block.setRead(readPermission);
|
||||||
block.setWrite(writePermission);
|
block.setWrite(writePermission);
|
||||||
block.setExecute(executePermission);
|
block.setExecute(executePermission);
|
||||||
block.setVolatile(volatilePermission);
|
block.setVolatile(isVolatile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -117,8 +117,8 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions() {
|
public int getFlags() {
|
||||||
return record.getByteValue(MemoryMapDBAdapter.PERMISSIONS_COL);
|
return record.getByteValue(MemoryMapDBAdapter.FLAGS_COL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -224,7 +224,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRead() {
|
public boolean isRead() {
|
||||||
return (record.getByteValue(MemoryMapDBAdapter.PERMISSIONS_COL) & READ) != 0;
|
return (record.getByteValue(MemoryMapDBAdapter.FLAGS_COL) & READ) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -232,9 +232,10 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
memMap.lock.acquire();
|
memMap.lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkValid();
|
checkValid();
|
||||||
setPermissionBit(READ, r);
|
if (setFlagBit(READ, r)) {
|
||||||
memMap.fireBlockChanged(this);
|
memMap.fireBlockChanged(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
memMap.lock.release();
|
memMap.lock.release();
|
||||||
}
|
}
|
||||||
|
@ -242,7 +243,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWrite() {
|
public boolean isWrite() {
|
||||||
return (record.getByteValue(MemoryMapDBAdapter.PERMISSIONS_COL) & WRITE) != 0;
|
return (record.getByteValue(MemoryMapDBAdapter.FLAGS_COL) & WRITE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -250,9 +251,10 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
memMap.lock.acquire();
|
memMap.lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkValid();
|
checkValid();
|
||||||
setPermissionBit(WRITE, w);
|
if (setFlagBit(WRITE, w)) {
|
||||||
memMap.fireBlockChanged(this);
|
memMap.fireBlockChanged(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
memMap.lock.release();
|
memMap.lock.release();
|
||||||
}
|
}
|
||||||
|
@ -260,7 +262,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExecute() {
|
public boolean isExecute() {
|
||||||
return (record.getByteValue(MemoryMapDBAdapter.PERMISSIONS_COL) & EXECUTE) != 0;
|
return (record.getByteValue(MemoryMapDBAdapter.FLAGS_COL) & EXECUTE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -268,10 +270,11 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
memMap.lock.acquire();
|
memMap.lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkValid();
|
checkValid();
|
||||||
setPermissionBit(EXECUTE, x);
|
if (setFlagBit(EXECUTE, x)) {
|
||||||
memMap.blockExecuteChanged(this);
|
memMap.blockExecuteChanged(this);
|
||||||
memMap.fireBlockChanged(this);
|
memMap.fireBlockChanged(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
memMap.lock.release();
|
memMap.lock.release();
|
||||||
}
|
}
|
||||||
|
@ -282,12 +285,14 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
memMap.lock.acquire();
|
memMap.lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkValid();
|
checkValid();
|
||||||
setPermissionBit(READ, read);
|
boolean changed = setFlagBit(READ, read);
|
||||||
setPermissionBit(WRITE, write);
|
changed |= setFlagBit(WRITE, write);
|
||||||
setPermissionBit(EXECUTE, execute);
|
changed |= setFlagBit(EXECUTE, execute);
|
||||||
|
if (changed) {
|
||||||
memMap.blockExecuteChanged(this);
|
memMap.blockExecuteChanged(this);
|
||||||
memMap.fireBlockChanged(this);
|
memMap.fireBlockChanged(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
memMap.lock.release();
|
memMap.lock.release();
|
||||||
}
|
}
|
||||||
|
@ -295,7 +300,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isVolatile() {
|
public boolean isVolatile() {
|
||||||
return (record.getByteValue(MemoryMapDBAdapter.PERMISSIONS_COL) & VOLATILE) != 0;
|
return (record.getByteValue(MemoryMapDBAdapter.FLAGS_COL) & VOLATILE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -303,9 +308,29 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
memMap.lock.acquire();
|
memMap.lock.acquire();
|
||||||
try {
|
try {
|
||||||
checkValid();
|
checkValid();
|
||||||
setPermissionBit(VOLATILE, v);
|
if (setFlagBit(VOLATILE, v)) {
|
||||||
memMap.fireBlockChanged(this);
|
memMap.fireBlockChanged(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
memMap.lock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArtificial() {
|
||||||
|
return (record.getByteValue(MemoryMapDBAdapter.FLAGS_COL) & ARTIFICIAL) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
memMap.lock.acquire();
|
||||||
|
try {
|
||||||
|
checkValid();
|
||||||
|
if (setFlagBit(ARTIFICIAL, a)) {
|
||||||
|
memMap.fireBlockChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
memMap.lock.release();
|
memMap.lock.release();
|
||||||
}
|
}
|
||||||
|
@ -430,21 +455,28 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPermissionBit(int permBitMask, boolean enable) {
|
private boolean setFlagBit(int flagBitMask, boolean enable) {
|
||||||
byte p = record.getByteValue(MemoryMapDBAdapter.PERMISSIONS_COL);
|
byte p = record.getByteValue(MemoryMapDBAdapter.FLAGS_COL);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
p |= permBitMask;
|
if ((p & flagBitMask) == flagBitMask) {
|
||||||
|
return false; // no change
|
||||||
|
}
|
||||||
|
p |= flagBitMask;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p &= ~permBitMask;
|
if ((p & flagBitMask) == 0) {
|
||||||
|
return false; // no change
|
||||||
}
|
}
|
||||||
record.setByteValue(MemoryMapDBAdapter.PERMISSIONS_COL, p);
|
p &= ~flagBitMask;
|
||||||
|
}
|
||||||
|
record.setByteValue(MemoryMapDBAdapter.FLAGS_COL, p);
|
||||||
try {
|
try {
|
||||||
adapter.updateBlockRecord(record);
|
adapter.updateBlockRecord(record);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
memMap.dbError(e);
|
memMap.dbError(e);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -634,8 +666,7 @@ public class MemoryBlockDB implements MemoryBlock {
|
||||||
splitBlocks.addAll(subList);
|
splitBlocks.addAll(subList);
|
||||||
subList.clear();
|
subList.clear();
|
||||||
}
|
}
|
||||||
return adapter.createBlock(getName() + ".split", addr, newLength, getPermissions(),
|
return adapter.createBlock(getName() + ".split", addr, newLength, getFlags(), splitBlocks);
|
||||||
splitBlocks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getIndexOfSubBlockToSplit(long offset) {
|
private int getIndexOfSubBlockToSplit(long offset) {
|
||||||
|
|
|
@ -901,7 +901,7 @@ public class MemoryMapDB implements Memory, ManagerDB, LiveMemoryListener {
|
||||||
mappedAddr = info.getMappedRange().get().getMinAddress();
|
mappedAddr = info.getMappedRange().get().getMinAddress();
|
||||||
}
|
}
|
||||||
MemoryBlockDB newBlock = adapter.createBlock(block.getType(), name, start, length,
|
MemoryBlockDB newBlock = adapter.createBlock(block.getType(), name, start, length,
|
||||||
mappedAddr, block.isInitialized(), block.getPermissions(), mappingScheme);
|
mappedAddr, block.isInitialized(), block.getFlags(), mappingScheme);
|
||||||
allAddrSet.add(newBlock.getStart(), newBlock.getEnd());
|
allAddrSet.add(newBlock.getStart(), newBlock.getEnd());
|
||||||
initializeBlocks();
|
initializeBlocks();
|
||||||
fireBlockAdded(newBlock);
|
fireBlockAdded(newBlock);
|
||||||
|
|
|
@ -35,7 +35,7 @@ abstract class MemoryMapDBAdapter {
|
||||||
static final int NAME_COL = MemoryMapDBAdapterV3.V3_NAME_COL;
|
static final int NAME_COL = MemoryMapDBAdapterV3.V3_NAME_COL;
|
||||||
static final int COMMENTS_COL = MemoryMapDBAdapterV3.V3_COMMENTS_COL;
|
static final int COMMENTS_COL = MemoryMapDBAdapterV3.V3_COMMENTS_COL;
|
||||||
static final int SOURCE_COL = MemoryMapDBAdapterV3.V3_SOURCE_COL;
|
static final int SOURCE_COL = MemoryMapDBAdapterV3.V3_SOURCE_COL;
|
||||||
static final int PERMISSIONS_COL = MemoryMapDBAdapterV3.V3_PERMISSIONS_COL;
|
static final int FLAGS_COL = MemoryMapDBAdapterV3.V3_FLAGS_COL;
|
||||||
static final int START_ADDR_COL = MemoryMapDBAdapterV3.V3_START_ADDR_COL;
|
static final int START_ADDR_COL = MemoryMapDBAdapterV3.V3_START_ADDR_COL;
|
||||||
static final int LENGTH_COL = MemoryMapDBAdapterV3.V3_LENGTH_COL;
|
static final int LENGTH_COL = MemoryMapDBAdapterV3.V3_LENGTH_COL;
|
||||||
static final int SEGMENT_COL = MemoryMapDBAdapterV3.V3_SEGMENT_COL;
|
static final int SEGMENT_COL = MemoryMapDBAdapterV3.V3_SEGMENT_COL;
|
||||||
|
@ -130,7 +130,7 @@ abstract class MemoryMapDBAdapter {
|
||||||
if (block.isInitialized()) {
|
if (block.isInitialized()) {
|
||||||
DBBuffer buf = block.getBuffer();
|
DBBuffer buf = block.getBuffer();
|
||||||
newBlock = newAdapter.createInitializedBlock(block.getName(), block.getStart(),
|
newBlock = newAdapter.createInitializedBlock(block.getName(), block.getStart(),
|
||||||
buf, block.getPermissions());
|
buf, block.getFlags());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Address mappedAddress = null;
|
Address mappedAddress = null;
|
||||||
|
@ -141,7 +141,7 @@ abstract class MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
newBlock =
|
newBlock =
|
||||||
newAdapter.createBlock(block.getType(), block.getName(), block.getStart(),
|
newAdapter.createBlock(block.getType(), block.getName(), block.getStart(),
|
||||||
block.getSize(), mappedAddress, false, block.getPermissions(), 0);
|
block.getSize(), mappedAddress, false, block.getFlags(), 0);
|
||||||
}
|
}
|
||||||
newBlock.setComment(block.getComment());
|
newBlock.setComment(block.getComment());
|
||||||
newBlock.setSourceName(block.getSourceName());
|
newBlock.setSourceName(block.getSourceName());
|
||||||
|
@ -185,26 +185,26 @@ abstract class MemoryMapDBAdapter {
|
||||||
* @param startAddr the start address of the block.
|
* @param startAddr the start address of the block.
|
||||||
* @param is data source or null for zero initialization
|
* @param is data source or null for zero initialization
|
||||||
* @param length size of block
|
* @param length size of block
|
||||||
* @param permissions the new block permissions
|
* @param flags the new block flags
|
||||||
* @return new memory block
|
* @return new memory block
|
||||||
* @throws IOException
|
* @throws IOException if a database IO error occurs.
|
||||||
* @throws AddressOverflowException if block length is too large for the underlying space
|
* @throws AddressOverflowException if block length is too large for the underlying space
|
||||||
*/
|
*/
|
||||||
abstract MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
abstract MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
||||||
long length, int permissions) throws AddressOverflowException, IOException;
|
long length, int flags) throws AddressOverflowException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new initialized block object
|
* Creates a new initialized block object
|
||||||
* @param name the name of the block
|
* @param name the name of the block
|
||||||
* @param startAddr the start address of the block.
|
* @param startAddr the start address of the block.
|
||||||
* @param buf the DBBuffer used to hold the bytes for the block.
|
* @param buf the DBBuffer used to hold the bytes for the block.
|
||||||
* @param permissions the new block permissions
|
* @param flags the new block flags
|
||||||
* @return new memory block
|
* @return new memory block
|
||||||
* @throws IOException if a database IO error occurs.
|
* @throws IOException if a database IO error occurs.
|
||||||
* @throws AddressOverflowException if block length is too large for the underlying space
|
* @throws AddressOverflowException if block length is too large for the underlying space
|
||||||
*/
|
*/
|
||||||
abstract MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf,
|
abstract MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf,
|
||||||
int permissions) throws AddressOverflowException, IOException;
|
int flags) throws AddressOverflowException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new memory block that doesn't have associated bytes.
|
* Creates a new memory block that doesn't have associated bytes.
|
||||||
|
@ -216,14 +216,14 @@ abstract class MemoryMapDBAdapter {
|
||||||
* the block. (used for bit/byte-mapped blocks only)
|
* the block. (used for bit/byte-mapped blocks only)
|
||||||
* @param initializeBytes if true, creates a database buffer for storing the
|
* @param initializeBytes if true, creates a database buffer for storing the
|
||||||
* bytes in the block (applies to initialized default blocks only)
|
* bytes in the block (applies to initialized default blocks only)
|
||||||
* @param permissions the new block permissions
|
* @param flags the new block flags
|
||||||
* @param encodedMappingScheme byte mapping scheme (used by byte-mapped blocks only)
|
* @param encodedMappingScheme byte mapping scheme (used by byte-mapped blocks only)
|
||||||
* @return new memory block
|
* @return new memory block
|
||||||
* @throws IOException if a database IO error occurs.
|
* @throws IOException if a database IO error occurs.
|
||||||
* @throws AddressOverflowException if block length is too large for the underlying space
|
* @throws AddressOverflowException if block length is too large for the underlying space
|
||||||
*/
|
*/
|
||||||
abstract MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
abstract MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
||||||
long length, Address mappedAddress, boolean initializeBytes, int permissions,
|
long length, Address mappedAddress, boolean initializeBytes, int flags,
|
||||||
int encodedMappingScheme) throws AddressOverflowException, IOException;
|
int encodedMappingScheme) throws AddressOverflowException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,13 +289,13 @@ abstract class MemoryMapDBAdapter {
|
||||||
* @param name the name of the block
|
* @param name the name of the block
|
||||||
* @param startAddress the start address of the block
|
* @param startAddress the start address of the block
|
||||||
* @param length the length of the block
|
* @param length the length of the block
|
||||||
* @param permissions the permissions for the block
|
* @param flags the flags for the block
|
||||||
* @param splitBlocks the list of subBlock objects that make up this block
|
* @param splitBlocks the list of subBlock objects that make up this block
|
||||||
* @return the new MemoryBlock
|
* @return the new MemoryBlock
|
||||||
* @throws IOException if a database error occurs
|
* @throws IOException if a database error occurs
|
||||||
*/
|
*/
|
||||||
protected abstract MemoryBlockDB createBlock(String name, Address startAddress, long length,
|
protected abstract MemoryBlockDB createBlock(String name, Address startAddress, long length,
|
||||||
int permissions, List<SubMemoryBlock> splitBlocks) throws IOException;
|
int flags, List<SubMemoryBlock> splitBlocks) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new memory block using a FileBytes
|
* Creates a new memory block using a FileBytes
|
||||||
|
@ -304,12 +304,12 @@ abstract class MemoryMapDBAdapter {
|
||||||
* @param length the length of the block
|
* @param length the length of the block
|
||||||
* @param fileBytes the {@link FileBytes} object that provides the bytes for this block
|
* @param fileBytes the {@link FileBytes} object that provides the bytes for this block
|
||||||
* @param offset the offset into the {@link FileBytes} object
|
* @param offset the offset into the {@link FileBytes} object
|
||||||
* @param permissions the permissions for the block
|
* @param flags the flags for the block
|
||||||
* @return the new MemoryBlock
|
* @return the new MemoryBlock
|
||||||
* @throws IOException if a database error occurs
|
* @throws IOException if a database error occurs
|
||||||
* @throws AddressOverflowException if block length is too large for the underlying space
|
* @throws AddressOverflowException if block length is too large for the underlying space
|
||||||
*/
|
*/
|
||||||
protected abstract MemoryBlockDB createFileBytesBlock(String name, Address startAddress,
|
protected abstract MemoryBlockDB createFileBytesBlock(String name, Address startAddress,
|
||||||
long length, FileBytes fileBytes, long offset, int permissions)
|
long length, FileBytes fileBytes, long offset, int flags)
|
||||||
throws IOException, AddressOverflowException;
|
throws IOException, AddressOverflowException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,15 +106,15 @@ class MemoryMapDBAdapterV0 extends MemoryMapDBAdapter {
|
||||||
RecordIterator it = table.iterator();
|
RecordIterator it = table.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
DBRecord rec = it.next();
|
DBRecord rec = it.next();
|
||||||
int permissions = 0;
|
int flags = 0;
|
||||||
if (rec.getBooleanValue(V0_IS_READ_COL)) {
|
if (rec.getBooleanValue(V0_IS_READ_COL)) {
|
||||||
permissions |= MemoryBlock.READ;
|
flags |= MemoryBlock.READ;
|
||||||
}
|
}
|
||||||
if (rec.getBooleanValue(V0_IS_WRITE_COL)) {
|
if (rec.getBooleanValue(V0_IS_WRITE_COL)) {
|
||||||
permissions |= MemoryBlock.WRITE;
|
flags |= MemoryBlock.WRITE;
|
||||||
}
|
}
|
||||||
if (rec.getBooleanValue(V0_IS_EXECUTE_COL)) {
|
if (rec.getBooleanValue(V0_IS_EXECUTE_COL)) {
|
||||||
permissions |= MemoryBlock.EXECUTE;
|
flags |= MemoryBlock.EXECUTE;
|
||||||
}
|
}
|
||||||
Address start = addrFactory.oldGetAddressFromLong(rec.getLongValue(V0_START_ADDR_COL));
|
Address start = addrFactory.oldGetAddressFromLong(rec.getLongValue(V0_START_ADDR_COL));
|
||||||
long startAddr = addrMap.getKey(start, false);
|
long startAddr = addrMap.getKey(start, false);
|
||||||
|
@ -131,7 +131,7 @@ class MemoryMapDBAdapterV0 extends MemoryMapDBAdapter {
|
||||||
blockRecord.setString(NAME_COL, rec.getString(V0_NAME_COL));
|
blockRecord.setString(NAME_COL, rec.getString(V0_NAME_COL));
|
||||||
blockRecord.setString(COMMENTS_COL, rec.getString(V0_COMMENTS_COL));
|
blockRecord.setString(COMMENTS_COL, rec.getString(V0_COMMENTS_COL));
|
||||||
blockRecord.setString(SOURCE_COL, rec.getString(V0_SOURCE_NAME_COL));
|
blockRecord.setString(SOURCE_COL, rec.getString(V0_SOURCE_NAME_COL));
|
||||||
blockRecord.setByteValue(PERMISSIONS_COL, (byte) permissions);
|
blockRecord.setByteValue(FLAGS_COL, (byte) flags);
|
||||||
blockRecord.setLongValue(START_ADDR_COL, startAddr);
|
blockRecord.setLongValue(START_ADDR_COL, startAddr);
|
||||||
blockRecord.setLongValue(LENGTH_COL, length);
|
blockRecord.setLongValue(LENGTH_COL, length);
|
||||||
blockRecord.setIntValue(SEGMENT_COL, segment);
|
blockRecord.setIntValue(SEGMENT_COL, segment);
|
||||||
|
@ -195,13 +195,13 @@ class MemoryMapDBAdapterV0 extends MemoryMapDBAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
||||||
long length, int permissions) throws IOException {
|
long length, int flags) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf,
|
MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf, int flags)
|
||||||
int permissions) throws IOException {
|
throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +231,7 @@ class MemoryMapDBAdapterV0 extends MemoryMapDBAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
||||||
long length, Address overlayAddr, boolean initializeBytes, int permissions,
|
long length, Address overlayAddr, boolean initializeBytes, int flags, int mappingScheme)
|
||||||
int mappingScheme)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
@ -267,14 +266,14 @@ class MemoryMapDBAdapterV0 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MemoryBlockDB createBlock(String name, Address addr, long length, int permissions,
|
protected MemoryBlockDB createBlock(String name, Address addr, long length, int flags,
|
||||||
List<SubMemoryBlock> splitBlocks) {
|
List<SubMemoryBlock> splitBlocks) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MemoryBlockDB createFileBytesBlock(String name, Address startAddress, long length,
|
protected MemoryBlockDB createFileBytesBlock(String name, Address startAddress, long length,
|
||||||
FileBytes fileBytes, long offset, int permissions)
|
FileBytes fileBytes, long offset, int flags)
|
||||||
throws IOException, AddressOverflowException {
|
throws IOException, AddressOverflowException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,6 @@ class MemoryMapDBAdapterV1 extends MemoryMapDBAdapterV0 {
|
||||||
// "Source Block ID","Segment"});
|
// "Source Block ID","Segment"});
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
|
||||||
* @param handle
|
|
||||||
*/
|
|
||||||
MemoryMapDBAdapterV1(DBHandle handle, MemoryMapDB memMap) throws VersionException, IOException {
|
MemoryMapDBAdapterV1(DBHandle handle, MemoryMapDB memMap) throws VersionException, IOException {
|
||||||
super(handle, memMap, VERSION);
|
super(handle, memMap, VERSION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,6 @@ class MemoryMapDBAdapterV2 extends MemoryMapDBAdapter {
|
||||||
// new String[] { "Name", "Comments", "Source Name", "Permissions", "Start Address",
|
// new String[] { "Name", "Comments", "Source Name", "Permissions", "Start Address",
|
||||||
// "Block Type", "Overlay Address", "Length", "Chain Buffer ID", "Segment" });
|
// "Block Type", "Overlay Address", "Length", "Chain Buffer ID", "Segment" });
|
||||||
|
|
||||||
|
|
||||||
protected MemoryMapDBAdapterV2(DBHandle handle, MemoryMapDB memMap)
|
protected MemoryMapDBAdapterV2(DBHandle handle, MemoryMapDB memMap)
|
||||||
throws VersionException, IOException {
|
throws VersionException, IOException {
|
||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
|
@ -86,7 +85,7 @@ class MemoryMapDBAdapterV2 extends MemoryMapDBAdapter {
|
||||||
RecordIterator it = table.iterator();
|
RecordIterator it = table.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
DBRecord rec = it.next();
|
DBRecord rec = it.next();
|
||||||
int permissions = rec.getByteValue(V2_PERMISSIONS_COL);
|
int flags = rec.getByteValue(V2_PERMISSIONS_COL);
|
||||||
|
|
||||||
long startAddr = rec.getLongValue(V2_START_ADDR_COL);
|
long startAddr = rec.getLongValue(V2_START_ADDR_COL);
|
||||||
long length = rec.getLongValue(V2_LENGTH_COL);
|
long length = rec.getLongValue(V2_LENGTH_COL);
|
||||||
|
@ -99,7 +98,7 @@ class MemoryMapDBAdapterV2 extends MemoryMapDBAdapter {
|
||||||
blockRecord.setString(NAME_COL, rec.getString(V2_NAME_COL));
|
blockRecord.setString(NAME_COL, rec.getString(V2_NAME_COL));
|
||||||
blockRecord.setString(COMMENTS_COL, rec.getString(V2_COMMENTS_COL));
|
blockRecord.setString(COMMENTS_COL, rec.getString(V2_COMMENTS_COL));
|
||||||
blockRecord.setString(SOURCE_COL, rec.getString(V2_SOURCE_COL));
|
blockRecord.setString(SOURCE_COL, rec.getString(V2_SOURCE_COL));
|
||||||
blockRecord.setByteValue(PERMISSIONS_COL, (byte) permissions);
|
blockRecord.setByteValue(FLAGS_COL, (byte) flags);
|
||||||
blockRecord.setLongValue(START_ADDR_COL, startAddr);
|
blockRecord.setLongValue(START_ADDR_COL, startAddr);
|
||||||
blockRecord.setLongValue(LENGTH_COL, length);
|
blockRecord.setLongValue(LENGTH_COL, length);
|
||||||
blockRecord.setIntValue(SEGMENT_COL, segment);
|
blockRecord.setIntValue(SEGMENT_COL, segment);
|
||||||
|
@ -149,22 +148,21 @@ class MemoryMapDBAdapterV2 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf,
|
MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf, int flags)
|
||||||
int permissions) throws AddressOverflowException, IOException {
|
throws AddressOverflowException, IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
||||||
long length, int permissions) throws AddressOverflowException, IOException {
|
long length, int flags) throws AddressOverflowException, IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
||||||
long length, Address mappedAddress, boolean initializeBytes, int permissions,
|
long length, Address mappedAddress, boolean initializeBytes, int flags,
|
||||||
int mappingScheme)
|
int mappingScheme) throws AddressOverflowException, IOException {
|
||||||
throws AddressOverflowException, IOException {
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,14 +221,14 @@ class MemoryMapDBAdapterV2 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MemoryBlockDB createBlock(String name, Address addr, long length, int permissions,
|
protected MemoryBlockDB createBlock(String name, Address addr, long length, int flags,
|
||||||
List<SubMemoryBlock> splitBlocks) {
|
List<SubMemoryBlock> splitBlocks) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MemoryBlockDB createFileBytesBlock(String name, Address startAddress, long length,
|
protected MemoryBlockDB createFileBytesBlock(String name, Address startAddress, long length,
|
||||||
FileBytes fileBytes, long offset, int permissions)
|
FileBytes fileBytes, long offset, int flags)
|
||||||
throws IOException, AddressOverflowException {
|
throws IOException, AddressOverflowException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
static final int V3_NAME_COL = 0;
|
static final int V3_NAME_COL = 0;
|
||||||
static final int V3_COMMENTS_COL = 1;
|
static final int V3_COMMENTS_COL = 1;
|
||||||
static final int V3_SOURCE_COL = 2;
|
static final int V3_SOURCE_COL = 2;
|
||||||
static final int V3_PERMISSIONS_COL = 3;
|
static final int V3_FLAGS_COL = 3;
|
||||||
static final int V3_START_ADDR_COL = 4;
|
static final int V3_START_ADDR_COL = 4;
|
||||||
static final int V3_LENGTH_COL = 5;
|
static final int V3_LENGTH_COL = 5;
|
||||||
static final int V3_SEGMENT_COL = 6;
|
static final int V3_SEGMENT_COL = 6;
|
||||||
|
@ -60,7 +60,7 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
static Schema V3_BLOCK_SCHEMA = new Schema(V3_VERSION, "Key",
|
static Schema V3_BLOCK_SCHEMA = new Schema(V3_VERSION, "Key",
|
||||||
new Field[] { StringField.INSTANCE, StringField.INSTANCE, StringField.INSTANCE,
|
new Field[] { StringField.INSTANCE, StringField.INSTANCE, StringField.INSTANCE,
|
||||||
ByteField.INSTANCE, LongField.INSTANCE, LongField.INSTANCE, IntField.INSTANCE },
|
ByteField.INSTANCE, LongField.INSTANCE, LongField.INSTANCE, IntField.INSTANCE },
|
||||||
new String[] { "Name", "Comments", "Source Name", "Permissions", "Start Address", "Length",
|
new String[] { "Name", "Comments", "Source Name", "Flags", "Start Address", "Length",
|
||||||
"Segment" });
|
"Segment" });
|
||||||
|
|
||||||
static Schema V3_SUB_BLOCK_SCHEMA = new Schema(V3_VERSION, "Key",
|
static Schema V3_SUB_BLOCK_SCHEMA = new Schema(V3_VERSION, "Key",
|
||||||
|
@ -116,8 +116,8 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
void refreshMemory() throws IOException {
|
void refreshMemory() throws IOException {
|
||||||
Map<Long, List<SubMemoryBlock>> subBlockMap = getSubBlockMap();
|
Map<Long, List<SubMemoryBlock>> subBlockMap = getSubBlockMap();
|
||||||
|
|
||||||
Map<Long, MemoryBlockDB> blockMap = memoryBlocks.stream().collect(
|
Map<Long, MemoryBlockDB> blockMap = memoryBlocks.stream()
|
||||||
Collectors.toMap(MemoryBlockDB::getID, Function.identity()));
|
.collect(Collectors.toMap(MemoryBlockDB::getID, Function.identity()));
|
||||||
|
|
||||||
List<MemoryBlockDB> newBlocks = new ArrayList<>();
|
List<MemoryBlockDB> newBlocks = new ArrayList<>();
|
||||||
RecordIterator it = memBlockTable.iterator();
|
RecordIterator it = memBlockTable.iterator();
|
||||||
|
@ -163,14 +163,14 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
MemoryBlockDB createInitializedBlock(String name, Address startAddr, InputStream is,
|
||||||
long length, int permissions) throws AddressOverflowException, IOException {
|
long length, int flags) throws AddressOverflowException, IOException {
|
||||||
|
|
||||||
// TODO verify that it is necessary to pre-define all segments in the address map
|
// TODO verify that it is necessary to pre-define all segments in the address map
|
||||||
updateAddressMapForAllAddresses(startAddr, length);
|
updateAddressMapForAllAddresses(startAddr, length);
|
||||||
|
|
||||||
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
DBRecord blockRecord = createMemoryBlockRecord(name, startAddr, length, permissions);
|
DBRecord blockRecord = createMemoryBlockRecord(name, startAddr, length, flags);
|
||||||
long key = blockRecord.getKey();
|
long key = blockRecord.getKey();
|
||||||
int numFullBlocks = (int) (length / maxSubBlockSize);
|
int numFullBlocks = (int) (length / maxSubBlockSize);
|
||||||
int lastSubBlockSize = (int) (length % maxSubBlockSize);
|
int lastSubBlockSize = (int) (length % maxSubBlockSize);
|
||||||
|
@ -201,30 +201,30 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
MemoryBlockDB createBlock(MemoryBlockType blockType, String name, Address startAddr,
|
||||||
long length, Address mappedAddress, boolean initializeBytes, int permissions,
|
long length, Address mappedAddress, boolean initializeBytes, int flags,
|
||||||
int encodedMappingScheme) throws AddressOverflowException, IOException {
|
int encodedMappingScheme) throws AddressOverflowException, IOException {
|
||||||
|
|
||||||
if (blockType == MemoryBlockType.BIT_MAPPED) {
|
if (blockType == MemoryBlockType.BIT_MAPPED) {
|
||||||
return createBitMappedBlock(name, startAddr, length, mappedAddress, permissions);
|
return createBitMappedBlock(name, startAddr, length, mappedAddress, flags);
|
||||||
}
|
}
|
||||||
if (blockType == MemoryBlockType.BYTE_MAPPED) {
|
if (blockType == MemoryBlockType.BYTE_MAPPED) {
|
||||||
return createByteMappedBlock(name, startAddr, length, mappedAddress, permissions,
|
return createByteMappedBlock(name, startAddr, length, mappedAddress, flags,
|
||||||
encodedMappingScheme);
|
encodedMappingScheme);
|
||||||
}
|
}
|
||||||
// DEFAULT block type
|
// DEFAULT block type
|
||||||
if (initializeBytes) {
|
if (initializeBytes) {
|
||||||
return createInitializedBlock(name, startAddr, null, length, permissions);
|
return createInitializedBlock(name, startAddr, null, length, flags);
|
||||||
}
|
}
|
||||||
return createUninitializedBlock(name, startAddr, length, permissions);
|
return createUninitializedBlock(name, startAddr, length, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf,
|
MemoryBlockDB createInitializedBlock(String name, Address startAddr, DBBuffer buf, int flags)
|
||||||
int permissions) throws AddressOverflowException, IOException {
|
throws AddressOverflowException, IOException {
|
||||||
updateAddressMapForAllAddresses(startAddr, buf.length());
|
updateAddressMapForAllAddresses(startAddr, buf.length());
|
||||||
|
|
||||||
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
||||||
DBRecord blockRecord = createMemoryBlockRecord(name, startAddr, buf.length(), permissions);
|
DBRecord blockRecord = createMemoryBlockRecord(name, startAddr, buf.length(), flags);
|
||||||
long key = blockRecord.getKey();
|
long key = blockRecord.getKey();
|
||||||
|
|
||||||
DBRecord subRecord =
|
DBRecord subRecord =
|
||||||
|
@ -239,11 +239,11 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBlockDB createUninitializedBlock(String name, Address startAddress, long length,
|
MemoryBlockDB createUninitializedBlock(String name, Address startAddress, long length,
|
||||||
int permissions) throws IOException, AddressOverflowException {
|
int flags) throws IOException, AddressOverflowException {
|
||||||
updateAddressMapForAllAddresses(startAddress, length);
|
updateAddressMapForAllAddresses(startAddress, length);
|
||||||
|
|
||||||
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
||||||
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, permissions);
|
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, flags);
|
||||||
long key = blockRecord.getKey();
|
long key = blockRecord.getKey();
|
||||||
|
|
||||||
DBRecord subRecord = createSubBlockRecord(key, 0, length, V3_SUB_TYPE_UNINITIALIZED, 0, 0);
|
DBRecord subRecord = createSubBlockRecord(key, 0, length, V3_SUB_TYPE_UNINITIALIZED, 0, 0);
|
||||||
|
@ -256,9 +256,9 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MemoryBlockDB createBlock(String name, Address startAddress, long length,
|
protected MemoryBlockDB createBlock(String name, Address startAddress, long length, int flags,
|
||||||
int permissions, List<SubMemoryBlock> splitBlocks) throws IOException {
|
List<SubMemoryBlock> splitBlocks) throws IOException {
|
||||||
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, permissions);
|
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, flags);
|
||||||
long key = blockRecord.getKey();
|
long key = blockRecord.getKey();
|
||||||
|
|
||||||
long startingOffset = 0;
|
long startingOffset = 0;
|
||||||
|
@ -274,26 +274,26 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBlockDB createBitMappedBlock(String name, Address startAddress, long length,
|
MemoryBlockDB createBitMappedBlock(String name, Address startAddress, long length,
|
||||||
Address mappedAddress, int permissions) throws IOException, AddressOverflowException {
|
Address mappedAddress, int flags) throws IOException, AddressOverflowException {
|
||||||
return createMappedBlock(V3_SUB_TYPE_BIT_MAPPED, name, startAddress, length, mappedAddress,
|
return createMappedBlock(V3_SUB_TYPE_BIT_MAPPED, name, startAddress, length, mappedAddress,
|
||||||
permissions, 0);
|
flags, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBlockDB createByteMappedBlock(String name, Address startAddress, long length,
|
MemoryBlockDB createByteMappedBlock(String name, Address startAddress, long length,
|
||||||
Address mappedAddress, int permissions, int mappingScheme)
|
Address mappedAddress, int flags, int mappingScheme)
|
||||||
throws IOException, AddressOverflowException {
|
throws IOException, AddressOverflowException {
|
||||||
return createMappedBlock(V3_SUB_TYPE_BYTE_MAPPED, name, startAddress, length, mappedAddress,
|
return createMappedBlock(V3_SUB_TYPE_BYTE_MAPPED, name, startAddress, length, mappedAddress,
|
||||||
permissions, mappingScheme);
|
flags, mappingScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MemoryBlockDB createFileBytesBlock(String name, Address startAddress, long length,
|
protected MemoryBlockDB createFileBytesBlock(String name, Address startAddress, long length,
|
||||||
FileBytes fileBytes, long offset, int permissions)
|
FileBytes fileBytes, long offset, int flags)
|
||||||
throws IOException, AddressOverflowException {
|
throws IOException, AddressOverflowException {
|
||||||
|
|
||||||
updateAddressMapForAllAddresses(startAddress, length);
|
updateAddressMapForAllAddresses(startAddress, length);
|
||||||
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
||||||
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, permissions);
|
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, flags);
|
||||||
long key = blockRecord.getKey();
|
long key = blockRecord.getKey();
|
||||||
|
|
||||||
DBRecord subRecord = createSubBlockRecord(key, 0, length, V3_SUB_TYPE_FILE_BYTES,
|
DBRecord subRecord = createSubBlockRecord(key, 0, length, V3_SUB_TYPE_FILE_BYTES,
|
||||||
|
@ -307,13 +307,12 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private MemoryBlockDB createMappedBlock(byte type, String name, Address startAddress,
|
private MemoryBlockDB createMappedBlock(byte type, String name, Address startAddress,
|
||||||
long length, Address mappedAddress, int permissions,
|
long length, Address mappedAddress, int flags, int mappingScheme)
|
||||||
int mappingScheme)
|
|
||||||
throws IOException, AddressOverflowException {
|
throws IOException, AddressOverflowException {
|
||||||
updateAddressMapForAllAddresses(startAddress, length);
|
updateAddressMapForAllAddresses(startAddress, length);
|
||||||
|
|
||||||
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
List<SubMemoryBlock> subBlocks = new ArrayList<>();
|
||||||
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, permissions);
|
DBRecord blockRecord = createMemoryBlockRecord(name, startAddress, length, flags);
|
||||||
long key = blockRecord.getKey();
|
long key = blockRecord.getKey();
|
||||||
|
|
||||||
long encoded = addrMap.getKey(mappedAddress, true);
|
long encoded = addrMap.getKey(mappedAddress, true);
|
||||||
|
@ -377,12 +376,12 @@ public class MemoryMapDBAdapterV3 extends MemoryMapDBAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DBRecord createMemoryBlockRecord(String name, Address startAddr, long length,
|
private DBRecord createMemoryBlockRecord(String name, Address startAddr, long length,
|
||||||
int permissions) {
|
int flags) {
|
||||||
DBRecord record = V3_BLOCK_SCHEMA.createRecord(memBlockTable.getKey());
|
DBRecord record = V3_BLOCK_SCHEMA.createRecord(memBlockTable.getKey());
|
||||||
record.setString(V3_NAME_COL, name);
|
record.setString(V3_NAME_COL, name);
|
||||||
record.setLongValue(V3_START_ADDR_COL, addrMap.getKey(startAddr, true));
|
record.setLongValue(V3_START_ADDR_COL, addrMap.getKey(startAddr, true));
|
||||||
record.setLongValue(V3_LENGTH_COL, length);
|
record.setLongValue(V3_LENGTH_COL, length);
|
||||||
record.setByteValue(V3_PERMISSIONS_COL, (byte) permissions);
|
record.setByteValue(V3_FLAGS_COL, (byte) flags);
|
||||||
record.setIntValue(V3_SEGMENT_COL, getSegment(startAddr));
|
record.setIntValue(V3_SEGMENT_COL, getSegment(startAddr));
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,17 +46,22 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
*/
|
*/
|
||||||
public static final String EXTERNAL_BLOCK_NAME = "EXTERNAL";
|
public static final String EXTERNAL_BLOCK_NAME = "EXTERNAL";
|
||||||
|
|
||||||
// Memory block permission bits
|
// Memory block flag bits
|
||||||
|
// NOTE: These are used by stored Flags with DB (8-bits) and
|
||||||
|
// should be changed other than to add values.
|
||||||
|
public static int ARTIFICIAL = 0x10;
|
||||||
public static int VOLATILE = 0x8;
|
public static int VOLATILE = 0x8;
|
||||||
public static int READ = 0x4;
|
public static int READ = 0x4;
|
||||||
public static int WRITE = 0x2;
|
public static int WRITE = 0x2;
|
||||||
public static int EXECUTE = 0x1;
|
public static int EXECUTE = 0x1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns block permissions as a bit mask. Permission bits defined as READ, WRITE, EXECUTE and
|
* Returns block flags (i.e., permissions and attributes) as a bit mask.
|
||||||
* VOLATILE
|
* These bits defined as {@link #READ}, {@link #WRITE}, {@link #EXECUTE}, {@link #VOLATILE},
|
||||||
|
* {@link #ARTIFICIAL}.
|
||||||
|
* @return block flag bits
|
||||||
*/
|
*/
|
||||||
public int getPermissions();
|
public int getFlags();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get memory data in the form of an InputStream. Null is returned for thos memory blocks which
|
* Get memory data in the form of an InputStream. Null is returned for thos memory blocks which
|
||||||
|
@ -107,6 +112,8 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of this block
|
* Get the name of this block
|
||||||
|
*
|
||||||
|
* @return block name
|
||||||
*/
|
*/
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
|
@ -122,6 +129,8 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the comment associated with this block.
|
* Get the comment associated with this block.
|
||||||
|
*
|
||||||
|
* @return block comment string
|
||||||
*/
|
*/
|
||||||
public String getComment();
|
public String getComment();
|
||||||
|
|
||||||
|
@ -134,6 +143,8 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the read property associated with this block
|
* Returns the value of the read property associated with this block
|
||||||
|
*
|
||||||
|
* @return true if enabled else false
|
||||||
*/
|
*/
|
||||||
public boolean isRead();
|
public boolean isRead();
|
||||||
|
|
||||||
|
@ -146,6 +157,8 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the write property associated with this block
|
* Returns the value of the write property associated with this block
|
||||||
|
*
|
||||||
|
* @return true if enabled else false
|
||||||
*/
|
*/
|
||||||
public boolean isWrite();
|
public boolean isWrite();
|
||||||
|
|
||||||
|
@ -158,6 +171,8 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the execute property associated with this block
|
* Returns the value of the execute property associated with this block
|
||||||
|
*
|
||||||
|
* @return true if enabled else false
|
||||||
*/
|
*/
|
||||||
public boolean isExecute();
|
public boolean isExecute();
|
||||||
|
|
||||||
|
@ -178,18 +193,41 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
public void setPermissions(boolean read, boolean write, boolean execute);
|
public void setPermissions(boolean read, boolean write, boolean execute);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of the volatile property associated with this block. This attribute is
|
* Returns the volatile attribute state of this block. This attribute is
|
||||||
* generally associated with block of I/O regions of memory.
|
* generally associated with block of I/O regions of memory.
|
||||||
|
*
|
||||||
|
* @return true if enabled else false
|
||||||
*/
|
*/
|
||||||
public boolean isVolatile();
|
public boolean isVolatile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the volatile property associated with this block.
|
* Sets the volatile attribute state associated of this block. This attribute is
|
||||||
|
* generally associated with block of I/O regions of memory.
|
||||||
*
|
*
|
||||||
* @param v the value to set the volatile property to.
|
* @param v the volatile attribute state.
|
||||||
*/
|
*/
|
||||||
public void setVolatile(boolean v);
|
public void setVolatile(boolean v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the artificial attribute state of this block. This attribute is
|
||||||
|
* generally associated with blocks which have been fabricated to facilitate
|
||||||
|
* analysis but do not exist in the same form within a running/loaded process
|
||||||
|
* state.
|
||||||
|
*
|
||||||
|
* @return true if enabled else false
|
||||||
|
*/
|
||||||
|
public boolean isArtificial();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the artificial attribute state associated with this block. This attribute is
|
||||||
|
* generally associated with blocks which have been fabricated to facilitate
|
||||||
|
* analysis but do not exist in the same form within a running/loaded process
|
||||||
|
* state.
|
||||||
|
*
|
||||||
|
* @param a the artificial attribute state.
|
||||||
|
*/
|
||||||
|
public void setArtificial(boolean a);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of the source of this memory block.
|
* Get the name of the source of this memory block.
|
||||||
*
|
*
|
||||||
|
@ -208,6 +246,7 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
* Returns the byte at the given address in this block.
|
* Returns the byte at the given address in this block.
|
||||||
*
|
*
|
||||||
* @param addr the address.
|
* @param addr the address.
|
||||||
|
* @return byte value from this block and specified address
|
||||||
* @throws MemoryAccessException if any of the requested bytes are uninitialized.
|
* @throws MemoryAccessException if any of the requested bytes are uninitialized.
|
||||||
* @throws IllegalArgumentException if the Address is not in this block.
|
* @throws IllegalArgumentException if the Address is not in this block.
|
||||||
*/
|
*/
|
||||||
|
@ -246,6 +285,7 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||||
* Puts the given byte at the given address in this block.
|
* Puts the given byte at the given address in this block.
|
||||||
*
|
*
|
||||||
* @param addr the address.
|
* @param addr the address.
|
||||||
|
* @param b byte value
|
||||||
* @throws MemoryAccessException if the block is uninitialized
|
* @throws MemoryAccessException if the block is uninitialized
|
||||||
* @throws IllegalArgumentException if the Address is not in this block.
|
* @throws IllegalArgumentException if the Address is not in this block.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class MemoryBlockStub implements MemoryBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPermissions() {
|
public int getFlags() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +150,16 @@ public class MemoryBlockStub implements MemoryBlock {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isArtificial() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArtificial(boolean a) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOverlay() {
|
public boolean isOverlay() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class MemBlockDBTest extends AbstractGenericTest {
|
||||||
assertEquals(false, block.isMapped());
|
assertEquals(false, block.isMapped());
|
||||||
assertNull(block.getComment());
|
assertNull(block.getComment());
|
||||||
assertNull(block.getSourceName());
|
assertNull(block.getSourceName());
|
||||||
assertEquals(MemoryBlock.READ, block.getPermissions());
|
assertEquals(MemoryBlock.READ, block.getFlags());
|
||||||
|
|
||||||
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ public class MemBlockDBTest extends AbstractGenericTest {
|
||||||
assertEquals(true, block.isMapped());
|
assertEquals(true, block.isMapped());
|
||||||
assertNull(block.getComment());
|
assertNull(block.getComment());
|
||||||
assertNull(block.getSourceName());
|
assertNull(block.getSourceName());
|
||||||
assertEquals(MemoryBlock.READ, block.getPermissions());
|
assertEquals(MemoryBlock.READ, block.getFlags());
|
||||||
|
|
||||||
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ public class MemBlockDBTest extends AbstractGenericTest {
|
||||||
assertEquals(true, block.isMapped());
|
assertEquals(true, block.isMapped());
|
||||||
assertNull(block.getComment());
|
assertNull(block.getComment());
|
||||||
assertNull(block.getSourceName());
|
assertNull(block.getSourceName());
|
||||||
assertEquals(MemoryBlock.READ, block.getPermissions());
|
assertEquals(MemoryBlock.READ, block.getFlags());
|
||||||
|
|
||||||
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ public class MemBlockDBTest extends AbstractGenericTest {
|
||||||
assertEquals(false, block.isMapped());
|
assertEquals(false, block.isMapped());
|
||||||
assertNull(block.getComment());
|
assertNull(block.getComment());
|
||||||
assertNull(block.getSourceName());
|
assertNull(block.getSourceName());
|
||||||
assertEquals(MemoryBlock.READ, block.getPermissions());
|
assertEquals(MemoryBlock.READ, block.getFlags());
|
||||||
|
|
||||||
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,10 @@ class MIPS_ElfRelocationContext extends ElfRelocationContext<MIPS_ElfRelocationH
|
||||||
sectionGotAddress, size,
|
sectionGotAddress, size,
|
||||||
"NOTE: This block is artificial and allows ELF Relocations to work correctly",
|
"NOTE: This block is artificial and allows ELF Relocations to work correctly",
|
||||||
"Elf Loader", true, false, false, loadHelper.getLog());
|
"Elf Loader", true, false, false, loadHelper.getLog());
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
DataConverter converter =
|
DataConverter converter =
|
||||||
program.getMemory().isBigEndian() ? BigEndianDataConverter.INSTANCE
|
program.getMemory().isBigEndian() ? BigEndianDataConverter.INSTANCE
|
||||||
: LittleEndianDataConverter.INSTANCE;
|
: LittleEndianDataConverter.INSTANCE;
|
||||||
|
|
|
@ -259,6 +259,10 @@ class X86_64_ElfRelocationContext extends ElfRelocationContext<X86_64_ElfRelocat
|
||||||
ElfRelocationHandler.GOT_BLOCK_NAME, allocatedGotAddress, size,
|
ElfRelocationHandler.GOT_BLOCK_NAME, allocatedGotAddress, size,
|
||||||
"NOTE: This block is artificial and allows ELF Relocations to work correctly",
|
"NOTE: This block is artificial and allows ELF Relocations to work correctly",
|
||||||
"Elf Loader", true, false, false, loadHelper.getLog());
|
"Elf Loader", true, false, false, loadHelper.getLog());
|
||||||
|
|
||||||
|
// Mark block as an artificial fabrication
|
||||||
|
block.setArtificial(true);
|
||||||
|
|
||||||
DataConverter converter =
|
DataConverter converter =
|
||||||
program.getMemory().isBigEndian() ? BigEndianDataConverter.INSTANCE
|
program.getMemory().isBigEndian() ? BigEndianDataConverter.INSTANCE
|
||||||
: LittleEndianDataConverter.INSTANCE;
|
: LittleEndianDataConverter.INSTANCE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue