diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index a6aeb0685bca48..6c67e4bbadee7e 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 271763d8fe869a..2ca8f00d2de50a 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 c97a539ca8da45..3faae3134ce2a4 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 d14047548e104f..1878b1ee2ae412 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, + [ArgSpec] + >, + FunctionSpec< + "dlerror", + RetValSpec, + [] + >, + FunctionSpec< + "dlopen", + RetValSpec, + [ArgSpec, ArgSpec] + >, + FunctionSpec< + "dlsym", + RetValSpec, + [ArgSpec, ArgSpec] + >, + ] + >; + 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 09b16be1e2d42e..9597e2380172b5 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 00000000000000..e3a51ba65764d4 --- /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 00000000000000..1f1bfabd798010 --- /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 00000000000000..27c0207d726e49 --- /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 00000000000000..711b5a39420b66 --- /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("unsupported"); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/dlfcn/dlerror.h b/libc/src/dlfcn/dlerror.h new file mode 100644 index 00000000000000..966496016d3ebd --- /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 00000000000000..9fa4d061c9c82a --- /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 00000000000000..4565953efd4943 --- /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 00000000000000..4c8dac698f61d7 --- /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 00000000000000..8157ac3e3fd4ca --- /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