From: <mic...@us...> - 2007-04-11 13:39:18
|
Revision: 24 http://svn.sourceforge.net/pearcolator/?rev=24&view=rev Author: michael_baer Date: 2007-04-11 06:39:17 -0700 (Wed, 11 Apr 2007) Log Message: ----------- Centrally parsing command line options in DBT_Options. Stopped passing argument arrays into the classes, but instead retrieving it from DBT_Options. Modified Paths: -------------- src/org/binarytranslator/DBT_Options.java src/org/binarytranslator/Main.java src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxProcessSpace.java src/org/binarytranslator/arch/x86/os/process/linux/X86_LinuxProcessSpace.java src/org/binarytranslator/generic/fault/BadInstructionException.java src/org/binarytranslator/generic/os/abi/linux/LinuxStackInitializer.java src/org/binarytranslator/generic/os/loader/Loader.java src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java src/org/binarytranslator/generic/os/loader/image/ImageLoader.java src/org/binarytranslator/generic/os/process/ProcessSpace.java Modified: src/org/binarytranslator/DBT_Options.java =================================================================== --- src/org/binarytranslator/DBT_Options.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/DBT_Options.java 2007-04-11 13:39:17 UTC (rev 24) @@ -8,6 +8,9 @@ */ package org.binarytranslator; +import java.util.HashMap; +import java.util.Map.Entry; + /** * Options for controlling the emulator */ @@ -25,6 +28,12 @@ public final static boolean unimplementedSystemCallsFatal = true; // -oO Translation settings Oo- + + /** The file that is currently being executed. */ + public static String executableFile; + + /** Arguments given to the executable.*/ + public static String[] executableArguments = null; /** * The initial optimisation level @@ -154,47 +163,132 @@ * The group ID for the user running the command */ public final static int GID = 100; - + + /** Stores the arguments given to the DBT by the user. These are NOT the arguments given to the executable. */ + private final static HashMap<String, String> dbtArguments = new HashMap<String, String>(); + /** - * Process a command line option - * - * @arg the command line argument starting "-X:dbt:" + * Read and parse the command line arguments. */ - public static void processArgument(String arg) { - if (arg.startsWith("-X:dbt:debugInstr=true")) { - debugInstr = true; - } else if (arg.startsWith("-X:dbt:debugRuntime=true")) { - debugRuntime = true; - } else if (arg.startsWith("-X:dbt:debugSyscall=true")) { - debugSyscall = true; - } else if (arg.startsWith("-X:dbt:debugSyscallMore=true")) { - debugSyscallMore = true; - } else if (arg.startsWith("-X:dbt:globalBranchLevel=")) { - globalBranchLevel = Integer.parseInt(arg.substring(25)); - } else if (arg.startsWith("-X:dbt:initialOptLevel=")) { - initialOptLevel = Integer.parseInt(arg.substring(23)); - } else if (arg.startsWith("-X:dbt:instrOpt0=")) { - instrOpt0 = Integer.parseInt(arg.substring(17)); - } else if (arg.startsWith("-X:dbt:instrOpt1=")) { - instrOpt1 = Integer.parseInt(arg.substring(17)); - } else if (arg.startsWith("-X:dbt:instrOpt2=")) { - instrOpt2 = Integer.parseInt(arg.substring(17)); - } else if (arg.startsWith("-X:dbt:singleInstrTranslation=true")) { - singleInstrTranslation = true; - } else if (arg.startsWith("-X:dbt:resolveBranchesAtOnce=true")) { - resolveBranchesAtOnce = true; - } else if (arg.startsWith("-X:dbt:resolveBranchesAtOnce=false")) { - resolveBranchesAtOnce = false; - } else if (arg.startsWith("-X:dbt:resolveProceduresBeforeBranches=true")) { - resolveProceduresBeforeBranches = true; - } else if (arg.startsWith("-X:dbt:resolveProceduresBeforeBranches=false")) { - resolveProceduresBeforeBranches = false; - } else if (arg.startsWith("-X:dbt:gdbStub=true")) { - gdbStub = true; - } else if (arg.startsWith("-X:dbt:gdbStubPort=")) { - gdbStubPort = Integer.parseInt(arg.substring(19)); + public static void parseArguments(String[] args) { + parseArgumentsToHashmap(args); + + for (Entry<String, String> argument : dbtArguments.entrySet()) { + String arg = argument.getKey(); + String value = argument.getValue(); + + try { + parseSingleArgument(arg, value); + } + catch (NumberFormatException e) { + throw new Error("Argument " + arg + " is not a valid integer."); + } + } + } + + /** + * Parses a single argument into the options class. + */ + private static void parseSingleArgument(String arg, String value) { + + if (arg.equalsIgnoreCase("-X:dbt:debugInstr")) { + debugInstr = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:debugRuntime")) { + debugRuntime = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:debugSyscall")) { + debugSyscall = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:debugSyscallMore")) { + debugSyscallMore = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:globalBranchLevel")) { + globalBranchLevel = Integer.parseInt(value); + } else if (arg.equalsIgnoreCase("-X:dbt:initialOptLevel")) { + initialOptLevel = Integer.parseInt(value); + } else if (arg.equalsIgnoreCase("-X:dbt:instrOpt0")) { + instrOpt0 = Integer.parseInt(value); + } else if (arg.equalsIgnoreCase("-X:dbt:instrOpt1")) { + instrOpt1 = Integer.parseInt(value); + } else if (arg.equalsIgnoreCase("-X:dbt:instrOpt2")) { + instrOpt2 = Integer.parseInt(value); + } else if (arg.equalsIgnoreCase("-X:dbt:singleInstrTranslation")) { + singleInstrTranslation = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:resolveBranchesAtOnce")) { + resolveBranchesAtOnce = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:resolveBranchesAtOnce")) { + resolveBranchesAtOnce = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:resolveProceduresBeforeBranches")) { + resolveProceduresBeforeBranches = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:resolveProceduresBeforeBranches")) { + resolveProceduresBeforeBranches = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:gdbStub")) { + gdbStub = Boolean.parseBoolean(value); + } else if (arg.equalsIgnoreCase("-X:dbt:gdbStubPort")) { + gdbStubPort = Integer.parseInt(value); } else { - throw new Error("DBT Options: Unrecongised emulator option " + arg); + throw new Error("DBT Options: Unknown emulator option " + arg); } } + + /** + * Takes an array of arguments and parses them as key=value pairs into the hashmap arguments. + */ + private static void parseArgumentsToHashmap(String[] args) { + + String key = null; + String value; + int next = 0; + + try { + //are there further arguments? + if (next == args.length) { + return; + } + + key = args[next++].trim(); + + if (!key.startsWith("-")) { + //this is not an argument to the DBT, so it must the file we're trying to execute. + executableFile = key; + + //the remaining arguments may be passed to the executable + executableArguments = new String[args.length - next]; + for (int i = next; i < args.length; i++) + executableArguments[i] = args[next + i]; + + return; + } + + //did the user give an argument without spaces in it? + int pos = key.indexOf('='); + if (pos != -1) { + value = key.substring(pos + 1); + key = key.substring(0, pos); + } + else { + + //extract the argument's value + do { + value = args[next++].trim(); + + if (value.startsWith("=")) + { + if (value.length() > 1) + value = value.substring(1); + else + value = ""; + } + } + while ( value.length() == 0 ); + } + + //store the argument's key and value + if (dbtArguments.containsKey(key)) { + throw new Error(String.format("Parameter %s already defined", key)); + } + + dbtArguments.put(key, value); + } + catch (Exception e) { + throw new Error("Invalid argument format for argument " + key); + } + } } Modified: src/org/binarytranslator/Main.java =================================================================== --- src/org/binarytranslator/Main.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/Main.java 2007-04-11 13:39:17 UTC (rev 24) @@ -18,20 +18,7 @@ * */ public class Main { - /* - * Variables required for an instance of the emulator - */ - /** - * A process space encapsulating the execution of a process - */ - ProcessSpace ps; - - /* - * Utility functions - */ - - /** * Debug information * * @param s @@ -47,62 +34,44 @@ /** * Usage */ - public static void usage() { + public static void showUsage() { System.out .println("org.binarytranslator.Main [-X:dbt:...] <program> <args...>"); } /** - * Constructor - should only be run from main - * - * @param args - * command line arguments. args[0] is the program to load. - */ - private Main(String[] args) { - // Check we have a file to load - if (args.length < 1) { - usage(); - throw new Error("Error program ran without arguments"); - } else { - // Set up and load the process space - try { - report("Loading " + args[0]); - Loader loader = Loader.getLoader(args[0]); - ps = loader.readBinary(args); - } catch (java.io.IOException e) { - usage(); - throw new Error("Error accessing file: " + args[0], e); - } - report("Sucessfully created process"); - } - } - - /** * Main method * * @param args * command line arguments (see usage()) */ public static void main(String[] args) { + + if (args.length < 1) { + showUsage(); + return; + } + // Process any arguments for the emulator - for (int i = 0; i < args.length; i++) { - if (args[i].startsWith("-X:dbt:")) { - DBT_Options.processArgument(args[i]); - } else { - if (i != 0) { - String new_args[] = new String[args.length - i]; - for (int j = 0; j < (args.length - i); j++) { - new_args[j] = args[i + j]; - } - args = new_args; - } - break; - } + try { + DBT_Options.parseArguments(args); + } catch (Exception e) { + System.err.println("Error while parsing command line arguments."); + System.err.println(e.getMessage()); } - Main runtime = new Main(args); - for (int i = 0; i < args.length; i++) { - report("Argument " + i + ": " + args[i]); + + ProcessSpace ps; + + try { + report("Loading " + DBT_Options.executableFile); + Loader loader = Loader.getLoader(DBT_Options.executableFile); + ps = loader.readBinary(DBT_Options.executableFile); + } + catch (java.io.IOException e) { + throw new Error("Error accessing file: " + args[0], e); } - runtime.ps.run(); + + report("Sucessfully created process."); + ps.run(); } } Modified: src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/arch/arm/os/process/image/ARM_ImageProcessSpace.java 2007-04-11 13:39:17 UTC (rev 24) @@ -28,7 +28,7 @@ } @Override - public void initialise(Loader loader, int pc, int brk, String[] args) { + public void initialise(Loader loader, int pc, int brk) { registers.write(ARM_Registers.PC, pc); } Modified: src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/arch/arm/os/process/linux/ARM_LinuxProcessSpace.java 2007-04-11 13:39:17 UTC (rev 24) @@ -45,7 +45,7 @@ } @Override - public void initialise(Loader loader, int pc, int brk, String[] args) { + public void initialise(Loader loader, int pc, int brk) { registers.write(ARM_Registers.PC, pc); this.brk = brk; @@ -69,8 +69,7 @@ LinuxStackInitializer.AuxiliaryVectorType.AT_SECURE, 0, LinuxStackInitializer.AuxiliaryVectorType.AT_NULL, 0x0 }; - LinuxStackInitializer.stackInit(memory, STACK_TOP, args, - getEnvironmentVariables(), auxVector); + LinuxStackInitializer.stackInit(memory, STACK_TOP, getEnvironmentVariables(), auxVector); } public int getBrk() { Modified: src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxProcessSpace.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/arch/ppc/os/process/linux/PPC_LinuxProcessSpace.java 2007-04-11 13:39:17 UTC (rev 24) @@ -65,16 +65,16 @@ * @param args * command line arguments */ - public void initialise(Loader loader, int pc, int brk, String args[]) { + public void initialise(Loader loader, int pc, int brk) { this.pc = pc; this.brk = brk; - this.r1 = initialiseStack(loader, pc, args); + this.r1 = initialiseStack(loader, pc); } /** * Initialise the stack */ - private int initialiseStack(Loader loader, int pc, String args[]) { + private int initialiseStack(Loader loader, int pc) { int[] auxVector = { LinuxStackInitializer.AuxiliaryVectorType.AT_IGNOREPPC, LinuxStackInitializer.AuxiliaryVectorType.AT_IGNOREPPC, @@ -118,7 +118,7 @@ * binaries. */ - return LinuxStackInitializer.stackInit(memory, STACK_TOP, args, + return LinuxStackInitializer.stackInit(memory, STACK_TOP, getEnvironmentVariables(), auxVector); } Modified: src/org/binarytranslator/arch/x86/os/process/linux/X86_LinuxProcessSpace.java =================================================================== --- src/org/binarytranslator/arch/x86/os/process/linux/X86_LinuxProcessSpace.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/arch/x86/os/process/linux/X86_LinuxProcessSpace.java 2007-04-11 13:39:17 UTC (rev 24) @@ -56,16 +56,16 @@ * @param brk the initial value for the top of BSS * @param args command line arguments */ - public void initialise(Loader loader, int pc, int brk, String args[]) { + public void initialise(Loader loader, int pc, int brk) { registers.eip = pc; this.brk = brk; - registers.writeGP32(X86_Registers.ESP, initialiseStack(loader, pc, args)); + registers.writeGP32(X86_Registers.ESP, initialiseStack(loader, pc)); } /** * Initialise the stack */ - private int initialiseStack(Loader loader, int pc, String args[]) { + private int initialiseStack(Loader loader, int pc) { int[] auxVector = {LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO, 0xffffe400, LinuxStackInitializer.AuxiliaryVectorType.AT_SYSINFO_EHDR, 0xffffe000, LinuxStackInitializer.AuxiliaryVectorType.AT_HWCAP, 0x78bfbff, @@ -86,7 +86,7 @@ //LinuxStackInitializer.AuxiliaryVectorType.AT_PLATFORM, LinuxStackInitializer.AuxiliaryVectorType.STACK_TOP - getPlatformString().length, LinuxStackInitializer.AuxiliaryVectorType.AT_NULL, 0x0}; - return LinuxStackInitializer.stackInit(memory, STACK_TOP, args, getEnvironmentVariables(), auxVector); + return LinuxStackInitializer.stackInit(memory, STACK_TOP, getEnvironmentVariables(), auxVector); } /** Modified: src/org/binarytranslator/generic/fault/BadInstructionException.java =================================================================== --- src/org/binarytranslator/generic/fault/BadInstructionException.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/generic/fault/BadInstructionException.java 2007-04-11 13:39:17 UTC (rev 24) @@ -11,7 +11,21 @@ import org.binarytranslator.generic.os.process.ProcessSpace; public class BadInstructionException extends Exception { + + private final int pc; + private final ProcessSpace ps; + public BadInstructionException(int pc, ProcessSpace ps) { super("Bad instruction encountered at 0x" + Integer.toHexString(pc)); + this.pc = pc; + this.ps = ps; } + + public int getInstructionAddress() { + return pc; + } + + public ProcessSpace getProcessSpace() { + return ps; + } } Modified: src/org/binarytranslator/generic/os/abi/linux/LinuxStackInitializer.java =================================================================== --- src/org/binarytranslator/generic/os/abi/linux/LinuxStackInitializer.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/generic/os/abi/linux/LinuxStackInitializer.java 2007-04-11 13:39:17 UTC (rev 24) @@ -10,6 +10,7 @@ import java.io.UnsupportedEncodingException; +import org.binarytranslator.DBT_Options; import org.binarytranslator.generic.memory.Memory; import org.binarytranslator.generic.memory.MemoryMapException; @@ -274,7 +275,11 @@ * @param the auxiliary vector, including the terminating AT_NULL (two zeroes). * @return the bottom of the stack in memory */ - public static int stackInit(Memory memory, int stackTop, String[] argv, String[] env, int[] auxVector) { + public static int stackInit(Memory memory, int stackTop, String[] env, int[] auxVector) { + + //grab the vector of command line options that are to be delivered to the linux program + String[] argv = DBT_Options.executableArguments; + // --- // First create the information block by concatenating all strings // together, then compute pointers to values in the information Modified: src/org/binarytranslator/generic/os/loader/Loader.java =================================================================== --- src/org/binarytranslator/generic/os/loader/Loader.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/generic/os/loader/Loader.java 2007-04-11 13:39:17 UTC (rev 24) @@ -20,9 +20,6 @@ * appropriate sub-class loader is chosen to actually load the binary. */ public abstract class Loader { - /* - * Utility functions - */ /** * Debug information @@ -45,11 +42,11 @@ * Create a process space, load the binary into it and initialise the stack, * etc. * - * @param args - * command line arguments + * @param filename + * The file, which is to be loaded and executed. * @return the process space to start executing */ - abstract public ProcessSpace readBinary(String[] args) throws IOException; + abstract public ProcessSpace readBinary(String filename) throws IOException; /** * Return the application binary interface (ABI) supported by this file Modified: src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java =================================================================== --- src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/generic/os/loader/elf/ELF_Loader.java 2007-04-11 13:39:17 UTC (rev 24) @@ -116,13 +116,13 @@ /** * Main entry point that loads the binary - * @param args command line arguments including the program file name + * @param filename the program file name * @return process space containing loaded binary */ - public ProcessSpace readBinary(String[] args) throws IOException + public ProcessSpace readBinary(String filename) throws IOException { - report("Opening File: " + args[0]); - RandomAccessFile rFile = new RandomAccessFile(args[0], "r"); + report("Opening File: " + filename); + RandomAccessFile rFile = new RandomAccessFile(filename, "r"); elfHeader = new ELF_Header(rFile); //NB also sets up reader report("ELF header read successfully"); @@ -149,7 +149,7 @@ "entry = 0x" + Integer.toHexString(elfHeader.getEntryPoint()) + " brk = 0x" + Integer.toHexString(brk) ); - ps.initialise(this, elfHeader.getEntryPoint(), brk, args); + ps.initialise(this, elfHeader.getEntryPoint(), brk); return ps; } Modified: src/org/binarytranslator/generic/os/loader/image/ImageLoader.java =================================================================== --- src/org/binarytranslator/generic/os/loader/image/ImageLoader.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/generic/os/loader/image/ImageLoader.java 2007-04-11 13:39:17 UTC (rev 24) @@ -82,10 +82,12 @@ } } - public ProcessSpace readBinary(String[] args) throws IOException { + /** + */ + public ProcessSpace readBinary(String filename) throws IOException { - report("Reading: " + args[0]); - RandomAccessFile file = new RandomAccessFile(args[0], "r"); + report("Reading: " + filename); + RandomAccessFile file = new RandomAccessFile(filename, "r"); if (!readAndCheckID(file)) throw new IOException("File does not contain the expected EXT_IMG ID string."); @@ -118,7 +120,7 @@ return null; } - ps.initialise(this, 0, -1, args); + ps.initialise(this, 0, -1); return ps; } Modified: src/org/binarytranslator/generic/os/process/ProcessSpace.java =================================================================== --- src/org/binarytranslator/generic/os/process/ProcessSpace.java 2007-04-06 11:51:35 UTC (rev 23) +++ src/org/binarytranslator/generic/os/process/ProcessSpace.java 2007-04-11 13:39:17 UTC (rev 24) @@ -293,10 +293,8 @@ * the entry point * @param brk * the initial value for the top of BSS - * @param args - * command line arguments */ - public abstract void initialise(Loader loader, int pc, int brk, String args[]); + public abstract void initialise(Loader loader, int pc, int brk); /** * Constructor This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |