mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-5189 Add range attributes to VarargsFilter
This commit is contained in:
parent
57df41297f
commit
e3aa064061
10 changed files with 128 additions and 28 deletions
|
@ -3433,6 +3433,10 @@ void ProtoStoreInternal::decode(Decoder &decoder,ProtoModel *model)
|
||||||
addressesdetermined = false;
|
addressesdetermined = false;
|
||||||
|
|
||||||
uint4 elemId = decoder.openElement(ELEM_INTERNALLIST);
|
uint4 elemId = decoder.openElement(ELEM_INTERNALLIST);
|
||||||
|
uint4 firstId = decoder.getNextAttributeId();
|
||||||
|
if (firstId == ATTRIB_FIRST) {
|
||||||
|
proto.firstVarArgSlot = decoder.readSignedInteger();
|
||||||
|
}
|
||||||
for(;;) { // This is only the input params
|
for(;;) { // This is only the input params
|
||||||
uint4 subId = decoder.openElement(); // <retparam> or <param>
|
uint4 subId = decoder.openElement(); // <retparam> or <param>
|
||||||
if (subId == 0) break;
|
if (subId == 0) break;
|
||||||
|
|
|
@ -412,13 +412,22 @@ bool VarargsFilter::filter(const PrototypePieces &proto,int4 pos) const
|
||||||
|
|
||||||
{
|
{
|
||||||
if (proto.firstVarArgSlot < 0) return false;
|
if (proto.firstVarArgSlot < 0) return false;
|
||||||
return (pos >= proto.firstVarArgSlot);
|
pos -= proto.firstVarArgSlot;
|
||||||
|
return (pos >= firstPos && pos <= lastPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VarargsFilter::decode(Decoder &decoder)
|
void VarargsFilter::decode(Decoder &decoder)
|
||||||
|
|
||||||
{
|
{
|
||||||
uint4 elemId = decoder.openElement(ELEM_VARARGS);
|
uint4 elemId = decoder.openElement(ELEM_VARARGS);
|
||||||
|
for(;;) {
|
||||||
|
uint4 attribId = decoder.getNextAttributeId();
|
||||||
|
if (attribId == 0) break;
|
||||||
|
if (attribId == ATTRIB_FIRST)
|
||||||
|
firstPos = decoder.readSignedInteger();
|
||||||
|
else if (attribId == ATTRIB_LAST)
|
||||||
|
lastPos = decoder.readSignedInteger();
|
||||||
|
}
|
||||||
decoder.closeElement(elemId);
|
decoder.closeElement(elemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -190,15 +190,24 @@ public:
|
||||||
virtual void decode(Decoder &decoder) {}
|
virtual void decode(Decoder &decoder) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A filter that selects function parameters that are considered optional
|
/// \brief A filter that selects a range of function parameters that are considered optional.
|
||||||
///
|
///
|
||||||
/// If the underlying function prototype is considered to take variable arguments, the first
|
/// If the underlying function prototype is considered to take variable arguments, the first
|
||||||
/// \e n parameters (as determined by PrototypePieces.firstVarArgSlot) are considered non-optional.
|
/// n parameters (as determined by PrototypePieces.firstVarArgSlot) are considered non-optional.
|
||||||
/// If additional data-types are provided beyond the initial \e n, these are considered optional.
|
///\e If additional data-types are provided beyond the initial \e n, these are considered optional.
|
||||||
/// This filter returns \b true for these optional parameters
|
/// By default this filter matches on any parameter in a prototype with variable arguments.
|
||||||
|
/// Optionally, it can filter on a range of parameters that are specified relative to the
|
||||||
|
/// first variable argument.
|
||||||
|
/// - \<varargs first="0"/> - matches optional arguments but not non-optional ones.
|
||||||
|
/// - \<varargs first="0" last="0"/> - matches the first optional argument.
|
||||||
|
/// - \<varargs first="-1"/> - matches the last non-optional argument and all optional ones.
|
||||||
class VarargsFilter : public QualifierFilter {
|
class VarargsFilter : public QualifierFilter {
|
||||||
|
int4 firstPos; ///< Start of range to match (offset relative to first variable arg)
|
||||||
|
int4 lastPos; ///< End of range to match
|
||||||
public:
|
public:
|
||||||
virtual QualifierFilter *clone(void) const { return new VarargsFilter(); }
|
VarargsFilter(void) { firstPos = 0x80000000; lastPos = 0x7fffffff; }
|
||||||
|
VarargsFilter(int4 first,int4 last) { firstPos = first; lastPos = last; }
|
||||||
|
virtual QualifierFilter *clone(void) const { return new VarargsFilter(firstPos,lastPos); }
|
||||||
virtual bool filter(const PrototypePieces &proto,int4 pos) const;
|
virtual bool filter(const PrototypePieces &proto,int4 pos) const;
|
||||||
virtual void decode(Decoder &decoder);
|
virtual void decode(Decoder &decoder);
|
||||||
};
|
};
|
||||||
|
|
|
@ -355,7 +355,12 @@
|
||||||
<interleave>
|
<interleave>
|
||||||
<optional>
|
<optional>
|
||||||
<element name="varargs">
|
<element name="varargs">
|
||||||
<empty/>
|
<optional>
|
||||||
|
<attribute name="first"/>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="last"/>
|
||||||
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
|
|
|
@ -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,30 +15,54 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.model.lang.protorules;
|
package ghidra.program.model.lang.protorules;
|
||||||
|
|
||||||
|
import static ghidra.program.model.pcode.AttributeId.*;
|
||||||
import static ghidra.program.model.pcode.ElementId.*;
|
import static ghidra.program.model.pcode.ElementId.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.program.model.lang.PrototypePieces;
|
import ghidra.program.model.lang.PrototypePieces;
|
||||||
import ghidra.program.model.pcode.Encoder;
|
import ghidra.program.model.pcode.Encoder;
|
||||||
|
import ghidra.util.xml.SpecXmlUtils;
|
||||||
import ghidra.xml.*;
|
import ghidra.xml.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A filter that selects function parameters that are considered optional.
|
* A filter that selects a range of function parameters that are considered optional.
|
||||||
* If the underlying function prototype is considered to take variable arguments, the first
|
* If the underlying function prototype takes variable arguments, the first n
|
||||||
* n parameters (as determined by PrototypePieces.firstVarArgSlot) are considered non-optional.
|
* parameters (as determined by PrototypePieces.firstVarArgSlot) are considered non-optional.
|
||||||
* If additional data-types are provided beyond the initial n, these are considered optional.
|
* If additional data-types are provided beyond the initial n, these are considered optional.
|
||||||
* This filter returns true for these optional parameters
|
* By default this filter matches on all parameters in a prototype with variable arguments.
|
||||||
|
* Optionally, it can filter on a range of parameters that are specified relative to the
|
||||||
|
* first variable argument.
|
||||||
|
* {@code <varargs first="0"/>} - matches optional arguments but not non-optional ones.
|
||||||
|
* {@code <varargs first="0" last="0"/>} - matches the first optional argument.
|
||||||
|
* {@code <varargs first="-1"/>} - matches the last non-optional argument and all optional ones.
|
||||||
*/
|
*/
|
||||||
public class VarargsFilter implements QualifierFilter {
|
public class VarargsFilter implements QualifierFilter {
|
||||||
|
private int firstPos; // Range of params to match (relative to first variable arg)
|
||||||
|
private int lastPos;
|
||||||
|
|
||||||
|
public VarargsFilter() {
|
||||||
|
firstPos = Integer.MIN_VALUE;
|
||||||
|
lastPos = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VarargsFilter(int first, int last) {
|
||||||
|
firstPos = first;
|
||||||
|
lastPos = last;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QualifierFilter clone() {
|
public QualifierFilter clone() {
|
||||||
return new VarargsFilter();
|
return new VarargsFilter(firstPos, lastPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEquivalent(QualifierFilter op) {
|
public boolean isEquivalent(QualifierFilter op) {
|
||||||
return (this.getClass() == op.getClass());
|
if (this.getClass() != op.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
VarargsFilter otherFilter = (VarargsFilter) op;
|
||||||
|
return (firstPos == otherFilter.firstPos && lastPos == otherFilter.lastPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,18 +70,33 @@ public class VarargsFilter implements QualifierFilter {
|
||||||
if (proto.firstVarArgSlot < 0) {
|
if (proto.firstVarArgSlot < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (pos >= proto.firstVarArgSlot);
|
pos -= proto.firstVarArgSlot;
|
||||||
|
return (pos >= firstPos && pos <= lastPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(Encoder encoder) throws IOException {
|
public void encode(Encoder encoder) throws IOException {
|
||||||
encoder.openElement(ELEM_VARARGS);
|
encoder.openElement(ELEM_VARARGS);
|
||||||
|
if (firstPos != Integer.MIN_VALUE) {
|
||||||
|
encoder.writeSignedInteger(ATTRIB_FIRST, firstPos);
|
||||||
|
}
|
||||||
|
if (lastPos != Integer.MAX_VALUE) {
|
||||||
|
encoder.writeSignedInteger(ATTRIB_LAST, lastPos);
|
||||||
|
}
|
||||||
encoder.closeElement(ELEM_VARARGS);
|
encoder.closeElement(ELEM_VARARGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void restoreXml(XmlPullParser parser) throws XmlParseException {
|
public void restoreXml(XmlPullParser parser) throws XmlParseException {
|
||||||
XmlElement elem = parser.start(ELEM_VARARGS.name());
|
XmlElement elem = parser.start(ELEM_VARARGS.name());
|
||||||
|
String firstPosString = elem.getAttribute(ATTRIB_FIRST.name());
|
||||||
|
if (firstPosString != null) {
|
||||||
|
firstPos = SpecXmlUtils.decodeInt(firstPosString);
|
||||||
|
}
|
||||||
|
String lastPosString = elem.getAttribute(ATTRIB_LAST.name());
|
||||||
|
if (lastPosString != null) {
|
||||||
|
lastPos = SpecXmlUtils.decodeInt(lastPosString);
|
||||||
|
}
|
||||||
parser.end(elem);
|
parser.end(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -311,9 +311,11 @@ public class FunctionPrototype {
|
||||||
* Encode this function prototype to a stream.
|
* Encode this function prototype to a stream.
|
||||||
* @param encoder is the stream encoder
|
* @param encoder is the stream encoder
|
||||||
* @param dtmanage is the DataTypeManager for building type reference tags
|
* @param dtmanage is the DataTypeManager for building type reference tags
|
||||||
|
* @param firstVarArg is index of first variable argument or -1
|
||||||
* @throws IOException for errors in the underlying stream
|
* @throws IOException for errors in the underlying stream
|
||||||
*/
|
*/
|
||||||
public void encodePrototype(Encoder encoder, PcodeDataTypeManager dtmanage) throws IOException {
|
public void encodePrototype(Encoder encoder, PcodeDataTypeManager dtmanage, int firstVarArg)
|
||||||
|
throws IOException {
|
||||||
encoder.openElement(ELEM_PROTOTYPE);
|
encoder.openElement(ELEM_PROTOTYPE);
|
||||||
if (extrapop == PrototypeModel.UNKNOWN_EXTRAPOP) {
|
if (extrapop == PrototypeModel.UNKNOWN_EXTRAPOP) {
|
||||||
encoder.writeString(ATTRIB_EXTRAPOP, "unknown");
|
encoder.writeString(ATTRIB_EXTRAPOP, "unknown");
|
||||||
|
@ -378,6 +380,10 @@ public class FunctionPrototype {
|
||||||
}
|
}
|
||||||
if (params != null) {
|
if (params != null) {
|
||||||
encoder.openElement(ELEM_INTERNALLIST);
|
encoder.openElement(ELEM_INTERNALLIST);
|
||||||
|
if (firstVarArg >= 0) {
|
||||||
|
// Encoding detail because we are not sending the storage address
|
||||||
|
encoder.writeSignedInteger(ATTRIB_FIRST, firstVarArg);
|
||||||
|
}
|
||||||
for (ParameterDefinition param : params) {
|
for (ParameterDefinition param : params) {
|
||||||
encoder.openElement(ELEM_PARAM);
|
encoder.openElement(ELEM_PARAM);
|
||||||
String name = param.getName();
|
String name = param.getName();
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -454,7 +454,7 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
AddressXML.encode(encoder, entryPoint); // Address is forced on XML
|
AddressXML.encode(encoder, entryPoint); // Address is forced on XML
|
||||||
}
|
}
|
||||||
localSymbols.encodeLocalDb(encoder, namespace, getDataTypeManager().getNameTransformer());
|
localSymbols.encodeLocalDb(encoder, namespace, getDataTypeManager().getNameTransformer());
|
||||||
proto.encodePrototype(encoder, getDataTypeManager());
|
proto.encodePrototype(encoder, getDataTypeManager(), -1);
|
||||||
if ((jumpTables != null) && (jumpTables.size() > 0)) {
|
if ((jumpTables != null) && (jumpTables.size() > 0)) {
|
||||||
encoder.openElement(ELEM_JUMPTABLELIST);
|
encoder.openElement(ELEM_JUMPTABLELIST);
|
||||||
for (JumpTable jumpTable : jumpTables) {
|
for (JumpTable jumpTable : jumpTables) {
|
||||||
|
@ -466,13 +466,15 @@ public class HighFunction extends PcodeSyntaxTree {
|
||||||
if (hasOverrideTag) {
|
if (hasOverrideTag) {
|
||||||
encoder.openElement(ELEM_OVERRIDE);
|
encoder.openElement(ELEM_OVERRIDE);
|
||||||
PcodeDataTypeManager dtmanage = getDataTypeManager();
|
PcodeDataTypeManager dtmanage = getDataTypeManager();
|
||||||
|
Program prog = func.getProgram();
|
||||||
for (DataTypeSymbol sym : protoOverrides) {
|
for (DataTypeSymbol sym : protoOverrides) {
|
||||||
Address addr = sym.getAddress();
|
Address addr = sym.getAddress();
|
||||||
|
int firstVarArg = HighFunctionDBUtil.getFirstVarArg(prog, addr);
|
||||||
FunctionPrototype fproto = new FunctionPrototype(
|
FunctionPrototype fproto = new FunctionPrototype(
|
||||||
(FunctionSignature) sym.getDataType(), compilerSpec, false);
|
(FunctionSignature) sym.getDataType(), compilerSpec, false);
|
||||||
encoder.openElement(ELEM_PROTOOVERRIDE);
|
encoder.openElement(ELEM_PROTOOVERRIDE);
|
||||||
AddressXML.encode(encoder, addr);
|
AddressXML.encode(encoder, addr);
|
||||||
fproto.encodePrototype(encoder, dtmanage);
|
fproto.encodePrototype(encoder, dtmanage, firstVarArg);
|
||||||
encoder.closeElement(ELEM_PROTOOVERRIDE);
|
encoder.closeElement(ELEM_PROTOOVERRIDE);
|
||||||
}
|
}
|
||||||
encoder.closeElement(ELEM_OVERRIDE);
|
encoder.closeElement(ELEM_OVERRIDE);
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -739,6 +739,27 @@ public class HighFunctionDBUtil {
|
||||||
return datsym;
|
return datsym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is a call to a function at the given address, and the function takes variable arguments,
|
||||||
|
* return the index of the first variable argument. Return -1 otherwise.
|
||||||
|
* @param program is the Program
|
||||||
|
* @param addr is the given address of the call
|
||||||
|
* @return the index of the first variable argument or -1
|
||||||
|
*/
|
||||||
|
public static int getFirstVarArg(Program program, Address addr) {
|
||||||
|
for (Reference ref : program.getReferenceManager().getReferencesFrom(addr)) {
|
||||||
|
if (ref.isPrimary() && ref.getReferenceType().isCall()) {
|
||||||
|
Address callDestAddr = ref.getToAddress();
|
||||||
|
Function func = program.getFunctionManager().getFunctionAt(callDestAddr);
|
||||||
|
if (func != null && func.hasVarArgs()) {
|
||||||
|
return func.getParameterCount();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Address referred to by a spacebase reference. Address-of references are encoded in
|
* Get the Address referred to by a spacebase reference. Address-of references are encoded in
|
||||||
* the p-code syntax tree as: {@code vn = PTRSUB(<spacebase>, #const)}. This decodes the reference and
|
* the p-code syntax tree as: {@code vn = PTRSUB(<spacebase>, #const)}. This decodes the reference and
|
||||||
|
|
|
@ -681,7 +681,7 @@ public class PcodeDataTypeManager {
|
||||||
encoder.writeSignedInteger(ATTRIB_SIZE, 1); // Force size of 1
|
encoder.writeSignedInteger(ATTRIB_SIZE, 1); // Force size of 1
|
||||||
CompilerSpec cspec = program.getCompilerSpec();
|
CompilerSpec cspec = program.getCompilerSpec();
|
||||||
FunctionPrototype fproto = new FunctionPrototype(type, cspec, voidInputIsVarargs);
|
FunctionPrototype fproto = new FunctionPrototype(type, cspec, voidInputIsVarargs);
|
||||||
fproto.encodePrototype(encoder, this);
|
fproto.encodePrototype(encoder, this, -1);
|
||||||
encoder.closeElement(ELEM_TYPE);
|
encoder.closeElement(ELEM_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@
|
||||||
<pentry maxsize="500" minsize="1" align="1">
|
<pentry maxsize="500" minsize="1" align="1">
|
||||||
<addr space="stack" offset="2"/>
|
<addr space="stack" offset="2"/>
|
||||||
</pentry>
|
</pentry>
|
||||||
|
<rule>
|
||||||
|
<datatype name="any"/>
|
||||||
|
<varargs first="-1"/>
|
||||||
|
<goto_stack/>
|
||||||
|
</rule>
|
||||||
<rule>
|
<rule>
|
||||||
<datatype name="struct" minsize="1"/>
|
<datatype name="struct" minsize="1"/>
|
||||||
<convert_to_ptr/>
|
<convert_to_ptr/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue