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
@@ -34,7 +34,6 @@ import ghidra.trace.database.memory.DBTraceMemoryManager;
import ghidra.trace.database.memory.DBTraceMemorySpace; import ghidra.trace.database.memory.DBTraceMemorySpace;
import ghidra.util.MathUtilities; import ghidra.util.MathUtilities;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
@@ -305,31 +304,31 @@ public class DBTraceGuestPlatformMappedMemory implements Memory {
@Override @Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor) public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException, throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException { AddressOverflowException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void split(MemoryBlock block, Address addr) public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException { throws MemoryBlockException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo) public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException { throws LockException, MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue) public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException { throws LockException, MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock) public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock)
throws MemoryBlockException, NotFoundException, LockException { throws MemoryBlockException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -33,7 +33,6 @@ import ghidra.trace.util.MemoryAdapter;
import ghidra.util.LockHold; import ghidra.util.LockHold;
import ghidra.util.MathUtilities; import ghidra.util.MathUtilities;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public abstract class AbstractDBTraceProgramViewMemory public abstract class AbstractDBTraceProgramViewMemory
@@ -206,31 +205,31 @@ public abstract class AbstractDBTraceProgramViewMemory
@Override @Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor) public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException, throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException { AddressOverflowException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void split(MemoryBlock block, Address addr) public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException { throws MemoryBlockException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo) public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException { throws LockException, MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue) public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException { throws LockException, MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock) public MemoryBlock convertToUninitialized(MemoryBlock itializedBlock)
throws MemoryBlockException, NotFoundException, LockException { throws MemoryBlockException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -20,7 +20,6 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.program.util.ProgramTask; import ghidra.program.util.ProgramTask;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.NotFoundException;
import ghidra.util.exception.RollbackException; import ghidra.util.exception.RollbackException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@@ -80,10 +79,6 @@ public class MoveBlockTask extends ProgramTask {
statusMessage = "Insufficient memory to complete operation"; statusMessage = "Insufficient memory to complete operation";
cause = e; cause = e;
} }
catch (NotFoundException e) {
statusMessage = "Memory block not found";
cause = e;
}
catch (MemoryConflictException | MemoryBlockException | IllegalArgumentException e) { catch (MemoryConflictException | MemoryBlockException | IllegalArgumentException e) {
statusMessage = e.getMessage(); statusMessage = e.getMessage();
cause = e; cause = e;
@@ -693,7 +693,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer {
memBlk = memory.getBlock(afterFlag); memBlk = memory.getBlock(afterFlag);
memBlk.setName(memBlk.getName().replaceFirst("(\\.split)+$", ".part2")); 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); Msg.error(this, "Failed to fixup runtime.writeBarrier flag", e);
} }
} }
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 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.listing.*;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.Msg; 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. * Helper class to make changes to memory blocks.
@@ -270,10 +271,6 @@ class MemoryMapManager {
msg = e.getMessage(); msg = e.getMessage();
return false; return false;
} }
catch (NotFoundException e) {
msg = e.getMessage();
return false;
}
catch (LockException e) { catch (LockException e) {
msg = e.getMessage(); msg = e.getMessage();
return false; return false;
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 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.main.ApplicationLevelPlugin;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.AddressSpace; import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
import ghidra.program.model.listing.IncompatibleLanguageException; import ghidra.program.model.listing.IncompatibleLanguageException;
@@ -50,6 +51,7 @@ import ghidra.program.util.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.AssertException; import ghidra.util.exception.AssertException;
import ghidra.util.filechooser.ExtensionFileFilter; import ghidra.util.filechooser.ExtensionFileFilter;
import ghidra.util.task.TaskMonitor;
import ghidra.util.xml.GenericXMLOutputter; import ghidra.util.xml.GenericXMLOutputter;
//@formatter:off //@formatter:off
@@ -395,8 +397,7 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
Register oldCtx = oldLang.getContextBaseRegister(); Register oldCtx = oldLang.getContextBaseRegister();
Register newCtx = newLang.getContextBaseRegister(); Register newCtx = newLang.getContextBaseRegister();
boolean contextWarning = false; boolean contextWarning = false;
if (oldCtx != Register.NO_CONTEXT && if (oldCtx != Register.NO_CONTEXT && defaultTrans.isValueTranslationRequired(oldCtx)) {
defaultTrans.isValueTranslationRequired(oldCtx)) {
contextWarning = true; contextWarning = true;
} }
else if (oldCtx == Register.NO_CONTEXT && newCtx != Register.NO_CONTEXT) { else if (oldCtx == Register.NO_CONTEXT && newCtx != Register.NO_CONTEXT) {
@@ -325,9 +325,8 @@ public abstract class AbstractProgramLoader implements Loader {
prog.setExecutableFormat(executableFormatName); prog.setExecutableFormat(executableFormatName);
} }
FSRL fsrl = provider.getFSRL(); FSRL fsrl = provider.getFSRL();
String md5 = (fsrl != null && fsrl.getMD5() != null) String md5 =
? fsrl.getMD5() (fsrl != null && fsrl.getMD5() != null) ? fsrl.getMD5() : computeBinaryMD5(provider);
: computeBinaryMD5(provider);
if (fsrl != null) { if (fsrl != null) {
if (fsrl.getMD5() == null) { if (fsrl.getMD5() == null) {
fsrl = fsrl.withMD5(md5); fsrl = fsrl.withMD5(md5);
@@ -470,6 +469,19 @@ public abstract class AbstractProgramLoader implements Loader {
return DefaultLanguageService.getLanguageService(); 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) { private void applyProcessorLabels(List<Option> options, Program program) {
int id = program.startTransaction("Finalize load"); int id = program.startTransaction("Finalize load");
try { try {
@@ -482,15 +494,25 @@ public abstract class AbstractProgramLoader implements Loader {
createSymbol(program, reg.getName(), addr, null, false, true, true); createSymbol(program, reg.getName(), addr, null, false, true, true);
} }
} }
// optionally create default symbols defined by pspec
if (shouldApplyProcessorLabels(options)) { // NOTE: pspec defined labels should always be defined if they correspond to a memory
boolean anchorSymbols = shouldAnchorSymbols(options); // block defined by the pspec.
List<AddressLabelInfo> labels = lang.getDefaultSymbols(); boolean applyAllProcessorLabels = shouldApplyProcessorLabels(options);
for (AddressLabelInfo info : labels) { AddressSetView pspecDefinedBlockSet = getProcessorDefinedMemoryBlockAddresses(program);
createSymbol(program, info.getLabel(), info.getAddress(), info.getDescription(), info.isEntry(), boolean anchorSymbols = shouldAnchorSymbols(options);
info.isPrimary(), anchorSymbols); 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); GhidraProgramUtilities.resetAnalysisFlags(program);
} }
finally { finally {
@@ -269,7 +269,7 @@ public class NeLoader extends AbstractOrdinalSupportLoader {
try { try {
block = program.getMemory().join(block, zeroBlock); // expand block = program.getMemory().join(block, zeroBlock); // expand
} }
catch (MemoryBlockException | LockException | NotFoundException e) { catch (MemoryBlockException | LockException e) {
throw new IOException(e); throw new IOException(e);
} }
} }
@@ -23,7 +23,6 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
@@ -297,9 +296,6 @@ public class MemoryDiff {
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) {
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);
} }
@@ -25,7 +25,6 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class MyTestMemory extends AddressSet implements Memory { public class MyTestMemory extends AddressSet implements Memory {
@@ -153,30 +152,30 @@ public class MyTestMemory extends AddressSet implements Memory {
@Override @Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor) public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws MemoryConflictException, AddressOverflowException, NotFoundException { throws MemoryConflictException, AddressOverflowException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void split(MemoryBlock block, Address addr) throws NotFoundException { public void split(MemoryBlock block, Address addr) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo) public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws MemoryBlockException, NotFoundException { throws MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue) public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws MemoryBlockException, NotFoundException { throws MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock) public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, NotFoundException { throws MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -44,7 +44,8 @@ import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.SymbolTable; import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.util.CodeUnitInsertionException; import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.*; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
@@ -177,8 +178,7 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
DumpAddressObject d = daos.get(address); DumpAddressObject d = daos.get(address);
try { try {
MemoryBlockUtils.createInitializedBlock(program, false, d.getRangeName(), MemoryBlockUtils.createInitializedBlock(program, false, d.getRangeName(),
address, fileBytes, address, fileBytes, d.getRVA(), // offset into filebytes
d.getRVA(), // offset into filebytes
d.getLength(), // size d.getLength(), // size
d.getComment(), // comment d.getComment(), // comment
null, // source null, // source
@@ -215,7 +215,7 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
try { try {
m = memory.join(m, next); m = memory.join(m, next);
} }
catch (MemoryBlockException | LockException | NotFoundException e) { catch (MemoryBlockException | LockException e) {
break; break;
} }
deleted.add(next.getStart()); deleted.add(next.getStart());
@@ -281,9 +281,8 @@ public class DumpFileLoader extends AbstractProgramWrapperLoader {
symbolTable.createLabel(address, dd.getName(), SourceType.IMPORTED); symbolTable.createLabel(address, dd.getName(), SourceType.IMPORTED);
} }
catch (InvalidInputException e) { catch (InvalidInputException e) {
Msg.error(this, Msg.error(this, "Error creating label " + dd.getName() + " at address " +
"Error creating label " + dd.getName() + " at address " + address + address + ": " + e.getMessage());
": " + e.getMessage());
} }
continue; continue;
} }
@@ -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
}
}
}
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,11 +15,15 @@
*/ */
package ghidra.app.plugin.processors.generic; package ghidra.app.plugin.processors.generic;
import java.util.List;
import ghidra.framework.store.LockException; import ghidra.framework.store.LockException;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.mem.ByteMappingScheme; import ghidra.program.database.mem.ByteMappingScheme;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.util.Msg;
import ghidra.util.XmlProgramUtilities; import ghidra.util.XmlProgramUtilities;
import ghidra.util.exception.AssertException; import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
@@ -36,18 +40,22 @@ import ghidra.xml.XmlElement;
*/ */
public class MemoryBlockDefinition { public class MemoryBlockDefinition {
private String blockName; private final String blockName;
private String addressString; private final String addressString;
private int length; private final int length;
private boolean initialized; private final boolean initialized;
private boolean overlay; private final boolean overlay;
private String bitMappedAddress; private final String bitMappedAddress;
private String byteMappedAddress; private final String byteMappedAddress;
private ByteMappingScheme byteMappingScheme; private final ByteMappingScheme byteMappingScheme;
private boolean readPermission = true;
private boolean writePermission = true; private final String mode;
private boolean executePermission = false; private final boolean readPermission;
private boolean isVolatile = false; 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. * 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 * 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 * 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). * 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> * <pre>
* r - read mode enabled * r - read mode enabled
* w - write mode enabled * w - write mode enabled
@@ -71,18 +80,33 @@ public class MemoryBlockDefinition {
* </pre> * </pre>
* @param lengthString length of memory block in bytes (required) * @param lengthString length of memory block in bytes (required)
* @param initializedString boolean (y | n | true | false) indicating if memory block is * @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 * @param overlayString boolean (y | n | true | false) indicating if memory block is an overlay
* (false assumed if null). * (false assumed if null).
* @throws XmlAttributeException if parse failure occurs (NOTE: address parsing is not performed) * @throws XmlAttributeException if parse failure occurs (NOTE: address parsing is not performed)
*/ */
private MemoryBlockDefinition(String blockName, String addressString, String bitMappedAddress, private MemoryBlockDefinition(String blockName, String addressString, String bitMappedAddress,
String byteMappedAddressRatio, String mode, String lengthString, String byteMappedAddressRatio, String mode, String lengthString,
String initializedString, String overlayString) String initializedString, String overlayString) throws XmlAttributeException {
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; this.blockName = blockName;
if (addressString == null) {
throw new XmlAttributeException("Missing default memory block 'start_address'");
}
this.addressString = addressString; this.addressString = addressString;
this.bitMappedAddress = bitMappedAddress; this.bitMappedAddress = bitMappedAddress;
if (byteMappedAddressRatio != null) { if (byteMappedAddressRatio != null) {
@@ -98,30 +122,35 @@ public class MemoryBlockDefinition {
} }
else { else {
// 1:1 mapping scheme assumed (null byteMappingScheme) // 1:1 mapping scheme assumed (null byteMappingScheme)
byteMappingScheme = null;
byteMappedAddress = byteMappedAddressRatio; byteMappedAddress = byteMappedAddressRatio;
} }
} }
else {
if (mode != null) { byteMappedAddress = null;
mode = mode.toLowerCase(); byteMappingScheme = null;
readPermission = mode.indexOf('r') >= 0;
writePermission = mode.indexOf('w') >= 0;
executePermission = mode.indexOf('x') >= 0;
isVolatile = mode.indexOf('v') >= 0;
} }
// Parse specified length string
int parsedLen = -1;
try { try {
length = XmlUtilities.parseInt(lengthString); parsedLen = XmlUtilities.parseInt(lengthString);
} }
catch (NumberFormatException e) { 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 (initializedString != null) {
if (bitMappedAddress != null || byteMappedAddress != null) { if (bitMappedAddress != null || byteMappedAddress != null) {
throw new XmlAttributeException( throw new XmlAttributeException(
"mapped block specifications must not specify initialized attribute"); "mapped block specifications must not specify initialized attribute");
} }
initialized = XmlUtilities.parseBoolean(initializedString);
} }
initialized = XmlUtilities.parseBoolean(initializedString);
overlay = XmlUtilities.parseBoolean(overlayString); overlay = XmlUtilities.parseBoolean(overlayString);
} }
@@ -142,20 +171,164 @@ public class MemoryBlockDefinition {
return addr; 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. * Create memory block within specified program based upon this block specification.
* @param program target program * @param program target program
* @return newly created memory block
* @throws LockException if program does not have exclusive access required when adding memory blocks. * @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 MemoryConflictException if this specification conflicts with an existing memory block in program
* @throws AddressOverflowException if memory space constraints are violated by block specification * @throws AddressOverflowException if memory space constraints are violated by block specification
* @throws InvalidAddressException if address defined by this block specification is invalid * @throws InvalidAddressException if address defined by this block specification is invalid
* for the specified program. May also indicate an improperly formatted address attribute. * 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 { AddressOverflowException, InvalidAddressException {
if (blockName == null || addressString == null || length <= 0) {
return;
}
Memory mem = program.getMemory(); Memory mem = program.getMemory();
Address addr = parseAddress(addressString, program, "block address"); Address addr = parseAddress(addressString, program, "block address");
@@ -172,9 +345,8 @@ public class MemoryBlockDefinition {
} }
else if (initialized) { else if (initialized) {
try { try {
block = block = mem.createInitializedBlock(blockName, addr, length, (byte) 0,
mem.createInitializedBlock(blockName, addr, length, (byte) 0, TaskMonitor.DUMMY, overlay);
TaskMonitor.DUMMY, overlay);
} }
catch (CancelledException e) { catch (CancelledException e) {
throw new AssertException(e); // unexpected throw new AssertException(e); // unexpected
@@ -187,6 +359,7 @@ public class MemoryBlockDefinition {
block.setWrite(writePermission); block.setWrite(writePermission);
block.setExecute(executePermission); block.setExecute(executePermission);
block.setVolatile(isVolatile); block.setVolatile(isVolatile);
return block;
} }
@Override @Override
@@ -47,6 +47,7 @@ import ghidra.program.model.util.ProcessorSymbolType;
import ghidra.sleigh.grammar.SleighPreprocessor; import ghidra.sleigh.grammar.SleighPreprocessor;
import ghidra.sleigh.grammar.SourceFileIndexer; import ghidra.sleigh.grammar.SourceFileIndexer;
import ghidra.util.*; import ghidra.util.*;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import ghidra.util.xml.SpecXmlUtils; import ghidra.util.xml.SpecXmlUtils;
import ghidra.xml.*; import ghidra.xml.*;
@@ -787,10 +788,9 @@ public class SleighLanguage implements Language {
AddressLabelInfo info; AddressLabelInfo info;
try { try {
info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment, info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment,
false, false, isEntry, type, isVolatile);
isEntry, type, isVolatile);
} }
catch (AddressOverflowException e) { catch (AddressOverflowException | InvalidInputException e) {
throw new XmlParseException("invalid symbol definition: " + labelName, throw new XmlParseException("invalid symbol definition: " + labelName,
e); e);
} }
@@ -1242,9 +1242,7 @@ public class SleighLanguage implements Language {
ManualEntry manualEntry = null; ManualEntry manualEntry = null;
int maxInCommon = -1; int maxInCommon = -1;
Iterator<Entry<String, ManualEntry>> ii = subMap.entrySet().iterator(); for (Entry<String, ManualEntry> mapEntry : subMap.entrySet()) {
while (ii.hasNext()) {
Entry<String, ManualEntry> mapEntry = ii.next();
String key = mapEntry.getKey(); String key = mapEntry.getKey();
if (instruction.startsWith(key) && key.length() > maxInCommon) { if (instruction.startsWith(key) && key.length() > maxInCommon) {
manualEntry = mapEntry.getValue(); manualEntry = mapEntry.getValue();
@@ -22,6 +22,7 @@ import java.util.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import db.DBHandle; import db.DBHandle;
import ghidra.app.plugin.processors.generic.LanguageFixupUtil;
import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.framework.Application; import ghidra.framework.Application;
import ghidra.framework.data.DomainObjectAdapterDB; import ghidra.framework.data.DomainObjectAdapterDB;
@@ -2065,8 +2066,10 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
newCompilerSpecID = translator.getNewCompilerSpecID(compilerSpecID); newCompilerSpecID = translator.getNewCompilerSpecID(compilerSpecID);
} }
Msg.info(this, "Setting language for Program " + getName() + ": " + translator); Msg.info(this, "Setting language for Program " + getName() + ": " + translator);
Msg.info(this, "Setting compiler spec for Program " + getName() + ": " + if (!compilerSpecID.equals(newCompilerSpecID)) {
compilerSpecID + " -> " + newCompilerSpecID); Msg.info(this, "Setting compiler spec for Program " + getName() + ": " +
compilerSpecID + " -> " + newCompilerSpecID);
}
} }
else if (!forceRedisassembly && language.getVersion() == languageVersion && else if (!forceRedisassembly && language.getVersion() == languageVersion &&
language.getMinorVersion() == languageMinorVersion) { language.getMinorVersion() == languageMinorVersion) {
@@ -2138,6 +2141,9 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
translator.fixupInstructions(this, translator.getOldLanguage(), monitor); 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(LANGUAGE_ID, languageID.getIdAsString());
dataMap.put(COMPILER_SPEC_ID, compilerSpecID.getIdAsString()); dataMap.put(COMPILER_SPEC_ID, compilerSpecID.getIdAsString());
dataMap.put(LANGUAGE_VERSION, languageVersion + "." + languageMinorVersion); dataMap.put(LANGUAGE_VERSION, languageVersion + "." + languageMinorVersion);
@@ -941,7 +941,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override @Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor) public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws MemoryBlockException, MemoryConflictException, AddressOverflowException, throws MemoryBlockException, MemoryConflictException, AddressOverflowException,
NotFoundException, LockException { LockException {
lock.acquire(); lock.acquire();
try { try {
program.checkExclusiveAccess(); program.checkExclusiveAccess();
@@ -986,8 +986,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
} }
@Override @Override
public void split(MemoryBlock block, Address addr) public void split(MemoryBlock block, Address addr) throws MemoryBlockException, LockException {
throws MemoryBlockException, NotFoundException, LockException {
lock.acquire(); lock.acquire();
try { try {
program.checkExclusiveAccess(); program.checkExclusiveAccess();
@@ -1037,7 +1036,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override @Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo) public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws MemoryBlockException, NotFoundException, LockException { throws MemoryBlockException, LockException {
lock.acquire(); lock.acquire();
try { try {
// swap if second block is before first block // swap if second block is before first block
@@ -1111,7 +1110,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override @Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue) public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws MemoryBlockException, NotFoundException, LockException { throws MemoryBlockException, LockException {
lock.acquire(); lock.acquire();
try { try {
checkBlock(uninitializedBlock); checkBlock(uninitializedBlock);
@@ -1149,7 +1148,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
@Override @Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock) public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, NotFoundException, LockException { throws MemoryBlockException, LockException {
lock.acquire(); lock.acquire();
try { try {
program.checkExclusiveAccess(); program.checkExclusiveAccess();
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,10 +15,12 @@
*/ */
package ghidra.program.model.data; package ghidra.program.model.data;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
import ghidra.program.model.listing.IncompatibleLanguageException; import ghidra.program.model.listing.IncompatibleLanguageException;
import ghidra.program.util.DefaultLanguageService; import ghidra.program.util.DefaultLanguageService;
import ghidra.program.util.LanguageTranslatorAdapter; import ghidra.program.util.LanguageTranslatorAdapter;
import ghidra.util.task.TaskMonitor;
public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter { public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter {
@@ -40,9 +42,8 @@ public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter {
public ProgramArchitectureTranslator(LanguageID oldLanguageId, int oldLanguageVersion, public ProgramArchitectureTranslator(LanguageID oldLanguageId, int oldLanguageVersion,
CompilerSpecID oldCompilerSpecId, Language newLanguage, CompilerSpecID oldCompilerSpecId, Language newLanguage,
CompilerSpecID newCompilerSpecId) CompilerSpecID newCompilerSpecId) throws LanguageNotFoundException,
throws LanguageNotFoundException, CompilerSpecNotFoundException, CompilerSpecNotFoundException, IncompatibleLanguageException {
IncompatibleLanguageException {
this(getLanguage(oldLanguageId, oldLanguageVersion), oldCompilerSpecId, newLanguage, this(getLanguage(oldLanguageId, oldLanguageVersion), oldCompilerSpecId, newLanguage,
newCompilerSpecId); newCompilerSpecId);
} }
@@ -65,5 +66,4 @@ public class ProgramArchitectureTranslator extends LanguageTranslatorAdapter {
return newCompilerSpec; return newCompilerSpec;
} }
} }
@@ -17,7 +17,9 @@ package ghidra.program.model.lang;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.symbol.SymbolUtilities;
import ghidra.program.model.util.ProcessorSymbolType; import ghidra.program.model.util.ProcessorSymbolType;
import ghidra.util.exception.InvalidInputException;
/** /**
* <CODE>AddressLabelInfo</CODE> is a utility class for storing * <CODE>AddressLabelInfo</CODE> is a utility class for storing
@@ -35,7 +37,7 @@ public class AddressLabelInfo implements Comparable<AddressLabelInfo> {
private ProcessorSymbolType processorSymbolType; private ProcessorSymbolType processorSymbolType;
private int sizeInBytes; private int sizeInBytes;
private Boolean isVolatile; private Boolean isVolatile;
/** /**
* Constructor for class AddressLabelInfo * 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 isEntry boolean describes if this object is an entry label for the Address 'addr'
* @param type ProcessorSymbolType the type of symbol * @param type ProcessorSymbolType the type of symbol
* @param isVolatile Boolean describes if the memory at this address is volatile * @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, public AddressLabelInfo(Address addr, Integer sizeInBytes, String label, String description,
boolean isEntry, ProcessorSymbolType type, Boolean isVolatile) throws AddressOverflowException { boolean isPrimary, boolean isEntry, ProcessorSymbolType type, Boolean isVolatile)
throws AddressOverflowException, InvalidInputException {
SymbolUtilities.validateName(label);
this.addr = addr; this.addr = addr;
if ( sizeInBytes == null || sizeInBytes <= 0 ) { if (sizeInBytes == null || sizeInBytes <= 0) {
// Default size in addressable units // Default size in addressable units
this.sizeInBytes = addr.getAddressSpace().getAddressableUnitSize(); this.sizeInBytes = addr.getAddressSpace().getAddressableUnitSize();
} else { }
else {
this.sizeInBytes = sizeInBytes; this.sizeInBytes = sizeInBytes;
} }
this.endAddr = this.addr.addNoWrap(this.sizeInBytes-1); this.endAddr = this.addr.addNoWrap(this.sizeInBytes - 1);
this.label = label; this.label = label;
this.description = description; this.description = description;
this.isPrimary = isPrimary; this.isPrimary = isPrimary;
@@ -72,21 +79,21 @@ public class AddressLabelInfo implements Comparable<AddressLabelInfo> {
public final Address getAddress() { public final Address getAddress() {
return addr; return addr;
} }
/** /**
* @return the object's end address. * @return the object's end address.
*/ */
public final Address getEndAddress() { public final Address getEndAddress() {
return endAddr; return endAddr;
} }
/** /**
* @return the object's label or alias. * @return the object's label or alias.
*/ */
public final String getLabel() { public final String getLabel() {
return label; return label;
} }
/** /**
* @return the object's description if it has one, null otherwise * @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() { public final int getByteSize() {
return sizeInBytes; return sizeInBytes;
} }
/** /**
* @return whether the object is the primary label at the address. * @return whether the object is the primary label at the address.
*/ */
public final boolean isPrimary() { public final boolean isPrimary() {
return isPrimary; return isPrimary;
} }
/** /**
* @return whether the object is volatile. * @return whether the object is volatile.
* Boolean.False when the address is explicitly not volatile. * Boolean.False when the address is explicitly not volatile.
@@ -25,7 +25,6 @@ import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.OffsetReference; import ghidra.program.model.symbol.OffsetReference;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
@@ -462,16 +461,14 @@ public interface Memory extends AddressSetView {
* @param newStartAddr new start address for block * @param newStartAddr new start address for block
* @param monitor task monitor so the move block can be canceled * @param monitor task monitor so the move block can be canceled
* @throws LockException if exclusive lock not in place (see haveLock()) * @throws LockException if exclusive lock not in place (see haveLock())
* @throws MemoryBlockException if block movement is not permitted
* @throws MemoryConflictException if move would cause * @throws MemoryConflictException if move would cause
* blocks to overlap. * blocks to overlap.
* @throws MemoryBlockException if block movement is not permitted
* @throws AddressOverflowException if block movement would violate bounds of address space * @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) public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException, throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException; AddressOverflowException;
/** /**
* Split a block at the given addr and create a new block * 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 block block to be split into two
* @param addr address (within block) that will be the * @param addr address (within block) that will be the
* start of new block * 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 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 * @throws AddressOutOfBoundsException thrown if address is not in the block
*/ */
public void split(MemoryBlock block, Address addr) public void split(MemoryBlock block, Address addr) throws MemoryBlockException, LockException;
throws MemoryBlockException, LockException, NotFoundException;
/** /**
* Join the two blocks to create a single memory block. * 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, * not contiguous in the address space,
*/ */
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo) public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException; throws LockException, MemoryBlockException;
/** /**
* Convert an existing uninitialized block with an initialized block. * Convert an existing uninitialized block with an initialized block.
@@ -512,10 +506,20 @@ public interface Memory extends AddressSetView {
* the same. * the same.
*/ */
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue) 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 * Finds a sequence of contiguous bytes that match the
@@ -1,13 +1,12 @@
/* ### /* ###
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,7 +15,6 @@
*/ */
package ghidra.program.model.mem; package ghidra.program.model.mem;
/** /**
* Exception thrown for memory block-related problems. * Exception thrown for memory block-related problems.
*/ */
@@ -29,11 +27,21 @@ public class MemoryBlockException extends MemoryAccessException {
public MemoryBlockException() { public MemoryBlockException() {
super(); super();
} }
/** /**
* Constructs a new MemoryBlockException with a detailed message. * Constructs a new MemoryBlockException with a detailed message.
* @param msg detailed message * @param msg detailed message
*/ */
public MemoryBlockException(String msg) { public MemoryBlockException(String msg) {
super(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);
}
}
@@ -24,7 +24,6 @@ import ghidra.framework.store.LockException;
import ghidra.program.database.mem.*; import ghidra.program.database.mem.*;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
@@ -241,31 +240,31 @@ public class StubMemory extends AddressSet implements Memory {
@Override @Override
public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor) public void moveBlock(MemoryBlock block, Address newStartAddr, TaskMonitor monitor)
throws LockException, MemoryBlockException, MemoryConflictException, throws LockException, MemoryBlockException, MemoryConflictException,
AddressOverflowException, NotFoundException { AddressOverflowException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void split(MemoryBlock block, Address addr) public void split(MemoryBlock block, Address addr)
throws MemoryBlockException, LockException, NotFoundException { throws MemoryBlockException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo) public MemoryBlock join(MemoryBlock blockOne, MemoryBlock blockTwo)
throws LockException, MemoryBlockException, NotFoundException { throws LockException, MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue) public MemoryBlock convertToInitialized(MemoryBlock uninitializedBlock, byte initialValue)
throws LockException, MemoryBlockException, NotFoundException { throws LockException, MemoryBlockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock) public MemoryBlock convertToUninitialized(MemoryBlock initializedBlock)
throws MemoryBlockException, NotFoundException, LockException { throws MemoryBlockException, LockException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,6 +15,7 @@
*/ */
package ghidra.program.util; package ghidra.program.util;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace; import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*; 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. * instantiate Language, AddressSpace, AddressFactory or Register objects until isValid() is invoked.
*/ */
public interface LanguageTranslator extends ExtensionPoint { public interface LanguageTranslator extends ExtensionPoint {
/** /**
* Validate translator to complete initialization and ensure language compatibility. * Validate translator to complete initialization and ensure language compatibility.
* This method will be invoked by the LanguageTranslatorFactory before handing out this * 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 * @return true if translator successfully validated
*/ */
public boolean isValid(); public boolean isValid();
/** /**
* Returns old language * Returns old language
* @throws IllegalStateException if instance has not been validated * @throws IllegalStateException if instance has not been validated
@@ -54,27 +55,27 @@ public interface LanguageTranslator extends ExtensionPoint {
* Returns new language * Returns new language
*/ */
public Language getNewLanguage(); public Language getNewLanguage();
/** /**
* Returns old language name * Returns old language name
*/ */
public LanguageID getOldLanguageID(); public LanguageID getOldLanguageID();
/** /**
* Returns new language name * Returns new language name
*/ */
public LanguageID getNewLanguageID(); public LanguageID getNewLanguageID();
/** /**
* Returns old language version * Returns old language version
*/ */
public int getOldVersion(); public int getOldVersion();
/** /**
* Returns new language version * Returns new language version
*/ */
public int getNewVersion(); public int getNewVersion();
/** /**
* Translate BASE address spaces (Overlay spaces are not handled) * Translate BASE address spaces (Overlay spaces are not handled)
* @param oldSpaceName old space name * @param oldSpaceName old space name
@@ -92,7 +93,7 @@ public interface LanguageTranslator extends ExtensionPoint {
* @see #getOldRegisterContaining(Address) * @see #getOldRegisterContaining(Address)
*/ */
public Register getOldRegister(Address oldAddr, int size); public Register getOldRegister(Address oldAddr, int size);
/** /**
* Get the largest old register which contains the specified oldAddr * Get the largest old register which contains the specified oldAddr
* @param oldAddr old register address which may be offcut * @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 * Returns the old processor context register or null if not defined
*/ */
public Register getOldContextRegister(); public Register getOldContextRegister();
/** /**
* Find new register which corresponds to the specified old register. * Find new register which corresponds to the specified old register.
* @param oldReg old register * @param oldReg old register
* @return new register or null if corresponding register not found. * @return new register or null if corresponding register not found.
*/ */
public Register getNewRegister(Register oldReg); public Register getNewRegister(Register oldReg);
/** /**
* Returns the new processor context register or null if not defined * 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 * @throws CompilerSpecNotFoundException if new compiler spec not found based upon
* translator mappings. * translator mappings.
*/ */
public CompilerSpec getOldCompilerSpec(CompilerSpecID oldCompilerSpecID) throws CompilerSpecNotFoundException; public CompilerSpec getOldCompilerSpec(CompilerSpecID oldCompilerSpecID)
throws CompilerSpecNotFoundException;
/** /**
* Invoked after Program language upgrade has completed. * 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) public void fixupInstructions(Program program, Language oldLanguage, TaskMonitor monitor)
throws Exception, CancelledException; throws Exception, CancelledException;
} }
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 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, protected static AddressSpace findSpaceSameName(AddressSpace oldSpace,
ArrayList<AddressSpace> newSpaces) throws IncompatibleLanguageException { ArrayList<AddressSpace> newSpaces) throws IncompatibleLanguageException {
Iterator<AddressSpace> it = newSpaces.iterator(); for (AddressSpace space : newSpaces) {
while (it.hasNext()) {
AddressSpace space = it.next();
if (space.getName().equals(oldSpace.getName())) { if (space.getName().equals(oldSpace.getName())) {
if (oldSpace.getSize() > space.getSize()) { if (oldSpace.getSize() > space.getSize()) {
throw new IncompatibleLanguageException("Old language space (" + throw new IncompatibleLanguageException("Old language space (" +
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,6 +20,7 @@ import java.util.*;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.framework.Application; import ghidra.framework.Application;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace; import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
@@ -405,10 +406,10 @@ public class LanguageTranslatorFactory {
} }
/** /**
* * Get language translator
* @param versionTranslatorList sorted list of version translators * @param versionTranslatorList sorted list of version translators
* @param version * @param version old/from language version
* @return * @return translator from specified version or next greater versionor null if not found
*/ */
private LanguageTranslator getNextTranslator(List<LanguageTranslator> versionTranslatorList, private LanguageTranslator getNextTranslator(List<LanguageTranslator> versionTranslatorList,
int version) { int version) {
@@ -561,4 +562,5 @@ class FactoryLanguageTranslator implements LanguageTranslator {
public String toString() { public String toString() {
return t1.toString() + "; " + System.getProperty("line.separator") + t2.toString(); return t1.toString() + "; " + System.getProperty("line.separator") + t2.toString();
} }
} }
@@ -289,7 +289,8 @@ class OldLanguage implements Language {
throw new SAXException("Missing required 'spaces' element"); throw new SAXException("Missing required 'spaces' element");
} }
if (!registersFound) { if (!registersFound) {
throw new SAXException("Missing required 'registers' element"); // register mapping will not be performed
registerMgr = (new RegisterBuilder()).getRegisterManager();
} }
} }
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -471,9 +471,4 @@ class SimpleLanguageTranslator extends LanguageTranslatorAdapter {
contextSettings.put(name, val); contextSettings.put(name, val);
} }
public CompilerSpec getCompilerSpec() {
// TODO Auto-generated method stub
return null;
}
} }
@@ -6,6 +6,7 @@ data/languages/RV64.pspec||GHIDRA||||END|
data/languages/andestar_v5.instr.sinc||GHIDRA||||END| data/languages/andestar_v5.instr.sinc||GHIDRA||||END|
data/languages/andestar_v5.ldefs||GHIDRA||||END| data/languages/andestar_v5.ldefs||GHIDRA||||END|
data/languages/andestar_v5.slaspec||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.csr.sinc||GHIDRA||||END|
data/languages/riscv.custom.sinc||GHIDRA||||END| data/languages/riscv.custom.sinc||GHIDRA||||END|
data/languages/riscv.ilp32d.slaspec||GHIDRA||||END| data/languages/riscv.ilp32d.slaspec||GHIDRA||||END|
@@ -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>
@@ -2,22 +2,6 @@
<language_definitions> <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" <language processor="RISCV"
endian="little" endian="little"
size="64" size="64"
@@ -33,149 +17,21 @@
<external_name tool="qemu" name="qemu-riscv64"/> <external_name tool="qemu" name="qemu-riscv64"/>
<external_name tool="qemu_system" name="qemu-system-riscv64"/> <external_name tool="qemu_system" name="qemu-system-riscv64"/>
</language> </language>
<language processor="RISCV" <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" endian="little"
size="32" size="32"
variant="RV32I" variant="default"
version="1.4" version="1.4"
slafile="riscv.ilp32d.sla" slafile="riscv.ilp32d.sla"
processorspec="RV32.pspec" processorspec="RV32.pspec"
id="RISCV:LE:32:RV32I"> id="RISCV:LE:32:default">
<description>RISC-V 32 little base</description> <description>RISC-V 32 little default</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"/> <compiler name="gcc" spec="riscv32-fp.cspec" id="gcc"/>
<external_name tool="gnu" name="riscv:rv32"/> <external_name tool="gnu" name="riscv:rv32"/>
<external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/> <external_name tool="DWARF.register.mapping.file" name="riscv32.dwarf"/>
<external_name tool="qemu" name="qemu-riscv32"/> <external_name tool="qemu" name="qemu-riscv32"/>
<external_name tool="qemu_system" name="qemu-system-riscv32"/> <external_name tool="qemu_system" name="qemu-system-riscv32"/>
</language> </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> </language_definitions>
@@ -22,6 +22,7 @@
</data_organization> </data_organization>
<global> <global>
<range space="ram"/> <range space="ram"/>
<range space="csreg"/>
<register name="gp"/> <register name="gp"/>
<register name="tp"/> <register name="tp"/>
</global> </global>