@@ -34,10 +34,12 @@ fn main() -> hyperlight_host::Result<()> {
3434 . host_function ( "Sleep5Secs" , sleep_5_secs)
3535 . build ( ) ?;
3636
37- // Call guest function
37+ # [ cfg ( target_arch = "x86_64" ) ]
3838 multi_use_sandbox_dbg
3939 . call :: < ( ) > ( "UseSSE2Registers" , ( ) )
4040 . unwrap ( ) ;
41+ #[ cfg( target_arch = "aarch64" ) ]
42+ multi_use_sandbox_dbg. call :: < ( ) > ( "NoOp" , ( ) ) . unwrap ( ) ;
4143
4244 let message =
4345 "Hello, World! I am executing inside of a VM with debugger attached :)\n " . to_string ( ) ;
@@ -291,6 +293,205 @@ mod tests {
291293 }
292294
293295 #[ test]
296+ #[ cfg( target_arch = "aarch64" ) ]
297+ #[ serial]
298+ fn test_gdb_bootstrap_step_preserves_live_stack ( ) {
299+ let ( out_file_path, cmd_file_path, manifest_dir) =
300+ gdb_test_paths ( "gdb-aarch64-bootstrap-stack" ) ;
301+ let cmd = format ! (
302+ "set osabi none
303+ file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest
304+ target remote :8080
305+ set pagination off
306+ set logging file {out_file_path}
307+ set logging enabled on
308+ set language c
309+ set $entry = $pc
310+ set $instruction = *(unsigned int *)$entry
311+ set *(unsigned int *)$entry = 0xd503201f
312+ set $bootstrap_sp = $sp
313+ set $canary = $sp - 16
314+ set $saved = *(unsigned long long *)$canary
315+ set *(unsigned long long *)$canary = 0x123456789abcdef0
316+ set $sp = $sp - 32
317+ stepi
318+ if *(unsigned long long *)$canary != 0x123456789abcdef0
319+ echo Bootstrap debug step overwrote the live stack\\ n
320+ quit 1
321+ end
322+ set *(unsigned long long *)$canary = $saved
323+ set $sp = $bootstrap_sp
324+ set *(unsigned int *)$entry = $instruction
325+ set $pc = $entry
326+ echo Bootstrap debug step preserved the live stack\\ n
327+ set logging enabled off
328+ detach
329+ quit
330+ "
331+ ) ;
332+ let result = run_guest_and_gdb ( & cmd_file_path, & out_file_path, & cmd, |contents| {
333+ contents. contains ( "Bootstrap debug step preserved the live stack" )
334+ } ) ;
335+ cleanup ( & out_file_path, & cmd_file_path) ;
336+ assert ! ( result. is_ok( ) , "{}" , result. unwrap_err( ) ) ;
337+ }
338+
339+ #[ test]
340+ #[ cfg( target_arch = "aarch64" ) ]
341+ #[ serial]
342+ fn test_gdb_continue_over_sw_breakpoint ( ) {
343+ let ( out_file_path, cmd_file_path, manifest_dir) = gdb_test_paths ( "gdb-aarch64-continue" ) ;
344+ let cmd = format ! (
345+ "file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest
346+ target remote :8080
347+ set pagination off
348+ set logging file {out_file_path}
349+ set logging enabled on
350+ break simpleguest::no_op
351+ commands 1
352+ continue
353+ end
354+ break simpleguest::print_output
355+ commands 2
356+ echo Continued over ARM64 software breakpoint\\ n
357+ set logging enabled off
358+ detach
359+ quit
360+ end
361+ continue
362+ "
363+ ) ;
364+ #[ cfg( windows) ]
365+ let cmd = format ! ( "set osabi none\n {cmd}" ) ;
366+ let checker =
367+ |contents : String | contents. contains ( "Continued over ARM64 software breakpoint" ) ;
368+ let result = run_guest_and_gdb ( & cmd_file_path, & out_file_path, & cmd, checker) ;
369+
370+ cleanup ( & out_file_path, & cmd_file_path) ;
371+ assert ! ( result. is_ok( ) , "{}" , result. unwrap_err( ) ) ;
372+ }
373+
374+ #[ test]
375+ #[ cfg( target_arch = "aarch64" ) ]
376+ #[ serial]
377+ fn test_gdb_hardware_breakpoint_and_step ( ) {
378+ let ( out_file_path, cmd_file_path, manifest_dir) = gdb_test_paths ( "gdb-aarch64-hardware" ) ;
379+ let cmd = format ! (
380+ "set osabi none
381+ file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest
382+ target remote :8080
383+ set pagination off
384+ set logging file {out_file_path}
385+ set logging enabled on
386+ set $entry_pc = $pc
387+ stepi
388+ if $pc != $entry_pc + 4
389+ echo Entry step did not execute one instruction\\ n
390+ quit 1
391+ end
392+ hbreak simpleguest::no_op
393+ continue
394+ set $return_pc = $x30
395+ stepi
396+ if $pc != $return_pc
397+ echo Hardware RET step missed its destination\\ n
398+ quit 1
399+ end
400+ echo Hardware breakpoint and entry/RET stepping passed\\ n
401+ set logging enabled off
402+ detach
403+ quit
404+ "
405+ ) ;
406+ let checker = |contents : String | {
407+ contents. contains ( "Hardware breakpoint and entry/RET stepping passed" )
408+ } ;
409+ let result = run_guest_and_gdb ( & cmd_file_path, & out_file_path, & cmd, checker) ;
410+ cleanup ( & out_file_path, & cmd_file_path) ;
411+ assert ! ( result. is_ok( ) , "{}" , result. unwrap_err( ) ) ;
412+ }
413+
414+ #[ test]
415+ #[ cfg( target_arch = "aarch64" ) ]
416+ #[ serial]
417+ fn test_gdb_code_writes_and_self_loop ( ) {
418+ let ( out_file_path, cmd_file_path, manifest_dir) =
419+ gdb_test_paths ( "gdb-aarch64-code-writes" ) ;
420+ let cmd = format ! (
421+ "set osabi none
422+ file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest
423+ target remote :8080
424+ set pagination off
425+ set logging file {out_file_path}
426+ set logging enabled on
427+ hbreak simpleguest::no_op
428+ continue
429+ delete 1
430+ set language c
431+ set $loop_pc = $pc
432+ set $instruction = *(unsigned int *)$pc
433+ set *(unsigned int *)$pc = 0x14000000
434+ stepi
435+ if $pc != $loop_pc
436+ echo Self-loop step missed its destination\\ n
437+ quit 1
438+ end
439+ set *(unsigned int *)$pc = $instruction
440+ set $return_pc = $x30
441+ stepi
442+ if $pc != $return_pc
443+ echo Restored RET missed its destination\\ n
444+ quit 1
445+ end
446+ echo Code writes and self-loop stepping passed\\ n
447+ set logging enabled off
448+ detach
449+ quit
450+ "
451+ ) ;
452+ let checker =
453+ |contents : String | contents. contains ( "Code writes and self-loop stepping passed" ) ;
454+ let result = run_guest_and_gdb ( & cmd_file_path, & out_file_path, & cmd, checker) ;
455+ cleanup ( & out_file_path, & cmd_file_path) ;
456+ assert ! ( result. is_ok( ) , "{}" , result. unwrap_err( ) ) ;
457+ }
458+
459+ #[ test]
460+ #[ cfg( target_arch = "aarch64" ) ]
461+ #[ serial]
462+ fn test_gdb_single_step ( ) {
463+ let ( out_file_path, cmd_file_path, manifest_dir) = gdb_test_paths ( "gdb-aarch64-step" ) ;
464+ let cmd = format ! (
465+ "file {manifest_dir}/../tests/rust_guests/bin/debug/simpleguest
466+ target remote :8080
467+ set pagination off
468+ set logging file {out_file_path}
469+ set logging enabled on
470+ break simpleguest::no_op
471+ stepi
472+ echo Stepped over ARM64 linear instruction\\ n
473+ continue
474+ stepi
475+ echo Stepped over ARM64 RET\\ n
476+ set logging enabled off
477+ detach
478+ quit
479+ "
480+ ) ;
481+ #[ cfg( windows) ]
482+ let cmd = format ! ( "set osabi none\n {cmd}" ) ;
483+ let checker = |contents : String | {
484+ contents. contains ( "Stepped over ARM64 linear instruction" )
485+ && contents. contains ( "Stepped over ARM64 RET" )
486+ } ;
487+ let result = run_guest_and_gdb ( & cmd_file_path, & out_file_path, & cmd, checker) ;
488+
489+ cleanup ( & out_file_path, & cmd_file_path) ;
490+ assert ! ( result. is_ok( ) , "{}" , result. unwrap_err( ) ) ;
491+ }
492+
493+ #[ test]
494+ #[ cfg( target_arch = "x86_64" ) ]
294495 #[ serial]
295496 fn test_gdb_sse_check ( ) {
296497 let ( out_file_path, cmd_file_path, manifest_dir) = gdb_test_paths ( "gdb-sse" ) ;
0 commit comments