This updates the bazel version and changes from workspace to modules.
This also updates gdbserver and adds a test.

PiperOrigin-RevId: 893448002
Change-Id: Ia72a44852ec35d101cfe57b0ff1118bf3ca3f1aa
diff --git a/.bazeliskrc b/.bazeliskrc
index e679d7f..1ab2228 100644
--- a/.bazeliskrc
+++ b/.bazeliskrc
@@ -1 +1 @@
-USE_BAZEL_VERSION=7.1.2
\ No newline at end of file
+USE_BAZEL_VERSION=8.6.0
diff --git a/.bazelrc b/.bazelrc
index e363e37..98cb785 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -21,6 +21,8 @@
 
 build --copt=-Wno-unused-function --cxxopt="-std=c++17"
 build --host_copt=-Wno-unused-function --host_cxxopt="-std=c++17"
-# TODO: migrate all dependencies from WORKSPACE to MODULE.bazel
-# https://github.com/protocolbuffers/protobuf/issues/14313
-common --noenable_bzlmod
+
+# Force include cstdint to provide uintptr_t for Abseil and other deps
+build --cxxopt=-include --cxxopt=cstdint
+build --host_cxxopt=-include --host_cxxopt=cstdint
+
diff --git a/.bazelversion b/.bazelversion
index a8a1887..acd405b 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-7.1.2
+8.6.0
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..af9ac3d
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,63 @@
+# Copyright 2026 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module(
+    name = "com_google_mpact-sim",
+    version = "1.0.0",
+)
+
+# Core Dependencies
+bazel_dep(
+    name = "abseil-cpp",
+    version = "20240116.2",
+)
+bazel_dep(
+    name = "protobuf",
+    version = "29.0",
+    repo_name = "com_google_protobuf",
+)
+bazel_dep(
+    name = "googletest",
+    version = "1.14.0.bcr.1",
+    repo_name = "com_google_googletest",
+)
+bazel_dep(
+    name = "re2",
+    version = "2023-11-01",
+    repo_name = "com_googlesource_code_re2",
+)
+bazel_dep(
+    name = "rules_license",
+    version = "1.0.0",
+)
+bazel_dep(
+    name = "bazel_skylib",
+    version = "1.7.1",
+)
+bazel_dep(
+    name = "rules_cc",
+    version = "0.1.3",
+)
+
+# In MODULE.bazel
+non_module_deps = use_extension(
+    "//:extensions.bzl",
+    "non_module_deps",
+)
+use_repo(
+    non_module_deps,
+    "com_github_serge1_elfio",
+    "org_antlr4_cpp_runtime",
+    "org_antlr_tool",
+)
diff --git a/WORKSPACE b/WORKSPACE
deleted file mode 100644
index 1df72fb..0000000
--- a/WORKSPACE
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2023 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This is the base library for the fundamental interfaces and data structures
-# used in the simulator. All pieces are meant to be generic. If any
-# specialization is required, architecture dependent projects should define
-# appropriate (possibly derived) supplementary structures.
-
-workspace(name = "com_google_mpact-sim")
-
-# Setup dependent repositories.
-load("//:repos.bzl", "mpact_sim_repos")
-
-mpact_sim_repos()
-
-load("//:deps.bzl", "mpact_sim_deps")
-
-mpact_sim_deps()
-
-load("//:protobuf_deps.bzl", "mpact_sim_protobuf_deps")
-
-mpact_sim_protobuf_deps()
diff --git a/extensions.bzl b/extensions.bzl
new file mode 100644
index 0000000..5aee910
--- /dev/null
+++ b/extensions.bzl
@@ -0,0 +1,46 @@
+# Copyright 2026 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Extensions for mpact-sim that are not handled by MODULE.bazel."""
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
+
+def _non_module_deps_impl(ctx):  # @unused
+    # ELFIO header based library
+    http_archive(
+        name = "com_github_serge1_elfio",
+        build_file = "@com_google_mpact-sim//:external/BUILD.elfio",
+        sha256 = "caf49f3bf55a9c99c98ebea4b05c79281875783802e892729eea0415505f68c4",
+        strip_prefix = "elfio-3.12",
+        urls = ["https://github.com/serge1/ELFIO/releases/download/Release_3.12/elfio-3.12.tar.gz"],
+    )
+
+    # Antlr4 tool (java)
+    http_file(
+        name = "org_antlr_tool",
+        sha256 = "bc13a9c57a8dd7d5196888211e5ede657cb64a3ce968608697e4f668251a8487",
+        url = "https://www.antlr.org/download/antlr-4.13.1-complete.jar",
+    )
+
+    # Antlr4 c++ runtime
+    http_archive(
+        name = "org_antlr4_cpp_runtime",
+        add_prefix = "antlr4-runtime",
+        build_file = "@com_google_mpact-sim//:external/BUILD.antlr4",
+        sha256 = "d350e09917a633b738c68e1d6dc7d7710e91f4d6543e154a78bb964cfd8eb4de",
+        strip_prefix = "runtime/src",
+        urls = ["https://www.antlr.org/download/antlr4-cpp-runtime-4.13.1-source.zip"],
+    )
+
+non_module_deps = module_extension(implementation = _non_module_deps_impl)
diff --git a/external/BUILD.antlr4 b/external/BUILD.antlr4
index 15ffad5..2cddbaa 100644
--- a/external/BUILD.antlr4
+++ b/external/BUILD.antlr4
@@ -27,10 +27,10 @@
         exclude = ["antlr4-runtime/antlr4-runtime.h"],
     ),
     deps = [
-        "@com_google_absl//absl/base",
-        "@com_google_absl//absl/base:core_headers",
-        "@com_google_absl//absl/container:flat_hash_map",
-        "@com_google_absl//absl/container:flat_hash_set",
-        "@com_google_absl//absl/synchronization",
+        "@abseil-cpp//absl/base",
+        "@abseil-cpp//absl/base:core_headers",
+        "@abseil-cpp//absl/container:flat_hash_map",
+        "@abseil-cpp//absl/container:flat_hash_set",
+        "@abseil-cpp//absl/synchronization",
     ],
 )
