[libc-commits] [libc] 0acb639 - [libc] move strerror and strsignal to OS msg maps

Michael Jones via libc-commits libc-commits at lists.llvm.org
Tue Apr 18 16:42:49 PDT 2023


Author: Michael Jones
Date: 2023-04-18T16:42:43-07:00
New Revision: 0acb639fd2350d831f149035e078654a655c209b

URL: https://github.com/llvm/llvm-project/commit/0acb639fd2350d831f149035e078654a655c209b
DIFF: https://github.com/llvm/llvm-project/commit/0acb639fd2350d831f149035e078654a655c209b.diff

LOG: [libc] move strerror and strsignal to OS msg maps

Other OSes may have different mappings from error number to message.
This creates a system to allow new platforms to define their own
mappings.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D147967

Added: 
    libc/src/__support/StringUtil/tables/CMakeLists.txt
    libc/src/__support/StringUtil/tables/error_table.h
    libc/src/__support/StringUtil/tables/linux/CMakeLists.txt
    libc/src/__support/StringUtil/tables/linux/error_table.h
    libc/src/__support/StringUtil/tables/linux/signal_table.h
    libc/src/__support/StringUtil/tables/posix_error_table.h
    libc/src/__support/StringUtil/tables/posix_signal_table.h
    libc/src/__support/StringUtil/tables/signal_table.h
    libc/src/__support/StringUtil/tables/stdc_error_table.h
    libc/src/__support/StringUtil/tables/stdc_signal_table.h

Modified: 
    libc/src/__support/StringUtil/CMakeLists.txt
    libc/src/__support/StringUtil/error_to_string.cpp
    libc/src/__support/StringUtil/error_to_string.h
    libc/src/__support/StringUtil/message_mapper.h
    libc/src/__support/StringUtil/signal_to_string.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/StringUtil/CMakeLists.txt b/libc/src/__support/StringUtil/CMakeLists.txt
index e440792be2777..528f1e8896637 100644
--- a/libc/src/__support/StringUtil/CMakeLists.txt
+++ b/libc/src/__support/StringUtil/CMakeLists.txt
@@ -3,10 +3,13 @@ add_header_library(
   HDRS
     message_mapper.h
   DEPENDS
-  libc.src.__support.CPP.string_view
-  libc.src.__support.CPP.optional
+    libc.src.__support.CPP.string_view
+    libc.src.__support.CPP.optional
 )
 
