mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch 'origin/GP-3174_PieceMarshaling'
This commit is contained in:
commit
67625f5b9c
16 changed files with 162 additions and 66 deletions
|
@ -45,6 +45,8 @@ import ghidra.xml.XmlParseException;
|
|||
* The static restoreXML methods read an \<addr> tag and produce a general AddressXML object.
|
||||
*/
|
||||
public class AddressXML {
|
||||
|
||||
public static int MAX_PIECES = 64; // Maximum pieces that can be marshaled in one join address
|
||||
private AddressSpace space; // Address space containing the memory range
|
||||
private long offset; // Starting offset of the range
|
||||
private long size; // Number of bytes in the size
|
||||
|
@ -596,32 +598,13 @@ public class AddressXML {
|
|||
AddressXML.encode(encoder, varnodes[0].getAddress(), varnodes[0].getSize());
|
||||
return;
|
||||
}
|
||||
if (varnodes.length > MAX_PIECES) {
|
||||
throw new IOException("Exceeded maximum pieces in one join address");
|
||||
}
|
||||
encoder.openElement(ELEM_ADDR);
|
||||
encoder.writeSpace(ATTRIB_SPACE, AddressSpace.VARIABLE_SPACE);
|
||||
encoder.writeString(ATTRIB_PIECE1, varnodes[0].encodePiece());
|
||||
if (varnodes.length > 1) {
|
||||
encoder.writeString(ATTRIB_PIECE2, varnodes[1].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 2) {
|
||||
encoder.writeString(ATTRIB_PIECE3, varnodes[2].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 3) {
|
||||
encoder.writeString(ATTRIB_PIECE4, varnodes[3].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 4) {
|
||||
encoder.writeString(ATTRIB_PIECE5, varnodes[4].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 5) {
|
||||
encoder.writeString(ATTRIB_PIECE6, varnodes[5].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 6) {
|
||||
encoder.writeString(ATTRIB_PIECE7, varnodes[6].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 7) {
|
||||
encoder.writeString(ATTRIB_PIECE8, varnodes[7].encodePiece());
|
||||
}
|
||||
if (varnodes.length > 8) {
|
||||
encoder.writeString(ATTRIB_PIECE9, varnodes[8].encodePiece());
|
||||
for (int i = 0; i < varnodes.length; ++i) {
|
||||
encoder.writeStringIndexed(ATTRIB_PIECE, i, varnodes[i].encodePiece());
|
||||
}
|
||||
if (logicalsize != 0) {
|
||||
encoder.writeUnsignedInteger(ATTRIB_LOGICALSIZE, logicalsize);
|
||||
|
|
|
@ -175,15 +175,7 @@ public record AttributeId(String name, int id) {
|
|||
public static final AttributeId ATTRIB_DELAY = new AttributeId("delay", 91);
|
||||
public static final AttributeId ATTRIB_LOGICALSIZE = new AttributeId("logicalsize", 92);
|
||||
public static final AttributeId ATTRIB_PHYSICAL = new AttributeId("physical", 93);
|
||||
public static final AttributeId ATTRIB_PIECE1 = new AttributeId("piece1", 94); // piece attributes must have sequential ids
|
||||
public static final AttributeId ATTRIB_PIECE2 = new AttributeId("piece2", 95);
|
||||
public static final AttributeId ATTRIB_PIECE3 = new AttributeId("piece3", 96);
|
||||
public static final AttributeId ATTRIB_PIECE4 = new AttributeId("piece4", 97);
|
||||
public static final AttributeId ATTRIB_PIECE5 = new AttributeId("piece5", 98);
|
||||
public static final AttributeId ATTRIB_PIECE6 = new AttributeId("piece6", 99);
|
||||
public static final AttributeId ATTRIB_PIECE7 = new AttributeId("piece7", 100);
|
||||
public static final AttributeId ATTRIB_PIECE8 = new AttributeId("piece8", 101);
|
||||
public static final AttributeId ATTRIB_PIECE9 = new AttributeId("piece9", 102);
|
||||
public static final AttributeId ATTRIB_PIECE = new AttributeId("piece", 94);
|
||||
|
||||
// architecture
|
||||
public static final AttributeId ATTRIB_ADJUSTVMA = new AttributeId("adjustvma", 103);
|
||||
|
|
|
@ -92,6 +92,17 @@ public interface Decoder extends ByteIngest {
|
|||
*/
|
||||
public int getNextAttributeId() throws DecoderException;
|
||||
|
||||
/**
|
||||
* Get the id for the (current) attribute, assuming it is indexed.
|
||||
* Assuming the previous call to getNextAttributeId() returned the id of ATTRIB_UNKNOWN,
|
||||
* reinterpret the attribute as being an indexed form of the given attribute. If the attribute
|
||||
* matches, return this indexed id, otherwise return ATTRIB_UNKNOWN.
|
||||
* @param attribId is the attribute being indexed
|
||||
* @return the indexed id or ATTRIB_UNKNOWN
|
||||
* @throws DecoderException for unexpected end of stream
|
||||
*/
|
||||
public int getIndexedAttributeId(AttributeId attribId) throws DecoderException;
|
||||
|
||||
/**
|
||||
* Reset attribute traversal for the current element
|
||||
* Attributes for a single element can be traversed more than once using the getNextAttributeId
|
||||
|
|
|
@ -93,6 +93,19 @@ public interface Encoder {
|
|||
*/
|
||||
void writeString(AttributeId attribId, String val) throws IOException;
|
||||
|
||||
/**
|
||||
* Write an annotated string, using an indexed attribute, into the encoding.
|
||||
* Multiple attributes with a shared name can be written to the same element by calling this
|
||||
* method multiple times with a different index value. The encoding will use attribute ids up
|
||||
* to the base id plus the maximum index passed in. Implementors must be careful to not use
|
||||
* other attributes with ids bigger than the base id within the element taking the indexed attribute.
|
||||
* @param attribId is the shared AttributeId
|
||||
* @param index is the unique index to associated with the string
|
||||
* @param val is the string to encode
|
||||
* @throws IOException for errors in the underlying stream
|
||||
*/
|
||||
void writeStringIndexed(AttributeId attribId, int index, String val) throws IOException;
|
||||
|
||||
/**
|
||||
* Write an address space reference into the encoding
|
||||
* The address space is associated with the given AttributeId annotation and the current open element.
|
||||
|
|
|
@ -310,6 +310,11 @@ public class PackedDecode implements Decoder {
|
|||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexedAttributeId(AttributeId attribId) throws DecoderException {
|
||||
return AttributeId.ATTRIB_UNKNOWN.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rewindAttributes() {
|
||||
curPos.copy(startPos);
|
||||
|
|
|
@ -165,6 +165,14 @@ public class PackedEncode implements PatchEncoder {
|
|||
outStream.write(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStringIndexed(AttributeId attribId, int index, String val) throws IOException {
|
||||
byte[] bytes = val.getBytes();
|
||||
writeHeader(ATTRIBUTE, attribId.id() + index);
|
||||
writeInteger((TYPECODE_STRING << TYPECODE_SHIFT), bytes.length);
|
||||
outStream.write(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
||||
writeHeader(ATTRIBUTE, attribId.id());
|
||||
|
|
|
@ -497,8 +497,15 @@ public class Varnode {
|
|||
if (attribId == 0) {
|
||||
break;
|
||||
}
|
||||
else if (attribId >= ATTRIB_PIECE1.id() && attribId <= ATTRIB_PIECE9.id()) {
|
||||
int index = attribId - ATTRIB_PIECE1.id();
|
||||
else if (attribId == ATTRIB_UNKNOWN.id()) {
|
||||
attribId = decoder.getIndexedAttributeId(ATTRIB_PIECE);
|
||||
}
|
||||
|
||||
if (attribId >= ATTRIB_PIECE.id()) {
|
||||
int index = attribId - ATTRIB_PIECE.id();
|
||||
if (index > AddressXML.MAX_PIECES) {
|
||||
continue;
|
||||
}
|
||||
if (index != list.size()) {
|
||||
throw new DecoderException("\"piece\" attributes must be in order");
|
||||
}
|
||||
|
|
|
@ -144,6 +144,16 @@ public class XmlEncode implements Encoder {
|
|||
buffer.append("\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStringIndexed(AttributeId attribId, int index, String val) throws IOException {
|
||||
buffer.append(' ');
|
||||
buffer.append(attribId.name());
|
||||
buffer.append(index + 1);
|
||||
buffer.append("=\"");
|
||||
SpecXmlUtils.xmlEscape(buffer, val);
|
||||
buffer.append("\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpace(AttributeId attribId, AddressSpace spc) throws IOException {
|
||||
String spcName;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue