[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
This commit is contained in:
Izaak Schroeder
2024-07-06 16:01:59 -07:00
committed by GitHub
parent f4e6ddbc2e
commit b151c7e36a
14 changed files with 238 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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,

View File

@@ -1,6 +1,7 @@
add_subdirectory(__support)
add_subdirectory(ctype)
add_subdirectory(dlfcn)
add_subdirectory(errno)
add_subdirectory(fenv)
add_subdirectory(inttypes)

View File

@@ -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
)

View File

@@ -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

18
libc/src/dlfcn/dlclose.h Normal file
View File

@@ -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

View File

@@ -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

18
libc/src/dlfcn/dlerror.h Normal file
View File

@@ -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

18
libc/src/dlfcn/dlopen.cpp Normal file
View File

@@ -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

18
libc/src/dlfcn/dlopen.h Normal file
View File

@@ -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

18
libc/src/dlfcn/dlsym.cpp Normal file
View File

@@ -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

18
libc/src/dlfcn/dlsym.h Normal file
View File

@@ -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