+# The table maps depend on message_mapper.
+add_subdirectory(tables)
+
 add_object_library(
   error_to_string
   HDRS
@@ -14,15 +17,15 @@ add_object_library(
   SRCS
     error_to_string.cpp
   DEPENDS
-  .message_mapper
-  libc.src.errno.errno
-  libc.src.__support.CPP.span
-  libc.src.__support.CPP.string_view
-  libc.src.__support.CPP.stringstream
-  libc.src.__support.integer_to_string
+    .message_mapper
+    libc.src.errno.errno
+    libc.src.__support.CPP.span
+    libc.src.__support.CPP.string_view
+    libc.src.__support.CPP.stringstream
+    libc.src.__support.integer_to_string
+    libc.src.__support.StringUtil.tables.error_table
 )
 
-
 add_object_library(
   signal_to_string
   HDRS
@@ -30,10 +33,11 @@ add_object_library(
   SRCS
     signal_to_string.cpp
   DEPENDS
-  .message_mapper
-  libc.include.signal
-  libc.src.__support.CPP.span
-  libc.src.__support.CPP.string_view
-  libc.src.__support.CPP.stringstream
-  libc.src.__support.integer_to_string
+    .message_mapper
+    libc.include.signal
+    libc.src.__support.CPP.span
+    libc.src.__support.CPP.string_view
+    libc.src.__support.CPP.stringstream
+    libc.src.__support.integer_to_string
+    libc.src.__support.StringUtil.tables.signal_table
 )

diff  --git a/libc/src/__support/StringUtil/error_to_string.cpp b/libc/src/__support/StringUtil/error_to_string.cpp
index 59e34c5c070df..cd314cb3d4e6c 100644
--- a/libc/src/__support/StringUtil/error_to_string.cpp
+++ b/libc/src/__support/StringUtil/error_to_string.cpp
@@ -8,12 +8,16 @@
 
 #include "src/__support/StringUtil/error_to_string.h"
 
+#include "src/errno/libc_errno.h" // For error macros
+
+#include "src/__support/CPP/array.h"
 #include "src/__support/CPP/span.h"
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/CPP/stringstream.h"
 #include "src/__support/StringUtil/message_mapper.h"
 #include "src/__support/integer_to_string.h"
-#include "src/errno/libc_errno.h" // For error macros
+
+#include "src/__support/StringUtil/tables/error_table.h"
 
 #include <stddef.h>
 
@@ -33,157 +37,21 @@ constexpr size_t max_buff_size() {
 constexpr size_t ERR_BUFFER_SIZE = max_buff_size();
 thread_local char error_buffer[ERR_BUFFER_SIZE];
 
+constexpr size_t RAW_ARRAY_LEN = PLATFORM_ERRORS.size();
+constexpr size_t TOTAL_STR_LEN =
+    total_str_len(PLATFORM_ERRORS.data(), RAW_ARRAY_LEN);
+
 // Since the StringMappings array is a map from error numbers to their
 // corresponding strings, we have to have an array large enough we can use the
-// error numbers as indexes. Thankfully there are 132 errors in the above list
-// (41 and 58 are skipped) and the highest number is 133. If other platforms use
-// 
diff erent error numbers, then this number may need to be adjusted.
-// Also if negative numbers or particularly large numbers are used, then the
-// array should be turned into a proper hashmap.
-constexpr size_t ERR_ARRAY_SIZE = 134;
-
-constexpr MsgMapping raw_err_array[] = {
-    MsgMapping(0, "Success"),
-    MsgMapping(EPERM, "Operation not permitted"),
-    MsgMapping(ENOENT, "No such file or directory"),
-    MsgMapping(ESRCH, "No such process"),
-    MsgMapping(EINTR, "Interrupted system call"),
-    MsgMapping(EIO, "Input/output error"),
-    MsgMapping(ENXIO, "No such device or address"),
-    MsgMapping(E2BIG, "Argument list too long"),
-    MsgMapping(ENOEXEC, "Exec format error"),
-    MsgMapping(EBADF, "Bad file descriptor"),
-    MsgMapping(ECHILD, "No child processes"),
-    MsgMapping(EAGAIN, "Resource temporarily unavailable"),
-    MsgMapping(ENOMEM, "Cannot allocate memory"),
-    MsgMapping(EACCES, "Permission denied"),
-    MsgMapping(EFAULT, "Bad address"),
-    MsgMapping(ENOTBLK, "Block device required"),
-    MsgMapping(EBUSY, "Device or resource busy"),
-    MsgMapping(EEXIST, "File exists"),
-    MsgMapping(EXDEV, "Invalid cross-device link"),
-    MsgMapping(ENODEV, "No such device"),
-    MsgMapping(ENOTDIR, "Not a directory"),
-    MsgMapping(EISDIR, "Is a directory"),
-    MsgMapping(EINVAL, "Invalid argument"),
-    MsgMapping(ENFILE, "Too many open files in system"),
-    MsgMapping(EMFILE, "Too many open files"),
-    MsgMapping(ENOTTY, "Inappropriate ioctl for device"),
-    MsgMapping(ETXTBSY, "Text file busy"),
-    MsgMapping(EFBIG, "File too large"),
-    MsgMapping(ENOSPC, "No space left on device"),
-    MsgMapping(ESPIPE, "Illegal seek"),
-    MsgMapping(EROFS, "Read-only file system"),
-    MsgMapping(EMLINK, "Too many links"),
-    MsgMapping(EPIPE, "Broken pipe"),
-    MsgMapping(EDOM, "Numerical argument out of domain"),
-    MsgMapping(ERANGE, "Numerical result out of range"),
-    MsgMapping(EDEADLK, "Resource deadlock avoided"),
-    MsgMapping(ENAMETOOLONG, "File name too long"),
-    MsgMapping(ENOLCK, "No locks available"),
-    MsgMapping(ENOSYS, "Function not implemented"),
-    MsgMapping(ENOTEMPTY, "Directory not empty"),
-    MsgMapping(ELOOP, "Too many levels of symbolic links"),
-    // No error for 41. Would be EWOULDBLOCK
-    MsgMapping(ENOMSG, "No message of desired type"),
-    MsgMapping(EIDRM, "Identifier removed"),
-    MsgMapping(ECHRNG, "Channel number out of range"),
-    MsgMapping(EL2NSYNC, "Level 2 not synchronized"),
-    MsgMapping(EL3HLT, "Level 3 halted"),
-    MsgMapping(EL3RST, "Level 3 reset"),
-    MsgMapping(ELNRNG, "Link number out of range"),
-    MsgMapping(EUNATCH, "Protocol driver not attached"),
-    MsgMapping(ENOCSI, "No CSI structure available"),
-    MsgMapping(EL2HLT, "Level 2 halted"),
-    MsgMapping(EBADE, "Invalid exchange"),
-    MsgMapping(EBADR, "Invalid request descriptor"),
-    MsgMapping(EXFULL, "Exchange full"),
-    MsgMapping(ENOANO, "No anode"),
-    MsgMapping(EBADRQC, "Invalid request code"),
-    MsgMapping(EBADSLT, "Invalid slot"),
-    // No error for 58. Would be EDEADLOCK.
-    MsgMapping(EBFONT, "Bad font file format"),
-    MsgMapping(ENOSTR, "Device not a stream"),
-    MsgMapping(ENODATA, "No data available"),
-    MsgMapping(ETIME, "Timer expired"),
-    MsgMapping(ENOSR, "Out of streams resources"),
-    MsgMapping(ENONET, "Machine is not on the network"),
-    MsgMapping(ENOPKG, "Package not installed"),
-    MsgMapping(EREMOTE, "Object is remote"),
-    MsgMapping(ENOLINK, "Link has been severed"),
-    MsgMapping(EADV, "Advertise error"),
-    MsgMapping(ESRMNT, "Srmount error"),
-    MsgMapping(ECOMM, "Communication error on send"),
-    MsgMapping(EPROTO, "Protocol error"),
-    MsgMapping(EMULTIHOP, "Multihop attempted"),
-    MsgMapping(EDOTDOT, "RFS specific error"),
-    MsgMapping(EBADMSG, "Bad message"),
-    MsgMapping(EOVERFLOW, "Value too large for defined data type"),
-    MsgMapping(ENOTUNIQ, "Name not unique on network"),
-    MsgMapping(EBADFD, "File descriptor in bad state"),
-    MsgMapping(EREMCHG, "Remote address changed"),
-    MsgMapping(ELIBACC, "Can not access a needed shared library"),
-    MsgMapping(ELIBBAD, "Accessing a corrupted shared library"),
-    MsgMapping(ELIBSCN, ".lib section in a.out corrupted"),
-    MsgMapping(ELIBMAX, "Attempting to link in too many shared libraries"),
-    MsgMapping(ELIBEXEC, "Cannot exec a shared library directly"),
-    MsgMapping(EILSEQ, "Invalid or incomplete multibyte or wide character"),
-    MsgMapping(ERESTART, "Interrupted system call should be restarted"),
-    MsgMapping(ESTRPIPE, "Streams pipe error"),
-    MsgMapping(EUSERS, "Too many users"),
-    MsgMapping(ENOTSOCK, "Socket operation on non-socket"),
-    MsgMapping(EDESTADDRREQ, "Destination address required"),
-    MsgMapping(EMSGSIZE, "Message too long"),
-    MsgMapping(EPROTOTYPE, "Protocol wrong type for socket"),
-    MsgMapping(ENOPROTOOPT, "Protocol not available"),
-    MsgMapping(EPROTONOSUPPORT, "Protocol not supported"),
-    MsgMapping(ESOCKTNOSUPPORT, "Socket type not supported"),
-    MsgMapping(ENOTSUP, "Operation not supported"),
-    MsgMapping(EPFNOSUPPORT, "Protocol family not supported"),
-    MsgMapping(EAFNOSUPPORT, "Address family not supported by protocol"),
-    MsgMapping(EADDRINUSE, "Address already in use"),
-    MsgMapping(EADDRNOTAVAIL, "Cannot assign requested address"),
-    MsgMapping(ENETDOWN, "Network is down"),
-    MsgMapping(ENETUNREACH, "Network is unreachable"),
-    MsgMapping(ENETRESET, "Network dropped connection on reset"),
-    MsgMapping(ECONNABORTED, "Software caused connection abort"),
-    MsgMapping(ECONNRESET, "Connection reset by peer"),
-    MsgMapping(ENOBUFS, "No buffer space available"),
-    MsgMapping(EISCONN, "Transport endpoint is already connected"),
-    MsgMapping(ENOTCONN, "Transport endpoint is not connected"),
-    MsgMapping(ESHUTDOWN, "Cannot send after transport endpoint shutdown"),
-    MsgMapping(ETOOMANYREFS, "Too many references: cannot splice"),
-    MsgMapping(ETIMEDOUT, "Connection timed out"),
-    MsgMapping(ECONNREFUSED, "Connection refused"),
-    MsgMapping(EHOSTDOWN, "Host is down"),
-    MsgMapping(EHOSTUNREACH, "No route to host"),
-    MsgMapping(EALREADY, "Operation already in progress"),
-    MsgMapping(EINPROGRESS, "Operation now in progress"),
-    MsgMapping(ESTALE, "Stale file handle"),
-    MsgMapping(EUCLEAN, "Structure needs cleaning"),
-    MsgMapping(ENOTNAM, "Not a XENIX named type file"),
-    MsgMapping(ENAVAIL, "No XENIX semaphores available"),
-    MsgMapping(EISNAM, "Is a named type file"),
-    MsgMapping(EREMOTEIO, "Remote I/O error"),
-    MsgMapping(EDQUOT, "Disk quota exceeded"),
-    MsgMapping(ENOMEDIUM, "No medium found"),
-    MsgMapping(EMEDIUMTYPE, "Wrong medium type"),
-    MsgMapping(ECANCELED, "Operation canceled"),
-    MsgMapping(ENOKEY, "Required key not available"),
-    MsgMapping(EKEYEXPIRED, "Key has expired"),
-    MsgMapping(EKEYREVOKED, "Key has been revoked"),
-    MsgMapping(EKEYREJECTED, "Key was rejected by service"),
-    MsgMapping(EOWNERDEAD, "Owner died"),
-    MsgMapping(ENOTRECOVERABLE, "State not recoverable"),
-    MsgMapping(ERFKILL, "Operation not possible due to RF-kill"),
-    MsgMapping(EHWPOISON, "Memory page has hardware error"),
-};
-
-constexpr size_t RAW_ARRAY_LEN = sizeof(raw_err_array) / sizeof(MsgMapping);
-constexpr size_t TOTAL_STR_LEN = total_str_len(raw_err_array, RAW_ARRAY_LEN);
+// error numbers as indexes. The current linux configuration has 132 values with
+// the maximum value being 133 (41 and 58 are skipped). If other platforms use
+// negative numbers or discontiguous ranges, then the array should be turned
+// into a proper hashmap.
+constexpr size_t ERR_ARRAY_SIZE =
+    max_key_val(PLATFORM_ERRORS.data(), RAW_ARRAY_LEN) + 1;
 
 static constexpr MessageMapper<ERR_ARRAY_SIZE, TOTAL_STR_LEN>
-    error_mapper(raw_err_array, RAW_ARRAY_LEN);
+    error_mapper(PLATFORM_ERRORS.data(), RAW_ARRAY_LEN);
 
 cpp::string_view build_error_string(int err_num, cpp::span<char> buffer) {
   // if the buffer can't hold "Unknown error" + ' ' + num_str, then just

diff  --git a/libc/src/__support/StringUtil/error_to_string.h b/libc/src/__support/StringUtil/error_to_string.h
index b09c8a2ea88ed..36c37e244691c 100644
--- a/libc/src/__support/StringUtil/error_to_string.h
+++ b/libc/src/__support/StringUtil/error_to_string.h
@@ -6,12 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/__support/CPP/span.h"
-#include "src/__support/CPP/string_view.h"
-
 #ifndef LLVM_LIBC_SRC_SUPPORT_ERROR_TO_STRING_H
 #define LLVM_LIBC_SRC_SUPPORT_ERROR_TO_STRING_H
 
+#include "src/__support/CPP/span.h"
+#include "src/__support/CPP/string_view.h"
+
 namespace __llvm_libc {
 
 cpp::string_view get_error_string(int err_num);

diff  --git a/libc/src/__support/StringUtil/message_mapper.h b/libc/src/__support/StringUtil/message_mapper.h
index 98b2cb169476b..26727cccd8d5a 100644
--- a/libc/src/__support/StringUtil/message_mapper.h
+++ b/libc/src/__support/StringUtil/message_mapper.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
 #define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
 
+#include "src/__support/CPP/array.h"
 #include "src/__support/CPP/optional.h"
 #include "src/__support/CPP/string_view.h"
 #include <stddef.h>
@@ -20,6 +21,8 @@ struct MsgMapping {
   int num;
   cpp::string_view msg;
 
+  constexpr MsgMapping() : num(0), msg() { ; }
+
   constexpr MsgMapping(int init_num, const char *init_msg)
       : num(init_num), msg(init_msg) {
     ;
@@ -35,6 +38,18 @@ constexpr size_t total_str_len(const MsgMapping *array, size_t len) {
   return total;
 }
 
+constexpr size_t max_key_val(const MsgMapping *array, size_t len) {
+  int max = 0;
+  for (size_t i = 0; i < len; ++i) {
+    if (array[i].num > max) {
+      max = array[i].num;
+    }
+  }
+  // max will never be negative since the starting value is 0. This is good,
+  // since it's used as a length.
+  return static_cast<size_t>(max);
+}
+
 template <size_t ARR_SIZE, size_t TOTAL_STR_LEN> class MessageMapper {
   int msg_offsets[ARR_SIZE] = {-1};
   char string_array[TOTAL_STR_LEN] = {'\0'};
@@ -71,6 +86,19 @@ template <size_t ARR_SIZE, size_t TOTAL_STR_LEN> class MessageMapper {
   }
 };
 
+template <size_t N> using MsgTable = cpp::array<MsgMapping, N>;
+
+template <size_t N1, size_t N2>
+constexpr MsgTable<N1 + N2> operator+(const MsgTable<N1> &t1,
+                                      const MsgTable<N2> &t2) {
+  MsgTable<N1 + N2> res{};
+  for (size_t i = 0; i < N1; ++i)
+    res[i] = t1[i];
+  for (size_t i = 0; i < N2; ++i)
+    res[N1 + i] = t2[i];
+  return res;
+}
+
 } // namespace internal
 } // namespace __llvm_libc
 

diff  --git a/libc/src/__support/StringUtil/signal_to_string.cpp b/libc/src/__support/StringUtil/signal_to_string.cpp
index a64f26adca650..cfe979b02feea 100644
--- a/libc/src/__support/StringUtil/signal_to_string.cpp
+++ b/libc/src/__support/StringUtil/signal_to_string.cpp
@@ -12,6 +12,7 @@
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/CPP/stringstream.h"
 #include "src/__support/StringUtil/message_mapper.h"
+#include "src/__support/StringUtil/tables/signal_table.h"
 #include "src/__support/integer_to_string.h"
 
 #include <signal.h>
@@ -33,50 +34,15 @@ constexpr size_t max_buff_size() {
 constexpr size_t SIG_BUFFER_SIZE = max_buff_size();
 thread_local char signal_buffer[SIG_BUFFER_SIZE];
 
-constexpr MsgMapping raw_sig_array[] = {
-    MsgMapping(SIGHUP, "Hangup"), MsgMapping(SIGINT, "Interrupt"),
-    MsgMapping(SIGQUIT, "Quit"), MsgMapping(SIGILL, "Illegal instruction"),
-    MsgMapping(SIGTRAP, "Trace/breakpoint trap"),
-    MsgMapping(SIGABRT, "Aborted"), MsgMapping(SIGBUS, "Bus error"),
-    MsgMapping(SIGFPE, "Floating point exception"),
-    MsgMapping(SIGKILL, "Killed"), MsgMapping(SIGUSR1, "User defined signal 1"),
-    MsgMapping(SIGSEGV, "Segmentation fault"),
-    MsgMapping(SIGUSR2, "User defined signal 2"),
-    MsgMapping(SIGPIPE, "Broken pipe"), MsgMapping(SIGALRM, "Alarm clock"),
-    MsgMapping(SIGTERM, "Terminated"),
-    // SIGSTKFLT (may not exist)
-    MsgMapping(SIGCHLD, "Child exited"), MsgMapping(SIGCONT, "Continued"),
-    MsgMapping(SIGSTOP, "Stopped (signal)"), MsgMapping(SIGTSTP, "Stopped"),
-    MsgMapping(SIGTTIN, "Stopped (tty input)"),
-    MsgMapping(SIGTTOU, "Stopped (tty output)"),
-    MsgMapping(SIGURG, "Urgent I/O condition"),
-    MsgMapping(SIGXCPU, "CPU time limit exceeded"),
-    MsgMapping(SIGXFSZ, "File size limit exceeded"),
-    MsgMapping(SIGVTALRM, "Virtual timer expired"),
-    MsgMapping(SIGPROF, "Profiling timer expired"),
-    MsgMapping(SIGWINCH, "Window changed"), MsgMapping(SIGPOLL, "I/O possible"),
-    // SIGPWR (may not exist)
-    MsgMapping(SIGSYS, "Bad system call"),
-
-#ifdef SIGSTKFLT
-    MsgMapping(SIGSTKFLT, "Stack fault"), // unused
-#endif
-#ifdef SIGPWR
-    MsgMapping(SIGPWR, "Power failure"), // ignored
-#endif
-};
-
-// Since the string_mappings array is a map from signal numbers to their
-// corresponding strings, we have to have an array large enough we can use the
-// signal numbers as indexes. The highest signal is SIGSYS at 31, so an array of
-// 32 elements will be large enough to hold all of them.
-constexpr size_t SIG_ARRAY_SIZE = 32;
-
-constexpr size_t RAW_ARRAY_LEN = sizeof(raw_sig_array) / sizeof(MsgMapping);
-constexpr size_t TOTAL_STR_LEN = total_str_len(raw_sig_array, RAW_ARRAY_LEN);
+constexpr size_t RAW_ARRAY_LEN = PLATFORM_SIGNALS.size();
+constexpr size_t TOTAL_STR_LEN =
+    total_str_len(PLATFORM_SIGNALS.data(), RAW_ARRAY_LEN);
+
+constexpr size_t SIG_ARRAY_SIZE =
+    max_key_val(PLATFORM_SIGNALS.data(), RAW_ARRAY_LEN) + 1;
 
 static constexpr MessageMapper<SIG_ARRAY_SIZE, TOTAL_STR_LEN>
-    signal_mapper(raw_sig_array, RAW_ARRAY_LEN);
+    signal_mapper(PLATFORM_SIGNALS.data(), RAW_ARRAY_LEN);
 
 cpp::string_view build_signal_string(int sig_num, cpp::span<char> buffer) {
   cpp::string_view base_str;

diff  --git a/libc/src/__support/StringUtil/tables/CMakeLists.txt b/libc/src/__support/StringUtil/tables/CMakeLists.txt
new file mode 100644
index 0000000000000..e8208f3973c8c
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/CMakeLists.txt
@@ -0,0 +1,35 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${LIBC_TARGET_OS})
+endif()
+
+set(error_to_string_platform_dep "")
+if(TARGET libc.src.__support.StringUtil.tables.${LIBC_TARGET_OS}.error_table)
+  set(error_to_string_platform_dep 
+  libc.src.__support.StringUtil.tables.${LIBC_TARGET_OS}.error_table)
+endif()
+
+add_header_library(
+  error_table
+  HDRS
+    error_table.h  
+    stdc_error_table.h  
+    posix_error_table.h  
+  DEPENDS
+    ${error_to_string_platform_dep}
+)
+
+set(signal_to_string_platform_dep "")
+if(TARGET libc.src.__support.StringUtil.tables.${LIBC_TARGET_OS}.signal_table)
+  set(signal_to_string_platform_dep 
+  libc.src.__support.StringUtil.tables.${LIBC_TARGET_OS}.signal_table)
+endif()
+
+add_header_library(
+  signal_table
+  HDRS
+    signal_table.h  
+    stdc_signal_table.h  
+    posix_signal_table.h  
+  DEPENDS
+    ${signal_to_string_platform_dep}
+)

diff  --git a/libc/src/__support/StringUtil/tables/error_table.h b/libc/src/__support/StringUtil/tables/error_table.h
new file mode 100644
index 0000000000000..78f58bc43d6a9
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/error_table.h
@@ -0,0 +1,32 @@
+//===-- Map from error numbers to strings -----------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_ERROR_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_ERROR_TABLE_H
+
+#include "src/__support/StringUtil/message_mapper.h"
+
+#include "posix_error_table.h"
+#include "stdc_error_table.h"
+
+#ifdef __linux__
+#include "linux/error_table.h"
+#endif
+
+namespace __llvm_libc::internal {
+
+#ifdef __linux__
+inline constexpr auto PLATFORM_ERRORS =
+    STDC_ERRORS + POSIX_ERRORS + LINUX_ERRORS;
+#else
+inline constexpr auto PLATFORM_ERRORS = STDC_ERRORS;
+#endif
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_ERROR_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/linux/CMakeLists.txt b/libc/src/__support/StringUtil/tables/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..82d3a293570e8
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/linux/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_header_library(
+  error_table
+  HDRS
+    error_table.h
+  DEPENDS
+  libc.src.__support.StringUtil.message_mapper
+  libc.src.errno.errno
+)
+
+add_header_library(
+  signal_table
+  HDRS
+    signal_table.h
+  DEPENDS
+  libc.src.__support.StringUtil.message_mapper
+  libc.include.signal
+)

diff  --git a/libc/src/__support/StringUtil/tables/linux/error_table.h b/libc/src/__support/StringUtil/tables/linux/error_table.h
new file mode 100644
index 0000000000000..c898cf9728d15
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/linux/error_table.h
@@ -0,0 +1,76 @@
+//===-- Map from error numbers to strings on linux --------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_ERROR_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_ERROR_TABLE_H
+
+#include "src/errno/libc_errno.h" // For error macros
+
+#include "src/__support/CPP/array.h"
+#include "src/__support/StringUtil/message_mapper.h"
+
+namespace __llvm_libc::internal {
+
+constexpr MsgTable<52> LINUX_ERRORS = {
+    MsgMapping(ENOTBLK, "Block device required"),
+    MsgMapping(ECHRNG, "Channel number out of range"),
+    MsgMapping(EL2NSYNC, "Level 2 not synchronized"),
+    MsgMapping(EL3HLT, "Level 3 halted"),
+    MsgMapping(EL3RST, "Level 3 reset"),
+    MsgMapping(ELNRNG, "Link number out of range"),
+    MsgMapping(EUNATCH, "Protocol driver not attached"),
+    MsgMapping(ENOCSI, "No CSI structure available"),
+    MsgMapping(EL2HLT, "Level 2 halted"),
+    MsgMapping(EBADE, "Invalid exchange"),
+    MsgMapping(EBADR, "Invalid request descriptor"),
+    MsgMapping(EXFULL, "Exchange full"),
+    MsgMapping(ENOANO, "No anode"),
+    MsgMapping(EBADRQC, "Invalid request code"),
+    MsgMapping(EBADSLT, "Invalid slot"),
+    MsgMapping(EBFONT, "Bad font file format"),
+    MsgMapping(ENONET, "Machine is not on the network"),
+    MsgMapping(ENOPKG, "Package not installed"),
+    MsgMapping(EREMOTE, "Object is remote"),
+    MsgMapping(EADV, "Advertise error"),
+    MsgMapping(ESRMNT, "Srmount error"),
+    MsgMapping(ECOMM, "Communication error on send"),
+    MsgMapping(EDOTDOT, "RFS specific error"),
+    MsgMapping(ENOTUNIQ, "Name not unique on network"),
+    MsgMapping(EBADFD, "File descriptor in bad state"),
+    MsgMapping(EREMCHG, "Remote address changed"),
+    MsgMapping(ELIBACC, "Can not access a needed shared library"),
+    MsgMapping(ELIBBAD, "Accessing a corrupted shared library"),
+    MsgMapping(ELIBSCN, ".lib section in a.out corrupted"),
+    MsgMapping(ELIBMAX, "Attempting to link in too many shared libraries"),
+    MsgMapping(ELIBEXEC, "Cannot exec a shared library directly"),
+    MsgMapping(ERESTART, "Interrupted system call should be restarted"),
+    MsgMapping(ESTRPIPE, "Streams pipe error"),
+    MsgMapping(EUSERS, "Too many users"),
+    MsgMapping(ESOCKTNOSUPPORT, "Socket type not supported"),
+    MsgMapping(EPFNOSUPPORT, "Protocol family not supported"),
+    MsgMapping(ESHUTDOWN, "Cannot send after transport endpoint shutdown"),
+    MsgMapping(ETOOMANYREFS, "Too many references: cannot splice"),
+    MsgMapping(EHOSTDOWN, "Host is down"),
+    MsgMapping(EUCLEAN, "Structure needs cleaning"),
+    MsgMapping(ENOTNAM, "Not a XENIX named type file"),
+    MsgMapping(ENAVAIL, "No XENIX semaphores available"),
+    MsgMapping(EISNAM, "Is a named type file"),
+    MsgMapping(EREMOTEIO, "Remote I/O error"),
+    MsgMapping(ENOMEDIUM, "No medium found"),
+    MsgMapping(EMEDIUMTYPE, "Wrong medium type"),
+    MsgMapping(ENOKEY, "Required key not available"),
+    MsgMapping(EKEYEXPIRED, "Key has expired"),
+    MsgMapping(EKEYREVOKED, "Key has been revoked"),
+    MsgMapping(EKEYREJECTED, "Key was rejected by service"),
+    MsgMapping(ERFKILL, "Operation not possible due to RF-kill"),
+    MsgMapping(EHWPOISON, "Memory page has hardware error"),
+};
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_ERROR_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/linux/signal_table.h b/libc/src/__support/StringUtil/tables/linux/signal_table.h
new file mode 100644
index 0000000000000..864cd6f9ba022
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/linux/signal_table.h
@@ -0,0 +1,33 @@
+//===-- Map from signal numbers to strings on linux -------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_SIGNAL_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_SIGNAL_TABLE_H
+
+#include <signal.h>
+
+#include "src/__support/StringUtil/message_mapper.h"
+
+namespace __llvm_libc::internal {
+
+// The array being larger than necessary isn't a problem. The MsgMappings will
+// be set to their default state which maps 0 to an empty string. This will get
+// filtered out in the MessageMapper building stage.
+inline constexpr const MsgTable<3> LINUX_SIGNALS = {
+#ifdef SIGSTKFLT
+    MsgMapping(SIGSTKFLT, "Stack fault"), // unused
+#endif
+    MsgMapping(SIGWINCH, "Window changed"),
+#ifdef SIGPWR
+    MsgMapping(SIGPWR, "Power failure"), // ignored
+#endif
+};
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_SIGNAL_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/posix_error_table.h b/libc/src/__support/StringUtil/tables/posix_error_table.h
new file mode 100644
index 0000000000000..1778eb9439df9
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/posix_error_table.h
@@ -0,0 +1,100 @@
+//===-- Map from error numbers to strings in posix --------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_POSIX_ERROR_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_POSIX_ERROR_TABLE_H
+
+#include "src/errno/libc_errno.h" // For error macros
+
+#include "src/__support/CPP/array.h"
+#include "src/__support/StringUtil/message_mapper.h"
+
+namespace __llvm_libc::internal {
+
+inline constexpr MsgTable<76> POSIX_ERRORS = {
+    MsgMapping(EPERM, "Operation not permitted"),
+    MsgMapping(ENOENT, "No such file or directory"),
+    MsgMapping(ESRCH, "No such process"),
+    MsgMapping(EINTR, "Interrupted system call"),
+    MsgMapping(EIO, "Input/output error"),
+    MsgMapping(ENXIO, "No such device or address"),
+    MsgMapping(E2BIG, "Argument list too long"),
+    MsgMapping(ENOEXEC, "Exec format error"),
+    MsgMapping(EBADF, "Bad file descriptor"),
+    MsgMapping(ECHILD, "No child processes"),
+    MsgMapping(EAGAIN, "Resource temporarily unavailable"),
+    MsgMapping(ENOMEM, "Cannot allocate memory"),
+    MsgMapping(EACCES, "Permission denied"),
+    MsgMapping(EFAULT, "Bad address"),
+    MsgMapping(EBUSY, "Device or resource busy"),
+    MsgMapping(EEXIST, "File exists"),
+    MsgMapping(EXDEV, "Invalid cross-device link"),
+    MsgMapping(ENODEV, "No such device"),
+    MsgMapping(ENOTDIR, "Not a directory"),
+    MsgMapping(EISDIR, "Is a directory"),
+    MsgMapping(EINVAL, "Invalid argument"),
+    MsgMapping(ENFILE, "Too many open files in system"),
+    MsgMapping(EMFILE, "Too many open files"),
+    MsgMapping(ENOTTY, "Inappropriate ioctl for device"),
+    MsgMapping(ETXTBSY, "Text file busy"),
+    MsgMapping(EFBIG, "File too large"),
+    MsgMapping(ENOSPC, "No space left on device"),
+    MsgMapping(ESPIPE, "Illegal seek"),
+    MsgMapping(EROFS, "Read-only file system"),
+    MsgMapping(EMLINK, "Too many links"),
+    MsgMapping(EPIPE, "Broken pipe"),
+    MsgMapping(EDEADLK, "Resource deadlock avoided"),
+    MsgMapping(ENAMETOOLONG, "File name too long"),
+    MsgMapping(ENOLCK, "No locks available"),
+    MsgMapping(ENOSYS, "Function not implemented"),
+    MsgMapping(ENOTEMPTY, "Directory not empty"),
+    MsgMapping(ELOOP, "Too many levels of symbolic links"),
+    MsgMapping(ENOMSG, "No message of desired type"),
+    MsgMapping(EIDRM, "Identifier removed"),
+    MsgMapping(ENOSTR, "Device not a stream"),
+    MsgMapping(ENODATA, "No data available"),
+    MsgMapping(ETIME, "Timer expired"),
+    MsgMapping(ENOSR, "Out of streams resources"),
+    MsgMapping(ENOLINK, "Link has been severed"),
+    MsgMapping(EPROTO, "Protocol error"),
+    MsgMapping(EMULTIHOP, "Multihop attempted"),
+    MsgMapping(EBADMSG, "Bad message"),
+    MsgMapping(EOVERFLOW, "Value too large for defined data type"),
+    MsgMapping(ENOTSOCK, "Socket operation on non-socket"),
+    MsgMapping(EDESTADDRREQ, "Destination address required"),
+    MsgMapping(EMSGSIZE, "Message too long"),
+    MsgMapping(EPROTOTYPE, "Protocol wrong type for socket"),
+    MsgMapping(ENOPROTOOPT, "Protocol not available"),
+    MsgMapping(EPROTONOSUPPORT, "Protocol not supported"),
+    MsgMapping(ENOTSUP, "Operation not supported"),
+    MsgMapping(EAFNOSUPPORT, "Address family not supported by protocol"),
+    MsgMapping(EADDRINUSE, "Address already in use"),
+    MsgMapping(EADDRNOTAVAIL, "Cannot assign requested address"),
+    MsgMapping(ENETDOWN, "Network is down"),
+    MsgMapping(ENETUNREACH, "Network is unreachable"),
+    MsgMapping(ENETRESET, "Network dropped connection on reset"),
+    MsgMapping(ECONNABORTED, "Software caused connection abort"),
+    MsgMapping(ECONNRESET, "Connection reset by peer"),
+    MsgMapping(ENOBUFS, "No buffer space available"),
+    MsgMapping(EISCONN, "Transport endpoint is already connected"),
+    MsgMapping(ENOTCONN, "Transport endpoint is not connected"),
+    MsgMapping(ETIMEDOUT, "Connection timed out"),
+    MsgMapping(ECONNREFUSED, "Connection refused"),
+    MsgMapping(EHOSTUNREACH, "No route to host"),
+    MsgMapping(EALREADY, "Operation already in progress"),
+    MsgMapping(EINPROGRESS, "Operation now in progress"),
+    MsgMapping(ESTALE, "Stale file handle"),
+    MsgMapping(EDQUOT, "Disk quota exceeded"),
+    MsgMapping(ECANCELED, "Operation canceled"),
+    MsgMapping(EOWNERDEAD, "Owner died"),
+    MsgMapping(ENOTRECOVERABLE, "State not recoverable"),
+};
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_POSIX_ERROR_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/posix_signal_table.h b/libc/src/__support/StringUtil/tables/posix_signal_table.h
new file mode 100644
index 0000000000000..aae0884424b74
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/posix_signal_table.h
@@ -0,0 +1,46 @@
+//===-- Map from signal numbers to strings in posix -------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_POSIX_SIGNAL_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_POSIX_SIGNAL_TABLE_H
+
+#include <signal.h>
+
+#include "src/__support/CPP/array.h"
+#include "src/__support/StringUtil/message_mapper.h"
+
+namespace __llvm_libc::internal {
+
+inline constexpr MsgTable<22> POSIX_SIGNALS = {
+    MsgMapping(SIGHUP, "Hangup"),
+    MsgMapping(SIGQUIT, "Quit"),
+    MsgMapping(SIGTRAP, "Trace/breakpoint trap"),
+    MsgMapping(SIGBUS, "Bus error"),
+    MsgMapping(SIGKILL, "Killed"),
+    MsgMapping(SIGUSR1, "User defined signal 1"),
+    MsgMapping(SIGUSR2, "User defined signal 2"),
+    MsgMapping(SIGPIPE, "Broken pipe"),
+    MsgMapping(SIGALRM, "Alarm clock"),
+    MsgMapping(SIGCHLD, "Child exited"),
+    MsgMapping(SIGCONT, "Continued"),
+    MsgMapping(SIGSTOP, "Stopped (signal)"),
+    MsgMapping(SIGTSTP, "Stopped"),
+    MsgMapping(SIGTTIN, "Stopped (tty input)"),
+    MsgMapping(SIGTTOU, "Stopped (tty output)"),
+    MsgMapping(SIGURG, "Urgent I/O condition"),
+    MsgMapping(SIGXCPU, "CPU time limit exceeded"),
+    MsgMapping(SIGXFSZ, "File size limit exceeded"),
+    MsgMapping(SIGVTALRM, "Virtual timer expired"),
+    MsgMapping(SIGPROF, "Profiling timer expired"),
+    MsgMapping(SIGPOLL, "I/O possible"),
+    MsgMapping(SIGSYS, "Bad system call"),
+};
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_POSIX_SIGNAL_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/signal_table.h b/libc/src/__support/StringUtil/tables/signal_table.h
new file mode 100644
index 0000000000000..b1b738abbac4a
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/signal_table.h
@@ -0,0 +1,32 @@
+//===-- Map from signal numbers to strings ----------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_SIGNAL_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_SIGNAL_TABLE_H
+
+#include "src/__support/StringUtil/message_mapper.h"
+
+#include "posix_signal_table.h"
+#include "stdc_signal_table.h"
+
+#ifdef __linux__
+#include "linux/signal_table.h"
+#endif
+
+namespace __llvm_libc::internal {
+
+#ifdef __linux__
+inline constexpr auto PLATFORM_SIGNALS =
+    STDC_SIGNALS + POSIX_SIGNALS + LINUX_SIGNALS;
+#else
+inline constexpr auto PLATFORM_SIGNALS = STDC_SIGNALS;
+#endif
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_SIGNAL_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/stdc_error_table.h b/libc/src/__support/StringUtil/tables/stdc_error_table.h
new file mode 100644
index 0000000000000..5a2a883d34f91
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/stdc_error_table.h
@@ -0,0 +1,27 @@
+//===-- Map from error numbers to strings in the c std ----------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_STDC_ERROR_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_STDC_ERROR_TABLE_H
+
+#include "src/errno/libc_errno.h" // For error macros
+
+#include "src/__support/StringUtil/message_mapper.h"
+
+namespace __llvm_libc::internal {
+
+inline constexpr const MsgTable<4> STDC_ERRORS = {
+    MsgMapping(0, "Success"),
+    MsgMapping(EDOM, "Numerical argument out of domain"),
+    MsgMapping(ERANGE, "Numerical result out of range"),
+    MsgMapping(EILSEQ, "Invalid or incomplete multibyte or wide character"),
+};
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_ERROR_TABLE_H

diff  --git a/libc/src/__support/StringUtil/tables/stdc_signal_table.h b/libc/src/__support/StringUtil/tables/stdc_signal_table.h
new file mode 100644
index 0000000000000..10cae1e022394
--- /dev/null
+++ b/libc/src/__support/StringUtil/tables/stdc_signal_table.h
@@ -0,0 +1,29 @@
+//===-- Map from signal numbers to strings in the c std ---------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_STDC_SIGNAL_TABLE_H
+#define LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_STDC_SIGNAL_TABLE_H
+
+#include <signal.h>
+
+#include "src/__support/StringUtil/message_mapper.h"
+
+namespace __llvm_libc::internal {
+
+inline constexpr const MsgTable<6> STDC_SIGNALS = {
+    MsgMapping(SIGINT, "Interrupt"),
+    MsgMapping(SIGILL, "Illegal instruction"),
+    MsgMapping(SIGABRT, "Aborted"),
+    MsgMapping(SIGFPE, "Floating point exception"),
+    MsgMapping(SIGSEGV, "Segmentation fault"),
+    MsgMapping(SIGTERM, "Terminated"),
+};
+
+} // namespace __llvm_libc::internal
+
+#endif // LLVM_LIBC_SRC_SUPPORT_STRING_UTIL_TABLES_LINUX_SIGNAL_TABLE_H


        


More information about the libc-commits mailing list