[libc-commits] [libc] 453c85f - [libc] Add implementation of errno and define the other macros of errno.h.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Mon Dec 9 13:36:16 PST 2019
Author: Siva Chandra Reddy
Date: 2019-12-09T13:34:08-08:00
New Revision: 453c85ff0f96048ea31037fed905ef6a06ac3fcc
URL: https://github.com/llvm/llvm-project/commit/453c85ff0f96048ea31037fed905ef6a06ac3fcc
DIFF: https://github.com/llvm/llvm-project/commit/453c85ff0f96048ea31037fed905ef6a06ac3fcc.diff
LOG: [libc] Add implementation of errno and define the other macros of errno.h.
Reviewers: stanshebs, alexbrachet
Subscribers: mgorny, MaskRay, tschuett, libc-commits
Tags: #libc-project
Differential Revision: https://reviews.llvm.org/D71094
Added:
libc/config/linux/errno.h.in
libc/include/errno.h.def
libc/spec/linux.td
libc/spec/posix.td
libc/src/errno/CMakeLists.txt
libc/src/errno/errno_location.cpp
libc/src/errno/errno_test.cpp
libc/src/errno/llvmlibc_errno.h
Modified:
libc/config/linux/api.td
libc/config/public_api.td
libc/include/CMakeLists.txt
libc/lib/CMakeLists.txt
libc/spec/stdc.td
libc/src/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index e0d4df8324a2..7568620b7000 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -1,5 +1,7 @@
include "config/public_api.td"
+include "spec/linux.td"
+include "spec/posix.td"
include "spec/stdc.td"
def FloatT : TypeDecl<"float_t"> {
@@ -28,6 +30,13 @@ def NullMacro : MacroDef<"NULL"> {
}];
}
+def ErrnoMacro : MacroDef<"errno"> {
+ let Defn = [{
+ int *__errno_location();
+ #define errno (*__errno_location())
+ }];
+}
+
def MathAPI : PublicAPI<"math.h"> {
let Functions = [
"acos",
@@ -83,3 +92,22 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
"snprintf",
];
}
+
+def ErrnoAPI : PublicAPI<"errno.h"> {
+ let Macros = [
+ ErrnoMacro,
+ // We largely depend on linux/errno.h to give us the
+ // various error macro definitions. However, some libc
+ // implementations have chosen to provide definitions
+ // for some of the error macros to account for the ones
+ // missing in linux/errno.h. There is no harm in doing
+ // the same here if we define the macros only when they
+ // are not already defined.
+ MacroDefineIfNot<"ENOTSUP", "EOPNOTSUPP">,
+ MacroDefineIfNot<"ECANCELED", "125">,
+ MacroDefineIfNot<"EOWNERDEAD", "130">,
+ MacroDefineIfNot<"ENOTRECOVERABLE", "131">,
+ MacroDefineIfNot<"ERFKILL", "132">,
+ MacroDefineIfNot<"EHWPOISON", "133">,
+ ];
+}
diff --git a/libc/config/linux/errno.h.in b/libc/config/linux/errno.h.in
new file mode 100644
index 000000000000..793f0f6affdc
--- /dev/null
+++ b/libc/config/linux/errno.h.in
@@ -0,0 +1,11 @@
+//===---------------- Linux specific errno.h definitions ------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+%%begin()
+
+#include <linux/errno.h>
diff --git a/libc/config/public_api.td b/libc/config/public_api.td
index 311833a190a8..3f409210e05c 100644
--- a/libc/config/public_api.td
+++ b/libc/config/public_api.td
@@ -10,6 +10,16 @@ class MacroDef<string name> {
string Defn = "";
}
+class SimpleMacroDef<string name, string value> : MacroDef<name> {
+ let Defn = !strconcat("#define ", name, " ", value);
+}
+
+class MacroDefineIfNot<string name, string value> : MacroDef<name> {
+ let Defn = !strconcat("#ifndef ", name, "\n",
+ "#define " , name, " ", value, "\n",
+ "#endif // ", name);
+}
+
class PublicAPI<string name> {
string HeaderName = name;
list<MacroDef> Macros = [];
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 9069ddb0f597..8d1c53297b1b 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -28,3 +28,13 @@ add_gen_header(
DEPENDS
llvm_libc_common_h
)
+
+add_gen_header(
+ errno_h
+ DEF_FILE errno.h.def
+ PARAMS
+ platform_errno=../config/${LIBC_TARGET_OS}/errno.h.in
+ GEN_HDR errno.h
+ DATA_FILES
+ ../config/${LIBC_TARGET_OS}/errno.h.in
+)
diff --git a/libc/include/errno.h.def b/libc/include/errno.h.def
new file mode 100644
index 000000000000..e5db86ce00e1
--- /dev/null
+++ b/libc/include/errno.h.def
@@ -0,0 +1,18 @@
+//===---------------- C standard library header errno.h ------------------===//
+//
+// 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_ERRNO_H
+#define LLVM_LIBC_ERRNO_H
+
+#include <__llvm-libc-common.h>
+
+%%include_file(${platform_errno})
+
+%%public_api()
+
+#endif // LLVM_LIBC_ERRNO_H
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 121cd1fbb77b..dd1975ba8548 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -2,8 +2,10 @@
add_entrypoint_library(
llvmlibc
DEPENDS
+ # errno.h entrypoints
+ __errno_location
+
# string.h entrypoints
- ## C standard library entrypoints
strcpy
strcat
)
diff --git a/libc/spec/linux.td b/libc/spec/linux.td
new file mode 100644
index 000000000000..da6812f88104
--- /dev/null
+++ b/libc/spec/linux.td
@@ -0,0 +1,66 @@
+def Linux : StandardSpec<"Linux"> {
+ HeaderSpec Errno = HeaderSpec<
+ "errno.h",
+ [
+ Macro<"ENOMEDIUM">,
+ Macro<"ENOTBLK">,
+ Macro<"EMEDIUMTYPE">,
+ Macro<"EBADSLT">,
+ Macro<"ECHRNG">,
+ Macro<"ERFKILL">,
+ Macro<"EUSERS">,
+ Macro<"EBADR">,
+ Macro<"EL3HLT">,
+ Macro<"ENOTUNIQ">,
+ Macro<"EXFULL">,
+ Macro<"EHOSTDOWN">,
+ Macro<"EL3RST">,
+ Macro<"ENOPKG">,
+ Macro<"ENOCSI">,
+ Macro<"EUNATCH">,
+ Macro<"EREMCHG">,
+ Macro<"ETOOMANYREFS">,
+ Macro<"EL2HLT">,
+ Macro<"EBADFD">,
+ Macro<"EREMOTEIO">,
+ Macro<"ENAVAIL">,
+ Macro<"ELIBEXEC">,
+ Macro<"ESHUTDOWN">,
+ Macro<"ENOKEY">,
+ Macro<"ESTRPIPE">,
+ Macro<"EKEYREJECTED">,
+ Macro<"ESRMNT">,
+ Macro<"EKEYREVOKED">,
+ Macro<"EBADE">,
+ Macro<"ELIBBAD">,
+ Macro<"EISNAM">,
+ Macro<"EBFONT">,
+ Macro<"EPFNOSUPPORT">,
+ Macro<"EREMOTE">,
+ Macro<"EDEADLOCK">,
+ Macro<"ENONET">,
+ Macro<"EDOTDOT">,
+ Macro<"EKEYEXPIRED">,
+ Macro<"ELIBSCN">,
+ Macro<"ERESTART">,
+ Macro<"EBADRQC">,
+ Macro<"EUCLEAN">,
+ Macro<"ENOANO">,
+ Macro<"ELIBACC">,
+ Macro<"EHWPOISON">,
+ Macro<"ELIBMAX">,
+ Macro<"ESOCKTNOSUPPORT">,
+ Macro<"ENOTNAM">,
+ Macro<"ELNRNG">,
+ Macro<"EL2NSYNC">,
+ Macro<"EADV">,
+ Macro<"ECOMM">,
+ ],
+ [], // Types
+ [] // Functions
+ >;
+
+ let Headers = [
+ Errno,
+ ];
+}
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
new file mode 100644
index 000000000000..ce7fd43aa83e
--- /dev/null
+++ b/libc/spec/posix.td
@@ -0,0 +1,91 @@
+def POSIX : StandardSpec<"POSIX"> {
+ HeaderSpec Errno = HeaderSpec<
+ "errno.h",
+ [
+ Macro<"E2BIG">,
+ Macro<"EACCES">,
+ Macro<"EADDRINUSE">,
+ Macro<"EADDRNOTAVAIL">,
+ Macro<"EAFNOSUPPORT">,
+ Macro<"EAGAIN">,
+ Macro<"EALREADY">,
+ Macro<"EBADF">,
+ Macro<"EBADMSG">,
+ Macro<"EBUSY">,
+ Macro<"ECANCELED">,
+ Macro<"ECHILD">,
+ Macro<"ECONNABORTED">,
+ Macro<"ECONNREFUSED">,
+ Macro<"ECONNRESET">,
+ Macro<"EDEADLK">,
+ Macro<"EDESTADDRREQ">,
+ Macro<"EDQUOT">,
+ Macro<"EEXIST">,
+ Macro<"EFAULT">,
+ Macro<"EFBIG">,
+ Macro<"EHOSTUNREACH">,
+ Macro<"EIDRM">,
+ Macro<"EINPROGRESS">,
+ Macro<"EINTR">,
+ Macro<"EINVAL">,
+ Macro<"EIO">,
+ Macro<"EISCONN">,
+ Macro<"EISDIR">,
+ Macro<"ELOOP">,
+ Macro<"EMFILE">,
+ Macro<"EMLINK">,
+ Macro<"EMSGSIZE">,
+ Macro<"EMULTIHOP">,
+ Macro<"ENAMETOOLONG">,
+ Macro<"ENETDOWN">,
+ Macro<"ENETRESET">,
+ Macro<"ENETUNREACH">,
+ Macro<"ENFILE">,
+ Macro<"ENOBUFS">,
+ Macro<"ENODATA">,
+ Macro<"ENODEV">,
+ Macro<"ENOENT">,
+ Macro<"ENOEXEC">,
+ Macro<"ENOLCK">,
+ Macro<"ENOLINK">,
+ Macro<"ENOMEM">,
+ Macro<"ENOMSG">,
+ Macro<"ENOPROTOOPT">,
+ Macro<"ENOSPC">,
+ Macro<"ENOSR">,
+ Macro<"ENOSTR">,
+ Macro<"ENOSYS">,
+ Macro<"ENOTCONN">,
+ Macro<"ENOTDIR">,
+ Macro<"ENOTEMPTY">,
+ Macro<"ENOTRECOVERABLE">,
+ Macro<"ENOTSOCK">,
+ Macro<"ENOTSUP">,
+ Macro<"ENOTTY">,
+ Macro<"ENXIO">,
+ Macro<"EOPNOTSUPP">,
+ Macro<"EOVERFLOW">,
+ Macro<"EOWNERDEAD">,
+ Macro<"EPERM">,
+ Macro<"EPIPE">,
+ Macro<"EPROTO">,
+ Macro<"EPROTONOSUPPORT">,
+ Macro<"EPROTOTYPE">,
+ Macro<"EROFS">,
+ Macro<"ESPIPE">,
+ Macro<"ESRCH">,
+ Macro<"ESTALE">,
+ Macro<"ETIME">,
+ Macro<"ETIMEDOUT">,
+ Macro<"ETXTBSY">,
+ Macro<"EWOULDBLOCK">,
+ Macro<"EXDEV">,
+ ],
+ [], // Types
+ [] // Functions
+ >;
+
+ let Headers = [
+ Errno,
+ ];
+}
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 154214dc5168..a17a3872fa27 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -170,7 +170,20 @@ def StdC : StandardSpec<"stdc"> {
]
>;
+ HeaderSpec Errno = HeaderSpec<
+ "errno.h",
+ [
+ Macro<"errno">,
+ Macro<"EDOM">,
+ Macro<"EILSEQ">,
+ Macro<"ERANGE">,
+ ],
+ [], // Types
+ [] // Functions
+ >;
+
let Headers = [
+ Errno,
Math,
String,
StdIO,
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 00df58860ff9..f9a86af7652a 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -1,4 +1,5 @@
-add_subdirectory(string)
+add_subdirectory(errno)
add_subdirectory(math)
+add_subdirectory(string)
add_subdirectory(__support)
diff --git a/libc/src/errno/CMakeLists.txt b/libc/src/errno/CMakeLists.txt
new file mode 100644
index 000000000000..32d7262044b2
--- /dev/null
+++ b/libc/src/errno/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_entrypoint_object(
+ __errno_location
+ SRCS
+ errno_location.cpp
+ HDRS
+ llvmlibc_errno.h
+)
+
+add_custom_target(libc_errno_unittests)
+
+add_libc_unittest(
+ errno_test
+ SUITE
+ libc_errno_unittests
+ SRCS
+ errno_test.cpp
+ DEPENDS
+ __errno_location
+)
diff --git a/libc/src/errno/errno_location.cpp b/libc/src/errno/errno_location.cpp
new file mode 100644
index 000000000000..1a1b2889c84b
--- /dev/null
+++ b/libc/src/errno/errno_location.cpp
@@ -0,0 +1,22 @@
+//===----------------- Implementation of __errno_location -----------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/llvmlibc_errno.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+static thread_local int __errno = 0;
+
+// __errno_location is not really an entry point but we still want it to behave
+// like an entry point because the errno macro resolves to the C symbol
+// "__errno_location".
+int *LLVM_LIBC_ENTRYPOINT(__errno_location)() { return &__errno; }
+
+} // namespace __llvm_libc
diff --git a/libc/src/errno/errno_test.cpp b/libc/src/errno/errno_test.cpp
new file mode 100644
index 000000000000..1ca61d5c625d
--- /dev/null
+++ b/libc/src/errno/errno_test.cpp
@@ -0,0 +1,17 @@
+//===---------------------- Unittests for errno --------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/llvmlibc_errno.h"
+
+#include "gtest/gtest.h"
+
+TEST(ErrnoTest, Basic) {
+ int test_val = 123;
+ llvmlibc_errno = test_val;
+ ASSERT_EQ(test_val, llvmlibc_errno);
+}
diff --git a/libc/src/errno/llvmlibc_errno.h b/libc/src/errno/llvmlibc_errno.h
new file mode 100644
index 000000000000..b5a8fdd26adc
--- /dev/null
+++ b/libc/src/errno/llvmlibc_errno.h
@@ -0,0 +1,22 @@
+//===------------------ Implementation header for errno -------------------===//
+//
+// 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_ERRNO_LLVMLIBC_ERRNO_H
+#define LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
+
+// Internal code should use this and not use the errno macro from the
+// public header.
+#define llvmlibc_errno (*__llvm_libc::__errno_location())
+
+namespace __llvm_libc {
+
+int *__errno_location();
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
More information about the libc-commits
mailing list