Added feature where if halt is performed by writing to 'tohost', then
the code that is written to '31..1' of 'tohost' is used as the program
exit code.

PiperOrigin-RevId: 708063430
Change-Id: I678ff01a5fa0be3f52809babe0b37149b215aa1e
diff --git a/cheriot/mpact_cheriot.cc b/cheriot/mpact_cheriot.cc
index 74efd2c..edc3006 100644
--- a/cheriot/mpact_cheriot.cc
+++ b/cheriot/mpact_cheriot.cc
@@ -243,6 +243,7 @@
 int main(int argc, char **argv) {
   absl::SetProgramUsageMessage(argv[0]);
   auto arg_vec = absl::ParseCommandLine(argc, argv);
+  int exit_code = 0;
 
   if (arg_vec.size() > 2) {
     std::cerr << "Only a single input file allowed" << std::endl;
@@ -342,12 +343,14 @@
     auto status = cheriot_top.tagged_watcher()->SetStoreWatchCallback(
         TaggedMemoryWatcher::AddressRange{
             tohost_addr, tohost_addr + 2 * sizeof(uint32_t) - 1},
-        [tagged_memory, tohost_addr, &db, &cheriot_top](uint64_t, int) {
+        [tagged_memory, tohost_addr, &db, &cheriot_top, &exit_code](uint64_t,
+                                                                    int) {
           if (db == nullptr) return;
           tagged_memory->Load(tohost_addr, db, nullptr, nullptr);
           uint32_t code = db->Get<uint32_t>(0);
           if (code & 0x1) {
             code >>= 1;
+            exit_code = code;
             std::cerr << absl::StrCat("Simulation halted: exit ",
                                       absl::Hex(code), "\n");
             (void)cheriot_top.Halt();
@@ -626,4 +629,5 @@
   delete memory_use_profiler;
   delete semihost;
   if (db != nullptr) db->DecRef();
+  return exit_code;
 }