//-------------------------------------------------------------------------------------------------- // // @ CopyRight Roberti & Parau Enterprises, Inc. 2021-2023 // // This work is licensed under the Creative Commons Attribution-NoDerivatives 4.0 International License. // To view a copy of this license, visit http://creativecommons.org/licenses/by-nd/4.0/ // or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. // //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- // // Utilities static methods // //-------------------------------------------------------------------------------------------------- package framework; import java.util.*; import java.math.BigInteger; import java.net.URL; public class DVUtil { // // Check expression token is ABSOLUTE boolean // public static boolean checkBoolean(DVExpression.ExprToken et) { return (et.type != DVExpression.TokenType.ABSOLUTE || (! et.intConstant.equals(BigInteger.ZERO) && ! et.intConstant.equals(BigInteger.ONE))); } // // Verify section name // public static boolean verifySectionName(DVStatements.Statement owner, String name) { if (name.startsWith(".rel")) return owner.putErrorFalse("Section names starting with [.rel] are reserved"); for (String s : sectionReservedNames) if (s.equals(name)) return owner.putErrorFalse("Section name [" + name + "] is reserved"); return true; } // // Verify section type // public static boolean verifySectionType(BigInteger typeValue) { return (typeValue.equals(DVUtil.sectionTypeProgbits) || typeValue.equals(DVUtil.sectionTypeNote) || typeValue.equals(DVUtil.sectionTypeNobits)); } // // Verify section attribute // public static boolean verifySectionAttribute(BigInteger attributeValue) { return attributeValue.and(DVUtil.sectionAttributeMask).equals(attributeValue); } // // Verify symbol bind // public static boolean verifyExternalSymbolBind(BigInteger bind) { return bind.equals(DVUtil.symbolBindGlobal) || bind.equals(DVUtil.symbolBindWeak); } public static boolean verifyExportedSymbolBind(BigInteger bind) { return bind.equals(DVUtil.symbolBindGlobal); } // // Verify symbol type // public static boolean verifySymbolType(BigInteger type) { return type.equals(DVUtil.symbolTypeNoType) || type.equals(DVUtil.symbolTypeObject) || type.equals(DVUtil.symbolTypeFunc); } // // Format java exception // public static String formatException(String title, Exception e) { String msg= title + "\n" + e.toString(); StackTraceElement[] stackTrace= e.getStackTrace(); for (StackTraceElement s : stackTrace) msg+= "\n" + s.toString(); return msg; } // // Format java error // public static String formatError(String title, Error e) { String msg= title + "\n" + e.toString(); StackTraceElement[] stackTrace= e.getStackTrace(); for (StackTraceElement s : stackTrace) msg+= "\n" + s.toString(); return msg; } // // Return file where class is located - if JAR the JAR file name is returned // public static boolean isClassInJar(Class klass) { return klass.getResource('/' + klass.getName().replace('.', '/') + ".class").toString().startsWith("jar:file:"); } // // Return file where class is located - if JAR the JAR file name is returned // public static URL getClassLocation(Class klass) { return klass.getProtectionDomain().getCodeSource().getLocation(); } // // Verify overflow // public static boolean verifyOverflow(byte[] bytes, int maxLength) { if (bytes.length <= maxLength) return true; return bytes.length == maxLength+1 && bytes[0] == 0; } // // Add integer(s) to code // public static int addIntegerToCode(byte[] code, int offset, int integer, DVUtil.Endianness endianness) { if (endianness == DVUtil.Endianness.BIG) { code[offset]= Integer.valueOf((integer >> 24) & 0xFF).byteValue(); code[offset+1]= Integer.valueOf((integer >> 16) & 0xFF).byteValue(); code[offset+2]= Integer.valueOf((integer >> 8) & 0xFF).byteValue(); code[offset+3]= Integer.valueOf(integer & 0xFF).byteValue(); return offset+4; } code[offset]= Integer.valueOf(integer & 0xFF).byteValue(); code[offset+1]= Integer.valueOf((integer >> 8) & 0xFF).byteValue(); code[offset+2]= Integer.valueOf((integer >> 16) & 0xFF).byteValue(); code[offset+3]= Integer.valueOf((integer >> 24) & 0xFF).byteValue(); return offset+4; } // // Add integer(s) to code // public static int addHalfIntegerToCode(byte[] code, int offset, int integer, DVUtil.Endianness endianness) { if (endianness == DVUtil.Endianness.BIG) { code[offset]= Integer.valueOf((integer >> 8) & 0xFF).byteValue(); code[offset+1]= Integer.valueOf(integer & 0xFF).byteValue(); return offset+2; } code[offset]= Integer.valueOf(integer & 0xFF).byteValue(); code[offset+1]= Integer.valueOf((integer >> 8) & 0xFF).byteValue(); return offset+2; } // // Add code in bitInteger and pad it if necessary // public static int addCode(byte[] code, int offset, byte[] newCode, int length, int repl, DVUtil.Endianness endianness) { if (repl == 0) return offset; int newCodeLength= newCode.length; int padLength= length-newCodeLength; if (padLength > 0) { byte padByte= newCode[0] >= 0 ? (byte) 0x00 : (byte) 0xFF; if (endianness == DVUtil.Endianness.LITTLE) { int padOffset= offset+length-padLength; for (int i= 0; i < padLength; i++) code[padOffset+i]= padByte; int copyOffset= offset+newCodeLength-1; for (int i= 0; i < newCodeLength; i++) code[copyOffset-i]= newCode[i]; } else { for (int i= 0; i < padLength; i++) code[offset+i]= padByte; System.arraycopy(newCode, padLength, code, offset+padLength, newCodeLength-padLength); } } else if (padLength == 0){ if (endianness == DVUtil.Endianness.LITTLE) { int copyOffset= offset+length-1; for (int i= 0; i < length; i++) code[copyOffset-i]= newCode[i]; } else System.arraycopy(newCode, padLength, code, offset+padLength, newCodeLength-padLength); } else { int skipStart= -padLength; if (endianness == DVUtil.Endianness.LITTLE){ int targetOffset= offset+length+skipStart-1; for (int i= skipStart; i < newCodeLength; i++) code[targetOffset-i]= newCode[i]; } else System.arraycopy(newCode, skipStart, code, offset, length); } if (repl < 2) return offset+length; int targetOffset= offset+length; for (int i= 1; i < repl; i++) { System.arraycopy(code, offset, code, targetOffset, length); targetOffset+= length; } return targetOffset; } // // Convert binary code to hex with sign, padding and direction // public static String convertCodeToHex(byte[] code, int length, boolean forward) { byte[] hex= new byte[length*2]; byte[] hexConv= DVUtil.hexConv; int s= Math.max(code.length-length, 0); int p= Math.max((length-code.length)*2, 0); if (forward) { int j; for (j= 0; j < p; j+= 2) { hex[j]= '0'; hex[j+1]= '0'; } for (int i= s; i < code.length; i++) { int k= (int) code[i]; hex[j]= hexConv[(k >> 4) & 0x0F]; hex[j+1]= hexConv[k & 0x0F]; j+= 2; } } else { int j; for (j= hex.length-2; j >= hex.length-p; j-= 2) { hex[j]= '0'; hex[j+1]= '0'; } for (int i= s; i < code.length; i++) { int k= (int) code[i]; hex[j]= hexConv[(k >> 4) & 0x0F]; hex[j+1]= hexConv[k & 0x0F]; j-= 2; } } return new String(hex); } // // Convert binary code to hex with padding and direction starting at offset // public static String convertCodeToHex(byte[] code, int offset, int length, boolean forward) { byte[] hex= new byte[length*2]; byte[] hexConv= DVUtil.hexConv; int s= Math.min(code.length, offset); int p= Math.max(offset+length-code.length, 0); length-= p; p*= 2; if (forward) { int j; for (j= 0; j < p; j+= 2) { hex[j]= '0'; hex[j+1]= '0'; } for (int i= s; i < s+length; i++) { int k= (int) code[i]; hex[j]= hexConv[(k >> 4) & 0x0F]; hex[j+1]= hexConv[k & 0x0F]; j+= 2; } } else { int j; for (j= hex.length-2; j >= hex.length-p; j-= 2) { hex[j]= '0'; hex[j+1]= '0'; } for (int i= s; i < s+length; i++) { int k= (int) code[i]; hex[j]= hexConv[(k >> 4) & 0x0F]; hex[j+1]= hexConv[k & 0x0F]; j-= 2; } } return new String(hex); } // // Convert binary code - plain // public static String convertCodeToHexPlain(byte[] code) { return DVUtil.convertCodeToHexPlain(code, code.length); } public static String convertCodeToHexPlain(byte[] code, int length) { length= Math.min(length, code.length); byte[] hex= new byte[length*2]; byte[] hexConv= DVUtil.hexConv; int j= 0; for (int i= 0; i < length; i++) { int k= (int) code[i]; hex[j]= hexConv[(k >> 4) & 0x0F]; hex[j+1]= hexConv[k & 0x0F]; j+= 2; } return new String(hex); } // // Format BigInteger to HEX // public static String formatHex(int n, int minWidth) { return DVUtil.formatHex(BigInteger.valueOf(n), minWidth); } public static String formatHex(BigInteger n, int minWidth) { if (n == null) return String.format("%" + Integer.toString(minWidth) + "s", ""); String field= DVUtil.convertCodeToHexPlain(n.toByteArray()); int pl= minWidth-field.length(); if (pl == 0) return field; char pad= '0'; if (n.compareTo(BigInteger.ZERO) < 0) pad= 'F'; if (pl > 0) { for (int i= 0; i < pl; i++) field= pad + field; return field; } pl= -pl; int i; for (i= 0; i < pl; i+=2) { if (field.charAt(i) != pad || field.charAt(i+1) != pad) return field.substring(i); } return field.substring(pl); } // // Format binary integer // public static String formatBinary(int n, int length, int mask) { String fmt= ""; for (int i=0; i < length; i++) { if ((mask & 1) == 1) fmt= ((n & 1) == 1 ? "1" : "0") + fmt; else fmt= "." + fmt; n= n >> 1; mask= mask >> 1; } return fmt; } //---------------------------------------------------------------------------------------------- // // Methods used by architecture modules // //---------------------------------------------------------------------------------------------- // // Get register operand // public static Long getRegister(DVStatements.Statement owner, int regBitLen, int parmNo) { return getRegister(owner, regBitLen, null, parmNo, null); } public static Long getRegister(DVStatements.Statement owner, int regBitLen, BigInteger[] exclList, int parmNo) { return getRegister(owner, regBitLen, exclList, parmNo, null); } public static Long getRegister(DVStatements.Statement owner, int regBitLen, int parmNo, Integer subParmNo) { return getRegister(owner, regBitLen, null, parmNo, subParmNo); } public static Long getRegister(DVStatements.Statement owner, int regBitLen, BigInteger[] exclList, int parmNo, Integer subParmNo) { DVExpression.ExprToken regToken; if (subParmNo == null) regToken= owner.getOpCodeParm().getPositionalParameterValue(parmNo); else regToken= owner.getOpCodeParm().getSubParmList(parmNo)[subParmNo].getSubParmValue(); if (regToken.getType() != DVExpression.TokenType.ABSOLUTE) { if (subParmNo == null) owner.putError("Register value for operand [%d] resolves to [%s] - must resolve to ABSOLUTE", parmNo+1, regToken.getType().name()); else owner.putError("Register value for operand [%d], sub-parm [%d] resolves to [%s] - must resolve to ABSOLUTE", parmNo+1, subParmNo+1, regToken.getType().name()); return null; } BigInteger reg= regToken.getIntConstant(); if (reg.compareTo(BigInteger.ZERO) < 0 || reg.bitLength() > regBitLen) { if (subParmNo == null) owner.putError("Register value [%s] for operand [%d] is out of range [0-%d]", reg.toString(), parmNo+1, 1 << (regBitLen-1)); else owner.putError("Register value [%s] for operand [%d], sub-parm [%d] is out of range [0-%d]", reg.toString(), parmNo+1, subParmNo+1, 1 << (regBitLen-1)); return null; } if (exclList != null) { for (int i= 0; i < exclList.length; i++) { if (reg.equals(exclList[i])) { if (subParmNo == null) owner.putError("Register value [%s] for operand [%d] is invalid", reg.toString(), parmNo+1); else owner.putError("Register value [%s] for operand [%d], sub-parm [%d] is invalid", reg.toString(), parmNo+1, subParmNo+1); } } } return reg.longValue(); } // // Get immediate operand - caller must check that operand exists // public static DVImmediateOperand getImmediate(DVStatements.Statement owner, int parmNo, Integer subParmNo, int maxBits, boolean signed, EnumSet immType) { return getImmediate(owner, parmNo, subParmNo, "Immediate", maxBits, signed, immType); } public static DVImmediateOperand getImmediate(DVStatements.Statement owner, int parmNo, int maxBits, boolean signed, EnumSet immType) { return getImmediate(owner, parmNo, null, "Immediate", maxBits, signed, immType); } public static DVImmediateOperand getImmediate(DVStatements.Statement owner, int parmNo, String name, int maxBits, boolean signed, EnumSet immType) { return getImmediate(owner, parmNo, null, name, maxBits, signed, immType); } public static DVImmediateOperand getImmediate(DVStatements.Statement owner, int parmNo, Integer subParmNo, String name, int maxBits, boolean signed, EnumSet immType) { DVExpression.ExprToken immToken= owner.getOpCodeParm().getPositionalParameterValue(parmNo); if (immToken == null) { owner.putError("Immediate at positional parameter [%d] is missing\n", parmNo+1); return null; } if ((immToken.getType() == DVExpression.TokenType.ABSOLUTE || immToken.getType() == DVExpression.TokenType.DISPLACEMENT) && immType.contains(ImmType.INTEGER)) { BigInteger imm= immToken.getIntConstant(); if (verifyImmediate(owner, name, imm, maxBits, signed, immToken.getType()) == null) return null; return new DVImmediateOperand(ImmType.INTEGER, imm, null, null, null); } if ((immToken.getType() == DVExpression.TokenType.EXTERNAL_VALUE || (immToken.getType() == DVExpression.TokenType.OFFSET && immToken.qualifier != null)) && immType.contains(ImmType.EXTERNAL)) return new DVImmediateOperand(ImmType.EXTERNAL, immToken.intConstant, null, null, immToken); if (immToken.getType() == DVExpression.TokenType.OFFSET) { if (immType.contains(ImmType.BASEDSP)) { DVStatements.Base base; if ((base= owner.getBase(immToken.getOffsetSection(), immToken.getIntConstant(), false)) == null) { owner.putError(name + ": Unable to locate base register for location [%s]\n", immToken.getOffsetSection().getOwner().getSymbol().getName() + (immToken.getIntConstant().compareTo(BigInteger.ZERO) >= 0 ? "+" : "") + immToken.getIntConstant().toString(16)); return null; } BigInteger displacement= immToken.intConstant.subtract((base.offset)); if (verifyImmediate(owner, name, displacement, maxBits, signed, immToken.getType()) == null) return null; return new DVImmediateOperand(ImmType.BASEDSP, displacement, base.register.longValue(), immToken.intConstant, null); } if (immType.contains(ImmType.PCREL)) { if (! owner.getOwnerSection().equals(immToken.getOffsetSection())) { owner.putError(name + ": immediate offset is outside current section " + "and cannot be used to form a PC relative offset"); return null; } BigInteger offset= immToken.getIntConstant().subtract(owner.getOffset()); if (verifyImmediate(owner, name, offset, maxBits, signed, immToken.getType()) == null) return null; return new DVImmediateOperand(ImmType.PCREL, offset, null, immToken.intConstant, null); } } if (immToken.getType() == DVExpression.TokenType.BASE_DISPLACEMENT && immType.contains(ImmType.BASEDSP)) { DVStatements.Base base= owner.getBase(immToken.getBaseID()); if (base == null) { owner.putError(String.format(name + ": Unable to location Base with ID [%s]\n", immToken.getBaseID())); return null; } if (base.getSection() != immToken.getBaseSection()) { owner.putError(String.format(name + ": Section/MMap mismatch between Base ID [%s] for location [%s]\n", base.getID(), immToken.getOffsetSection().getOwner().getSymbol().getName() + (immToken.getIntConstant().compareTo(BigInteger.ZERO) >= 0 ? "+" : "") + immToken.getIntConstant().toString(16))); return null; } return new DVImmediateOperand(ImmType.BASEDSP, immToken.getIntConstant().subtract(base.getOffset()), base.getRegister().longValue(), immToken.intConstant, null); } owner.putError(name + ": resolve to type [%s] and is not of valid type", immToken.getType().name()); return null; } // // Check immediate value and convert it to long masked // public static Long verifyImmediate(DVStatements.Statement owner, String name, BigInteger immediate, int maxBits, boolean signed, DVExpression.TokenType type) { if (! signed && immediate.compareTo(BigInteger.ZERO) < 0) owner.putError(name + " is unsigned but value [%s] is negative", immediate.toString()); int bitLength= immediate.bitLength(); if (bitLength < maxBits) return immediate.longValue(); if (type == DVExpression.TokenType.ABSOLUTE && immediate.compareTo(BigInteger.ZERO) >= 0 && bitLength <= maxBits) return immediate.longValue(); owner.putError(name + " value [%s] is too wide", immediate.toString()); return null; } // // Validate keyWord parameters // public static int validateKeyWordList(DVStatements.Statement owner, DVOpCodeParm.KeyWordParm[] kwParmList, String[] keyWordList) { if (kwParmList.length > keyWordList.length) { owner.putError(String.format("Only %d optional key-word parameters are allowed", keyWordList.length)); return -1; } int n= 0; for (DVOpCodeParm.KeyWordParm kwParm : kwParmList) { int i; for (i= 0; i < keyWordList.length; i++) if (keyWordList[i].equals(kwParm.getKeyValue().toUpperCase())) break; if ( i > keyWordList.length) { String okList= ""; for (int j= 0; j < keyWordList.length; j++) okList+= " " + keyWordList[j]; owner.putError("Key word value [" + kwParm.getKeyValue() + "] must be any of: " + okList); return -1; } n++; } return n; } // // Get boolean value // public static Long getBooleanValue(DVStatements.Statement owner, int parmNo, Long defaultValue, String name) { return getBooleanValue(owner, parmNo, null, defaultValue, name); } public static Long getBooleanValue(DVStatements.Statement owner, int parmNo, Integer subParmNo, Long defaultValue, String name) { DVExpression.ExprToken regToken; if (subParmNo == null) regToken= owner.getOpCodeParm().getPositionalParameterValue(parmNo); else regToken= owner.getOpCodeParm().getSubParmList(parmNo)[subParmNo].getSubParmValue(); if (regToken == null && defaultValue != null) return defaultValue; if (regToken.getType() != DVExpression.TokenType.ABSOLUTE) { owner.putError(name + " resolve to [%s] - must resolve to ABSOLUTE", regToken.getType().name()); return null; } if (! regToken.getIntConstant().equals(BigInteger.ZERO) && regToken.getIntConstant().equals(BigInteger.ONE)) { owner.putError(name + " resolves to [%s] - must resolve to either ZERO or ONE", regToken.getIntConstant().toString()); return null; } return regToken.getIntConstant().longValue(); } // // Get set value // public static Long getSetValue(DVStatements.Statement owner, int parmNo, long[] set, boolean defaultFirst, String name) { return getSetValue(owner, parmNo, null, set, defaultFirst, name); } public static Long getSetValue(DVStatements.Statement owner, int parmNo, Integer subParmNo, long[] set, String name) { return getSetValue(owner, parmNo, subParmNo, set, false, name); } public static Long getSetValue(DVStatements.Statement owner, int parmNo, long[] set, String name) { return getSetValue(owner, parmNo, null, set, false, name); } public static Long getSetValue(DVStatements.Statement owner, int parmNo, Integer subParmNo, long[] set, boolean defaultFirst, String name) { DVExpression.ExprToken valueToken; if (subParmNo == null) valueToken= owner.getOpCodeParm().getPositionalParameterValue(parmNo); else valueToken= owner.getOpCodeParm().getSubParmList(parmNo)[subParmNo].getSubParmValue(); if (valueToken == null && defaultFirst) return set[0]; if (valueToken.getType() != DVExpression.TokenType.ABSOLUTE) { owner.putError(name + " resolve to [%s] - must resolve to ABSOLUTE", valueToken.getType().name()); return null; } BigInteger value= valueToken.getIntConstant(); boolean err= true; for (int i= 0; i < set.length; i++) { if (value.equals(BigInteger.valueOf(set[i]))) { err= false; break; } } if (! err) return value.longValue(); owner.putError(name + " resolves to [%s] - the value is invalid", value.toString()); return null; } // // Validate keyWord parameters // public static DVExpression.ExprToken[] getKeyWordTokenList(DVStatements.Statement owner, String[] keyWordList) { ArrayList parmList= owner.opCodeParm.keyWordParmList; DVExpression.ExprToken[] values= new DVExpression.ExprToken[keyWordList.length]; for (DVOpCodeParm.KeyWordParm keyWordParm : parmList) { for (int i= 0; i < keyWordList.length; i++) { if (keyWordList[i].equals(keyWordParm.keyValue.toUpperCase())) { values[i]= keyWordParm.value; break; } } } return values; } // // Get boolean keyword values // public static Long getBooleanKeyWordValue(DVStatements.Statement owner, int keyIndex, String name, Long defaultValue) { return DVUtil.getAbsoluteKeyWordValue(owner, keyIndex, name, 0, 0, booleanValueList, defaultValue); } public static Long getAbsoluteKeyWordValue(DVStatements.Statement owner, int keyIndex, String name, long min, long max, Long defaultValue) { return getAbsoluteKeyWordValue(owner, keyIndex, name, min, max, null, defaultValue); } public static Long getAbsoluteKeyWordValue(DVStatements.Statement owner, int keyIndex, String name, long[] valueList, long defaultValue) { return getAbsoluteKeyWordValue(owner, keyIndex, name, 0, 0, valueList, defaultValue); } public static Long getAbsoluteKeyWordValue(DVStatements.Statement owner, int keyIndex, String name, long min, long max, long[] valueList, Long defaultValue) { DVOpCodeParm.KeyWordParm keyParm= owner.getOpCodeParm().getKeyWordParm(keyIndex); if (keyParm == null || keyParm.getValue() == null) { if (defaultValue == null) owner.putError(name + " key-word parameter is missing but it is required"); return defaultValue; } DVExpression.ExprToken keyToken= keyParm.getValue(); if (keyToken.getType() != DVExpression.TokenType.ABSOLUTE) { owner.putError(name + " resolves to [%s] - only ABSOLUTE is allowed", keyToken.getType().name()); return null; } BigInteger keyValue= keyToken.getIntConstant(); if (valueList != null) { for (int i= 0; i < valueList.length; i++) { if (keyValue.equals(BigInteger.valueOf(valueList[i]))) return valueList[i]; } String list= ""; for (int i= 0; i < valueList.length; i++) list+= String.format("%d, ", valueList[i]); list= "[" + list.substring(0, list.length()-2) + "]"; owner.putError(name + " resolves to [%s] - only the following values are allowed %s", keyValue.toString(), list); } if (keyValue.compareTo(BigInteger.valueOf(min)) >= 0 && keyValue.compareTo(BigInteger.valueOf(max)) <= 0) return keyValue.longValue(); owner.putError(name + " resolves to [%s] and is out of range", keyValue.toString()); return null; } // // Escape Java string // public static String escapeString(String jstr) { String estr= ""; for (int i= 0; i < jstr.length(); i++) { int c= jstr.charAt(i); if (c < 127) { int x= "\t\b\n\r\f\'\"\\".indexOf(c); if (x >= 0) { estr+= "\\t\\b\\n\\r\\f\\'\\\"\\\\".substring(x*2, x*2+2); continue; } estr+= jstr.substring(i, i+1); continue; } estr+= String.format("\\u%04X", c); } return estr; } // // Escape Java string // public static String unescapeString(String estr) throws Exception { String jstr= ""; int i= 0; while (true) { int x= estr.indexOf('\\', i); if (x < 0) return jstr+estr.substring(i); jstr+= estr.substring(i, x); i= x; if (x == estr.length()-1) throw new Exception( String.format("String terminates with a single backlash [\\] character\nString\nString [%s]", estr)); char cf= estr.charAt(i+1); int k= "tbnrf\'\"\\".indexOf(cf); if (k >= 0) { jstr+= "\t\b\n\r\f\'\"\\".charAt(k); i+= 2; continue; } if (cf != 'u') throw new Exception(String.format("Character following backslash at position [%d] is an invalid character\n" + "String [%s]", i+1, estr)); if (i+6 > estr.length()) throw new Exception(String.format("Unicode escape at position [%d] is not followed by four character\n" + "String [%s]", i+1, estr)); try { cf= (char) Integer.parseInt(estr.substring(i+2, i+6), 16); } catch (Exception e) { throw new Exception(String.format("Unicode escape at position [%d] is not followed by four digits\n" + "String [%s]", i+1, estr)); } jstr+= cf; i+= 6; } } // // Expand extensible macro parameters // protected static String[] expandList(String parm) { String lowBound= ""; String highBound= ""; int lb; int hb; int lbLength; int hbLength; int prefixLength; String[] ret= new String[1]; ret[0]= parm; int i= parm.length()-1; char c= 'a'; for (; i >= 0; i-- ) { c= parm.charAt(i); if (c < '0' || c > '9') break; highBound= c + highBound; } if (highBound.length() == 0 || i < 0 || c != '-') return ret; hbLength= parm.length()-i-1; for (i--; i >= 0; i-- ) { c= parm.charAt(i); if (c < '0' || c > '9') break; lowBound= c + lowBound; } if (lowBound.length() == 0 || i < 0) return ret; lbLength= parm.length()-hbLength-i-2; prefixLength= parm.length()-lbLength-hbLength-1; lb= Integer.valueOf(lowBound); hb= Integer.valueOf(highBound); int n= hb-lb+1; if (n <= 1 || prefixLength == 0) return ret; ret= new String[n]; ret[0]= parm.substring(0, prefixLength+lbLength); String format= parm.substring(0, prefixLength) + "%0" + Integer.toString(lbLength) + "d"; for (i= 1; i < n; i++) ret[i]= String.format(format, i+lb); return ret; } // // Constant array used to convert to hex // private final static byte[] hexConv= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private final static long[] booleanValueList= new long[] { 0, 1 }; // // Enumeration subsets for expression token type use by getImmediate // public static enum ImmType { INTEGER, BASEDSP, PCREL, EXTERNAL } // // Endianness enumeration // public static enum Endianness { BIG, LITTLE, UNDEFINED } // // Constants // public final static BigInteger max32BitUnsigned= BigInteger.valueOf(0xFFFFFFFF); public final static BigInteger max32BitSigned= BigInteger.valueOf(0x7FFFFFFF); public final static BigInteger min32BitSigned= BigInteger.valueOf(-(1<<31)); public final static BigInteger max64BitUnsigned= BigInteger.valueOf(0xFFFFFFFFFFFFFFFFL); public final static BigInteger max64BitSigned= BigInteger.valueOf(0x7FFFFFFFFFFFFFFFL); public final static BigInteger min64BitSigned= BigInteger.valueOf(-(1<<63)); public final static String[] sectionReservedNames= { ".dynamic", ".dynstr", ".dynsym", ".hash", ".shstrtab", ".strtab", ".symtab" }; public final static BigInteger sectionTypeNull= BigInteger.ZERO; public final static BigInteger sectionTypeProgbits= BigInteger.ONE; public final static BigInteger sectionTypeSymtab= BigInteger.valueOf(2); public final static BigInteger sectionTypeStrtab= BigInteger.valueOf(3); public final static BigInteger sectionTypeRela= BigInteger.valueOf(4); public final static BigInteger sectionTypeHash= BigInteger.valueOf(5); public final static BigInteger sectionTypeDynamic= BigInteger.valueOf(6); public final static BigInteger sectionTypeNote= BigInteger.valueOf(7); public final static BigInteger sectionTypeNobits= BigInteger.valueOf(8); public final static BigInteger sectionTypeRel= BigInteger.valueOf(9); public final static BigInteger sectionTypeShlib= BigInteger.valueOf(10); public final static BigInteger sectionTypeDynsym= BigInteger.valueOf(11); public final static BigInteger specialSectionType32Loproc= BigInteger.valueOf(0x70000000); public final static BigInteger specialSectionType32Hiproc= BigInteger.valueOf(0x7FFFFFFF); public final static BigInteger specialSectionType32Louser= BigInteger.valueOf(0x80000000); public final static BigInteger specialSectionType32Hiuser= BigInteger.valueOf(0xFFFFFFFF); public final static BigInteger specialSectionType64Loos= BigInteger.valueOf(0x60000000); public final static BigInteger specialSectionType64Hios= BigInteger.valueOf(0x6FFFFFFF); public final static BigInteger specialSectionType64Loproc= BigInteger.valueOf(0x70000000); public final static BigInteger specialSectionType64Hiproc= BigInteger.valueOf(0x7FFFFFFF); public final static BigInteger specialSectionIndexUndefined= BigInteger.valueOf(0x0000); public final static BigInteger specialSectionIndexLoReserve= BigInteger.valueOf(0xFF00); public final static BigInteger specialSectionIndexLoProc= BigInteger.valueOf(0xFF00); public final static BigInteger specialSectionIndexHiProc= BigInteger.valueOf(0xFF1F); public final static BigInteger specialSectionIndexAbsolute= BigInteger.valueOf(0xFFF1); public final static BigInteger specialSectionIndexCommon= BigInteger.valueOf(0xFFF2); public final static BigInteger specialSectionIndexHiReserve= BigInteger.valueOf(0xFFFF); public final static BigInteger sectionAttributeWrite= BigInteger.ONE; public final static BigInteger sectionAttributeAlloc= BigInteger.valueOf(2); public final static BigInteger sectionAttributeExec= BigInteger.valueOf(4); public final static BigInteger sectionAttributeMask= BigInteger.valueOf(1+2+4); public final static BigInteger symbolBindLocal= BigInteger.ZERO; public final static BigInteger symbolBindGlobal= BigInteger.ONE; public final static BigInteger symbolBindWeak=BigInteger.valueOf(2); public final static BigInteger symbolBindLoos= BigInteger.valueOf(10); public final static BigInteger symbolBindHios= BigInteger.valueOf(12); public final static BigInteger symbolBindLoproc= BigInteger.valueOf(13); public final static BigInteger symbolBindHiproc= BigInteger.valueOf(15); public final static BigInteger symbolTypeNoType= BigInteger.ZERO; public final static BigInteger symbolTypeObject= BigInteger.ONE; public final static BigInteger symbolTypeFunc= BigInteger.valueOf(2); public final static BigInteger symbolTypeSection= BigInteger.valueOf(3); public final static BigInteger symbolTypeFile= BigInteger.valueOf(4); public final static BigInteger symbolTypeLoos= BigInteger.valueOf(10); public final static BigInteger symbolTypeHios= BigInteger.valueOf(12); public final static BigInteger symbolTypeLoproc= BigInteger.valueOf(13); public final static BigInteger symbolTypeHiproc= BigInteger.valueOf(15); }