mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Fixes to support unaligned stack locations
This commit is contained in:
parent
2ce191d865
commit
fdcf0744ec
3 changed files with 142 additions and 64 deletions
|
@ -113,16 +113,19 @@ int4 ParamEntry::justifiedContain(const Address &addr,int4 sz) const
|
||||||
return entry.justifiedContain(size,addr,sz,((flags&force_left_justify)!=0));
|
return entry.justifiedContain(size,addr,sz,((flags&force_left_justify)!=0));
|
||||||
}
|
}
|
||||||
if (spaceid != addr.getSpace()) return -1;
|
if (spaceid != addr.getSpace()) return -1;
|
||||||
if (addr.getOffset() < addressbase) return -1;
|
uintb startaddr = addr.getOffset();
|
||||||
uintb endaddr = addr.getOffset() + sz - 1;
|
if (startaddr < addressbase) return -1;
|
||||||
if (endaddr < addr.getOffset()) return -1; // Don't allow wrap around
|
uintb endaddr = startaddr + sz - 1;
|
||||||
|
if (endaddr < startaddr) return -1; // Don't allow wrap around
|
||||||
if (endaddr > (addressbase+size-1)) return -1;
|
if (endaddr > (addressbase+size-1)) return -1;
|
||||||
|
startaddr -= addressbase;
|
||||||
|
endaddr -= addressbase;
|
||||||
if (!isLeftJustified()) { // For right justified (big endian), endaddr must be aligned
|
if (!isLeftJustified()) { // For right justified (big endian), endaddr must be aligned
|
||||||
int4 res = (int4)((endaddr+1) % alignment);
|
int4 res = (int4)((endaddr+1) % alignment);
|
||||||
if (res==0) return 0;
|
if (res==0) return 0;
|
||||||
return (alignment-res);
|
return (alignment-res);
|
||||||
}
|
}
|
||||||
return (int4)(addr.getOffset() % alignment);
|
return (int4)(startaddr % alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Calculate the containing memory range
|
/// \brief Calculate the containing memory range
|
||||||
|
@ -160,7 +163,7 @@ bool ParamEntry::getContainer(const Address &addr,int4 sz,VarnodeData &res) cons
|
||||||
res.size = size;
|
res.size = size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
uintb al = addr.getOffset() % alignment;
|
uintb al = (addr.getOffset() - addressbase) % alignment;
|
||||||
res.space = spaceid;
|
res.space = spaceid;
|
||||||
res.offset = addr.getOffset() - al;
|
res.offset = addr.getOffset() - al;
|
||||||
res.size = (int4)(endaddr.getOffset()-res.offset) + 1;
|
res.size = (int4)(endaddr.getOffset()-res.offset) + 1;
|
||||||
|
@ -203,7 +206,8 @@ OpCode ParamEntry::assumedExtension(const Address &addr,int4 sz,VarnodeData &res
|
||||||
}
|
}
|
||||||
else { // Otherwise take up whole alignment
|
else { // Otherwise take up whole alignment
|
||||||
res.space = spaceid;
|
res.space = spaceid;
|
||||||
res.offset = addr.getOffset() - addr.getOffset() % alignment;
|
int4 alignAdjust = (addr.getOffset() - addressbase) % alignment;
|
||||||
|
res.offset = addr.getOffset() - alignAdjust;
|
||||||
res.size = alignment;
|
res.size = alignment;
|
||||||
}
|
}
|
||||||
if ((flags & smallsize_zext)!=0)
|
if ((flags & smallsize_zext)!=0)
|
||||||
|
@ -229,7 +233,7 @@ int4 ParamEntry::getSlot(const Address &addr,int4 skip) const
|
||||||
{
|
{
|
||||||
int4 res = group;
|
int4 res = group;
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
uintb diff = addr.getOffset() + skip - addressbase; // Assume addressbase % alignment == 0
|
uintb diff = addr.getOffset() + skip - addressbase;
|
||||||
int4 baseslot = (int4)diff / alignment;
|
int4 baseslot = (int4)diff / alignment;
|
||||||
if (isReverseStack())
|
if (isReverseStack())
|
||||||
res += (numslots -1) - baseslot;
|
res += (numslots -1) - baseslot;
|
||||||
|
@ -365,8 +369,8 @@ void ParamEntry::restoreXml(const Element *el,const AddrSpaceManager *manage,boo
|
||||||
spaceid = addr.getSpace();
|
spaceid = addr.getSpace();
|
||||||
addressbase = addr.getOffset();
|
addressbase = addr.getOffset();
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
if ((addressbase % alignment) != 0)
|
// if ((addressbase % alignment) != 0)
|
||||||
throw LowlevelError("Stack <pentry> address must match alignment");
|
// throw LowlevelError("Stack <pentry> address must match alignment");
|
||||||
numslots = size / alignment;
|
numslots = size / alignment;
|
||||||
}
|
}
|
||||||
if (spaceid->isReverseJustified()) {
|
if (spaceid->isReverseJustified()) {
|
||||||
|
@ -890,8 +894,8 @@ bool ParamListStandard::checkJoin(const Address &hiaddr,int4 hisize,const Addres
|
||||||
if (entryHi->getGroup() == entryLo->getGroup()) {
|
if (entryHi->getGroup() == entryLo->getGroup()) {
|
||||||
if (entryHi->isExclusion()||entryLo->isExclusion()) return false;
|
if (entryHi->isExclusion()||entryLo->isExclusion()) return false;
|
||||||
if (!hiaddr.isContiguous(hisize,loaddr,losize)) return false;
|
if (!hiaddr.isContiguous(hisize,loaddr,losize)) return false;
|
||||||
if ((hiaddr.getOffset() % entryHi->getAlign()) != 0) return false;
|
if (((hiaddr.getOffset() - entryHi->getBase()) % entryHi->getAlign()) != 0) return false;
|
||||||
if ((loaddr.getOffset() % entryLo->getAlign()) != 0) return false;
|
if (((loaddr.getOffset() - entryLo->getBase()) % entryLo->getAlign()) != 0) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -113,13 +113,23 @@ public class ParamEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(ParamEntry op2) {
|
public boolean contains(ParamEntry op2) {
|
||||||
if ((type != TYPE_UNKNOWN)&&(op2.type != type)) return false;
|
if ((type != TYPE_UNKNOWN)&&(op2.type != type)) {
|
||||||
if (spaceid != op2.spaceid) return false;
|
return false;
|
||||||
if (unsignedCompare(op2.addressbase,addressbase)) return false;
|
}
|
||||||
|
if (spaceid != op2.spaceid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (unsignedCompare(op2.addressbase,addressbase)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
long op2end = op2.addressbase + op2.size -1;
|
long op2end = op2.addressbase + op2.size -1;
|
||||||
long end = addressbase+size-1;
|
long end = addressbase+size-1;
|
||||||
if (unsignedCompare(end,op2end)) return false;
|
if (unsignedCompare(end,op2end)) {
|
||||||
if (alignment != op2.alignment) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (alignment != op2.alignment) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +140,12 @@ public class ParamEntry {
|
||||||
Varnode vdata = joinrec[i];
|
Varnode vdata = joinrec[i];
|
||||||
int cur = justifiedContainAddress(vdata.getAddress().getAddressSpace(),vdata.getOffset(),vdata.getSize(),
|
int cur = justifiedContainAddress(vdata.getAddress().getAddressSpace(),vdata.getOffset(),vdata.getSize(),
|
||||||
addr.getAddressSpace(),addr.getOffset(),sz,false,((flags & IS_BIG_ENDIAN)!=0));
|
addr.getAddressSpace(),addr.getOffset(),sz,false,((flags & IS_BIG_ENDIAN)!=0));
|
||||||
if (cur<0)
|
if (cur<0) {
|
||||||
res += vdata.getSize(); // We skipped this many less significant bytes
|
res += vdata.getSize(); // We skipped this many less significant bytes
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return res + cur;
|
return res + cur;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1; // Not contained at all
|
return -1; // Not contained at all
|
||||||
}
|
}
|
||||||
|
@ -142,17 +154,30 @@ public class ParamEntry {
|
||||||
addr.getAddressSpace(),addr.getOffset(),sz,
|
addr.getAddressSpace(),addr.getOffset(),sz,
|
||||||
((flags & FORCE_LEFT_JUSTIFY)!=0),((flags & IS_BIG_ENDIAN)!=0));
|
((flags & FORCE_LEFT_JUSTIFY)!=0),((flags & IS_BIG_ENDIAN)!=0));
|
||||||
}
|
}
|
||||||
if (spaceid != addr.getAddressSpace()) return -1;
|
if (spaceid != addr.getAddressSpace()) {
|
||||||
if (unsignedCompare(addr.getOffset(), addressbase)) return -1;
|
return -1;
|
||||||
long endaddr = addr.getOffset() + sz -1;
|
}
|
||||||
if (unsignedCompare(endaddr,addr.getOffset())) return -1; // Don't allow wrap around
|
long startaddr = addr.getOffset();
|
||||||
if (unsignedCompare(addressbase + size-1,endaddr)) return -1;
|
if (unsignedCompare(startaddr, addressbase)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
long endaddr = startaddr + sz - 1;
|
||||||
|
if (unsignedCompare(endaddr, startaddr)) {
|
||||||
|
return -1; // Don't allow wrap around
|
||||||
|
}
|
||||||
|
if (unsignedCompare(addressbase + size-1,endaddr)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
startaddr -= addressbase;
|
||||||
|
endaddr -= addressbase;
|
||||||
if (!isLeftJustified()) { // For right justified (big endian), endaddr must be aligned
|
if (!isLeftJustified()) { // For right justified (big endian), endaddr must be aligned
|
||||||
int res = (int)((endaddr+1) % alignment);
|
int res = (int)((endaddr+1) % alignment);
|
||||||
if (res==0) return 0;
|
if (res==0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return (alignment-res);
|
return (alignment-res);
|
||||||
}
|
}
|
||||||
return (int)(addr.getOffset() % alignment);
|
return (int) (startaddr % alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,12 +190,14 @@ public class ParamEntry {
|
||||||
public int getSlot(Address addr,int skip) {
|
public int getSlot(Address addr,int skip) {
|
||||||
int res = group;
|
int res = group;
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
long diff = addr.getOffset() + skip - addressbase; // Assume addressbase % alignment == 0
|
long diff = addr.getOffset() + skip - addressbase;
|
||||||
int baseslot = (int)diff / alignment;
|
int baseslot = (int)diff / alignment;
|
||||||
if (isReverseStack())
|
if (isReverseStack()) {
|
||||||
res += (numslots-1) - baseslot;
|
res += (numslots-1) - baseslot;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
res += baseslot;
|
res += baseslot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (skip != 0) {
|
else if (skip != 0) {
|
||||||
res += (groupsize -1);
|
res += (groupsize -1);
|
||||||
|
@ -190,22 +217,31 @@ public class ParamEntry {
|
||||||
public int getAddrBySlot(int slotnum,int sz,VarnodeData res) {
|
public int getAddrBySlot(int slotnum,int sz,VarnodeData res) {
|
||||||
res.space = null; // Start with an invalid result
|
res.space = null; // Start with an invalid result
|
||||||
int spaceused;
|
int spaceused;
|
||||||
if (sz < minsize) return slotnum;
|
if (sz < minsize) {
|
||||||
|
return slotnum;
|
||||||
|
}
|
||||||
if (alignment == 0) { // If not an aligned entry (allowing multiple slots)
|
if (alignment == 0) { // If not an aligned entry (allowing multiple slots)
|
||||||
if (slotnum != 0) return slotnum; // Can only allocate slot 0
|
if (slotnum != 0) {
|
||||||
if (sz > size) return slotnum; // Check on maximum size
|
return slotnum; // Can only allocate slot 0
|
||||||
|
}
|
||||||
|
if (sz > size) {
|
||||||
|
return slotnum; // Check on maximum size
|
||||||
|
}
|
||||||
res.space = spaceid;
|
res.space = spaceid;
|
||||||
res.offset = addressbase; // Get base address of the slot
|
res.offset = addressbase; // Get base address of the slot
|
||||||
spaceused = size;
|
spaceused = size;
|
||||||
if ((flags & SMALLSIZE_FLOAT)!=0) // If the datatype is smaller than container, still return whole container
|
if ((flags & SMALLSIZE_FLOAT)!=0) {
|
||||||
return slotnum;
|
return slotnum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int slotsused = sz / alignment; // How many slots does a -sz- byte object need
|
int slotsused = sz / alignment; // How many slots does a -sz- byte object need
|
||||||
if ( (sz %alignment) != 0)
|
if ( (sz %alignment) != 0) {
|
||||||
slotsused += 1;
|
slotsused += 1;
|
||||||
if (slotnum + slotsused > numslots) // Check if there are enough slots left
|
}
|
||||||
|
if (slotnum + slotsused > numslots) {
|
||||||
return slotnum;
|
return slotnum;
|
||||||
|
}
|
||||||
spaceused = slotsused * alignment;
|
spaceused = slotsused * alignment;
|
||||||
int index;
|
int index;
|
||||||
if (isReverseStack()) {
|
if (isReverseStack()) {
|
||||||
|
@ -213,14 +249,16 @@ public class ParamEntry {
|
||||||
index -= slotnum;
|
index -= slotnum;
|
||||||
index -= slotsused;
|
index -= slotsused;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
index = slotnum;
|
index = slotnum;
|
||||||
|
}
|
||||||
res.space = spaceid;
|
res.space = spaceid;
|
||||||
res.offset = addressbase + index * alignment;
|
res.offset = addressbase + index * alignment;
|
||||||
slotnum += slotsused; // Inform caller of number of slots used
|
slotnum += slotsused; // Inform caller of number of slots used
|
||||||
}
|
}
|
||||||
if (!isLeftJustified()) // Adjust for right justified (big endian)
|
if (!isLeftJustified()) {
|
||||||
res.offset += (spaceused - sz);
|
res.offset += (spaceused - sz);
|
||||||
|
}
|
||||||
return slotnum;
|
return slotnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +274,9 @@ public class ParamEntry {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
String attrName = "piece" + Integer.toString(pos+1);
|
String attrName = "piece" + Integer.toString(pos+1);
|
||||||
String attrVal = el.getAttribute(attrName);
|
String attrVal = el.getAttribute(attrName);
|
||||||
if (attrVal == null) break;
|
if (attrVal == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
int offpos = attrVal.indexOf(':');
|
int offpos = attrVal.indexOf(':');
|
||||||
Varnode newvn;
|
Varnode newvn;
|
||||||
if (offpos == -1) {
|
if (offpos == -1) {
|
||||||
|
@ -248,8 +288,9 @@ public class ParamEntry {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int szpos = attrVal.indexOf(':', offpos+1);
|
int szpos = attrVal.indexOf(':', offpos+1);
|
||||||
if (szpos == -1)
|
if (szpos == -1) {
|
||||||
throw new XmlParseException("join address piece attribute is malformed");
|
throw new XmlParseException("join address piece attribute is malformed");
|
||||||
|
}
|
||||||
String spcname = attrVal.substring(0, offpos);
|
String spcname = attrVal.substring(0, offpos);
|
||||||
AddressSpace spc = cspec.getAddressSpace(spcname);
|
AddressSpace spc = cspec.getAddressSpace(spcname);
|
||||||
long offset = SpecXmlUtils.decodeLong(attrVal.substring(offpos+1,szpos));
|
long offset = SpecXmlUtils.decodeLong(attrVal.substring(offpos+1,szpos));
|
||||||
|
@ -312,15 +353,18 @@ public class ParamEntry {
|
||||||
while(iter.hasNext()) {
|
while(iter.hasNext()) {
|
||||||
Entry<String, String> entry = iter.next();
|
Entry<String, String> entry = iter.next();
|
||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
if (name.equals("minsize"))
|
if (name.equals("minsize")) {
|
||||||
minsize = SpecXmlUtils.decodeInt(entry.getValue());
|
minsize = SpecXmlUtils.decodeInt(entry.getValue());
|
||||||
|
}
|
||||||
else if (name.equals("size")) { // old style
|
else if (name.equals("size")) { // old style
|
||||||
alignment = SpecXmlUtils.decodeInt(entry.getValue());
|
alignment = SpecXmlUtils.decodeInt(entry.getValue());
|
||||||
}
|
}
|
||||||
else if (name.equals("align")) // New style
|
else if (name.equals("align")) {
|
||||||
alignment = SpecXmlUtils.decodeInt(entry.getValue());
|
alignment = SpecXmlUtils.decodeInt(entry.getValue());
|
||||||
else if (name.equals("maxsize"))
|
}
|
||||||
|
else if (name.equals("maxsize")) {
|
||||||
size = SpecXmlUtils.decodeInt(entry.getValue());
|
size = SpecXmlUtils.decodeInt(entry.getValue());
|
||||||
|
}
|
||||||
else if (name.equals("metatype")) { // Not implemented at the moment
|
else if (name.equals("metatype")) { // Not implemented at the moment
|
||||||
String meta = entry.getValue();
|
String meta = entry.getValue();
|
||||||
// TODO: Currently only supporting "float", "ptr", and "unknown" metatypes
|
// TODO: Currently only supporting "float", "ptr", and "unknown" metatypes
|
||||||
|
@ -333,41 +377,52 @@ public class ParamEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name.equals("group")) // Override the group
|
else if (name.equals("group")) {
|
||||||
group = SpecXmlUtils.decodeInt(entry.getValue());
|
group = SpecXmlUtils.decodeInt(entry.getValue());
|
||||||
else if (name.equals("groupsize"))
|
}
|
||||||
|
else if (name.equals("groupsize")) {
|
||||||
groupsize = SpecXmlUtils.decodeInt(entry.getValue());
|
groupsize = SpecXmlUtils.decodeInt(entry.getValue());
|
||||||
|
}
|
||||||
else if (name.equals("extension")) {
|
else if (name.equals("extension")) {
|
||||||
flags &= ~(SMALLSIZE_ZEXT | SMALLSIZE_SEXT | SMALLSIZE_INTTYPE);
|
flags &= ~(SMALLSIZE_ZEXT | SMALLSIZE_SEXT | SMALLSIZE_INTTYPE);
|
||||||
String value = entry.getValue();
|
String value = entry.getValue();
|
||||||
if (value.equals("sign"))
|
if (value.equals("sign")) {
|
||||||
flags |= SMALLSIZE_SEXT;
|
flags |= SMALLSIZE_SEXT;
|
||||||
else if (value.equals("zero"))
|
}
|
||||||
|
else if (value.equals("zero")) {
|
||||||
flags |= SMALLSIZE_ZEXT;
|
flags |= SMALLSIZE_ZEXT;
|
||||||
else if (value.equals("inttype"))
|
}
|
||||||
|
else if (value.equals("inttype")) {
|
||||||
flags |= SMALLSIZE_INTTYPE;
|
flags |= SMALLSIZE_INTTYPE;
|
||||||
else if (value.equals("float"))
|
}
|
||||||
|
else if (value.equals("float")) {
|
||||||
flags |= SMALLSIZE_FLOAT;
|
flags |= SMALLSIZE_FLOAT;
|
||||||
else if (!value.equals("none"))
|
}
|
||||||
|
else if (!value.equals("none")) {
|
||||||
throw new XmlParseException("Bad extension attribute: "+value);
|
throw new XmlParseException("Bad extension attribute: "+value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
throw new XmlParseException("Unknown paramentry attribute: "+name);
|
throw new XmlParseException("Unknown paramentry attribute: "+name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (minsize < 1 || size < minsize)
|
if (minsize < 1 || size < minsize) {
|
||||||
throw new XmlParseException(
|
throw new XmlParseException(
|
||||||
"paramentry size not specified properly: minsize=" + minsize + " maxsize=" + size);
|
"paramentry size not specified properly: minsize=" + minsize + " maxsize=" + size);
|
||||||
if (alignment == size)
|
}
|
||||||
|
if (alignment == size) {
|
||||||
alignment = 0;
|
alignment = 0;
|
||||||
|
}
|
||||||
|
|
||||||
readXMLAddress(parser, cspec, size);
|
readXMLAddress(parser, cspec, size);
|
||||||
|
|
||||||
boolean isbigendian = cspec.getLanguage().isBigEndian();
|
boolean isbigendian = cspec.getLanguage().isBigEndian();
|
||||||
if (isbigendian)
|
if (isbigendian) {
|
||||||
flags |= IS_BIG_ENDIAN;
|
flags |= IS_BIG_ENDIAN;
|
||||||
|
}
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
if ((addressbase % alignment) != 0)
|
// if ((addressbase % alignment) != 0)
|
||||||
throw new XmlParseException("Stack <pentry> address must match alignment");
|
// throw new XmlParseException("Stack <pentry> address must match alignment");
|
||||||
numslots = size / alignment;
|
numslots = size / alignment;
|
||||||
}
|
}
|
||||||
if (spaceid.isStackSpace() && (!cspec.isStackRightJustified()) && isbigendian) {
|
if (spaceid.isStackSpace() && (!cspec.isStackRightJustified()) && isbigendian) {
|
||||||
|
@ -376,8 +431,9 @@ public class ParamEntry {
|
||||||
if (!normalstack) {
|
if (!normalstack) {
|
||||||
flags |= REVERSE_STACK;
|
flags |= REVERSE_STACK;
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
if ((size % alignment) != 0)
|
if ((size % alignment) != 0) {
|
||||||
throw new XmlParseException("For positive stack growth, <pentry> size must match alignment");
|
throw new XmlParseException("For positive stack growth, <pentry> size must match alignment");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// resolveJoin
|
// resolveJoin
|
||||||
|
@ -407,24 +463,34 @@ public class ParamEntry {
|
||||||
* @return the endian aware offset or -1
|
* @return the endian aware offset or -1
|
||||||
*/
|
*/
|
||||||
public static int justifiedContainAddress(AddressSpace spc1,long offset1,int sz1,AddressSpace spc2,long offset2,int sz2,boolean forceleft,boolean isBigEndian) {
|
public static int justifiedContainAddress(AddressSpace spc1,long offset1,int sz1,AddressSpace spc2,long offset2,int sz2,boolean forceleft,boolean isBigEndian) {
|
||||||
if (spc1 != spc2) return -1;
|
if (spc1 != spc2) {
|
||||||
if (unsignedCompare(offset2,offset1)) return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
if (unsignedCompare(offset2,offset1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
long off1 = offset1 + (sz1 - 1);
|
long off1 = offset1 + (sz1 - 1);
|
||||||
long off2 = offset2 + (sz2 - 1);
|
long off2 = offset2 + (sz2 - 1);
|
||||||
if (unsignedCompare(off1,off2)) return -1;
|
if (unsignedCompare(off1,off2)) {
|
||||||
if (isBigEndian && (!forceleft))
|
return -1;
|
||||||
|
}
|
||||||
|
if (isBigEndian && (!forceleft)) {
|
||||||
return (int)(off1 - off2);
|
return (int)(off1 - off2);
|
||||||
|
}
|
||||||
return (int)(offset2 - offset1);
|
return (int)(offset2 - offset1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMetatype(DataType tp) {
|
public static int getMetatype(DataType tp) {
|
||||||
// TODO: A complete metatype implementation
|
// TODO: A complete metatype implementation
|
||||||
if (tp instanceof TypeDef)
|
if (tp instanceof TypeDef) {
|
||||||
tp = ((TypeDef)tp).getBaseDataType();
|
tp = ((TypeDef)tp).getBaseDataType();
|
||||||
if (tp instanceof AbstractFloatDataType)
|
}
|
||||||
|
if (tp instanceof AbstractFloatDataType) {
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
if (tp instanceof Pointer)
|
}
|
||||||
|
if (tp instanceof Pointer) {
|
||||||
return TYPE_PTR;
|
return TYPE_PTR;
|
||||||
|
}
|
||||||
return TYPE_UNKNOWN;
|
return TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<register name="o5"/>
|
<register name="o5"/>
|
||||||
</pentry>
|
</pentry>
|
||||||
<pentry minsize="1" maxsize="500" align="8">
|
<pentry minsize="1" maxsize="500" align="8">
|
||||||
<addr offset="8" space="stack"/>
|
<addr offset="0x8af" space="stack"/> <!-- Big offset is due to SPARC 64-bit "stack bias" -->
|
||||||
</pentry>
|
</pentry>
|
||||||
</input>
|
</input>
|
||||||
<output>
|
<output>
|
||||||
|
@ -63,6 +63,10 @@
|
||||||
<register name="sp"/>
|
<register name="sp"/>
|
||||||
<register name="didrestore"/>
|
<register name="didrestore"/>
|
||||||
</unaffected>
|
</unaffected>
|
||||||
|
<localrange>
|
||||||
|
<range space="stack" first="0xfff0bdc1" last="0xffffffff"/>
|
||||||
|
<range space="stack" first="0x0" last="0x8ae"/> <!-- Stack bias of 7FF + 0xb0 window size -->
|
||||||
|
</localrange>
|
||||||
</prototype>
|
</prototype>
|
||||||
</default_proto>
|
</default_proto>
|
||||||
|
|
||||||
|
@ -87,7 +91,7 @@
|
||||||
<register name="g6"/>
|
<register name="g6"/>
|
||||||
</pentry>
|
</pentry>
|
||||||
<pentry minsize="1" maxsize="500" align="8">
|
<pentry minsize="1" maxsize="500" align="8">
|
||||||
<addr offset="8" space="stack"/>
|
<addr offset="0x8af" space="stack"/> <!-- Big offset is due to SPARC 64-bit "stack bias" -->
|
||||||
</pentry>
|
</pentry>
|
||||||
</input>
|
</input>
|
||||||
<output>
|
<output>
|
||||||
|
@ -123,5 +127,9 @@
|
||||||
<register name="sp"/>
|
<register name="sp"/>
|
||||||
<register name="didrestore"/>
|
<register name="didrestore"/>
|
||||||
</unaffected>
|
</unaffected>
|
||||||
|
<localrange>
|
||||||
|
<range space="stack" first="0xfff0bdc1" last="0xffffffff"/>
|
||||||
|
<range space="stack" first="0x0" last="0x8ae"/> <!-- Stack bias of 7FF + 0xb0 window size -->
|
||||||
|
</localrange>
|
||||||
</prototype>
|
</prototype>
|
||||||
</compiler_spec>
|
</compiler_spec>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue