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 {
import generic.stl.Pair;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.opcodes.OpCode;
import ghidra.pcodeCPort.semantics.*;
import ghidra.pcodeCPort.slgh_compile.*;
@ -445,7 +446,15 @@ wordsizemod
varnodedef
: ^(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;
}
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) {
entry("newSpace", location, qual);
if (qual.size == 0) {
@ -786,6 +794,19 @@ public class SleighCompile extends SleighBase {
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;
AddrSpace spc = new AddrSpace(this, spacetype.IPTR_PROCESSOR, qual.name, qual.size,
qual.wordsize, numSpaces(), AddrSpace.hasphysical, delay);
@ -815,7 +836,7 @@ public class SleighCompile extends SleighBase {
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) {
entry("defineVarnodes", spacesym, off, size, names, locations);
AddrSpace spc = spacesym.getSpace();
@ -823,7 +844,7 @@ public class SleighCompile extends SleighBase {
for (int i = 0; i < names.size(); ++i) {
Location location = locations.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;
}
@ -1537,7 +1558,8 @@ public class SleighCompile extends SleighBase {
entry("buildMacro", sym, rtl);
String errstring = checkSymbols(symtab.getCurrentScope());
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;
}
if (!expandMacros(rtl)) {

View file

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

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,11 +15,6 @@
*/
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.util.StringTokenizer;
@ -56,6 +50,11 @@ import org.jdom.Element;
/// 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 static final AddrSpace MIN_SPACE = new AddrSpace("MIN_SPACE", -1);
@ -82,7 +81,8 @@ public class AddrSpace {
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;
type = tp;
name = nm;
@ -155,7 +155,7 @@ public class AddrSpace {
return index;
}
int getWordSize() {
public int getWordSize() {
return wordsize;
}