aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIzaak Schroeder <izaak.schroeder@gmail.com>2024-07-06 16:01:59 -0700
committerGitHub <noreply@github.com>2024-07-06 16:01:59 -0700
commitb151c7e36a26a4168d0384c88295099e4b6470d0 (patch)
tree019c1086e9cf472e4bfd66d8730d2fc4459dbff9
parentf4e6ddbc2ed77ef73a036408f1d04bb792e2d357 (diff)
downloadllvm-b151c7e36a26a4168d0384c88295099e4b6470d0.zip
llvm-b151c7e36a26a4168d0384c88295099e4b6470d0.tar.gz
llvm-b151c7e36a26a4168d0384c88295099e4b6470d0.tar.bz2
[libc] Add `dlfcn.h` placeholder (#97501)
Adds `dlopen` and friends. This is needed as part of the effort to compile `libunwind` + `libc` without baremetal mode. This is part of https://github.com/llvm/llvm-project/issues/97191. This should still be spec compliant, since `dlopen` always returns `NULL` and `dlerror` always returns an error message. > If dlopen() fails for any reason, it returns NULL. > The function dlclose() returns 0 on success, and nonzero on error. > Since the value of the symbol could actually be NULL (so that a NULL return from dlsym() need not indicate an error), the correct way to test for an error is to call dlerror() to clear any old error conditions, then call dlsym(), and then call dlerror() again, saving its return value into a variable, and check whether this saved value is not NULL. See: - https://linux.die.net/man/3/dlopen
-rw-r--r--libc/config/linux/aarch64/entrypoints.txt6
-rw-r--r--libc/config/linux/x86_64/entrypoints.txt6
-rw-r--r--libc/docs/dev/undefined_behavior.rst4
-rw-r--r--libc/spec/posix.td35
-rw-r--r--libc/src/CMakeLists.txt1
-rw-r--r--libc/src/dlfcn/CMakeLists.txt40
-rw-r--r--libc/src/dlfcn/dlclose.cpp18
-rw-r--r--libc/src/dlfcn/dlclose.h18
-rw-r--r--libc/src/dlfcn/dlerror.cpp20
-rw-r--r--libc/src/dlfcn/dlerror.h18
-rw-r--r--libc/src/dlfcn/dlopen.cpp18
-rw-r--r--libc/src/dlfcn/dlopen.h18
-rw-r--r--libc/src/dlfcn/dlsym.cpp18
-rw-r--r--libc/src/dlfcn/dlsym.h18
14 files changed, 238 insertions, 0 deletions
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index a6aeb06..6c67e4b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -17,6 +17,12 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper
+ # dlfcn.h entrypoints
+ libc.src.dlfcn.dlclose
+ libc.src.dlfcn.dlerror
+ libc.src.dlfcn.dlopen
+ libc.src.dlfcn.dlsym
+
# errno.h entrypoints
libc.src.errno.errno
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 271763d..2ca8f00 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -17,6 +17,12 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper
+ # dlfcn.h entrypoints
+ libc.src.dlfcn.dlclose
+ libc.src.dlfcn.dlerror
+ libc.src.dlfcn.dlopen
+ libc.src.dlfcn.dlsym
+
# errno.h entrypoints
libc.src.errno.errno
diff --git a/libc/docs/dev/undefined_behavior.rst b/libc/docs/dev/undefined_behavior.rst
index c97a539..3faae31 100644
--- a/libc/docs/dev/undefined_behavior.rst
+++ b/libc/docs/dev/undefined_behavior.rst
@@ -89,3 +89,7 @@ The C23 standard states that if the value of the ``rnd`` argument of the
the value of a math rounding direction macro, the direction of rounding is
unspecified. LLVM's libc chooses to use the ``FP_INT_TONEAREST`` rounding
direction in this case.
+
+Non-const Constant Return Values
+--------------------------------
+Some libc functions, like ``dlerror()``, return ``char *`` instead of ``const char *`` and then tell the caller they promise not to to modify this value. Any modification of this value is undefined behavior.
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index d140475..1878b1e 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -222,6 +222,40 @@ def POSIX : StandardSpec<"POSIX"> {
[] // Functions
>;
+ HeaderSpec DlFcn = HeaderSpec<
+ "dlfcn.h",
+ [
+ Macro<"RTLD_LAZY">,
+ Macro<"RTLD_NOW">,
+ Macro<"RTLD_GLOBAL">,
+ Macro<"RTLD_LOCAL">,
+ ],
+ [], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<
+ "dlclose",
+ RetValSpec<IntType>,
+ [ArgSpec<VoidPtr>]
+ >,
+ FunctionSpec<
+ "dlerror",
+ RetValSpec<CharPtr>,
+ []
+ >,
+ FunctionSpec<
+ "dlopen",
+ RetValSpec<VoidPtr>,
+ [ArgSpec<ConstCharPtr>, ArgSpec<IntType>]
+ >,
+ FunctionSpec<
+ "dlsym",
+ RetValSpec<VoidPtr>,
+ [ArgSpec<VoidRestrictedPtr>, ArgSpec<ConstCharRestrictedPtr>]
+ >,
+ ]
+ >;
+
HeaderSpec FCntl = HeaderSpec<
"fcntl.h",
[], // Macros
@@ -1690,6 +1724,7 @@ def POSIX : StandardSpec<"POSIX"> {
ArpaInet,
CType,
Dirent,
+ DlFcn,
Errno,
FCntl,
PThread,
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 09b16be..9597e23 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -1,6 +1,7 @@
add_subdirectory(__support)
add_subdirectory(ctype)
+add_subdirectory(dlfcn)
add_subdirectory(errno)
add_subdirectory(fenv)
add_subdirectory(inttypes)
diff --git a/libc/src/dlfcn/CMakeLists.txt b/libc/src/dlfcn/CMakeLists.txt
new file mode 100644
index 0000000..e3a51ba
--- /dev/null
+++ b/libc/src/dlfcn/CMakeLists.txt
@@ -0,0 +1,40 @@
+add_entrypoint_object(
+ dlclose
+ SRCS
+ dlclose.cpp
+ HDRS
+ dlclose.h
+)
+
+add_entrypoint_object(
+ dlerror
+ SRCS
+ dlerror.cpp
+ HDRS
+ dlerror.h
+ DEPENDS
+ libc.include.dlfcn
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ dlopen
+ SRCS
+ dlopen.cpp
+ HDRS
+ dlopen.h
+ DEPENDS
+ libc.include.dlfcn
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ dlsym
+ SRCS
+ dlsym.cpp
+ HDRS
+ dlsym.h
+ DEPENDS
+ libc.include.dlfcn
+ libc.src.errno.errno
+)
diff --git a/libc/src/dlfcn/dlclose.cpp b/libc/src/dlfcn/dlclose.cpp
new file mode 100644
index 0000000..1f1bfab
--- /dev/null
+++ b/libc/src/dlfcn/dlclose.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of dlclose -----------------------------------------===//
+//
+// 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 "dlclose.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97917
+LLVM_LIBC_FUNCTION(int, dlclose, (void *)) { return -1; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/dlfcn/dlclose.h b/libc/src/dlfcn/dlclose.h
new file mode 100644
index 0000000..27c0207
--- /dev/null
+++ b/libc/src/dlfcn/dlclose.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of dlclose ------------------------*- 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_DLFCN_DLCLOSE_H
+#define LLVM_LIBC_SRC_DLFCN_DLCLOSE_H
+
+namespace LIBC_NAMESPACE {
+
+int dlclose(void *);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLCLOSE_H
diff --git a/libc/src/dlfcn/dlerror.cpp b/libc/src/dlfcn/dlerror.cpp
new file mode 100644
index 0000000..711b5a3
--- /dev/null
+++ b/libc/src/dlfcn/dlerror.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of delerror ----------------------------------------===//
+//
+// 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 "dlerror.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97918
+LLVM_LIBC_FUNCTION(char *, dlerror, ()) {
+ return const_cast<char *>("unsupported");
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/dlfcn/dlerror.h b/libc/src/dlfcn/dlerror.h
new file mode 100644
index 0000000..9664960
--- /dev/null
+++ b/libc/src/dlfcn/dlerror.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of dlerror ------------------------*- 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_DLFCN_DLERROR_H
+#define LLVM_LIBC_SRC_DLFCN_DLERROR_H
+
+namespace LIBC_NAMESPACE {
+
+char *dlerror();
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLERROR_H
diff --git a/libc/src/dlfcn/dlopen.cpp b/libc/src/dlfcn/dlopen.cpp
new file mode 100644
index 0000000..9fa4d06
--- /dev/null
+++ b/libc/src/dlfcn/dlopen.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of dlopen -----------------------------------------===//
+//
+// 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 "dlopen.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97919
+LLVM_LIBC_FUNCTION(void *, dlopen, (const char *, int)) { return nullptr; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/dlfcn/dlopen.h b/libc/src/dlfcn/dlopen.h
new file mode 100644
index 0000000..4565953
--- /dev/null
+++ b/libc/src/dlfcn/dlopen.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of dlopen -------------------------*- 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_DLFCN_DLOPEN_H
+#define LLVM_LIBC_SRC_DLFCN_DLOPEN_H
+
+namespace LIBC_NAMESPACE {
+
+void *dlopen(const char *, int);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLOPEN_H
diff --git a/libc/src/dlfcn/dlsym.cpp b/libc/src/dlfcn/dlsym.cpp
new file mode 100644
index 0000000..4c8dac6
--- /dev/null
+++ b/libc/src/dlfcn/dlsym.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of dlsym ------------------------------------------===//
+//
+// 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 "dlsym.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97920
+LLVM_LIBC_FUNCTION(void *, dlsym, (void *, const char *)) { return nullptr; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/dlfcn/dlsym.h b/libc/src/dlfcn/dlsym.h
new file mode 100644
index 0000000..8157ac3
--- /dev/null
+++ b/libc/src/dlfcn/dlsym.h
@@ -0,0 +1,18 @@
+//===-- Implementation header of dlsym --------------------------*- 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_DLFCN_DLSYM_H
+#define LLVM_LIBC_SRC_DLFCN_DLSYM_H
+
+namespace LIBC_NAMESPACE {
+
+void *dlsym(void *, const char *);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLSYM_H