diff options
author | Izaak Schroeder <izaak.schroeder@gmail.com> | 2024-07-06 16:01:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-06 16:01:59 -0700 |
commit | b151c7e36a26a4168d0384c88295099e4b6470d0 (patch) | |
tree | 019c1086e9cf472e4bfd66d8730d2fc4459dbff9 | |
parent | f4e6ddbc2ed77ef73a036408f1d04bb792e2d357 (diff) | |
download | llvm-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.txt | 6 | ||||
-rw-r--r-- | libc/config/linux/x86_64/entrypoints.txt | 6 | ||||
-rw-r--r-- | libc/docs/dev/undefined_behavior.rst | 4 | ||||
-rw-r--r-- | libc/spec/posix.td | 35 | ||||
-rw-r--r-- | libc/src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | libc/src/dlfcn/CMakeLists.txt | 40 | ||||
-rw-r--r-- | libc/src/dlfcn/dlclose.cpp | 18 | ||||
-rw-r--r-- | libc/src/dlfcn/dlclose.h | 18 | ||||
-rw-r--r-- | libc/src/dlfcn/dlerror.cpp | 20 | ||||
-rw-r--r-- | libc/src/dlfcn/dlerror.h | 18 | ||||
-rw-r--r-- | libc/src/dlfcn/dlopen.cpp | 18 | ||||
-rw-r--r-- | libc/src/dlfcn/dlopen.h | 18 | ||||
-rw-r--r-- | libc/src/dlfcn/dlsym.cpp | 18 | ||||
-rw-r--r-- | libc/src/dlfcn/dlsym.h | 18 |
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 |