[libc-commits] [libc] b151c7e - [libc] Add `dlfcn.h` placeholder (#97501)

via libc-commits libc-commits at lists.llvm.org
Sat Jul 6 16:02:03 PDT 2024


Author: Izaak Schroeder
Date: 2024-07-06T16:01:59-07:00
New Revision: b151c7e36a26a4168d0384c88295099e4b6470d0

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

LOG: [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

Added: 
    libc/src/dlfcn/CMakeLists.txt
    libc/src/dlfcn/dlclose.cpp
    libc/src/dlfcn/dlclose.h
    libc/src/dlfcn/dlerror.cpp
    libc/src/dlfcn/dlerror.h
    libc/src/dlfcn/dlopen.cpp
    libc/src/dlfcn/dlopen.h
    libc/src/dlfcn/dlsym.cpp
    libc/src/dlfcn/dlsym.h

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/docs/dev/undefined_behavior.rst
    libc/spec/posix.td
    libc/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index a6aeb0685bca4..6c67e4bbadee7 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 271763d8fe869..2ca8f00d2de50 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 c97a539ca8da4..3faae3134ce2a 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 d14047548e104..1878b1ee2ae41 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 09b16be1e2d42..9597e2380172b 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 0000000000000..e3a51ba65764d
--- /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 0000000000000..1f1bfabd79801
--- /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 0000000000000..27c0207d726e4
--- /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 0000000000000..711b5a39420b6
--- /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 0000000000000..966496016d3eb
--- /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 0000000000000..9fa4d061c9c82
--- /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 0000000000000..4565953efd494
--- /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 0000000000000..4c8dac698f61d
--- /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 0000000000000..8157ac3e3fd4c
--- /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


        


More information about the libc-commits mailing list