adds Debug tools
This commit is contained in:
		
							
								
								
									
										5
									
								
								Debug/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Debug/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| *.log | ||||
| *.dis | ||||
| *.asm | ||||
| *.ll | ||||
| *tcc_* | ||||
							
								
								
									
										154
									
								
								Debug/create_reg_traces.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								Debug/create_reg_traces.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| import argparse | ||||
| import os | ||||
| import shutil | ||||
| import subprocess | ||||
| from pathlib import Path | ||||
|  | ||||
|  | ||||
| def validate_elf_file(filepath: str) -> str: | ||||
|     if not os.path.isfile(filepath): | ||||
|         raise argparse.ArgumentTypeError(f"{filepath} is not a valid file.") | ||||
|  | ||||
|     # Use the 'file' command to check if it's an ELF file | ||||
|     result = subprocess.run( | ||||
|         ["file", filepath], capture_output=True, text=True, check=False | ||||
|     ) | ||||
|     if "ELF" not in result.stdout: | ||||
|         raise argparse.ArgumentTypeError(f"{filepath} is not a valid ELF file.") | ||||
|  | ||||
|     return filepath | ||||
|  | ||||
|  | ||||
| def run_test_and_move_output(elf_file: str, backend: str, isa: str = "tgc5c") -> None: | ||||
|     # Call 'test' with the specified backend mode | ||||
|     os.chdir(Path(__file__).parent.parent) | ||||
|     sim_path = "build/Debug/dbt-rise-tgc/tgc-sim" | ||||
|     run_command = [ | ||||
|         sim_path, | ||||
|         "-f", | ||||
|         elf_file, | ||||
|         "--backend", | ||||
|         backend, | ||||
|         "--isa", | ||||
|         isa, | ||||
|         "-p", | ||||
|         "build/Debug/dbt-rise-plugins/pctrace/pctrace.so=dbt-rise-tgc/contrib/instr/TGC5C_instr.yaml", | ||||
|         "-i", | ||||
|         "10000", | ||||
|     ] | ||||
|     print(f"Running: \n{' '.join(run_command)}") | ||||
|     try: | ||||
|         subprocess.run(run_command, check=False, timeout=10) | ||||
|     except subprocess.TimeoutExpired: | ||||
|         print("Execution timed out") | ||||
|  | ||||
|     # Move the output.trc file | ||||
|     if os.path.exists("output.trc"): | ||||
|         shutil.move("output.trc", f"Debug/{backend}.trc") | ||||
|     else: | ||||
|         print( | ||||
|             f"output.trc does not exist after running with backend {backend}, so it cannot be renamed." | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def create_shortened_diff_files(backend: str) -> None: | ||||
|     file1_path = "Debug/interp.trc" | ||||
|     file2_path = f"Debug/{backend}.trc" | ||||
|  | ||||
|     def validate_file(filepath: str) -> str: | ||||
|         if not os.path.isfile(filepath): | ||||
|             raise ValueError(f"{filepath} is not a valid file.") | ||||
|         return filepath | ||||
|  | ||||
|     file1_path = validate_file(file1_path) | ||||
|     file2_path = validate_file(file2_path) | ||||
|  | ||||
|     with open(file1_path, "r", encoding="utf8") as file1, open( | ||||
|         file2_path, "r", encoding="utf8" | ||||
|     ) as file2: | ||||
|         lines1 = file1.readlines() | ||||
|         lines2 = file2.readlines() | ||||
|  | ||||
|     diff_index = -1 | ||||
|     for index, (line1, line2) in enumerate(zip(lines1, lines2)): | ||||
|         if line1 != line2: | ||||
|             diff_index = index | ||||
|             break | ||||
|  | ||||
|     if diff_index == -1: | ||||
|         print("The files are identical.") | ||||
|         return | ||||
|  | ||||
|     start_index = max(0, diff_index - 5) | ||||
|     end_index = min(len(lines1), diff_index + 6) | ||||
|  | ||||
|     shortened_lines1 = lines1[start_index:end_index] | ||||
|     shortened_lines2 = lines2[start_index:end_index] | ||||
|  | ||||
|     with open("Debug/short_interp.trc", "w", encoding="utf8") as short_file1: | ||||
|         short_file1.writelines(shortened_lines1) | ||||
|  | ||||
|     with open(f"Debug/short_{backend}.trc", "w", encoding="utf8") as short_file2: | ||||
|         short_file2.writelines(shortened_lines2) | ||||
|  | ||||
|  | ||||
| def create_disassembly(elf_file_path: str) -> None: | ||||
|     def validate_file(filepath: str) -> str: | ||||
|         if not os.path.isfile(filepath): | ||||
|             raise ValueError(f"{filepath} is not a valid file.") | ||||
|         return filepath | ||||
|  | ||||
|     elf_file_path = validate_file(elf_file_path) | ||||
|  | ||||
|     output_file_path = "Debug/dut.dis" | ||||
|     with open(output_file_path, "w", encoding="utf8") as output_file: | ||||
|         subprocess.run( | ||||
|             [ | ||||
|                 "riscv64-unknown-elf-objdump", | ||||
|                 "-d", | ||||
|                 "-Mnumeric", | ||||
|                 "-Mno-aliases", | ||||
|                 elf_file_path, | ||||
|             ], | ||||
|             stdout=output_file, | ||||
|             check=True, | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def main(args: argparse.Namespace) -> None: | ||||
|     elf_file = args.elf_file | ||||
|     backend = args.backend | ||||
|     isa = args.isa | ||||
|  | ||||
|     # Set environment variable | ||||
|     os.environ["REGDUMP"] = "True" | ||||
|  | ||||
|     # Run the tests and move the output files | ||||
|     run_test_and_move_output(elf_file, "interp", isa) | ||||
|     run_test_and_move_output(elf_file, backend, isa) | ||||
|     create_shortened_diff_files(backend) | ||||
|     create_disassembly(elf_file) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     parser = argparse.ArgumentParser( | ||||
|         description="Process an ELF file with a specified backend. Generates register traces for interp and the specified backend" | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "elf_file", type=validate_elf_file, help="The ELF file to be processed." | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--backend", | ||||
|         type=str, | ||||
|         default="amsjit", | ||||
|         help="The backend to be used. Default is amsjit.", | ||||
|         required=False, | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--isa", | ||||
|         type=str, | ||||
|         default="tgc5c", | ||||
|         help="The isa to be used. Default 'tgc5c'", | ||||
|         required=False, | ||||
|     ) | ||||
|     main(args=parser.parse_args()) | ||||
							
								
								
									
										26
									
								
								Debug/makeJitOutputReadable.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Debug/makeJitOutputReadable.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| import re | ||||
| import os | ||||
| ''' | ||||
| This script takes all files that get dumped by the tcc backend when using the --dump-ir | ||||
| option and replaces the Integers of addresses with their hex representation to allow | ||||
| for easier debugging. | ||||
| ''' | ||||
| current_dir = os.getcwd()  # Get the current directory | ||||
|  | ||||
| files_with_tcc_jit = [file for file in os.listdir(current_dir) if"jit" in file and not file.startswith("readable")] | ||||
|  | ||||
| for each in files_with_tcc_jit:   | ||||
|     readable_file = f"readable_{each}" | ||||
|     if os.path.exists(readable_file): | ||||
|         os.remove(readable_file) | ||||
|     with open(each, "r") as file: | ||||
|         content = file.read() | ||||
| for each in files_with_tcc_jit: | ||||
|     with open(each, "r") as file: | ||||
|         content = file.read() | ||||
|  | ||||
|     # Replace numbers ending with "U" by their hex representation | ||||
|     content = re.sub(r'\b(\d+)U\b(?=U)?', lambda m: hex(int(m.group(1))), content) | ||||
|  | ||||
|     with open(f"readable_{each}", "w") as file: | ||||
|         file.write(content) | ||||
							
								
								
									
										43
									
								
								Debug/offsets.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								Debug/offsets.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| X0         (zero) : 0  (0x00) | ||||
| X1         (ra)   : 4  (0x04) | ||||
| X2         (sp)   : 8  (0x08) | ||||
| X3         (gp)   : 12 (0x0c) | ||||
| X4         (tp)   : 16 (0x10) | ||||
| X5         (t0)   : 20 (0x14) | ||||
| X6         (t1)   : 24 (0x18) | ||||
| X7         (t2)   : 28 (0x1c) | ||||
| X8         (s0/fp): 32 (0x20) | ||||
| X9         (s1)   : 36 (0x24) | ||||
| X10        (a0)   : 40 (0x28) | ||||
| X11        (a1)   : 44 (0x2c) | ||||
| X12        (a2)   : 48 (0x30) | ||||
| X13        (a3)   : 52 (0x34) | ||||
| X14        (a4)   : 56 (0x38) | ||||
| X15        (a5)   : 60 (0x3c) | ||||
| X16        (a6)   : 64 (0x40) | ||||
| X17        (a7)   : 68 (0x44) | ||||
| X18        (s2)   : 72 (0x48) | ||||
| X19        (s3)   : 76 (0x4c) | ||||
| X20        (s4)   : 80 (0x50) | ||||
| X21        (s5)   : 84 (0x54) | ||||
| X22        (s6)   : 88 (0x58) | ||||
| X23        (s7)   : 92 (0x5c) | ||||
| X24        (s8)   : 96 (0x60) | ||||
| X25        (s9)   : 100 (0x64) | ||||
| X26        (s10)  : 104 (0x68) | ||||
| X27        (s11)  : 108 (0x6c) | ||||
| X28        (t3)   : 112 (0x70) | ||||
| X29        (t4)   : 116 (0x74) | ||||
| X30        (t5)   : 120 (0x78) | ||||
| X31        (t6)   : 124 (0x7c) | ||||
| PC                : 128 (0x80) | ||||
| NEXT_PC           : 132 (0x84) | ||||
| PRIV              : 136 (0x88) | ||||
| DPC               : 137 (0x89) | ||||
| trap_state        : 141 (0x8d) | ||||
| pending_trap      : 145 (0x91) | ||||
| icount            : 149 (0x95) | ||||
| cycle             : 157 (0x9d) | ||||
| instret           : 165 (0xa5) | ||||
| instruction       : 173 (0xad) | ||||
| last_branch       : 177 (0xb1) | ||||
							
								
								
									
										29
									
								
								Debug/simplify_sail_trace.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Debug/simplify_sail_trace.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import argparse | ||||
| import re | ||||
|  | ||||
|  | ||||
| def simplify_trace(input_file, output_file): | ||||
|     with open(input_file, "r") as infile, open(output_file, "w") as outfile: | ||||
|         for line in infile: | ||||
|             # Enhanced regex to match the instruction number, mode, and PC | ||||
|             match = re.search(r"\[\d+\] \[[MI]\]: (0x[0-9A-Fa-f]+)", line) | ||||
|             if match: | ||||
|                 pc = match.group(1).lower() | ||||
|                 outfile.write(f"{pc}\n") | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     parser = argparse.ArgumentParser( | ||||
|         description="Simplify a trace from an instruction set simulator." | ||||
|     ) | ||||
|     parser.add_argument("input_file", type=str, help="The input trace file") | ||||
|     parser.add_argument( | ||||
|         "output_file", type=str, help="The output file for the simplified trace" | ||||
|     ) | ||||
|  | ||||
|     args = parser.parse_args() | ||||
|     simplify_trace(args.input_file, args.output_file) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
							
								
								
									
										26
									
								
								Debug/simplify_tgc_trace.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Debug/simplify_tgc_trace.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| import argparse | ||||
|  | ||||
|  | ||||
| def simplify_trace(input_file, output_file): | ||||
|     with open(input_file, "r") as infile, open(output_file, "w") as outfile: | ||||
|         for line in infile: | ||||
|             # Split the line by the first comma and take the PC part | ||||
|             pc = line.split(",")[0].strip().lower() | ||||
|             outfile.write(f"{pc}\n") | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     parser = argparse.ArgumentParser( | ||||
|         description="Simplify traces from instruction set simulators." | ||||
|     ) | ||||
|     parser.add_argument("input_file", type=str, help="The input trace file") | ||||
|     parser.add_argument( | ||||
|         "output_file", type=str, help="The output file for the simplified trace" | ||||
|     ) | ||||
|  | ||||
|     args = parser.parse_args() | ||||
|     simplify_trace(args.input_file, args.output_file) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
		Reference in New Issue
	
	Block a user