[libc-commits] [libc] Enable bare-metal hermetic tests on Arm (PR #207361)

Petr Hosek via libc-commits libc-commits at lists.llvm.org
Tue Jul 7 01:05:44 PDT 2026


================
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Arm bare-metal hermetic test utilities.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/ssize_t.h"
+#include "hdr/types/struct_timespec.h"
+
+// Redirect stdout/stderr, time and exit from libc tests to semihosting
+
+namespace {
+// Semihosting constants and semihosting call wrapper.
+// https://github.com/ARM-software/abi-aa/blob/main/semihosting/semihosting.rst
+constexpr uint32_t SYS_OPEN = 0x01;
+constexpr uint32_t SYS_WRITE = 0x05;
+constexpr uint32_t SYS_CLOCK = 0x10;
+constexpr uint32_t SYS_TIME = 0x11;
+constexpr uint32_t SYS_EXIT = 0x18;
+
+constexpr uint32_t OPENMODE_W = 4;
+
+constexpr uint32_t ADP_Stopped_ApplicationExit = 0x20026;
+constexpr uint32_t ADP_Stopped_RunTimeErrorUnknown = 0x20023;
+
+#if defined(__thumb__) // T32
+#if defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
+#define SEMIHOST_INSTRUCTION "bkpt #0xAB"
+#else
+#define SEMIHOST_INSTRUCTION "svc 0xab"
+#endif
+#else // A32
+#define SEMIHOST_INSTRUCTION "svc 0x123456"
+#endif
+
+long semihosting_call(long val, const void *ptr) {
+  register long v __asm__("r0") = val;
+  register const void *p __asm__("r1") = ptr;
+  __asm__ __volatile__(SEMIHOST_INSTRUCTION
+                       : "+r"(v), "+r"(p)
+                       :
+                       : "memory", "cc");
+  return v;
+}
+} // namespace
+
+extern "C" {
+struct __llvm_libc_stdio_cookie {
+  int handle;
+};
+
+struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
+struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
+
+static void stdio_open(struct __llvm_libc_stdio_cookie *cookie, size_t mode) {
+  const char std_stream_name[] = ":tt";
+  size_t args[3];
+  args[0] = reinterpret_cast<size_t>(std_stream_name);
+  args[1] = mode;
+  args[2] = sizeof(std_stream_name) - 1UL;
----------------
petrhosek wrote:

I'd prefer the following so you don't need to manually specify the size or indices which is error-prone.
```suggestion
  size_t args[] = {
    reinterpret_cast<size_t>(std_stream_name),
    mode,
    sizeof(std_stream_name) - 1UL,
  }
```

https://github.com/llvm/llvm-project/pull/207361


More information about the libc-commits mailing list