mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
c87707cc4e
9 changed files with 250 additions and 28 deletions
|
@ -141,6 +141,38 @@ public interface Decoder extends ByteIngest {
|
|||
*/
|
||||
public long readSignedInteger(AttributeId attribId) throws DecoderException;
|
||||
|
||||
/**
|
||||
* Parse the current attribute as either a signed integer value or a string.
|
||||
* If the attribute is an integer, its value is returned.
|
||||
* If the attribute is a string, it must match an expected string passed to the method,
|
||||
* and a predetermined integer value associated with the string is returned.
|
||||
* If the attribute string does not match, or the attribute is encoded as anything other than
|
||||
* a string or signed integer, an exception is thrown.
|
||||
* @param expect is the string value to expect if the attribute is encoded as a string
|
||||
* @param expectval is the integer value to return if the attribute matches the expected string
|
||||
* @return the encoded integer or the integer value associated with the expected string
|
||||
* @throws DecoderException is an integer value or expected string cannot be parsed
|
||||
*/
|
||||
public long readSignedIntegerExpectString(String expect, long expectval)
|
||||
throws DecoderException;
|
||||
|
||||
/**
|
||||
* Find and parse a specific attribute in the current element as either a signed integer
|
||||
* or a string. If the attribute is an integer, its value is returned.
|
||||
* If the attribute is encoded as a string, it must match an expected string
|
||||
* passed to this method. In this case, a predetermined integer value is passed back,
|
||||
* indicating a matching string was parsed. If the attribute string does not match, or
|
||||
* the attribute is encoded as anything other than a string or signed integer, an exception
|
||||
* is thrown.
|
||||
* @param attribId is the specific attribute id to match
|
||||
* @param expect is the string to expect, if the attribute is not encoded as an integer
|
||||
* @param expectval is the integer value to return if the attribute matches the expected string
|
||||
* @return the encoded integer or the integer value associated with the expected string
|
||||
* @throws DecoderException if an integer value or expected string cannot be parsed
|
||||
*/
|
||||
public long readSignedIntegerExpectString(AttributeId attribId, String expect, long expectval)
|
||||
throws DecoderException;
|
||||
|
||||
/**
|
||||
* Parse the current attribute as an unsigned integer value
|
||||
* The last attribute, as returned by getNextAttributeId, is treated as an unsigned integer,
|
||||
|
|
|
@ -427,12 +427,8 @@ public class FunctionPrototype {
|
|||
PrototypeModel protoModel =
|
||||
dtmanage.getProgram().getCompilerSpec().getCallingConvention(modelname);
|
||||
hasThis = (protoModel == null) ? false : protoModel.hasThisPointer();
|
||||
try {
|
||||
extrapop = (int) decoder.readSignedInteger(ATTRIB_EXTRAPOP);
|
||||
}
|
||||
catch (DecoderException e) {
|
||||
extrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
||||
}
|
||||
extrapop = (int) decoder.readSignedIntegerExpectString(ATTRIB_EXTRAPOP, "unknown",
|
||||
PrototypeModel.UNKNOWN_EXTRAPOP);
|
||||
modellock = false;
|
||||
dotdotdot = false;
|
||||
voidinputlock = false;
|
||||
|
|
|
@ -32,7 +32,6 @@ import ghidra.program.model.symbol.SourceType;
|
|||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.xml.SpecXmlUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -155,13 +154,8 @@ public class HighParamID extends PcodeSyntaxTree {
|
|||
else if (subel == ELEM_PROTO.id()) {
|
||||
decoder.openElement();
|
||||
modelname = decoder.readString(ATTRIB_MODEL);
|
||||
String val = decoder.readString(ATTRIB_EXTRAPOP);
|
||||
if (val.equals("unknown")) {
|
||||
protoextrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
||||
}
|
||||
else {
|
||||
protoextrapop = SpecXmlUtils.decodeInt(val);
|
||||
}
|
||||
protoextrapop = (int) decoder.readSignedIntegerExpectString(ATTRIB_EXTRAPOP,
|
||||
"unknown", PrototypeModel.UNKNOWN_EXTRAPOP);
|
||||
decoder.closeElement(subel);
|
||||
}
|
||||
else if (subel == ELEM_INPUT.id()) {
|
||||
|
|
|
@ -370,6 +370,41 @@ public class PackedDecode implements Decoder {
|
|||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readSignedIntegerExpectString(String expect, long expectval)
|
||||
throws DecoderException {
|
||||
long res;
|
||||
LinkedByteBuffer.Position tmpPos = new LinkedByteBuffer.Position();
|
||||
tmpPos.copy(curPos);
|
||||
byte header1 = tmpPos.getNextByte();
|
||||
if ((header1 & HEADEREXTEND_MASK) != 0) {
|
||||
tmpPos.getNextByte();
|
||||
}
|
||||
byte typeByte = tmpPos.getNextByte();
|
||||
int typeCode = typeByte >> TYPECODE_SHIFT;
|
||||
if (typeCode == TYPECODE_STRING) {
|
||||
String val = readString();
|
||||
if (!val.equals(expect)) {
|
||||
throw new DecoderException(
|
||||
"Expecting string \"" + expect + "\" but read \"" + val + "\"");
|
||||
}
|
||||
res = expectval;
|
||||
}
|
||||
else {
|
||||
res = readSignedInteger();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readSignedIntegerExpectString(AttributeId attribId, String expect, long expectval)
|
||||
throws DecoderException {
|
||||
findMatchingAttribute(attribId);
|
||||
long res = readSignedIntegerExpectString(expect, expectval);
|
||||
curPos.copy(startPos);
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readUnsignedInteger() throws DecoderException {
|
||||
byte header1 = curPos.getNextByte();
|
||||
|
|
|
@ -155,6 +155,38 @@ public class EncodeDecodeTest extends AbstractGenericTest {
|
|||
decoder.closeElement(el);
|
||||
}
|
||||
|
||||
private void testMixedAttributes(Encoder encoder, Decoder decoder)
|
||||
throws DecoderException, IOException {
|
||||
encoder.openElement(ELEM_ADDR);
|
||||
encoder.writeSignedInteger(ATTRIB_ALIGN, 456);
|
||||
encoder.writeString(ATTRIB_EXTRAPOP, "unknown");
|
||||
encoder.closeElement(ELEM_ADDR);
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
encoder.writeTo(outStream);
|
||||
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
|
||||
decoder.open(1 << 20, "testMixedAttributes");
|
||||
decoder.ingestStream(inStream);
|
||||
decoder.endIngest();
|
||||
int alignVal = -1;
|
||||
int extrapopVal = -1;
|
||||
int el = decoder.openElement(ELEM_ADDR);
|
||||
for (;;) {
|
||||
int attribId = decoder.getNextAttributeId();
|
||||
if (attribId == 0) {
|
||||
break;
|
||||
}
|
||||
if (attribId == ATTRIB_ALIGN.id()) {
|
||||
alignVal = (int) decoder.readSignedIntegerExpectString("00blah", 700);
|
||||
}
|
||||
else if (attribId == ATTRIB_EXTRAPOP.id()) {
|
||||
extrapopVal = (int) decoder.readSignedIntegerExpectString("unknown", 800);
|
||||
}
|
||||
}
|
||||
decoder.closeElement(el);
|
||||
assertEquals(alignVal, 456);
|
||||
assertEquals(extrapopVal, 800);
|
||||
}
|
||||
|
||||
private void testAttributes(Encoder encoder, Decoder decoder)
|
||||
throws DecoderException, IOException
|
||||
|
||||
|
@ -401,6 +433,14 @@ public class EncodeDecodeTest extends AbstractGenericTest {
|
|||
testUnsignedAttributes(encoder, decoder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void marshalMixedPacked() throws DecoderException, IOException {
|
||||
PackedEncode encoder = new PackedEncode();
|
||||
encoder.clear();
|
||||
PackedDecode decoder = new PackedDecode(addrFactory);
|
||||
testMixedAttributes(encoder, decoder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void marshalAttribsPacked() throws DecoderException, IOException {
|
||||
PackedEncode encoder = new PackedEncode();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue