114086849SPavel Labathimport argparse 214086849SPavel Labathimport socket 314086849SPavel Labathimport json 445aa4356SPavel Labathimport os 55c4cb323SPavel Labathimport sys 614086849SPavel Labath 714086849SPavel Labathimport use_lldb_suite 814086849SPavel Labathfrom lldbsuite.test.gdbclientutils import * 914086849SPavel Labath 105c4cb323SPavel Labath_description = """\ 115c4cb323SPavel LabathImplements a fake qemu for testing purposes. The executable program 125c4cb323SPavel Labathis not actually run. Instead a very basic mock process is presented 135c4cb323SPavel Labathto lldb. This allows us to check the invocation parameters. 145c4cb323SPavel Labath 155c4cb323SPavel LabathThe behavior of the emulated "process" is controlled via its command line 165c4cb323SPavel Labatharguments, which should take the form of key:value pairs. Currently supported 175c4cb323SPavel Labathactions are: 185c4cb323SPavel Labath- dump: Dump the state of the emulator as a json dictionary. <value> specifies 195c4cb323SPavel Labath the target filename. 205c4cb323SPavel Labath- stdout: Write <value> to program stdout. 215c4cb323SPavel Labath- stderr: Write <value> to program stderr. 225c4cb323SPavel Labath- stdin: Read a line from stdin and store it in the emulator state. <value> 235c4cb323SPavel Labath specifies the dictionary key. 245c4cb323SPavel Labath""" 255c4cb323SPavel Labath 26*2238dcc3SJonas Devlieghere 2714086849SPavel Labathclass MyResponder(MockGDBServerResponder): 285c4cb323SPavel Labath def __init__(self, state): 295c4cb323SPavel Labath super().__init__() 305c4cb323SPavel Labath self._state = state 315c4cb323SPavel Labath 3214086849SPavel Labath def cont(self): 335c4cb323SPavel Labath for a in self._state["args"]: 345c4cb323SPavel Labath action, data = a.split(":", 1) 355c4cb323SPavel Labath if action == "dump": 365c4cb323SPavel Labath with open(data, "w") as f: 375c4cb323SPavel Labath json.dump(self._state, f) 385c4cb323SPavel Labath elif action == "stdout": 395c4cb323SPavel Labath sys.stdout.write(data) 40d4083a29SPavel Labath sys.stdout.flush() 415c4cb323SPavel Labath elif action == "stderr": 425c4cb323SPavel Labath sys.stderr.write(data) 43d4083a29SPavel Labath sys.stderr.flush() 445c4cb323SPavel Labath elif action == "stdin": 455c4cb323SPavel Labath self._state[data] = sys.stdin.readline() 465c4cb323SPavel Labath else: 475c4cb323SPavel Labath print("Unknown action: %r\n" % a) 485c4cb323SPavel Labath return "X01" 4914086849SPavel Labath return "W47" 5014086849SPavel Labath 51*2238dcc3SJonas Devlieghere 5214086849SPavel Labathclass FakeEmulator(MockGDBServer): 535c4cb323SPavel Labath def __init__(self, addr, state): 5414086849SPavel Labath super().__init__(UnixServerSocket(addr)) 555c4cb323SPavel Labath self.responder = MyResponder(state) 5614086849SPavel Labath 57*2238dcc3SJonas Devlieghere 5814086849SPavel Labathdef main(): 59*2238dcc3SJonas Devlieghere parser = argparse.ArgumentParser( 60*2238dcc3SJonas Devlieghere description=_description, formatter_class=argparse.RawDescriptionHelpFormatter 61*2238dcc3SJonas Devlieghere ) 62*2238dcc3SJonas Devlieghere parser.add_argument("-g", metavar="unix-socket", required=True) 63*2238dcc3SJonas Devlieghere parser.add_argument("-0", metavar="arg0") 64*2238dcc3SJonas Devlieghere parser.add_argument("-fake-arg", dest="fake-arg") 65*2238dcc3SJonas Devlieghere parser.add_argument("program", help="The program to 'emulate'.") 665c4cb323SPavel Labath parser.add_argument("args", nargs=argparse.REMAINDER) 675c4cb323SPavel Labath args = parser.parse_args() 6814086849SPavel Labath 6945aa4356SPavel Labath state = vars(args) 7045aa4356SPavel Labath state["environ"] = dict(os.environ) 7145aa4356SPavel Labath emulator = FakeEmulator(args.g, state) 7214086849SPavel Labath emulator.run() 7314086849SPavel Labath 74*2238dcc3SJonas Devlieghere 7514086849SPavel Labathif __name__ == "__main__": 7614086849SPavel Labath main() 77