Skip to content

Commit

Permalink
[libc] Add dlfcn.h placeholder (#97501)
Browse files Browse the repository at this point in the history
Adds `dlopen` and friends. This is needed as part of the effort to
compile `libunwind` + `libc` without baremetal mode. This is part of
#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
  • Loading branch information
izaakschroeder authored Jul 6, 2024
1 parent f4e6ddb commit b151c7e
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 0 deletions.
6 changes: 6 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions libc/docs/dev/undefined_behavior.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
35 changes: 35 additions & 0 deletions libc/spec/posix.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1690,6 +1724,7 @@ def POSIX : StandardSpec<"POSIX"> {
ArpaInet,
CType,
Dirent,
DlFcn,
Errno,
FCntl,
PThread,
Expand Down
1 change: 1 addition & 0 deletions libc/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_subdirectory(__support)

add_subdirectory(ctype)
add_subdirectory(dlfcn)
add_subdirectory(errno)
add_subdirectory(fenv)
add_subdirectory(inttypes)
Expand Down
40 changes: 40 additions & 0 deletions libc/src/dlfcn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
)
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlclose.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions libc/src/dlfcn/dlclose.h
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions libc/src/dlfcn/dlerror.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions libc/src/dlfcn/dlerror.h
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions libc/src/dlfcn/dlopen.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions libc/src/dlfcn/dlopen.h
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions libc/src/dlfcn/dlsym.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions libc/src/dlfcn/dlsym.h
Original file line number Diff line number Diff line change
@@ -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 *);

This comment has been minimized.

Copy link
@RoseZhang03

RoseZhang03 Jul 10, 2024

Contributor

In posix.td you wrote that the arguments should be restricted, shouldn't it look like const char *__restrict?


} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_DLFCN_DLSYM_H

0 comments on commit b151c7e

Please sign in to comment.