diff --git a/mpact/sim/generic/debug_info.h b/mpact/sim/generic/debug_info.h
index 9635dd2..3c4430b 100644
--- a/mpact/sim/generic/debug_info.h
+++ b/mpact/sim/generic/debug_info.h
@@ -41,6 +41,8 @@
   // Returns the first and last general purpose register numbers.
   virtual int GetFirstGpr() const = 0;
   virtual int GetLastGpr() const = 0;
+  // Get the pc register number.
+  virtual int GetPcRegister() const = 0;
   // Returns the byte width of the general purpose registers.
   virtual int GetGprWidth() const = 0;
   // Returns the byte width of the register with the given number.
diff --git a/mpact/sim/generic/decode_cache.h b/mpact/sim/generic/decode_cache.h
index d87cd6a..e523649 100644
--- a/mpact/sim/generic/decode_cache.h
+++ b/mpact/sim/generic/decode_cache.h
@@ -45,9 +45,10 @@
 
 // Instructions are decoded into an internal representation for the simulator.
 // Because the decode process can be slow (at least there's no requirement that
-// it be fast), the decoded internal represenations are cached in a DecodeCache.
-// The organization of the decode cache is specified by a DecodeCacheProperties
-// struct which is passed in to the DecodeCache constructor.
+// it be fast), the decoded internal representations are cached in a
+// DecodeCache. The organization of the decode cache is specified by a
+// DecodeCacheProperties struct which is passed in to the DecodeCache
+// constructor.
 //
 // Instruction decode invalidation is supported, for the whole decode cache,
 // an address range in the decode cache, or for a single instruction address.
