GT-3034 improved sleigh compiler error checking for address spaces and

variable definition
This commit is contained in:
ghidra1 2019-07-25 16:58:22 -04:00
parent 4ae98f93c8
commit 6d4908f0cd
4 changed files with 62 additions and 24 deletions

View file

@ -20,6 +20,7 @@ scope Block {
@header { @header {
import generic.stl.Pair; import generic.stl.Pair;
import generic.stl.VectorSTL; import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.opcodes.OpCode; import ghidra.pcodeCPort.opcodes.OpCode;
import ghidra.pcodeCPort.semantics.*; import ghidra.pcodeCPort.semantics.*;
import ghidra.pcodeCPort.slgh_compile.*; import ghidra.pcodeCPort.slgh_compile.*;
@ -445,7 +446,15 @@ wordsizemod
varnodedef varnodedef
: ^(OP_VARNODE s=space_symbol["varnode definition"] offset=integer size=integer l=identifierlist) { : ^(OP_VARNODE s=space_symbol["varnode definition"] offset=integer size=integer l=identifierlist) {
sc.defineVarnodes(s, $offset.value.longValue(), $size.value.longValue(), l.first, l.second); if (offset.bitLength() > 64) {
throw new SleighError("Unsupported offset: " + String.format("0x\%x", offset),
l.second.get(0));
}
if (size.bitLength() >= 32) {
throw new SleighError("Unsupported size: " + String.format("0x\%x", size),
l.second.get(0));
}
sc.defineVarnodes(s, $offset.value.longValue(), $size.value.intValue(), l.first, l.second);
} }
; ;

View file

@ -779,6 +779,14 @@ public class SleighCompile extends SleighBase {
return true; return true;
} }
private int bitsConsumedByUnitSize(int ws) {
int cnt = 0;
for (int test = ws - 1; test != 0; test >>= 1) {
++cnt;
}
return cnt;
}
public void newSpace(Location location, SpaceQuality qual) { public void newSpace(Location location, SpaceQuality qual) {
entry("newSpace", location, qual); entry("newSpace", location, qual);
if (qual.size == 0) { if (qual.size == 0) {
@ -786,6 +794,19 @@ public class SleighCompile extends SleighBase {
return; return;
} }
if (qual.size <= 0 || qual.size > 8) {
throw new SleighError("Space " + qual.name + " has unsupported size: " + 16, location);
}
if (qual.wordsize < 1 || qual.wordsize > 8) {
throw new SleighError(
"Space " + qual.name + " has unsupported wordsize: " + qual.wordsize, location);
}
int addressBits = bitsConsumedByUnitSize(qual.wordsize) + (8 * qual.size);
if (addressBits > 64) {
throw new SleighError("Space " + qual.name + " has unsupported dimensions, requires " +
addressBits + "-bits (limit is 64-bits)", location);
}
int delay = (qual.type == space_class.register_space) ? 0 : 1; int delay = (qual.type == space_class.register_space) ? 0 : 1;
AddrSpace spc = new AddrSpace(this, spacetype.IPTR_PROCESSOR, qual.name, qual.size, AddrSpace spc = new AddrSpace(this, spacetype.IPTR_PROCESSOR, qual.name, qual.size,
qual.wordsize, numSpaces(), AddrSpace.hasphysical, delay); qual.wordsize, numSpaces(), AddrSpace.hasphysical, delay);
@ -815,7 +836,7 @@ public class SleighCompile extends SleighBase {
alignment = val; alignment = val;
} }
public void defineVarnodes(SpaceSymbol spacesym, long off, long size, VectorSTL<String> names, public void defineVarnodes(SpaceSymbol spacesym, long off, int size, VectorSTL<String> names,
VectorSTL<Location> locations) { VectorSTL<Location> locations) {
entry("defineVarnodes", spacesym, off, size, names, locations); entry("defineVarnodes", spacesym, off, size, names, locations);
AddrSpace spc = spacesym.getSpace(); AddrSpace spc = spacesym.getSpace();
@ -823,7 +844,7 @@ public class SleighCompile extends SleighBase {
for (int i = 0; i < names.size(); ++i) { for (int i = 0; i < names.size(); ++i) {
Location location = locations.get(i); Location location = locations.get(i);
if (!"_".equals(names.get(i))) { if (!"_".equals(names.get(i))) {
addSymbol(new VarnodeSymbol(location, names.get(i), spc, myoff, (int) size)); addSymbol(new VarnodeSymbol(location, names.get(i), spc, myoff, size));
} }
myoff += size; myoff += size;
} }
@ -1537,7 +1558,8 @@ public class SleighCompile extends SleighBase {
entry("buildMacro", sym, rtl); entry("buildMacro", sym, rtl);
String errstring = checkSymbols(symtab.getCurrentScope()); String errstring = checkSymbols(symtab.getCurrentScope());
if (errstring.length() != 0) { if (errstring.length() != 0) {
reportError(sym.getLocation(), " in definition of macro " + sym.getName() + ":" + errstring); reportError(sym.getLocation(),
" in definition of macro " + sym.getName() + ":" + errstring);
return; return;
} }
if (!expandMacros(rtl)) { if (!expandMacros(rtl)) {

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* 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.
@ -16,6 +15,11 @@
*/ */
package ghidra.pcodeCPort.slghsymbol; package ghidra.pcodeCPort.slghsymbol;
import java.io.PrintStream;
import org.jdom.Element;
import generic.util.UnsignedDataUtils;
// A global varnode // A global varnode
import ghidra.pcodeCPort.context.*; import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.pcoderaw.VarnodeData; import ghidra.pcodeCPort.pcoderaw.VarnodeData;
@ -26,10 +30,6 @@ import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.utils.XmlUtils; import ghidra.pcodeCPort.utils.XmlUtils;
import ghidra.sleigh.grammar.Location; import ghidra.sleigh.grammar.Location;
import java.io.PrintStream;
import org.jdom.Element;
public class VarnodeSymbol extends PatternlessSymbol { public class VarnodeSymbol extends PatternlessSymbol {
private VarnodeData fix = new VarnodeData(); private VarnodeData fix = new VarnodeData();
@ -65,12 +65,18 @@ public class VarnodeSymbol extends PatternlessSymbol {
public VarnodeSymbol(Location location, String nm, AddrSpace base, long offset, int size) { public VarnodeSymbol(Location location, String nm, AddrSpace base, long offset, int size) {
super(location, nm); super(location, nm);
int addrSize = base.getAddrSize(); int addrSize = base.getAddrSize();
long offsetTooBig = 1; long maxByteOffset = ((long) base.getWordSize() << (8 * addrSize)) - 1;
offsetTooBig <<= (8 * addrSize); long endOffset = offset + size - 1;
if (offset >= offsetTooBig) { boolean sizeError = size != 0 && UnsignedDataUtils.unsignedGreaterThan(offset, endOffset);
throw new SleighError("offset " + String.format("0x%x", offset) + if (!sizeError && addrSize < 8) {
" is too large for space " + base.getName(), location); sizeError = UnsignedDataUtils.unsignedGreaterThan(endOffset, maxByteOffset);
} }
if (sizeError) {
throw new SleighError(nm + ":" + size + " @ " + base.getName() + ":" +
String.format("0x%x", offset) + " extends beyond end of space (max offset is " +
String.format("0x%x", maxByteOffset) + ")", location);
}
fix.space = base; fix.space = base;
fix.offset = offset; fix.offset = offset;
fix.size = size; fix.size = size;
@ -78,8 +84,9 @@ public class VarnodeSymbol extends PatternlessSymbol {
@Override @Override
public VarnodeTpl getVarnode() { public VarnodeTpl getVarnode() {
return new VarnodeTpl(location, new ConstTpl(fix.space), new ConstTpl( return new VarnodeTpl(location, new ConstTpl(fix.space),
ConstTpl.const_type.real, fix.offset), new ConstTpl(ConstTpl.const_type.real, fix.size)); new ConstTpl(ConstTpl.const_type.real, fix.offset),
new ConstTpl(ConstTpl.const_type.real, fix.size));
} }
@Override @Override

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* 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.
@ -16,11 +15,6 @@
*/ */
package ghidra.pcodeCPort.space; package ghidra.pcodeCPort.space;
import ghidra.pcodeCPort.error.LowlevelError;
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.*;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -56,6 +50,11 @@ import org.jdom.Element;
/// as a pool for temporary registers. (See UniqueSpace) /// as a pool for temporary registers. (See UniqueSpace)
/// ///
import ghidra.pcodeCPort.error.LowlevelError;
import ghidra.pcodeCPort.pcoderaw.VarnodeData;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.pcodeCPort.utils.*;
public class AddrSpace { public class AddrSpace {
public static final AddrSpace MIN_SPACE = new AddrSpace("MIN_SPACE", -1); public static final AddrSpace MIN_SPACE = new AddrSpace("MIN_SPACE", -1);
@ -82,7 +81,8 @@ public class AddrSpace {
this.index = index; this.index = index;
} }
public AddrSpace(Translate t, spacetype tp, String nm, int size, int ws, int ind, int fl, int dl) { public AddrSpace(Translate t, spacetype tp, String nm, int size, int ws, int ind, int fl,
int dl) {
trans = t; trans = t;
type = tp; type = tp;
name = nm; name = nm;
@ -155,7 +155,7 @@ public class AddrSpace {
return index; return index;
} }
int getWordSize() { public int getWordSize() {
return wordsize; return wordsize;
} }