//-------------------------------------------------------------------------------------------------- // // @ 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. // //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- // // Class to manage input statements // //-------------------------------------------------------------------------------------------------- package framework; import java.util.*; import java.math.BigInteger; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Constructor; import java.lang.reflect.TypeVariable; import java.net.URL; import java.net.URLClassLoader; public class DVStatements { protected DVStatements(String inputFileName, ArrayList macroDirectories, String archDirectory, String archExtDirectory, DVParseInput parseInput, DVMacros macros) { this.parseInput= parseInput; this.inputFileName= inputFileName; this.archDirectory= archDirectory; this.extDirectory= archExtDirectory; this.macros= macros; this.jSApi= new DVMacroJSApi(parseInput, macros); this.symbols= new DVSymbols(this); this.sections= new DVSections(this, this.symbols); if (DVUtil.isClassInJar(this.getClass())) logMsg(String.format("Framework JAR file is [%s]", DVUtil.getClassLocation(this.getClass()))); else logMsg(String.format("Framework base directory is [%s]", DVUtil.getClassLocation(this.getClass()))); if (this.archDirectory != null) logMsg(String.format("User architectural directory is [%s]", this.archDirectory)); if (this.extDirectory != null) logMsg(String.format("User arch. extension directory is [%s]", this.extDirectory)); int i= 1; for (String md : macroDirectories) { logMsg(String.format("User macro directory[%d] is: [%s]", i, md)); i++; } } // // Errors and messages // public class Statement { public void putInfo(String format, Object ... objects) { this.putInfo(String.format(format, objects)); } public void putInfo(String msg) { addMessage("Note: "+msg); } public void putWarning(String format, Object ... objects) { this.putWarning(String.format(format, objects)); } public void putWarning(String msg) { addMessage("Warning: "+msg); if (DVStatements.this.secondPhase) { this.warning= true; DVStatements.this.warnings++; } else { this.firstPhaseWarning= true; DVStatements.this.firstPhaseWarnings++; } } public boolean putErrorFalse(String format, Object ... objects) { this.putError(String.format(format, objects)); return false; } public DVCode putErrorNoCode(String format, Object ... objects) { this.putError(String.format(format, objects)); return null; } public void putError(String format, Object ... objects) { this.putError(String.format(format, objects)); } public void putError(String msg) { addMessage("Error: "+msg); this.error= true; DVStatements.this.errors++; } private void addMessage(String msg) { ArrayList messages= (DVStatements.this.secondPhase ? this.secondPhaseMessages : this.firstPhaseMessages); int x; if (! msg.endsWith("\n")) msg+= "\n"; while(true) { x= msg.indexOf('\n'); messages.add(msg.substring(0, x)); if (x == msg.length()-1) return; msg= " " + msg.substring(x+1); } } // // Get statement offset // public BigInteger getOffset() { if (this.offsetCurr != null) return this.symbol.resultValue.intConstant.add(this.offsetCurr); return this.symbol.resultValue.intConstant; } // // Get alignment // public BigInteger getAlignment() { return this.symbol.align; } // // Get opCode // public String getOpCode() { if (this.opCodeCurr != null) return this.opCodeCurr; return this.opCode.image.toUpperCase(); } // // Get opCodeParms // public DVOpCodeParm getOpCodeParm() { if (this.opCodeParmCurr != null) return this.opCodeParmCurr; return this.opCodeParm; } // // Return owner section if any // public DVSections.Section getOwnerSection() { return this.ownerSection; } // // Get first line number of statement // public String getFirstLineNumber() { return this.lines[0].lineNo; } // // Set environment // protected boolean setEnv(String architecture, String options, String abi, String os) { if (DVStatements.this.architectureOpCodes != null) return this.putErrorFalse("Duplicate SETENV opcope"); // // Get architecture and extension DVOpCodes // if ((DVStatements.this.architectureOpCodes= getOpCodes(architecture, DVStatements.this.archDirectory, options, abi, os)) == null) return false; if (DVUtil.isClassInJar(DVStatements.this.architectureOpCodes.getClass())) logMsg(String.format("Architecture JAR file selected is [%s]", DVUtil.getClassLocation(DVStatements.this.architectureOpCodes.getClass()))); else logMsg(String.format("Architecture directory selected is [%s]", DVUtil.getClassLocation(DVStatements.this.architectureOpCodes.getClass()))); if (! DVStatements.this.architectureOpCodes.verifyArchitecture(this, architecture)) return false; DVStatements.this.hexCodeHeader= DVStatements.this.architectureOpCodes.getHexCodeHeader(); DVStatements.this.frameworkOpCodes.putHexCodeHeader(DVStatements.this.hexCodeHeader); if ((DVStatements.this.abi= DVStatements.this.architectureOpCodes.getAbi()) == null) return this.putErrorFalse("Abi [" + abi + "] not supported by architecture [" + architecture + "]"); String extension= DVStatements.this.architectureOpCodes.getExtension(); if (extension != null) { if ((DVStatements.this.extensionOpCodes= getOpCodes(architecture, DVStatements.this.archDirectory)) == null) return false; if (DVUtil.isClassInJar(DVStatements.this.architectureOpCodes.getClass())) logMsg(String.format("Architecture extension JAR file selected is [%s]", DVUtil.getClassLocation(DVStatements.this.architectureOpCodes.getClass()))); else logMsg(String.format("Architecture extension directory selected is [%s]", DVUtil.getClassLocation(DVStatements.this.architectureOpCodes.getClass()))); if (! DVStatements.this.extensionOpCodes.verifyArchitecture(this, architecture)) return false; if (! DVStatements.this.extensionOpCodes.verifyExtension(this, extension)) return false; } else logMsg("No architecture extension used"); // // Set up macro interface // if (! DVStatements.this.macros.addArchitectureMacro(this, DVStatements.this.jSApi, architecture, extension, options, abi, os, DVStatements.this.abi.getEnv(), DVStatements.this.architectureOpCodes, DVStatements.this.archDirectory, DVStatements.this.extensionOpCodes, DVStatements.this.extDirectory)) return false; this.setEndianness(DVStatements.this.abi.getDefaultEndianness()); return true; } // // Service methods to load architecture and extension DVOpCodes class // private DVOpCodes getOpCodes(String name, String directory, String options, String abi, String os) { return getOpCodes(name, directory, options, abi, os, true); } private DVOpCodes getOpCodes(String name, String directory) { return getOpCodes(name, directory, null, null, null, false); } private DVOpCodes getOpCodes(String name, String directory, String options, String abi, String os, boolean arch) { String className= (arch ? "arch." + name + ".DVArchOpCodes" : "arch." + name + ".ext.DVExtOpCodes"); DVOpCodes opCodes= null; String tail= ""; try { if (directory == null) { if (arch) opCodes= (DVOpCodes) Class.forName(className) .getConstructor(DVStatements.Statement.class, String.class, String.class, String.class) .newInstance(new Object[] { this, options, abi, os }); else opCodes= (DVOpCodes) Class.forName(className) .getConstructor(DVStatements.Statement.class).newInstance(new Object[] { this }); } else { URLClassLoader classLoader= URLClassLoader.newInstance( new URL[] { new File(DVStatements.this.archDirectory).toURI().toURL() } ); tail= "\n URL [" + directory + "]"; if (arch) opCodes= (DVOpCodes) classLoader.loadClass(className) .getConstructor(DVStatements.Statement.class, String.class, String.class, String.class) .newInstance(new Object[] { this, options, abi, os }); else opCodes= (DVOpCodes) classLoader.loadClass(className) .getConstructor(DVStatements.Statement.class).newInstance(new Object[] { this }); } } catch(Exception e) { Exception cause= (Exception) e.getCause(); if (cause == null) this.putError(DVUtil.formatException("Unable to load DVOpCodes class [" + className + "]" + tail + "\n", e)); else { StringWriter sw= new StringWriter(); cause.printStackTrace(new PrintWriter(sw)); this.putError("Unable to load DVOpCodes class [" + className + "]" + tail + "\n%s\n%s\n", cause.toString(), sw.toString()); } return null; } catch(NoClassDefFoundError e) { this.putError("Unable to load DVOpCodes class [" + className + "]" + tail + "\n", e); return null; } return opCodes; } // // Set endianness // protected void setBigEndianness() { this.setEndianness(DVUtil.Endianness.BIG); } protected void setLittleEndianness() { this.setEndianness(DVUtil.Endianness.LITTLE); } protected void setEndianness(DVUtil.Endianness endianness) { if (DVStatements.this.defaultEndianness == DVUtil.Endianness.UNDEFINED) DVStatements.this.defaultEndianness= endianness; DVStatements.this.currentEndianness= endianness; } // // Set default endianness // protected void setDefEndianness(DVUtil.Endianness endianness) { DVStatements.this.currentEndianness= endianness= DVStatements.this.defaultEndianness; } // // Get current endianness // public DVUtil.Endianness getEndianness() { return DVStatements.this.currentEndianness; } // // Initialize statement for macro // protected boolean initializeMacro(Token label, Token macro) { this.isMacro= true; this.label= label; this.opCode= macro; return true; } // // Add a new Base to active list // protected void addBase(String id, DVSections.Section section, BigInteger offset, BigInteger register) { for (Base b : DVStatements.this.activeBaseList) { if (register.equals(b.register)) { this.putError("Base for register [%s] already active - defined in statement [%s]\n", register.toString(), b.owner.lines[0].lineNo); return; } if (id != null && id.equals(b.id)) { this.putError(String.format("Base for id [%s] already active - defined in statement [%s]\n", id, b.owner.lines[0].lineNo)); return; } } DVStatements.this.activeBaseList.add(new Base(this, id, section, offset, register)); if (id == null) this.putInfo("Base register [%d] added for section [%s] at offset [%012X]", register.intValue(), section.name, offset.longValue()); else this.putInfo("Base register [%d] added for section [%s] at offset [%012X] with ID [%s]", register.intValue(), section.name, offset.longValue(), id); } // // Drop an existing base by register number // protected boolean dropBase(BigInteger register) { for (int i= 0; i < DVStatements.this.activeBaseList.size(); i++) { Base b= DVStatements.this.activeBaseList.get(i); if (! register.equals(b.register)) continue; this.putInfo("Base set in statement " + b.owner.lines[0].lineNo + " dropped"); DVStatements.this.activeBaseList.remove(i); return true; } this.putError("Base with base register " + register.toString() + " not droppped: it was not set"); return true; } // // Drop an existing base by register number // protected boolean dropAllBases() { int n= 0; for (; ! DVStatements.this.activeBaseList.isEmpty(); n++) { Base b= DVStatements.this.activeBaseList.get(0); this.putInfo("Base register [%d] set in statement %s dropped", b.register, b.owner.lines[0].lineNo); DVStatements.this.activeBaseList.remove(0); } if (n == 0) this.putWarning("NO active base registers found"); return true; } // // Get base by id // public Base getBase(String id) { for (int i= 0; i < DVStatements.this.activeBaseList.size(); i++) { Base b= DVStatements.this.activeBaseList.get(i); if (b.id == null || ! id.equals(b.id)) continue; return b; } return null; } // // Get base by section/offset // public Base getBase(DVSections.Section section, BigInteger offset, boolean unsignedFlag) { Base base= null; BigInteger off= null; for (int i= 0; i < DVStatements.this.activeBaseList.size(); i++) { Base b= DVStatements.this.activeBaseList.get(i); if (b.id != null) continue; if (section != b.section) continue; BigInteger t= offset.subtract(b.offset); if (t.signum() < 0 && unsignedFlag) continue; if (base == null || t.abs().compareTo(off.abs()) < 0) { base= b; off= t; } } return base; } // // Process opCode // protected boolean processOpCode(Token label, Token opCode, DVOpCodeParm parm) { this.label= label; this.opCode= opCode; this.opCodeParm= parm; this.endianness= DVStatements.this.currentEndianness; if (DVStatements.this.endOpCode) { this.putError("Only comments allowed after END opCode"); return false; } if (DVStatements.this.abi == null && ! this.opCode.image.toUpperCase().equals("SETENV")) return this.putErrorFalse("Missing or failed preeceding SETENV statement - only macros are allowed before SETENV opCode"); this.opCodeProcessor= DVStatements.this.frameworkOpCodes.getOpCodeProcessor(this, opCode); if (this.opCodeProcessor == null && DVStatements.this.extensionOpCodes != null) this.opCodeProcessor= DVStatements.this.extensionOpCodes.getOpCodeProcessor(this, opCode); if (this.opCodeProcessor == null) this.opCodeProcessor= DVStatements.this.architectureOpCodes.getOpCodeProcessor(this, opCode); if (this.opCodeProcessor == null) return this.putErrorFalse(String.format("Invalid opCode [%s] at line %s column %d", opCode.image, this.lines[opCode.beginLine-1].lineNo, opCode.beginColumn)); boolean noLabel= this.opCodeProcessor.getNoLabel(); boolean needSection= this.opCodeProcessor.getNeedSection(); boolean needLabel= this.opCodeProcessor.getNeedLabel(); boolean needSymbol= (! noLabel) || needSection; // // Check if any parm combination not allowed // if (this.opCodeProcessor.getNoLabel() && this.label != null) return this.putErrorFalse("Label specified but not allowed for this opCode"); int n= parm.getPositionalParmListSize(); int[] posMinMax= this.opCodeProcessor.getPosParmMinMax(); if (posMinMax == null) { if (n > 0) return this.putErrorFalse("No positional parameters allowed for this opCode\n"); } else { if (n < posMinMax[0] || n > posMinMax[1]) { if (posMinMax[0] == posMinMax[1]) return this.putErrorFalse( String.format("Number of positional parameters is [%d] - it must be %d\n", n, posMinMax[0])); else return this.putErrorFalse(String.format( "Number of positional parameters is [%d] - it must be between %d and %d included\n", n, posMinMax[0], posMinMax[1])); } boolean[] posDef= this.opCodeProcessor.getPosParmDefault(); int [][] subMinMax= this.opCodeProcessor.getSubParmMinMax(); boolean[][] subDef= this.opCodeProcessor.getSubParmDefault(); for (int i= 0; i < n; i++) { if ((posDef == null || posDef != null && ! posDef[i]) && parm.getPositionalParameter(i).isEmpty()) return this.putErrorFalse(String.format( "Positional parameter in position [%d] is defaulted - default not available", i+1)); int m= parm.getSubParmListSize(i); if (subMinMax == null) { if (m > 0) return this.putErrorFalse(String.format("Positional parameter [%d] cannot have any sub-parameters\n", i+1)); } else { if (m < subMinMax[i][0] || m > subMinMax[i][1]) { if (subMinMax[i][0] == subMinMax[i][1]) return this.putErrorFalse(String.format( "Number of sub-parameters for positional parameter [%d] is [%d] - it must be %d\n", i+1, m, subMinMax[i][0])); else return this.putErrorFalse(String.format( "Number of sub-parameters for positional parameter [%d] is [%d] - it must be between %d and %d included\n", i+1, m, posMinMax[0], posMinMax[1])); } DVOpCodeParm.SubParm[] subParmList= parm.getSubParmList(i); for (int j= 0; j < m; j++) { if ((subDef == null || subDef != null && ! subDef[i][j]) && subParmList[j].getSubParm().isEmpty()) return this.putErrorFalse(String.format( "Sub-parameter for positional parameter [%d] in position [%d] is defaulted - default not available", i, j)); } } } } String[] keyWordList= this.opCodeProcessor.getKeyWordList(); if (keyWordList != null) { n= parm.getKeyWordParmListSize(); DVOpCodeParm.KeyWordParm[] kwIndex= new DVOpCodeParm.KeyWordParm[keyWordList.length]; DVOpCodeParm.KeyWordParm[] kwParmList= parm.getKeyWordParmList(); for (int i= 0; i < n; i++) { String kw= kwParmList[i].getKeyValue().toUpperCase(); if (kwParmList[i].parameter.isEmpty()) return this.putErrorFalse("Key-word paramter [%s=] has not been assigned any valaue", kw); int j; for (j= 0; j < kwParmList.length; j++) { if (kw.equals(keyWordList[j])) { kwIndex[j]= kwParmList[i]; break; } } if (j >= kwParmList.length) { String kwAllowed= ""; for (j= 0; j < keyWordList.length; j++) kwAllowed+= " " + keyWordList[j]; return this.putErrorFalse(String.format( "Key-word parameter [%s=] is not allowed - possible key-words are" + kwAllowed, kw)); } } parm.keyWordParmIndex= kwIndex; } // // Get symbol if one needed/allowed // if (needSymbol) { this.symbol= symbols.getSymbol(label, this); if (this.symbol == null) return this.putErrorFalse("Duplicate symbol [" + label + "]"); if (needLabel && this.symbol.name.startsWith("#")) return this.putErrorFalse("Label required but missing"); this.symbol.align= this.opCodeProcessor.getAlign(); this.symbol.length= this.opCodeProcessor.getLength(); // // Get value and replicating expression if provided by the opCode // if (this.opCodeProcessor.getValueInParm()) this.symbol.valueExpression= this.opCodeProcessor.getValueExpression(this); if (this.opCodeProcessor.getRepl() != null) this.symbol.replExpression= DVExpression.getConstantExpression(this.opCodeProcessor.getRepl(), this); else this.symbol.replExpression= this.opCodeProcessor.getReplExpression(parm, this); } // // Connect statement to section if section is needed // if (needSection) { if (sections.currSection == null) { this.putError("An active section/memory map is required but none has been started"); return false; } sections.currSection.alignValue= sections.currSection.alignValue.max(this.symbol.align); this.ownerSection= sections.currSection; sections.setNextSymbolValueExpression(this); } if (this.symbol != null && this.symbol.valueExpression == null) this.symbol.valueExpression= DVExpression.getConstantExpression(BigInteger.ZERO, this); // // Call opCode preprocessor // return this.opCodeProcessor.preProcessOpCode(this); } public void guaranteeAlignment(BigInteger alignValue) { this.ownerSection.alignValue= this.ownerSection.alignValue.max(alignValue); } // // Return Section for this statement // protected DVSections getSections() { return DVStatements.this.sections; } // // Return DVSymbol instance // protected DVSymbols getSymbols() { return DVStatements.this.symbols; } // // Get statement label // public String getLabel() { return this.getLabel(); } // // Get statement symbol // public DVSymbols.Symbol getSymbol() { return this.symbol; } // // Set/Get user object // public void setUserObject(Object obj) { this.userObject= obj; } public Object getUserObject() { return this.userObject; } // // Add a relocation // public void addRelocation(DVSymbols.Symbol symbol, BigInteger addEnd, DVAbi.RelocationID relocationID) { this.ownerSection.addRelocation(this, symbol, this.getOffset(), addEnd, relocationID); } // // get PC relative displacement // public Object getRelativeDisplacement(int parmNo, int maxBits) { return this.getRelativeDisplacement(parmNo, maxBits, 0); } public Object getRelativeDisplacement(int parmNo, int maxBits, int align) { DVExpression.ExprToken target= this.getOpCodeParm().getPositionalParameterValue(parmNo); if (target == null) { this.putError("PC Relative displacement is required but it is missing"); return null; } BigInteger displacement; if (DVExpression.INT_VALUE.contains(target.type)) displacement= target.intConstant; else if (target.type == DVExpression.TokenType.OFFSET) { if (target.getOffsetSection() != this.ownerSection) return target; displacement= target.intConstant.subtract(this.symbol.resultValue.intConstant); } else if (target.type == DVExpression.TokenType.EXTERNAL_VALUE) return target; else { this.putError("PC Relative displacement resolves to invalid type [%s]", target.type.name()); return null; } if (displacement.bitLength() >= maxBits) { this.putError("PC Relative displacement is [%d] wide - maximum allowed is [%d]", displacement.bitLength()+1, maxBits); return null; } if (align > 0 && displacement.divideAndRemainder(BigInteger.valueOf(align))[1].intValue() > 0) { this.putError("PC Relative displacement is out of alignment"); return null; } return displacement.and(BigInteger.valueOf((1l << maxBits)-1l)); } // // Get previouse section statement // protected DVStatements.Statement getPrevSectStatement() { int i= this.statements.statementList.indexOf(this); DVStatements.Statement stmt; for (; i >= 0; i--) if ((stmt= this.statements.statementList.get(i)).ownerSection != null) return stmt; return null; } // // Log an entry // public void logMsg(String msg) { DVStatements.this.log(msg, false); } public void logErr(String errMsg) { DVStatements.this.log(errMsg, true); } public void logTrace(String traceMsg) { if (DVStatements.this.traceFlag) DVStatements.this.log(traceMsg, false); } // // Reset statements for a new code generation cycle // protected void resetStatement() { this.secondPhaseMessages.clear(); this.warning= this.firstPhaseWarning; } // // Class fields // protected final DVStatements statements= DVStatements.this; protected boolean isMacro= false; protected int sectionIndex= -1; protected DVParseInput.Line[] lines= null; protected ArrayList firstPhaseMessages= new ArrayList(); protected ArrayList secondPhaseMessages= new ArrayList(); protected boolean firstPhaseWarning= false; protected boolean warning= false; protected boolean error= false; protected Token label; protected Token opCode= null; protected String opCodeCurr; protected DVOpCodeParm opCodeParm; protected DVOpCodeParm opCodeParmCurr; protected BigInteger offsetCurr; protected DVOpCodeProcessor opCodeProcessor; protected DVCode genCode; protected DVSymbols.Symbol symbol= null; protected DVUtil.Endianness endianness= DVUtil.Endianness.UNDEFINED; protected DVSections.Section ownerSection= null; protected Object userObject= null; } // // Get last statement // protected Statement getLastStatement() { int s= this.statementList.size()-1; if (s < 0) return null; return this.statementList.get(s); } // // Commit current statement // protected DVStatements.Statement add(DVParseInput.Line[] lines) { this.currStatement= new Statement(); this.currStatement.lines= lines; this.statementList.add(this.currStatement); return this.currStatement; } // // Check if end statement is present // protected void checkEndStatement() { if (! this.endOpCode) { Statement last= this.getLastStatement(); if (last == null) return; last.putError("Missing END statement"); } } // // Log an entry // public void logMsg(String msg) { this.log(msg, false); } public void logErr(String errMsg) { this.log(errMsg, true); } public void logTrace(String traceMsg) { if (this.traceFlag) this.log(traceMsg, false); } protected void log(String logEntry, boolean errFlag) { if (! logEntry.endsWith("\n")) logEntry+= "\n"; if (errFlag) System.err.print(logEntry); if (this.secondPhase) this.logListSecondPhase.add(logEntry); else this.logListFirstPhase.add(logEntry); } public void setLogTrace(boolean traceFlag) { this.traceFlag= traceFlag; } // // Generate code for each statement // protected void genCode() { for (Statement s : this.statementList) { if (s.opCodeProcessor != null) { if (s.opCodeParm != null) { for (DVOpCodeParm.PositionalParm pp : s.opCodeParm.posParmList) { pp.parameterValue= pp.parameter.evaluate(false); for (DVOpCodeParm.SubParm sp : pp.subParmList) { sp.subParmValue= sp.subParm.evaluate(false); } } for (DVOpCodeParm.KeyWordParm kp : s.opCodeParm.keyWordParmList) { kp.value= kp.parameter.evaluate(false); } } if (s.error) continue; s.opCodeCurr= null; s.opCodeParmCurr= null; s.offsetCurr= null; s.genCode= s.opCodeProcessor.generateCode(s); s.opCodeCurr= null; s.opCodeParmCurr= null; s.offsetCurr= null; if (s.genCode != null) { if (s.genCode.next != null) { for (DVCode dvc= s.genCode.next; dvc != null; dvc= dvc.next) { if (s.genCode.code == null) { if (dvc.code == null) continue; s.genCode.code= dvc.code; continue; } if (dvc.code == null) continue; byte[] c= s.genCode.code; int l= s.genCode.code.length; s.genCode.code= new byte[l+dvc.code.length]; for (int i= 0; i < l; i++) s.genCode.code[i]= c[i]; for (int i= 0; i < dvc.code.length; i++) s.genCode.code[l+i]= dvc.code[i]; } } if (s.genCode.code != null && s.genCode.code.length != s.symbol.length.multiply(s.symbol.resultRepl.intConstant).intValue()) { this.changedLengthFlag= true; s.symbol.length= BigInteger.valueOf(s.genCode.code.length).divide(s.symbol.resultRepl.intConstant); } } } } // // Check branch to branch // architectureOpCodes.postProcess(); } // // Generate ELF binary // protected byte[] generateElfBinary() { DVSectionTable sectionTable= new DVSectionTable(this.abi, this.sections, this.symbols, this.setFile ? this.inputFileName : null); return sectionTable.getElfBinary(); } // // Base internal class // public class Base { protected Base(Statement owner, String id, DVSections.Section section, BigInteger offset, BigInteger register) { this.owner= owner; this.id= id; this.section= section; this.offset= offset; this.register= register; } // // Getter methods // public Statement getOwner() { return this.getOwner(); } public String getID() { return this.id; } public DVSections.Section getSection() { return this.section; } public BigInteger getOffset() { return this.offset; } public BigInteger getRegister() { return this.register; } // // Class fields // protected final Statement owner; protected final String id; protected final DVSections.Section section; protected final BigInteger offset; protected final BigInteger register; } // // Prepare for first cycle of code generation // protected void setSecondPhase() { this.secondPhase= true; } // // Reset statements for a new cycle of code generation // protected void resetSecondPhase() { this.changedLengthFlag= false; this.activeBaseList.clear(); this.warnings= this.firstPhaseWarnings; for (Statement s : this.statementList) s.resetStatement(); sections.resetSections(); } // // Class fields // protected final String inputFileName; protected final String archDirectory; protected final String extDirectory; protected final DVParseInput parseInput; protected final DVMacros macros; protected final DVMacroJSApi jSApi; protected String hexCodeHeader= "--- Architecture/Abi no found ---"; protected final DVFrameworkOpCodes frameworkOpCodes= new DVFrameworkOpCodes(); protected DVOpCodes architectureOpCodes= null; protected DVOpCodes extensionOpCodes= null; protected DVAbi abi= null; protected final DVSymbols symbols; protected final DVSections sections; protected DVUtil.Endianness defaultEndianness= DVUtil.Endianness.UNDEFINED; protected DVUtil.Endianness currentEndianness= DVUtil.Endianness.UNDEFINED; protected int currStatementFirstLineIndex= 0; protected Statement currStatement= new Statement(); protected boolean endOpCode= false; protected boolean setFile= false; protected final ArrayList statementList= new ArrayList(); protected boolean changedLengthFlag= false; protected int firstPhaseWarnings= 0; protected int warnings= 0; protected int errors= 0; protected final ArrayList activeBaseList= new ArrayList(); protected final LinkedList logListFirstPhase= new LinkedList(); protected final LinkedList logListSecondPhase= new LinkedList(); protected boolean secondPhase= false; protected boolean traceFlag= false; }