diff --git a/mpact/sim/util/gdbserver/gdbserver.cc b/mpact/sim/util/gdbserver/gdbserver.cc
index 3f8467e..b4d9ee9 100644
--- a/mpact/sim/util/gdbserver/gdbserver.cc
+++ b/mpact/sim/util/gdbserver/gdbserver.cc
@@ -70,12 +70,12 @@
 
 namespace mpact::sim::util::gdbserver {
 
-LazyRE2 GdbServer::gdb_command_re_(R"(\$([^#]*)#([0-9a-fA-F]{2}))");
-LazyRE2 GdbServer::thread_re_(R"(;?thread\:(\d+);?)");
-LazyRE2 GdbServer::xfer_read_target_re_(
-    R"(Xfer\:features\:read\:target\.xml\:([0-9a-fA-F]+),([0-9a-fA-F]+))");
-LazyRE2 GdbServer::swbreak_set_re_(R"(Z0,([0-9a-fA-F]+),(.+))");
-LazyRE2 GdbServer::swbreak_clear_re_(R"(z0,([0-9a-fA-F]+),(.+))");
+LazyRE2 GdbServer::gdb_command_re_{R"(\$([^#]*)#([0-9a-fA-F]{2}))"};
+LazyRE2 GdbServer::thread_re_{R"(;?thread\:(\d+);?)"};
+LazyRE2 GdbServer::xfer_read_target_re_{
+    R"(Xfer\:features\:read\:target\.xml\:([0-9a-fA-F]+),([0-9a-fA-F]+))"};
+LazyRE2 GdbServer::swbreak_set_re_{R"(Z0,([0-9a-fA-F]+),(.+))"};
+LazyRE2 GdbServer::swbreak_clear_re_{R"(z0,([0-9a-fA-F]+),(.+))"};
 
 using ::mpact::sim::generic::operator*;  // NOLINT
 using HaltReason = ::mpact::sim::generic::CoreDebugInterface::HaltReason;
@@ -495,13 +495,14 @@
   return encoded_str;
 }
 
-std::string GdbServer::HexEncodeNumberInTargetEndianness(uint64_t number) {
+std::string GdbServer::HexEncodeNumberInTargetEndianness(int bit_width,
+                                                         uint64_t number) {
   std::string encoded_number;
   // Encode the number into a hex string in little endian format.
-  do {
+  for (int i = 0; i < bit_width; i += 8) {
     absl::StrAppend(&encoded_number, absl::Hex(number & 0xff, absl::kZeroPad2));
     number >>= 8;
-  } while (number > 0);
+  }
   return encoded_number;
 }
 
@@ -519,26 +520,42 @@
 }
 
 std::string GdbServer::GetHaltReason(int thread_id) {
+  auto pc_result = core_debug_interfaces_[thread_id]->ReadRegister("pc");
+  if (!pc_result.ok()) {
+    return "E01";
+  }
+  std::string encoded_pc =
+      absl::StrCat(absl::Hex(debug_info_.GetPcRegister()), ":",
+                   HexEncodeNumberInTargetEndianness(debug_info_.GetGprWidth(),
+                                                     pc_result.value()),
+                   ";");
   auto result = core_debug_interfaces_[thread_id]->GetLastHaltReason();
   if (!result.ok()) {
     return "E01";
   }
   halt_reasons_[0] = result.value();
+  std::string halt_reason_str;
   switch (result.value()) {
     default:
-      return "T05thread:1;";
+      halt_reason_str = "T05thread:1;";
+      break;
     case *HaltReason::kSoftwareBreakpoint:
     case *HaltReason::kHardwareBreakpoint:
     case *HaltReason::kDataWatchPoint:
     case *HaltReason::kActionPoint:
-      return "T02thread:1;";
+      halt_reason_str = "T02thread:1;";
+      break;
     case *HaltReason::kSimulatorError:
-      return "T06thread:1;";
+      halt_reason_str = "T06thread:1;";
+      break;
     case *HaltReason::kUserRequest:
-      return "T03thread:1;";
+      halt_reason_str = "T03thread:1;";
+      break;
     case *HaltReason::kProgramDone:
-      return "W00thread:1;";
+      halt_reason_str = "W00thread:1;";
+      break;
   }
+  return absl::StrCat(halt_reason_str, encoded_pc);
 }
 
 void GdbServer::GdbHaltReason() { Respond(GetHaltReason(0)); }
