mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-1818 Refactor decompiler overlay translations
This commit is contained in:
parent
6911befabb
commit
8b5ec1b439
21 changed files with 259 additions and 279 deletions
|
@ -13,10 +13,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on Feb 4, 2005
|
||||
*
|
||||
*/
|
||||
package ghidra.app.plugin.processors.sleigh;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -63,7 +59,6 @@ public abstract class PcodeEmit {
|
|||
private AddressSpace uniq_space;
|
||||
private long uniquemask;
|
||||
private long uniqueoffset;
|
||||
private AddressSpace overlayspace = null;
|
||||
|
||||
/**
|
||||
* Pcode emitter constructor for empty or unimiplemented instructions
|
||||
|
@ -85,12 +80,6 @@ public abstract class PcodeEmit {
|
|||
this.instcontext = ictx;
|
||||
this.const_space = walk.getConstSpace();
|
||||
this.startAddress = parsercontext.getAddr();
|
||||
AddressSpace myspace = startAddress.getAddressSpace();
|
||||
if (myspace.isOverlaySpace()) {
|
||||
overlayspace = myspace;
|
||||
startAddress = ((OverlayAddressSpace) myspace).getOverlayedSpace()
|
||||
.getAddress(startAddress.getOffset());
|
||||
}
|
||||
this.fallOffset = fallOffset;
|
||||
this.override = override;
|
||||
SleighInstructionPrototype sleighproto = parsercontext.getPrototype();
|
||||
|
@ -202,7 +191,7 @@ public abstract class PcodeEmit {
|
|||
}
|
||||
|
||||
VarnodeData dest = new VarnodeData();
|
||||
dest.space = fallOverride.getAddressSpace().getPhysicalSpace();
|
||||
dest.space = fallOverride.getAddressSpace();
|
||||
dest.offset = fallOverride.getOffset();
|
||||
dest.size = dest.space.getPointerSize();
|
||||
|
||||
|
@ -675,9 +664,6 @@ public abstract class PcodeEmit {
|
|||
AddressSpace spc = vn.getSpace().fixSpace(walker);
|
||||
Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false);
|
||||
// translate the address into the overlayspace if we have an overlayspace.
|
||||
if (overlayspace != null) {
|
||||
addr = overlayspace.getOverlayAddress(addr);
|
||||
}
|
||||
ParserWalker oldwalker = walker;
|
||||
long olduniqueoffset = uniqueoffset;
|
||||
setUniqueOffset(addr);
|
||||
|
@ -770,30 +756,6 @@ public abstract class PcodeEmit {
|
|||
}
|
||||
}
|
||||
|
||||
void checkOverlays(int opcode, VarnodeData[] in, int isize, VarnodeData out) {
|
||||
if (overlayspace != null) {
|
||||
if ((opcode == PcodeOp.LOAD) || (opcode == PcodeOp.STORE)) {
|
||||
int spaceId = (int) in[0].offset;
|
||||
AddressSpace space = addressFactory.getAddressSpace(spaceId);
|
||||
if (space.isOverlaySpace()) {
|
||||
space = ((OverlayAddressSpace) space).getOverlayedSpace();
|
||||
in[0].offset = space.getSpaceID();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < isize; ++i) {
|
||||
VarnodeData v = in[i];
|
||||
if (v.space.equals(overlayspace)) {
|
||||
v.space = ((OverlayAddressSpace) v.space).getOverlayedSpace();
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
if (out.space.equals(overlayspace)) {
|
||||
out.space = ((OverlayAddressSpace) out.space).getOverlayedSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies opcode-specific overrides
|
||||
* @param opcode opcode of instruction
|
||||
|
|
|
@ -125,7 +125,6 @@ public class PcodeEmitPacked extends PcodeEmit {
|
|||
void dump(Address instrAddr, int opcode, VarnodeData[] in, int isize, VarnodeData out)
|
||||
throws IOException {
|
||||
opcode = checkOverrides(opcode, in);
|
||||
checkOverlays(opcode, in, isize, out);
|
||||
encoder.openElement(ELEM_OP);
|
||||
encoder.writeSignedInteger(ATTRIB_CODE, opcode);
|
||||
encoder.writeSignedInteger(ATTRIB_SIZE, isize);
|
||||
|
|
|
@ -606,7 +606,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
|||
VarnodeTpl vn = rec.op.getInput()[0];
|
||||
AddressSpace spc = vn.getSpace().fixSpace(walker);
|
||||
Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false);
|
||||
addr = handleOverlayAddress(context, addr);
|
||||
SleighParserContext crosscontext =
|
||||
(SleighParserContext) context.getParserContext(addr);
|
||||
int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal();
|
||||
|
@ -621,15 +620,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
|||
return curflags;
|
||||
}
|
||||
|
||||
private Address handleOverlayAddress(InstructionContext context, Address addr) {
|
||||
AddressSpace addressSpace = context.getAddress().getAddressSpace();
|
||||
if (addressSpace.isOverlaySpace()) {
|
||||
OverlayAddressSpace ospace = (OverlayAddressSpace) addressSpace;
|
||||
addr = ospace.getOverlayAddress(addr);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather all the flow records (perhaps across multiple InstructionPrototypes via crossbuilds)
|
||||
* and convert to Addresses
|
||||
|
@ -663,7 +653,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
|||
VarnodeTpl vn = rec.op.getInput()[0];
|
||||
AddressSpace spc = vn.getSpace().fixSpace(walker);
|
||||
Address addr = spc.getTruncatedAddress(vn.getOffset().fix(walker), false);
|
||||
addr = handleOverlayAddress(context, addr);
|
||||
SleighParserContext crosscontext =
|
||||
(SleighParserContext) context.getParserContext(addr);
|
||||
int newsecnum = (int) rec.op.getInput()[1].getOffset().getReal();
|
||||
|
@ -1555,13 +1544,6 @@ public class SleighInstructionPrototype implements InstructionPrototype {
|
|||
return null;
|
||||
}
|
||||
Address newaddr = hand.space.getTruncatedAddress(hand.offset_offset, false);
|
||||
|
||||
newaddr = newaddr.getPhysicalAddress();
|
||||
|
||||
// if we are in an address space, translate it
|
||||
if (curSpace.isOverlaySpace()) {
|
||||
newaddr = curSpace.getOverlayAddress(newaddr);
|
||||
}
|
||||
return newaddr;
|
||||
}
|
||||
|
||||
|
|
|
@ -487,12 +487,6 @@ public class AddressXML {
|
|||
*/
|
||||
public static void encodeAttributes(Encoder encoder, Address addr) throws IOException {
|
||||
AddressSpace space = addr.getAddressSpace();
|
||||
if (space.isOverlaySpace()) {
|
||||
if (space.getType() != AddressSpace.TYPE_OTHER) {
|
||||
space = space.getPhysicalSpace();
|
||||
addr = space.getAddress(addr.getOffset());
|
||||
}
|
||||
}
|
||||
encoder.writeSpace(ATTRIB_SPACE, space);
|
||||
encoder.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset());
|
||||
}
|
||||
|
@ -508,12 +502,6 @@ public class AddressXML {
|
|||
public static void encodeAttributes(Encoder encoder, Address addr, int size)
|
||||
throws IOException {
|
||||
AddressSpace space = addr.getAddressSpace();
|
||||
if (space.isOverlaySpace()) {
|
||||
if (space.getType() != AddressSpace.TYPE_OTHER) {
|
||||
space = space.getPhysicalSpace();
|
||||
addr = space.getAddress(addr.getOffset());
|
||||
}
|
||||
}
|
||||
|
||||
encoder.writeSpace(ATTRIB_SPACE, space);
|
||||
encoder.writeUnsignedInteger(ATTRIB_OFFSET, addr.getUnsignedOffset());
|
||||
|
|
|
@ -204,20 +204,6 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Varnode newVarnode(int sz, Address addr) {
|
||||
// translate into function overlay space if possible
|
||||
addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr);
|
||||
return super.newVarnode(sz, addr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Varnode newVarnode(int sz, Address addr, int id) {
|
||||
// translate into function overlay space if possible
|
||||
addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr);
|
||||
return super.newVarnode(sz, addr, id);
|
||||
}
|
||||
|
||||
private void decodeHigh(Decoder decoder) throws DecoderException {
|
||||
int el = decoder.openElement(ELEM_HIGH);
|
||||
String classstring = decoder.readString(ATTRIB_CLASS);
|
||||
|
@ -267,7 +253,6 @@ public class HighFunction extends PcodeSyntaxTree {
|
|||
}
|
||||
if (subel == ELEM_ADDR.id()) {
|
||||
Address addr = AddressXML.decode(decoder);
|
||||
addr = func.getEntryPoint().getAddressSpace().getOverlayAddress(addr);
|
||||
if (!func.getEntryPoint().equals(addr)) {
|
||||
throw new DecoderException("Mismatched address in function tag");
|
||||
}
|
||||
|
|
|
@ -148,8 +148,6 @@ public class HighParamID extends PcodeSyntaxTree {
|
|||
}
|
||||
if (subel == ELEM_ADDR.id()) {
|
||||
functionaddress = AddressXML.decode(decoder);
|
||||
functionaddress =
|
||||
func.getEntryPoint().getAddressSpace().getOverlayAddress(functionaddress);
|
||||
if (!func.getEntryPoint().equals(functionaddress)) {
|
||||
throw new DecoderException("Mismatched address in function tag");
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import ghidra.program.database.symbol.CodeSymbol;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
|
@ -37,19 +38,6 @@ import ghidra.util.exception.InvalidInputException;
|
|||
|
||||
public class JumpTable {
|
||||
|
||||
/**
|
||||
* Translate address into preferred memory space (JumpTable.preferredSpace)
|
||||
* @param addr is the given Address
|
||||
* @return preferred address or original addr
|
||||
*/
|
||||
private Address translateOverlayAddress(Address addr) {
|
||||
if (addr != null && preferredSpace.isOverlaySpace()) {
|
||||
OverlayAddressSpace overlaySpace = (OverlayAddressSpace) preferredSpace;
|
||||
return overlaySpace.getOverlayAddress(addr);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
public class LoadTable {
|
||||
Address addr; // Starting address of table
|
||||
int size; // Size of a table entry in bytes
|
||||
|
@ -83,7 +71,7 @@ public class JumpTable {
|
|||
int el = decoder.openElement(ELEM_LOADTABLE);
|
||||
size = (int) decoder.readSignedInteger(ATTRIB_SIZE);
|
||||
num = (int) decoder.readSignedInteger(ATTRIB_NUM);
|
||||
addr = translateOverlayAddress(AddressXML.decode(decoder));
|
||||
addr = AddressXML.decode(decoder);
|
||||
decoder.closeElement(el);
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +160,7 @@ public class JumpTable {
|
|||
ArrayList<Integer> lTable = new ArrayList<>();
|
||||
ArrayList<LoadTable> ldTable = new ArrayList<>();
|
||||
|
||||
Address switchAddr = translateOverlayAddress(AddressXML.decode(decoder));
|
||||
Address switchAddr = AddressXML.decode(decoder);
|
||||
|
||||
for (;;) {
|
||||
int subel = decoder.peekElement();
|
||||
|
@ -181,8 +169,7 @@ public class JumpTable {
|
|||
}
|
||||
if (subel == ELEM_DEST.id()) {
|
||||
decoder.openElement();
|
||||
Address caseAddr =
|
||||
translateOverlayAddress(AddressXML.decodeFromAttributes(decoder));
|
||||
Address caseAddr = AddressXML.decodeFromAttributes(decoder);
|
||||
aTable.add(caseAddr);
|
||||
decoder.rewindAttributes();
|
||||
for (;;) {
|
||||
|
|
|
@ -77,7 +77,7 @@ public class PackedDecode implements Decoder {
|
|||
public static final int SPECIALSPACE_SPACEBASE = 4;
|
||||
|
||||
private AddressFactory addrFactory;
|
||||
private AddressSpace[] spaces;
|
||||
protected AddressSpace[] spaces;
|
||||
private LinkedByteBuffer inStream;
|
||||
private LinkedByteBuffer.Position startPos;
|
||||
private LinkedByteBuffer.Position curPos;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* ###
|
||||
* 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.program.model.pcode;
|
||||
|
||||
import ghidra.program.model.address.*;
|
||||
|
||||
/**
|
||||
* Alter address space decoding for a specific overlay space.
|
||||
* Any decoded space that matches the overlayed space is replaced with the overlay itself.
|
||||
* This causes addresses in the overlayed space to be converted into overlay addresses.
|
||||
*/
|
||||
public class PackedDecodeOverlay extends PackedDecode {
|
||||
|
||||
private OverlayAddressSpace overlay = null;
|
||||
|
||||
public PackedDecodeOverlay(AddressFactory addrFactory, OverlayAddressSpace spc)
|
||||
throws AddressFormatException {
|
||||
super(addrFactory);
|
||||
setOverlay(spc);
|
||||
}
|
||||
|
||||
public void setOverlay(OverlayAddressSpace spc) throws AddressFormatException {
|
||||
AddressSpace underlie;
|
||||
if (overlay != null) {
|
||||
underlie = overlay.getOverlayedSpace();
|
||||
spaces[underlie.getUnique()] = underlie;
|
||||
overlay = null;
|
||||
}
|
||||
underlie = spc.getOverlayedSpace();
|
||||
if (underlie.getUnique() == 0 || underlie.getUnique() >= spaces.length) {
|
||||
throw new AddressFormatException("Cannot set overlay over " + underlie.getName());
|
||||
}
|
||||
spaces[underlie.getUnique()] = spc;
|
||||
overlay = spc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/* ###
|
||||
* 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.program.model.pcode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.program.model.address.*;
|
||||
|
||||
/**
|
||||
* Alter address space encoding for a specific overlay space.
|
||||
* Any space that matches the overlay space is encoded as the overlayed space.
|
||||
* This causes addresses in the overlay space to be converted into the underlying space.
|
||||
*/
|
||||
public class PackedEncodeOverlay extends PackedEncode {
|
||||
private OverlayAddressSpace overlay = null;
|
||||
private int overlayId; // Id of the overlay space
|
||||
private int underlyingId; // If of the space underlying the overlay
|
||||
|
||||
public PackedEncodeOverlay(OverlayAddressSpace spc) throws AddressFormatException {
|
||||
super();
|
||||
setOverlay(spc);
|
||||
}
|
||||
|
||||
public void setOverlay(OverlayAddressSpace spc) throws AddressFormatException {
|
||||
overlayId = spc.getUnique();
|
||||
AddressSpace underlie = spc.getOverlayedSpace();
|
||||
underlyingId = underlie.getUnique();
|
||||
if (underlyingId == 0) {
|
||||
throw new AddressFormatException("Cannot set overlay over " + underlie.getName());
|
||||
}
|
||||
overlay = spc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
||||
if (spc == overlay) {
|
||||
spc = overlay.getOverlayedSpace();
|
||||
}
|
||||
super.writeSpace(attribId, spc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpaceId(AttributeId attribId, long spaceId) {
|
||||
if (spaceId == overlayId) {
|
||||
spaceId = underlyingId;
|
||||
}
|
||||
super.writeSpaceId(attribId, spaceId);
|
||||
}
|
||||
}
|
|
@ -93,10 +93,6 @@ public abstract class SymbolEntry {
|
|||
AddressSpace spc = decoder.readSpace(ATTRIB_SPACE);
|
||||
long offset = decoder.readUnsignedInteger(ATTRIB_FIRST);
|
||||
pcaddr = spc.getAddress(offset);
|
||||
pcaddr = symbol.function.getFunction()
|
||||
.getEntryPoint()
|
||||
.getAddressSpace()
|
||||
.getOverlayAddress(pcaddr);
|
||||
decoder.closeElement(rangeel);
|
||||
}
|
||||
|
||||
|
@ -110,14 +106,7 @@ public abstract class SymbolEntry {
|
|||
return;
|
||||
}
|
||||
AddressSpace space = pcaddr.getAddressSpace();
|
||||
long off;
|
||||
if (space.isOverlaySpace()) {
|
||||
space = space.getPhysicalSpace();
|
||||
off = space.getAddress(pcaddr.getOffset()).getUnsignedOffset();
|
||||
}
|
||||
else {
|
||||
off = pcaddr.getUnsignedOffset();
|
||||
}
|
||||
long off = pcaddr.getUnsignedOffset();
|
||||
encoder.openElement(ELEM_RANGE);
|
||||
encoder.writeSpace(ATTRIB_SPACE, space);
|
||||
encoder.writeUnsignedInteger(ATTRIB_FIRST, off);
|
||||
|
|
|
@ -337,10 +337,6 @@ public class Varnode {
|
|||
StringBuilder buffer = new StringBuilder();
|
||||
Address addr = address;
|
||||
AddressSpace space = addr.getAddressSpace();
|
||||
if (space.isOverlaySpace()) {
|
||||
space = space.getPhysicalSpace();
|
||||
addr = space.getAddress(addr.getOffset());
|
||||
}
|
||||
buffer.append(space.getName());
|
||||
buffer.append(":0x");
|
||||
long off = addr.getUnsignedOffset();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue