GP-5975 Eliminated unused NotFoundException from Memory methods.

Revised import to always include pspec symbols within pcode-defined
memory blocks.  Added label name check.  Revised language version
upgrade to handle certain pspec-defined block and symbol changes.
Corrected RISC-V 64-bit-fp cspec.
This commit is contained in:
ghidra1
2025-11-05 14:39:41 -05:00
parent ade1ad71ba
commit c3a2482e18
30 changed files with 678 additions and 331 deletions

View File

@@ -34,7 +34,6 @@ import ghidra.trace.database.memory.DBTraceMemoryManager;
import ghidra.trace.database.memory.DBTraceMemorySpace;
import ghidra.util.MathUtilities;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
@@ -305,31 +304,31 @@ public class DBTraceGuestPlatformMappedMemory implements Memory {
@Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException {
AddressOverflowException {
throw new UnsupportedOperationException();
}
@Override
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException {
throws MemoryBlockException, LockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException {
throws LockException, MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException {
throws LockException, MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock)
throws MemoryBlockException, NotFoundException, LockException {
throws MemoryBlockException, LockException {
throw new UnsupportedOperationException();
}

View File

@@ -33,7 +33,6 @@ import ghidra.trace.util.MemoryAdapter;
import ghidra.util.LockHold;
import ghidra.util.MathUtilities;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
public abstract class AbstractDBTraceProgramViewMemory
@@ -206,31 +205,31 @@ public abstract class AbstractDBTraceProgramViewMemory
@Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException {
AddressOverflowException {
throw new UnsupportedOperationException();
}
@Override
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException {
throws MemoryBlockException, LockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException {
throws LockException, MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException {
throws LockException, MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock)
throws MemoryBlockException, NotFoundException, LockException {
throws MemoryBlockException, LockException {
throw new UnsupportedOperationException();
}

View File

@@ -20,7 +20,6 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.program.util.ProgramTask;
import ghidra.util.Msg;
import ghidra.util.exception.NotFoundException;
import ghidra.util.exception.RollbackException;
import ghidra.util.task.TaskMonitor;
@@ -80,10 +79,6 @@ public class MoveBlockTask extends ProgramTask {
statusMessage = "Insufficient memory to complete operation";
cause = e;
}
catch (NotFoundException e) {
statusMessage = "Memory block not found";
cause = e;
}
catch (MemoryConflictException | MemoryBlockException | IllegalArgumentException e) {
statusMessage = e.getMessage();
cause = e;

View File

@@ -693,7 +693,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
memBlk = memory.getBlock(afterFlag);
memBlk.setName(memBlk.getName().replaceFirst("(\\.split)+$", ".part2"));
}
catch (MemoryBlockException | LockException | NotFoundException e) {
catch (MemoryBlockException | LockException e) {
Msg.error(this, "Failed to fixup runtime.writeBarrier flag", e);
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,7 +27,8 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.*;
import ghidra.util.Msg;
import ghidra.util.exception.*;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.RollbackException;
/**
* Helper class to make changes to memory blocks.
@@ -270,10 +271,6 @@ class MemoryMapManager {
msg = e.getMessage();
return false;
}
catch (NotFoundException e) {
msg = e.getMessage();
return false;
}
catch (LockException e) {
msg = e.getMessage();
return false;

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -43,6 +43,7 @@ import ghidra.framework.Application;
import ghidra.framework.main.ApplicationLevelPlugin;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.IncompatibleLanguageException;
@@ -50,6 +51,7 @@ import ghidra.program.util.*;
import ghidra.util.Msg;
import ghidra.util.exception.AssertException;
import ghidra.util.filechooser.ExtensionFileFilter;
import ghidra.util.task.TaskMonitor;
import ghidra.util.xml.GenericXMLOutputter;
//@formatter:off
@@ -395,8 +397,7 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
Register oldCtx = oldLang.getContextBaseRegister();
Register newCtx = newLang.getContextBaseRegister();
boolean contextWarning = false;
if (oldCtx != Register.NO_CONTEXT &&
defaultTrans.isValueTranslationRequired(oldCtx)) {
if (oldCtx != Register.NO_CONTEXT && defaultTrans.isValueTranslationRequired(oldCtx)) {
contextWarning = true;
}
else if (oldCtx == Register.NO_CONTEXT && newCtx != Register.NO_CONTEXT) {

View File

@@ -325,9 +325,8 @@ public abstract class AbstractProgramLoader implements Loader {
prog.setExecutableFormat(executableFormatName);
}
FSRL fsrl = provider.getFSRL();
String md5 = (fsrl != null && fsrl.getMD5() != null)
? fsrl.getMD5()
: computeBinaryMD5(provider);
String md5 =
(fsrl != null && fsrl.getMD5() != null) ? fsrl.getMD5() : computeBinaryMD5(provider);
if (fsrl != null) {
if (fsrl.getMD5() == null) {
fsrl = fsrl.withMD5(md5);
@@ -470,6 +469,19 @@ public abstract class AbstractProgramLoader implements Loader {
return DefaultLanguageService.getLanguageService();
}
private AddressSetView getProcessorDefinedMemoryBlockAddresses(Program program) {
AddressSet blockAddrSet = new AddressSet();
Memory memory = program.getMemory();
Language language = program.getLanguage();
for (MemoryBlockDefinition defaultMemoryBlockDef : language.getDefaultMemoryBlocks()) {
MemoryBlock block = memory.getBlock(defaultMemoryBlockDef.getBlockName());
if (block != null) {
blockAddrSet.add(block.getAddressRange());
}
}
return blockAddrSet;
}
private void applyProcessorLabels(List<Option> options, Program program) {
int id = program.startTransaction("Finalize load");
try {
@@ -482,15 +494,25 @@ public abstract class AbstractProgramLoader implements Loader {
createSymbol(program, reg.getName(), addr, null, false, true, true);
}
}
// optionally create default symbols defined by pspec
if (shouldApplyProcessorLabels(options)) {
boolean anchorSymbols = shouldAnchorSymbols(options);
List<AddressLabelInfo> labels = lang.getDefaultSymbols();
for (AddressLabelInfo info : labels) {
createSymbol(program, info.getLabel(), info.getAddress(), info.getDescription(), info.isEntry(),
info.isPrimary(), anchorSymbols);
// NOTE: pspec defined labels should always be defined if they correspond to a memory
// block defined by the pspec.
boolean applyAllProcessorLabels = shouldApplyProcessorLabels(options);
AddressSetView pspecDefinedBlockSet = getProcessorDefinedMemoryBlockAddresses(program);
boolean anchorSymbols = shouldAnchorSymbols(options);
List<AddressLabelInfo> labels = lang.getDefaultSymbols();
for (AddressLabelInfo info : labels) {
Address addr = info.getAddress();
boolean isRequiredLabel = pspecDefinedBlockSet.contains(addr);
if (isRequiredLabel || applyAllProcessorLabels) {
// NOTE: Required labels contained within a pspec-defined memory block do not
// need to be pinned/anchored
boolean anchor = !isRequiredLabel && anchorSymbols;
createSymbol(program, info.getLabel(), info.getAddress(), info.getDescription(),
info.isEntry(), info.isPrimary(), anchor);
}
}
GhidraProgramUtilities.resetAnalysisFlags(program);
}
finally {

View File

@@ -269,7 +269,7 @@ public class NeLoader extends AbstractOrdinalSupportLoader {
try {
block = program.getMemory().join(block, zeroBlock); // expand
}
catch (MemoryBlockException | LockException | NotFoundException e) {
catch (MemoryBlockException | LockException e) {
throw new IOException(e);
}
}

View File

@@ -23,7 +23,6 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
@@ -297,9 +296,6 @@ public class MemoryDiff {
catch (LockException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
}
catch (NotFoundException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
}
catch (AddressOutOfBoundsException e) {
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
}

View File

@@ -25,7 +25,6 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
public class MyTestMemory extends AddressSet implements Memory {
@@ -153,30 +152,30 @@ public class MyTestMemory extends AddressSet implements Memory {
@Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws MemoryConflictException, AddressOverflowException, NotFoundException {
throws MemoryConflictException, AddressOverflowException {
throw new UnsupportedOperationException();
}
@Override
public void split(MemoryBlock block, Address addr) throws NotFoundException {
public void split(MemoryBlock block, Address addr) {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws MemoryBlockException, NotFoundException {
throws MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws MemoryBlockException, NotFoundException {
throws MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, NotFoundException {
throws MemoryBlockException {
throw new UnsupportedOperationException();
}

View File

@@ -44,7 +44,8 @@ import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.util.Msg;
import ghidra.util.exception.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor;
/**
@@ -177,8 +178,7 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
DumpAddressObject d = daos.get(address);
try {
MemoryBlockUtils.createInitializedBlock(program, false, d.getRangeName(),
address, fileBytes,
d.getRVA(), // offset into filebytes
address, fileBytes, d.getRVA(), // offset into filebytes
d.getLength(), // size
d.getComment(), // comment
null, // source
@@ -215,7 +215,7 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
try {
m = memory.join(m, next);
}
catch (MemoryBlockException | LockException | NotFoundException e) {
catch (MemoryBlockException | LockException e) {
break;
}
deleted.add(next.getStart());
@@ -281,9 +281,8 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
symbolTable.createLabel(address, dd.getName(), SourceType.IMPORTED);
}
catch (InvalidInputException e) {
Msg.error(this,
"Error creating label " + dd.getName() + " at address " + address +
": " + e.getMessage());
Msg.error(this, "Error creating label " + dd.getName() + " at address " +
address + ": " + e.getMessage());
}
continue;
}

View File

@@ -0,0 +1,139 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.processors.generic;
import java.util.*;
import ghidra.framework.store.LockException;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.symbol.SymbolManager;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.AddressLabelInfo;
import ghidra.program.model.lang.Language;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.mem.MemoryBlockException;
import ghidra.program.model.symbol.*;
import ghidra.util.Msg;
import ghidra.util.exception.*;
/**
* {@link LanguageFixupUtil} provides utility method intended for internal language upgrade
* situations.
*/
public class LanguageFixupUtil {
/**
* Apply pspec defined memory blocks and default symbols which are considered safe and
* generally required. Reconciling symbols is limited to those symbols contained within
* processor defined memory blocks which are not within either the default code or data spaces.
* @param programDB target program
*/
public static void applyPSpecFixups(ProgramDB programDB) throws CancelledException {
try {
Language language = programDB.getLanguage();
AddressSpace defaultSpace = language.getDefaultSpace();
AddressSpace defaultDataSpace = language.getDefaultDataSpace();
// Create or fixup processor defined memory blocks
// NOTE: Additional translator capability required if block removal is required which
// would likely remove any IMPORTED symbols contained within its bounds
AddressSet processorDefinedBlockSet = new AddressSet();
// Define address set which identifies processor define blocks which are safe to scrub
// of old imported symbols.
AddressSet processorDefinedSafeBlockSet = new AddressSet();
for (MemoryBlockDefinition defaultMemoryBlockDef : language.getDefaultMemoryBlocks()) {
try {
MemoryBlock block = defaultMemoryBlockDef.fixupBlock(programDB);
AddressRange blockRange = block.getAddressRange();
processorDefinedBlockSet.add(blockRange);
AddressSpace space = block.getStart().getAddressSpace();
if (!space.equals(defaultSpace) && !space.equals(defaultDataSpace)) {
processorDefinedSafeBlockSet.add(blockRange);
}
}
catch (MemoryBlockException e) {
Msg.error(LanguageFixupUtil.class,
"Failed to create or fixup processor defined memory block '" +
defaultMemoryBlockDef.getBlockName() + "': " + e.getMessage());
}
catch (LockException e) {
throw new RuntimeException(e); // upgrades require exclusive access
}
}
HashSet<Symbol> goodSymbols = new HashSet<>();
SymbolManager symbolTable = programDB.getSymbolTable();
for (AddressLabelInfo labelInfo : language.getDefaultSymbols()) {
String name = labelInfo.getLabel();
Address addr = labelInfo.getAddress();
// NOTE: For now we only add symbols which are defined within processor-defined blocks
if (!processorDefinedBlockSet.contains(addr)) {
continue;
}
// Check all symbols within processor-defined blocks
Symbol existingSymbol = null;
for (Symbol s : symbolTable.getGlobalSymbols(name)) {
if (s.getSymbolType() != SymbolType.LABEL) {
continue;
}
if (addr.equals(s.getAddress())) {
existingSymbol = s;
goodSymbols.add(s);
}
else if (s.getSource() == SourceType.IMPORTED) {
s.delete();
}
}
if (existingSymbol == null) {
// Add missing label
try {
Symbol s = symbolTable.createLabel(addr, name, null, SourceType.IMPORTED);
goodSymbols.add(s);
}
catch (InvalidInputException e) {
throw new AssertException(e); // unexpected
}
}
}
// Remove all symbols with processor defined blocks which are no longer defined.
// This is restricted to safe address spaces since loader may have imported other symbols
// which we do not want to delete.
List<Symbol> deleteSet = new ArrayList<>(); // defered delete to avoid iterator resets
for (Symbol s : symbolTable.getSymbols(processorDefinedSafeBlockSet, SymbolType.LABEL,
true)) {
if (s.getSource() == SourceType.IMPORTED && !goodSymbols.contains(s)) {
deleteSet.add(s);
}
}
for (Symbol s : deleteSet) {
s.delete();
}
}
catch (UnsupportedOperationException e) {
// skip
}
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,11 +15,15 @@
*/
package ghidra.app.plugin.processors.generic;
import java.util.List;
import ghidra.framework.store.LockException;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.mem.ByteMappingScheme;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.util.Msg;
import ghidra.util.XmlProgramUtilities;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException;
@@ -36,18 +40,22 @@ import ghidra.xml.XmlElement;
*/
public class MemoryBlockDefinition {
private String blockName;
private String addressString;
private int length;
private boolean initialized;
private boolean overlay;
private String bitMappedAddress;
private String byteMappedAddress;
private ByteMappingScheme byteMappingScheme;
private boolean readPermission = true;
private boolean writePermission = true;
private boolean executePermission = false;
private boolean isVolatile = false;
private final String blockName;
private final String addressString;
private final int length;
private final boolean initialized;
private final boolean overlay;
private final String bitMappedAddress;
private final String byteMappedAddress;
private final ByteMappingScheme byteMappingScheme;
private final String mode;
private final boolean readPermission;
private final boolean writePermission;
private final boolean executePermission;
private final boolean isVolatile;
private static final String DEFAULT_MODE = "rw";
/**
* Construct <code>MemoryBlockDefinition</code> using a text-based specified.
@@ -62,7 +70,8 @@ public class MemoryBlockDefinition {
* decimations may be specified using a mapping ratio. When specifying a mapping ratio both
* values must be in the range 1..127 where the right (source-byte count) value must be
* greater-than-or-equal to the left value (e.g., 2:4).
* @param mode block mode as concatenation of the following mode indicator characters:
* @param mode block mode as concatenation of the following mode indicator characters. If null
* the default mode (rw) will be used.
* <pre>
* r - read mode enabled
* w - write mode enabled
@@ -71,18 +80,33 @@ public class MemoryBlockDefinition {
* </pre>
* @param lengthString length of memory block in bytes (required)
* @param initializedString boolean (y | n | true | false) indicating if memory block is
* initialialized or not (must be null for mapped block specification)
* initialialized or not (ignored for mapped block specification)
* @param overlayString boolean (y | n | true | false) indicating if memory block is an overlay
* (false assumed if null).
* @throws XmlAttributeException if parse failure occurs (NOTE: address parsing is not performed)
*/
private MemoryBlockDefinition(String blockName, String addressString, String bitMappedAddress,
String byteMappedAddressRatio, String mode, String lengthString,
String initializedString, String overlayString)
throws XmlAttributeException {
String initializedString, String overlayString) throws XmlAttributeException {
this.mode = mode != null ? mode.toLowerCase() : DEFAULT_MODE;
// Parse specified access mode
readPermission = this.mode.indexOf('r') >= 0;
writePermission = this.mode.indexOf('w') >= 0;
executePermission = this.mode.indexOf('x') >= 0;
isVolatile = this.mode.indexOf('v') >= 0;
if (blockName == null) {
throw new XmlAttributeException("Missing default memory block 'name'");
}
this.blockName = blockName;
if (addressString == null) {
throw new XmlAttributeException("Missing default memory block 'start_address'");
}
this.addressString = addressString;
this.bitMappedAddress = bitMappedAddress;
if (byteMappedAddressRatio != null) {
@@ -98,30 +122,35 @@ public class MemoryBlockDefinition {
}
else {
// 1:1 mapping scheme assumed (null byteMappingScheme)
byteMappingScheme = null;
byteMappedAddress = byteMappedAddressRatio;
}
}
if (mode != null) {
mode = mode.toLowerCase();
readPermission = mode.indexOf('r') >= 0;
writePermission = mode.indexOf('w') >= 0;
executePermission = mode.indexOf('x') >= 0;
isVolatile = mode.indexOf('v') >= 0;
else {
byteMappedAddress = null;
byteMappingScheme = null;
}
// Parse specified length string
int parsedLen = -1;
try {
length = XmlUtilities.parseInt(lengthString);
parsedLen = XmlUtilities.parseInt(lengthString);
}
catch (NumberFormatException e) {
throw new XmlAttributeException(lengthString + " is not a valid integer");
// ignore - length will be checked below
}
if (parsedLen <= 0) {
throw new XmlAttributeException(lengthString + " is not a valid 'length'");
}
length = parsedLen;
if (initializedString != null) {
if (bitMappedAddress != null || byteMappedAddress != null) {
throw new XmlAttributeException(
"mapped block specifications must not specify initialized attribute");
}
initialized = XmlUtilities.parseBoolean(initializedString);
}
initialized = XmlUtilities.parseBoolean(initializedString);
overlay = XmlUtilities.parseBoolean(overlayString);
}
@@ -142,20 +171,164 @@ public class MemoryBlockDefinition {
return addr;
}
/**
* {@return memory block name}
*/
public String getBlockName() {
return blockName;
}
/**
* Create or fixup existing block found within specified program.
* @param program target program
* @return new or adjusted memory block
* @throws LockException if program does not have exclusive access
* @throws MemoryBlockException if failed to create or fixup default memory block
*/
public MemoryBlock fixupBlock(ProgramDB program) throws LockException, MemoryBlockException {
program.checkExclusiveAccess();
Memory memory = program.getMemory();
MemoryBlock block = memory.getBlock(blockName);
if (block == null) {
try {
Msg.info(this, "Adding process-defined memory block: " + blockName);
return createBlock(program);
}
catch (MemoryConflictException | AddressOverflowException | InvalidAddressException e) {
throw new MemoryBlockException("Create block failed", e);
}
}
MemoryBlockType blockType = getBlockType();
List<MemoryBlockSourceInfo> sourceInfos = block.getSourceInfos();
if (!blockType.equals(block.getType()) || overlay != block.isOverlay() ||
sourceInfos.size() != 1) {
throw new MemoryBlockException("Incompatible memory block type");
}
MemoryBlockSourceInfo sourceInfo = sourceInfos.get(0);
Address addr;
Address currentStartAddress;
try {
addr = parseAddress(addressString, program, "block address");
currentStartAddress = block.getStart();
AddressSpace currentAddressSpace = currentStartAddress.getAddressSpace();
if (currentAddressSpace instanceof OverlayAddressSpace overlaySpace) {
if (overlaySpace.getOverlayedSpace().equals(addr.getAddressSpace())) {
throw new MemoryBlockException("Incompatible overlay memory block");
}
// Redefine overlay block start address for comparison use
addr = overlaySpace.getAddressInThisSpaceOnly(addr.getOffset());
}
if (bitMappedAddress != null) {
Address mappedAddr = parseAddress(bitMappedAddress, program, "bit-mapped address");
if (addr.equals(currentStartAddress) &&
mappedAddr.equals(sourceInfo.getMappedRange().get().getMinAddress()) &&
length == block.getSize()) {
return block;
}
// We do not currently support modifying default bit-mapped block
throw new MemoryBlockException("inconsistent bit-mapped block");
}
else if (byteMappedAddress != null) {
Address mappedAddr =
parseAddress(byteMappedAddress, program, "byte-mapped address");
if (addr.equals(currentStartAddress) &&
mappedAddr.equals(sourceInfo.getMappedRange().get().getMinAddress()) &&
length == block.getSize()) {
return block;
}
// We do not currently support modifying default byte-mapped block
throw new MemoryBlockException("inconsistent byte-mapped block");
}
}
catch (InvalidAddressException e) {
throw new MemoryBlockException("failed to process processor block address", e);
}
if (sourceInfo.getFileBytes().isPresent() || sourceInfo.getMappedRange().isPresent()) {
throw new MemoryBlockException("unsupported file or memory-mapped block");
}
if (!addr.equals(currentStartAddress)) {
throw new MemoryBlockException(
"inconsistent block start address: " + addr + " / " + currentStartAddress);
}
try {
if (length > block.getSize()) {
// Expand processor defined memory block
Msg.info(this, "Expanding processor defined memory block from " + block.getSize() +
"-bytes to " + length + "-bytes: " + blockName);
MemoryBlock newBlock = memory.createBlock(block, block.getName() + ".exp",
block.getEnd().next(), length - block.getSize());
MemoryBlock b = memory.join(block, newBlock);
if (!b.getName().equals(blockName)) {
b.setName(blockName); // preserve block name
}
}
else {
Msg.warn(this, "Ignored processor block size reduction: " + blockName);
}
boolean accessAdjusted = false;
if (readPermission != block.isRead()) {
block.setRead(readPermission);
accessAdjusted = true;
}
if (writePermission != block.isWrite()) {
block.setWrite(writePermission);
accessAdjusted = true;
}
if (executePermission != block.isExecute()) {
block.setExecute(executePermission);
accessAdjusted = true;
}
if (isVolatile != block.isVolatile()) {
block.setVolatile(isVolatile);
accessAdjusted = true;
}
if (accessAdjusted) {
Msg.warn(this, "Updated processor block access mode (" + mode + "): " + blockName);
}
}
catch (IllegalArgumentException | MemoryConflictException | AddressOverflowException e) {
throw new MemoryBlockException("block adjustment failed", e);
}
return block;
}
private MemoryBlockType getBlockType() {
if (bitMappedAddress != null) {
return MemoryBlockType.BIT_MAPPED;
}
if (byteMappedAddress != null) {
return MemoryBlockType.BYTE_MAPPED;
}
return MemoryBlockType.DEFAULT;
}
/**
* Create memory block within specified program based upon this block specification.
* @param program target program
* @return newly created memory block
* @throws LockException if program does not have exclusive access required when adding memory blocks.
* @throws MemoryConflictException if this specification conflicts with an existing memory block in program
* @throws AddressOverflowException if memory space constraints are violated by block specification
* @throws InvalidAddressException if address defined by this block specification is invalid
* for the specified program. May also indicate an improperly formatted address attribute.
*/
public void createBlock(Program program) throws LockException, MemoryConflictException,
public MemoryBlock createBlock(Program program) throws LockException, MemoryConflictException,
AddressOverflowException, InvalidAddressException {
if (blockName == null || addressString == null || length <= 0) {
return;
}
Memory mem = program.getMemory();
Address addr = parseAddress(addressString, program, "block address");
@@ -172,9 +345,8 @@ public class MemoryBlockDefinition {
}
else if (initialized) {
try {
block =
mem.createInitializedBlock(blockName, addr, length, (byte) 0,
TaskMonitor.DUMMY, overlay);
block = mem.createInitializedBlock(blockName, addr, length, (byte) 0,
TaskMonitor.DUMMY, overlay);
}
catch (CancelledException e) {
throw new AssertException(e); // unexpected
@@ -187,6 +359,7 @@ public class MemoryBlockDefinition {
block.setWrite(writePermission);
block.setExecute(executePermission);
block.setVolatile(isVolatile);
return block;
}
@Override

View File

@@ -47,6 +47,7 @@ import ghidra.program.model.util.ProcessorSymbolType;
import ghidra.sleigh.grammar.SleighPreprocessor;
import ghidra.sleigh.grammar.SourceFileIndexer;
import ghidra.util.*;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor;
import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*;
@@ -787,10 +788,9 @@ public class SleighLanguage implements Language {
AddressLabelInfo info;
try {
info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment,
false,
isEntry, type, isVolatile);
false, isEntry, type, isVolatile);
}
catch (AddressOverflowException e) {
catch (AddressOverflowException | InvalidInputException e) {
throw new XmlParseException("invalid symbol definition: " + labelName,
e);
}
@@ -1242,9 +1242,7 @@ public class SleighLanguage implements Language {
ManualEntry manualEntry = null;
int maxInCommon = -1;
Iterator<Entry<String, ManualEntry>> ii = subMap.entrySet().iterator();
while (ii.hasNext()) {
Entry<String, ManualEntry> mapEntry = ii.next();
for (Entry<String, ManualEntry> mapEntry : subMap.entrySet()) {
String key = mapEntry.getKey();
if (instruction.startsWith(key) && key.length() > maxInCommon) {
manualEntry = mapEntry.getValue();

View File

@@ -22,6 +22,7 @@ import java.util.*;
import org.apache.commons.lang3.StringUtils;
import db.DBHandle;
import ghidra.app.plugin.processors.generic.LanguageFixupUtil;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.framework.Application;
import ghidra.framework.data.DomainObjectAdapterDB;
@@ -2065,8 +2066,10 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
newCompilerSpecID = translator.getNewCompilerSpecID(compilerSpecID);
}
Msg.info(this, "Setting language for Program " + getName() + ": " + translator);
Msg.info(this, "Setting compiler spec for Program " + getName() + ": " +
compilerSpecID + " -> " + newCompilerSpecID);
if (!compilerSpecID.equals(newCompilerSpecID)) {
Msg.info(this, "Setting compiler spec for Program " + getName() + ": " +
compilerSpecID + " -> " + newCompilerSpecID);
}
}
else if (!forceRedisassembly && language.getVersion() == languageVersion &&
language.getMinorVersion() == languageMinorVersion) {
@@ -2138,6 +2141,9 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
translator.fixupInstructions(this, translator.getOldLanguage(), monitor);
}
// apply pspec default markup as defined by translator and pspec
LanguageFixupUtil.applyPSpecFixups(this);
dataMap.put(LANGUAGE_ID, languageID.getIdAsString());
dataMap.put(COMPILER_SPEC_ID, compilerSpecID.getIdAsString());
dataMap.put(LANGUAGE_VERSION, languageVersion + "." + languageMinorVersion);

View File

@@ -941,7 +941,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws MemoryBlockException, MemoryConflictException, AddressOverflowException,
NotFoundException, LockException {
LockException {
lock.acquire();
try {
program.checkExclusiveAccess();
@@ -986,8 +986,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
}
@Override
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, NotFoundException, LockException {
public void split(MemoryBlock block, Address addr) throws MemoryBlockException, LockException {
lock.acquire();
try {
program.checkExclusiveAccess();
@@ -1037,7 +1036,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws MemoryBlockException, NotFoundException, LockException {
throws MemoryBlockException, LockException {
lock.acquire();
try {
// swap if second block is before first block
@@ -1111,7 +1110,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws MemoryBlockException, NotFoundException, LockException {
throws MemoryBlockException, LockException {
lock.acquire();
try {
checkBlock(uninitializedBlock);
@@ -1149,7 +1148,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, NotFoundException, LockException {
throws MemoryBlockException, LockException {
lock.acquire();
try {
program.checkExclusiveAccess();

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,10 +15,12 @@
*/
package ghidra.program.model.data;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.lang.*;
import ghidra.program.model.listing.IncompatibleLanguageException;
import ghidra.program.util.DefaultLanguageService;
import ghidra.program.util.LanguageTranslatorAdapter;
import ghidra.util.task.TaskMonitor;
public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter {
@@ -40,9 +42,8 @@ public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter {
public ProgramArchitectureTranslator(LanguageID oldLanguageId, int oldLanguageVersion,
CompilerSpecID oldCompilerSpecId, Language newLanguage,
CompilerSpecID newCompilerSpecId)
throws LanguageNotFoundException, CompilerSpecNotFoundException,
IncompatibleLanguageException {
CompilerSpecID newCompilerSpecId) throws LanguageNotFoundException,
CompilerSpecNotFoundException, IncompatibleLanguageException {
this(getLanguage(oldLanguageId, oldLanguageVersion), oldCompilerSpecId, newLanguage,
newCompilerSpecId);
}
@@ -65,5 +66,4 @@ public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter {
return newCompilerSpec;
}
}

View File

@@ -17,7 +17,9 @@ package ghidra.program.model.lang;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.symbol.SymbolUtilities;
import ghidra.program.model.util.ProcessorSymbolType;
import ghidra.util.exception.InvalidInputException;
/**
* <CODE>AddressLabelInfo</CODE> is a utility class for storing
@@ -35,7 +37,7 @@ public class AddressLabelInfo implements Comparable<AddressLabelInfo> {
private ProcessorSymbolType processorSymbolType;
private int sizeInBytes;
private Boolean isVolatile;
/**
* Constructor for class AddressLabelInfo
*
@@ -47,17 +49,22 @@ public class AddressLabelInfo implements Comparable<AddressLabelInfo> {
* @param isEntry boolean describes if this object is an entry label for the Address 'addr'
* @param type ProcessorSymbolType the type of symbol
* @param isVolatile Boolean describes if the memory at this address is volatile
* @throws AddressOverflowException if sizeInBytes cause an overflow relative to address
* @throws InvalidInputException if an invalid label name is specified
*/
public AddressLabelInfo(Address addr, Integer sizeInBytes, String label, String description, boolean isPrimary,
boolean isEntry, ProcessorSymbolType type, Boolean isVolatile) throws AddressOverflowException {
public AddressLabelInfo(Address addr, Integer sizeInBytes, String label, String description,
boolean isPrimary, boolean isEntry, ProcessorSymbolType type, Boolean isVolatile)
throws AddressOverflowException, InvalidInputException {
SymbolUtilities.validateName(label);
this.addr = addr;
if ( sizeInBytes == null || sizeInBytes <= 0 ) {
if (sizeInBytes == null || sizeInBytes <= 0) {
// Default size in addressable units
this.sizeInBytes = addr.getAddressSpace().getAddressableUnitSize();
} else {
}
else {
this.sizeInBytes = sizeInBytes;
}
this.endAddr = this.addr.addNoWrap(this.sizeInBytes-1);
this.endAddr = this.addr.addNoWrap(this.sizeInBytes - 1);
this.label = label;
this.description = description;
this.isPrimary = isPrimary;
@@ -72,21 +79,21 @@ public class AddressLabelInfo implements Comparable<AddressLabelInfo> {
public final Address getAddress() {
return addr;
}
/**
* @return the object's end address.
*/
public final Address getEndAddress() {
return endAddr;
}
/**
* @return the object's label or alias.
*/
public final String getLabel() {
return label;
}
/**
* @return the object's description if it has one, null otherwise
*/
@@ -101,14 +108,14 @@ public class AddressLabelInfo implements Comparable<AddressLabelInfo> {
public final int getByteSize() {
return sizeInBytes;
}
/**
* @return whether the object is the primary label at the address.
*/
public final boolean isPrimary() {
return isPrimary;
}
/**
* @return whether the object is volatile.
* Boolean.False when the address is explicitly not volatile.

View File

@@ -25,7 +25,6 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.OffsetReference;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
@@ -462,16 +461,14 @@ public interface Memory extends AddressSetView {
* @param newStartAddr new start address for block
* @param monitor task monitor so the move block can be canceled
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryBlockException if block movement is not permitted
* @throws MemoryConflictException if move would cause
* blocks to overlap.
* @throws MemoryBlockException if block movement is not permitted
* @throws AddressOverflowException if block movement would violate bounds of address space
* @throws NotFoundException if memoryBlock does not exist in
* this memory.
*/
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException;
AddressOverflowException;
/**
* Split a block at the given addr and create a new block
@@ -479,14 +476,11 @@ public interface Memory extends AddressSetView {
* @param block block to be split into two
* @param addr address (within block) that will be the
* start of new block
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws NotFoundException thrown if block does not exist
* in memory
* @throws MemoryBlockException memory split not permitted
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws AddressOutOfBoundsException thrown if address is not in the block
*/
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException;
public void split(MemoryBlock block, Address addr) throws MemoryBlockException, LockException;
/**
* Join the two blocks to create a single memory block.
@@ -499,7 +493,7 @@ public interface Memory extends AddressSetView {
* not contiguous in the address space,
*/
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException;
throws LockException, MemoryBlockException;
/**
* Convert an existing uninitialized block with an initialized block.
@@ -512,10 +506,20 @@ public interface Memory extends AddressSetView {
* the same.
*/
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException;
throws LockException, MemoryBlockException;
public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock)
throws MemoryBlockException, NotFoundException, LockException;
/**
* Convert an existing initialized block with an uninitialized block.
* Block will discard any associated memory bytes and drop source info.
* @param initializedBlock uninitialized block to convert
* @return the converted block
* @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryBlockException if there is no block in memory
* at the same address as block or if the block lengths are not
* the same.
*/
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, LockException;
/**
* Finds a sequence of contiguous bytes that match the

View File

@@ -1,13 +1,12 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,7 +15,6 @@
*/
package ghidra.program.model.mem;
/**
* Exception thrown for memory block-related problems.
*/
@@ -29,11 +27,21 @@ public class MemoryBlockException extends MemoryAccessException {
public MemoryBlockException() {
super();
}
/**
* Constructs a new MemoryBlockException with a detailed message.
* @param msg detailed message
*/
public MemoryBlockException(String msg) {
super(msg);
}
}
public MemoryBlockException(String msg) {
super(msg);
}
/**
* Constructs a new MemoryBlockException with a detailed message.
* @param msg detailed message
* @param cause original cause of this exception
*/
public MemoryBlockException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -24,7 +24,6 @@ import ghidra.framework.store.LockException;
import ghidra.program.database.mem.*;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
@@ -241,31 +240,31 @@ public class StubMemory extends AddressSet implements Memory {
@Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException {
AddressOverflowException {
throw new UnsupportedOperationException();
}
@Override
public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException {
throws MemoryBlockException, LockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException {
throws LockException, MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException {
throws LockException, MemoryBlockException {
throw new UnsupportedOperationException();
}
@Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, NotFoundException, LockException {
throws MemoryBlockException, LockException {
throw new UnsupportedOperationException();
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,6 +15,7 @@
*/
package ghidra.program.util;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*;
@@ -34,7 +35,7 @@ import ghidra.util.task.TaskMonitor;
* instantiate Language, AddressSpace, AddressFactory or Register objects until isValid() is invoked.
*/
public interface LanguageTranslator extends ExtensionPoint {
/**
* Validate translator to complete initialization and ensure language compatibility.
* This method will be invoked by the LanguageTranslatorFactory before handing out this
@@ -42,7 +43,7 @@ public interface LanguageTranslator extends ExtensionPoint {
* @return true if translator successfully validated
*/
public boolean isValid();
/**
* Returns old language
* @throws IllegalStateException if instance has not been validated
@@ -54,27 +55,27 @@ public interface LanguageTranslator extends ExtensionPoint {
* Returns new language
*/
public Language getNewLanguage();
/**
* Returns old language name
*/
public LanguageID getOldLanguageID();
/**
* Returns new language name
*/
public LanguageID getNewLanguageID();
/**
* Returns old language version
*/
public int getOldVersion();
/**
* Returns new language version
*/
public int getNewVersion();
/**
* Translate BASE address spaces (Overlay spaces are not handled)
* @param oldSpaceName old space name
@@ -92,7 +93,7 @@ public interface LanguageTranslator extends ExtensionPoint {
* @see #getOldRegisterContaining(Address)
*/
public Register getOldRegister(Address oldAddr, int size);
/**
* Get the largest old register which contains the specified oldAddr
* @param oldAddr old register address which may be offcut
@@ -104,14 +105,14 @@ public interface LanguageTranslator extends ExtensionPoint {
* Returns the old processor context register or null if not defined
*/
public Register getOldContextRegister();
/**
* Find new register which corresponds to the specified old register.
* @param oldReg old register
* @return new register or null if corresponding register not found.
*/
public Register getNewRegister(Register oldReg);
/**
* Returns the new processor context register or null if not defined
*/
@@ -150,7 +151,8 @@ public interface LanguageTranslator extends ExtensionPoint {
* @throws CompilerSpecNotFoundException if new compiler spec not found based upon
* translator mappings.
*/
public CompilerSpec getOldCompilerSpec(CompilerSpecID oldCompilerSpecID) throws CompilerSpecNotFoundException;
public CompilerSpec getOldCompilerSpec(CompilerSpecID oldCompilerSpecID)
throws CompilerSpecNotFoundException;
/**
* Invoked after Program language upgrade has completed.
@@ -172,4 +174,5 @@ public interface LanguageTranslator extends ExtensionPoint {
*/
public void fixupInstructions(Program program, Language oldLanguage, TaskMonitor monitor)
throws Exception, CancelledException;
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -225,9 +225,7 @@ public abstract class LanguageTranslatorAdapter implements LanguageTranslator {
protected static AddressSpace findSpaceSameName(AddressSpace oldSpace,
ArrayList<AddressSpace> newSpaces) throws IncompatibleLanguageException {
Iterator<AddressSpace> it = newSpaces.iterator();
while (it.hasNext()) {
AddressSpace space = it.next();
for (AddressSpace space : newSpaces) {
if (space.getName().equals(oldSpace.getName())) {
if (oldSpace.getSize() > space.getSize()) {
throw new IncompatibleLanguageException("Old language space (" +

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,6 +20,7 @@ import java.util.*;
import generic.jar.ResourceFile;
import ghidra.framework.Application;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*;
@@ -405,10 +406,10 @@ public class LanguageTranslatorFactory {
}
/**
*
* Get language translator
* @param versionTranslatorList sorted list of version translators
* @param version
* @return
* @param version old/from language version
* @return translator from specified version or next greater versionor null if not found
*/
private LanguageTranslator getNextTranslator(List<LanguageTranslator> versionTranslatorList,
int version) {
@@ -561,4 +562,5 @@ class FactoryLanguageTranslator implements LanguageTranslator {
public String toString() {
return t1.toString() + "; " + System.getProperty("line.separator") + t2.toString();
}
}

View File

@@ -289,7 +289,8 @@ class OldLanguage implements Language {
throw new SAXException("Missing required 'spaces' element");
}
if (!registersFound) {
throw new SAXException("Missing required 'registers' element");
// register mapping will not be performed
registerMgr = (new RegisterBuilder()).getRegisterManager();
}
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -471,9 +471,4 @@ class SimpleLanguageTranslator extends LanguageTranslatorAdapter {
contextSettings.put(name, val);
}
public CompilerSpec getCompilerSpec() {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -6,6 +6,7 @@ data/languages/RV64.pspec||GHIDRA||||END|
data/languages/andestar_v5.instr.sinc||GHIDRA||||END|
data/languages/andestar_v5.ldefs||GHIDRA||||END|
data/languages/andestar_v5.slaspec||GHIDRA||||END|
data/languages/old/riscv_deprecated.ldefs||GHIDRA||||END|
data/languages/riscv.csr.sinc||GHIDRA||||END|
data/languages/riscv.custom.sinc||GHIDRA||||END|
data/languages/riscv.ilp32d.slaspec||GHIDRA||||END|

View File

@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64I"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64I">
<description>RISC-V 64 little base</description>
<compiler name="gcc" spec="riscv64.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64IC"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64IC">
<description>RISC-V 64 little base compressed</description>
<compiler name="gcc" spec="riscv64.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64G"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64G">
<description>RISC-V 64 little general purpose</description>
<compiler name="gcc" spec="riscv64-fp.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64GC"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64GC">
<description>RISC-V 64 little general purpose compressed</description>
<compiler name="gcc" spec="riscv64-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32I"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32I">
<description>RISC-V 32 little base</description>
<compiler name="gcc" spec="riscv32.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32IC"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32IC">
<description>RISC-V 32 little base compressed</description>
<compiler name="gcc" spec="riscv32.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32IMC"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32IMC">
<description>RISC-V 32 little base compressed</description>
<compiler name="gcc" spec="riscv32.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32G"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32G">
<description>RISC-V 32 little general purpose</description>
<compiler name="gcc" spec="riscv32-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32GC"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32GC">
<description>RISC-V 32 little general purpose compressed</description>
<compiler name="gcc" spec="riscv32-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
</language_definitions>

View File

@@ -2,22 +2,6 @@
<language_definitions>
<language processor="RISCV"
endian="little"
size="32"
variant="default"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:default">
<description>RISC-V 32 little default</description>
<compiler name="gcc" spec="riscv32-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
endian="little"
size="64"
@@ -33,149 +17,21 @@
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64I"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64I">
<description>RISC-V 64 little base</description>
<compiler name="gcc" spec="riscv64.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64IC"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64IC">
<description>RISC-V 64 little base compressed</description>
<compiler name="gcc" spec="riscv64.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64G"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64G">
<description>RISC-V 64 little general purpose</description>
<compiler name="gcc" spec="riscv64-fp.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="64"
variant="RV64GC"
version="1.4"
slafile="riscv.lp64d.sla"
processorspec="RV64.pspec"
id="RISCV:LE:64:RV64GC">
<description>RISC-V 64 little general purpose compressed</description>
<compiler name="gcc" spec="riscv64-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv64"/>
<external_name tool="DWARF.register.mapping.file" name="riscv64.dwarf"/>
<external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32I"
variant="default"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32I">
<description>RISC-V 32 little base</description>
<compiler name="gcc" spec="riscv32.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32IC"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32IC">
<description>RISC-V 32 little base compressed</description>
<compiler name="gcc" spec="riscv32.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32IMC"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32IMC">
<description>RISC-V 32 little base compressed</description>
<compiler name="gcc" spec="riscv32.cspec" id="gcc"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32G"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32G">
<description>RISC-V 32 little general purpose</description>
id="RISCV:LE:32:default">
<description>RISC-V 32 little default</description>
<compiler name="gcc" spec="riscv32-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
<language processor="RISCV"
deprecated="true"
endian="little"
size="32"
variant="RV32GC"
version="1.4"
slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec"
id="RISCV:LE:32:RV32GC">
<description>RISC-V 32 little general purpose compressed</description>
<compiler name="gcc" spec="riscv32-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language>
</language_definitions>

View File

@@ -22,6 +22,7 @@
</data_organization>
<global>
<range space="ram"/>
<range space="csreg"/>
<register name="gp"/>
<register name="tp"/>
</global>