@@ -702,12 +719,14 @@
     case *HaltReason::kSoftwareBreakpoint:
       address = core_debug_interfaces_[0]->GetSwBreakpointInfo();
       return Respond(absl::StrCat("T05thread:1;swbreak:;",
-                                  HexEncodeNumberInTargetEndianness(address)));
+                                  HexEncodeNumberInTargetEndianness(
+                                      debug_info_.GetGprWidth(), address)));
     case *HaltReason::kHardwareBreakpoint:
       return Respond("T05thread:1;hwbreak:;");
     case *HaltReason::kDataWatchPoint: {
       core_debug_interfaces_[0]->GetWatchpointInfo(address, access_type);
-      std::string encoded_address = HexEncodeNumberInTargetEndianness(address);
+      std::string encoded_address =
+          HexEncodeNumberInTargetEndianness(debug_info_.GetGprWidth(), address);
       // Need to differentiate between write (watch), read (rwatch), and
       // read/write (awatch) watch points.
       switch (access_type) {
diff --git a/mpact/sim/util/gdbserver/gdbserver.h b/mpact/sim/util/gdbserver/gdbserver.h
index 791eccd..d2f90ad 100644
--- a/mpact/sim/util/gdbserver/gdbserver.h
+++ b/mpact/sim/util/gdbserver/gdbserver.h
@@ -109,7 +109,7 @@
   void ParseGdbCommand(std::string_view command);
 
   std::string HexEncodeString(std::string_view str);
-  std::string HexEncodeNumberInTargetEndianness(uint64_t number);
+  std::string HexEncodeNumberInTargetEndianness(int bit_width, uint64_t number);
   // GDB command handlers.
 
   // Halt the simulator.
diff --git a/mpact/sim/util/gdbserver/test/BUILD b/mpact/sim/util/gdbserver/test/BUILD
index 519999e..35a1e58 100644
--- a/mpact/sim/util/gdbserver/test/BUILD
+++ b/mpact/sim/util/gdbserver/test/BUILD
@@ -21,16 +21,16 @@
 
 cc_test(
     name = "gdbserver_test",
+    size = "small",
     srcs = ["gdbserver_test.cc"],
     deps = [
         "//mpact/sim/generic:core",
         "//mpact/sim/generic:core_debug_interface",
         "//mpact/sim/generic:instruction",
         "//mpact/sim/util/gdbserver",
-        "//net/util:ports",
-        "//thread/fiber",
         "@abseil-cpp//absl/container:flat_hash_map",
         "@abseil-cpp//absl/log",
+        "@abseil-cpp//absl/random",
         "@abseil-cpp//absl/status",
         "@abseil-cpp//absl/strings",
         "@abseil-cpp//absl/strings:str_format",
diff --git a/mpact/sim/util/gdbserver/test/gdbserver_test.cc b/mpact/sim/util/gdbserver/test/gdbserver_test.cc
index 2898b2f..275882f 100644
--- a/mpact/sim/util/gdbserver/test/gdbserver_test.cc
+++ b/mpact/sim/util/gdbserver/test/gdbserver_test.cc
@@ -25,10 +25,12 @@
 #include <cstdint>
 #include <cstring>
 #include <string>
+#include <thread>  // NOLINT
 #include <vector>
 
 #include "absl/container/flat_hash_map.h"
 #include "absl/log/log.h"
+#include "absl/random/random.h"
 #include "absl/status/status.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_cat.h"
@@ -43,8 +45,6 @@
 #include "mpact/sim/generic/data_buffer.h"
 #include "mpact/sim/generic/debug_info.h"
 #include "mpact/sim/generic/instruction.h"
-#include "net/util/ports.h"
-#include "thread/fiber/fiber.h"
 
 namespace mpact::sim::util::gdbserver {
 namespace {
@@ -61,6 +61,8 @@
 using ::testing::_;
 using ::testing::Return;
 
+constexpr int kNumPortsToTry = 100;
+
 // Mock debug interface for testing.
 class MockCoreDebugInterface : public CoreDebugInterface {
  public:
@@ -118,6 +120,7 @@
   int GetFirstGpr() const override { return 0; }
   int GetLastGpr() const override { return 31; }
   int GetGprWidth() const override { return 64; }
+  int GetPcRegister() const override { return 32; }
   int GetRegisterByteWidth(int register_number) const override {
     return 64 / 8;
   }
@@ -241,17 +244,52 @@
     delete debug_info_;
   }
 
+  bool isPortFree(int port) {
+    int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
+    if (sock_fd < 0) {
+      return false;
+    }
+    int one = 1;
+    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
+      return false;
+    }
+    sockaddr_in server_addr;
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_addr.s_addr = INADDR_ANY;
+    server_addr.sin_port = htons(port);
+    std::memset(&server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));
+    if (bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) <
+        0) {
+      return false;
+    }
+    close(sock_fd);
+    return true;
+  }
+
+  int PickUnusedPortOrDie() {
+    for (int i = 0; i < kNumPortsToTry; ++i) {
+      int port = absl::Uniform(bitgen_, 32768, 65535);
+      if (isPortFree(port)) {
+        absl::SleepFor(absl::Milliseconds(100));
+        return port;
+      }
+    }
+    LOG(FATAL) << "No unused port found";
+    return -1;
+  }
+
   MockCoreDebugInterface mock_core_;
   std::vector<CoreDebugInterface*> core_debug_interfaces_;
   DebugInfo* debug_info_;
   GdbServer* gdb_server_;
   DataBufferFactory db_factory_;
+  absl::BitGen bitgen_;
 };
 
 TEST_F(GdbServerTest, Detach) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   // Give server time to start up and listen.
   absl::SleepFor(absl::Milliseconds(100));
@@ -270,16 +308,19 @@
   // Client should ack response.
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, HaltReason) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
   EXPECT_CALL(mock_core_, GetLastHaltReason())
       .WillOnce(Return(
           static_cast<HaltReasonValueType>(HaltReason::kSoftwareBreakpoint)));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  // Reading register 32 ('pc', hex '20').
+  EXPECT_CALL(mock_core_, ReadRegister("pc")).WillOnce(Return(0x1234));
+
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   // Give server time to start up and listen.
   absl::SleepFor(absl::Milliseconds(100));
@@ -293,8 +334,8 @@
   client.SendCommand("?");
   // Server should ack command.
   EXPECT_TRUE(client.ExpectAck());
-  // Server should respond with T02thread:1;.
-  EXPECT_EQ("T02thread:1;", client.ReceiveResponse());
+  // Server should respond with T02thread:1;20:3421000000000000.
+  EXPECT_EQ("T02thread:1;20:3412000000000000;", client.ReceiveResponse());
   // Client should ack response.
   client.SendAck();
 
@@ -304,11 +345,11 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, ReadGpr) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   std::vector<std::array<uint8_t, 8>> reg_storage(32);
   std::vector<generic::DataBuffer*> dbs;
@@ -324,7 +365,7 @@
         .WillOnce(Return(dbs[i]));
   }
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -349,11 +390,11 @@
   EXPECT_TRUE(client.ExpectAck());
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, ReadRegister) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   uint64_t reg_val = 0x1234;
   generic::DataBuffer* db = db_factory_.Allocate<uint8_t>(8);
@@ -362,7 +403,7 @@
   // Reading register 32 ('pc', hex '20').
   EXPECT_CALL(mock_core_, GetRegisterDataBuffer("pc")).WillOnce(Return(db));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -383,11 +424,11 @@
   EXPECT_TRUE(client.ExpectAck());
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, ReadMemory) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   // Read 4 bytes from 0x1000.
   EXPECT_CALL(mock_core_, ReadMemory(0x1000, _, 4))
@@ -397,7 +438,7 @@
         return 4;
       });
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -416,11 +457,11 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, Continue) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   EXPECT_CALL(mock_core_, GetRunStatus()).WillOnce(Return(RunStatus::kHalted));
   EXPECT_CALL(mock_core_, Run()).WillOnce(Return(absl::OkStatus()));
@@ -428,8 +469,10 @@
   EXPECT_CALL(mock_core_, GetLastHaltReason())
       .WillOnce(Return(
           static_cast<HaltReasonValueType>(HaltReason::kHardwareBreakpoint)));
+  // Reading register 32 ('pc', hex '20').
+  EXPECT_CALL(mock_core_, ReadRegister("pc")).WillOnce(Return(0x1234));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -439,7 +482,7 @@
   client.SendAck();
   client.SendCommand("c");
   EXPECT_TRUE(client.ExpectAck());
-  EXPECT_EQ("T02thread:1;", client.ReceiveResponse());
+  EXPECT_EQ("T02thread:1;20:3412000000000000;", client.ReceiveResponse());
   client.SendAck();
 
   client.SendCommand("D");
@@ -447,15 +490,15 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, Step) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   EXPECT_CALL(mock_core_, Step(1)).WillOnce(Return(1));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -473,11 +516,11 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, WriteGpr) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   std::vector<generic::DataBuffer*> dbs;
   for (int i = 0; i < 32; ++i) {
@@ -490,7 +533,7 @@
         .WillOnce(Return(dbs[i]));
   }
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -517,18 +560,18 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, WriteRegister) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   generic::DataBuffer* db = db_factory_.Allocate<uint8_t>(8);
 
   // Writing register 32 ('pc', hex '20').
   EXPECT_CALL(mock_core_, GetRegisterDataBuffer("pc")).WillOnce(Return(db));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -551,11 +594,11 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, WriteMemory) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   // Write 4 bytes to 0x1000 with value 01020304.
   EXPECT_CALL(mock_core_, WriteMemory(0x1000, _, 4))
@@ -566,7 +609,7 @@
         return absl::InternalError("Memory content mismatch");
       });
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
 
@@ -585,16 +628,16 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, SetSwBreakpoint) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   EXPECT_CALL(mock_core_, SetSwBreakpoint(0x1000))
       .WillOnce(Return(absl::OkStatus()));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
   GdbTestClient client;
@@ -612,16 +655,16 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 TEST_F(GdbServerTest, ClearSwBreakpoint) {
-  int port = net_util::PickUnusedPortOrDie();
+  int port = PickUnusedPortOrDie();
 
   EXPECT_CALL(mock_core_, ClearSwBreakpoint(0x1000))
       .WillOnce(Return(absl::OkStatus()));
 
-  thread::Fiber server_fiber([&]() { gdb_server_->Connect(port); });
+  std::thread server_fiber([&]() { gdb_server_->Connect(port); });
 
   absl::SleepFor(absl::Milliseconds(100));
   GdbTestClient client;
@@ -639,7 +682,7 @@
   EXPECT_EQ("OK", client.ReceiveResponse());
   client.SendAck();
 
-  server_fiber.Join();
+  server_fiber.join();
 }
 
 }  // namespace
diff --git a/repos.bzl b/repos.bzl
index 2fde949..8369fb5 100644
--- a/repos.bzl
+++ b/repos.bzl
@@ -19,59 +19,6 @@
 def mpact_sim_repos():
     """ Load dependencies needed to use mpact-sim as a 3rd-party consumer"""
 
-    # Google Absail.
-    if not native.existing_rule("com_google_absl"):
-        http_archive(
-            name = "com_google_absl",
-            sha256 = "f50e5ac311a81382da7fa75b97310e4b9006474f9560ac46f54a9967f07d4ae3",
-            strip_prefix = "abseil-cpp-20240722.0",
-            url = "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240722.0.tar.gz",
-        )
-
-    # Google protobuf.
-    if not native.existing_rule("com_google_protobuf"):
-        http_archive(
-            name = "com_google_protobuf",
-            sha256 = "b2340aa47faf7ef10a0328190319d3f3bee1b24f426d4ce8f4253b6f27ce16db",
-            strip_prefix = "protobuf-28.2",
-            urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v28.2/protobuf-28.2.tar.gz"],
-        )
-
-    # Google test.
-    if not native.existing_rule("com_google_googletest"):
-        http_archive(
-            name = "com_google_googletest",
-            sha256 = "8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7",
-            strip_prefix = "googletest-1.14.0",
-            urls = ["https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz"],
-        )
-
-    # Transitive dependencies of googletest. Need to list explicitly for v1.13.0.
-    # Can load as deps in a later version.
-    if not native.existing_rule("com_googlesource_code_re2"):
-        http_archive(
-            name = "com_googlesource_code_re2",  # 2023-11-01
-            sha256 = "4e6593ac3c71de1c0f322735bc8b0492a72f66ffccfad76e259fa21c41d27d8a",
-            strip_prefix = "re2-2023-11-01",
-            urls = ["https://github.com/google/re2/archive/refs/tags/2023-11-01/re2-2023-11-01.tar.gz"],
-        )
-
-    # Additional rules for licenses
-    if not native.existing_rule("rules_license"):
-        http_archive(
-            name = "rules_license",
-            sha256 = "6157e1e68378532d0241ecd15d3c45f6e5cfd98fc10846045509fb2a7cc9e381",
-            url = "https://github.com/bazelbuild/rules_license/releases/download/0.0.4/rules_license-0.0.4.tar.gz",
-        )
-
-    if not native.existing_rule("cc_library"):
-        http_archive(
-            name = "rules_cc",
-            url = "https://github.com/bazelbuild/rules_cc/releases/download/0.1.3/rules_cc-0.1.3.tar.gz",
-            strip_prefix = "rules_cc-0.1.3",
-            sha256 = "64cb81641305dcf7b3b3d5a73095ee8fe7444b26f7b72a12227d36e15cfbb6cb",
-        )
-
     # ELFIO header based library.
     http_archive(
         name = "com_github_serge1_elfio",