Skip to content

[libc] Add link.h and elf.h placeholder #97504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

izaakschroeder
Copy link
Contributor

@izaakschroeder izaakschroeder commented Jul 3, 2024

This is a stacked PR that builds on #97501 and completes the effort to compile libunwind + libc without baremetal mode. This is part of #97191.

@llvmbot llvmbot added the libc label Jul 3, 2024
@izaakschroeder izaakschroeder changed the title [libc] Add link.h and elf.h [libc] Add link.h and elf.h Jul 3, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 3, 2024

@llvm/pr-subscribers-libc

Author: Izaak Schroeder (izaakschroeder)

Changes

Builds on #97501 and completes the effort to compile libunwind + libc without baremetal mode. This is part of #97191.


Patch is 27.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97504.diff

34 Files Affected:

  • (modified) libc/config/linux/aarch64/entrypoints.txt (+11)
  • (modified) libc/config/linux/aarch64/headers.txt (+3)
  • (modified) libc/config/linux/api.td (+13)
  • (modified) libc/config/linux/x86_64/entrypoints.txt (+11)
  • (modified) libc/config/linux/x86_64/headers.txt (+3)
  • (modified) libc/include/CMakeLists.txt (+29)
  • (added) libc/include/dlfcn.h.def (+17)
  • (added) libc/include/elf.h.def (+14)
  • (added) libc/include/link.h.def (+16)
  • (modified) libc/include/llvm-libc-macros/CMakeLists.txt (+12)
  • (added) libc/include/llvm-libc-macros/dlfcn-macros.h (+23)
  • (added) libc/include/llvm-libc-macros/elf-macros.h (+18)
  • (modified) libc/include/llvm-libc-macros/link-macros.h (+24-2)
  • (modified) libc/include/llvm-libc-types/CMakeLists.txt (+3)
  • (added) libc/include/llvm-libc-types/Dl_info.h (+19)
  • (added) libc/include/llvm-libc-types/__dl_iterate_phdr_callback_t.h (+17)
  • (added) libc/include/llvm-libc-types/struct_dl_phdr_info.h (+26)
  • (modified) libc/spec/linux.td (+30)
  • (modified) libc/spec/posix.td (+43)
  • (modified) libc/src/CMakeLists.txt (+2)
  • (added) libc/src/dlfcn/CMakeLists.txt (+54)
  • (added) libc/src/dlfcn/dladdr.cpp (+17)
  • (added) libc/src/dlfcn/dladdr.h (+20)
  • (added) libc/src/dlfcn/dlclose.cpp (+17)
  • (added) libc/src/dlfcn/dlclose.h (+18)
  • (added) libc/src/dlfcn/dlerror.cpp (+19)
  • (added) libc/src/dlfcn/dlerror.h (+18)
  • (added) libc/src/dlfcn/dlopen.cpp (+17)
  • (added) libc/src/dlfcn/dlopen.h (+18)
  • (added) libc/src/dlfcn/dlsym.cpp (+17)
  • (added) libc/src/dlfcn/dlsym.h (+18)
  • (added) libc/src/link/CMakeLists.txt (+9)
  • (added) libc/src/link/dl_iterate_phdr.cpp (+21)
  • (added) libc/src/link/dl_iterate_phdr.h (+20)
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 940df63e3912b..fe4cec1d7a77f 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -17,6 +17,14 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.tolower
     libc.src.ctype.toupper
 
+    # dlfcn.h entrypoints
+    libc.src.dlfcn.dlopen
+    libc.src.dlfcn.dlsym
+    libc.src.dlfcn.dlclose
+    libc.src.dlfcn.dlerror
+    libc.src.dlfcn.dlsym
+    libc.src.dlfcn.dladdr
+
     # errno.h entrypoints
     libc.src.errno.errno
 
@@ -26,6 +34,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.fcntl.open
     libc.src.fcntl.openat
 
+    # link.h entrypoints
+    libc.src.link.dl_iterate_phdr
+
     # sched.h entrypoints
     libc.src.sched.sched_get_priority_max
     libc.src.sched.sched_get_priority_min
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 7d25877cefcc8..ebe053af99d80 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -1,6 +1,8 @@
 set(TARGET_PUBLIC_HEADERS
     libc.include.assert
     libc.include.ctype
+    libc.include.dlfcn
+    libc.include.elf
     libc.include.errno
     libc.include.features
     libc.include.fenv
@@ -8,6 +10,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.stdint
     libc.include.inttypes
     libc.include.limits
+    libc.include.link
     libc.include.math
     libc.include.pthread
     libc.include.signal
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index eb0090c80b0da..3ff99f263f811 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -308,3 +308,16 @@ def SearchAPI : PublicAPI<"search.h"> {
 def SysStatvfsAPI : PublicAPI<"sys/statvfs.h"> {
   let Types = ["fsblkcnt_t", "fsfilcnt_t", "struct statvfs"];
 }
+
+def LinkAPI : PublicAPI<"link.h"> {
+  let Types = [
+    "struct dl_phdr_info",
+    "__dl_iterate_phdr_callback_t"
+  ];
+}
+
+def DlfcnAPI : PublicAPI<"dlfcn.h"> {
+  let Types = [
+    "Dl_info"
+  ];
+}
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 09f04fb31dfd8..18e682e52bb12 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -17,6 +17,14 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.tolower
     libc.src.ctype.toupper
 
+    # dlfcn.h entrypoints
+    libc.src.dlfcn.dlopen
+    libc.src.dlfcn.dlsym
+    libc.src.dlfcn.dlclose
+    libc.src.dlfcn.dlerror
+    libc.src.dlfcn.dlsym
+    libc.src.dlfcn.dladdr
+
     # errno.h entrypoints
     libc.src.errno.errno
 
@@ -26,6 +34,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.fcntl.open
     libc.src.fcntl.openat
 
+    # link.h entrypoints
+    libc.src.link.dl_iterate_phdr
+
     # sched.h entrypoints
     libc.src.sched.sched_get_priority_max
     libc.src.sched.sched_get_priority_min
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index 44d640b75e2bf..903771c5f96a6 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -2,6 +2,8 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.assert
     libc.include.ctype
     libc.include.dirent
+    libc.include.dlfcn
+    libc.include.elf
     libc.include.errno
     libc.include.fcntl
     libc.include.features
@@ -10,6 +12,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.stdint
     libc.include.inttypes
     libc.include.limits
+    libc.include.link
     libc.include.math
     libc.include.pthread
     libc.include.sched
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 3ab7817d8568b..a39c1c118165f 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -51,6 +51,16 @@ add_gen_header(
     .llvm_libc_common_h
 )
 
+add_gen_header(
+  dlfcn
+  DEF_FILE dlfcn.h.def
+  GEN_HDR dlfcn.h
+  DEPENDS
+    .llvm-libc-types.Dl_info
+    .llvm-libc-macros.dlfcn_macros
+    .llvm_libc_common_h
+)
+
 add_gen_header(
   features
   DEF_FILE features.h.def
@@ -358,6 +368,25 @@ add_gen_header(
     .llvm-libc-types.posix_spawn_file_actions_t
 )
 
+add_gen_header(
+  link
+  DEF_FILE link.h.def
+  GEN_HDR link.h
+  DEPENDS
+    .llvm_libc_common_h
+    .llvm-libc-types.struct_dl_phdr_info
+    .llvm-libc-types.__dl_iterate_phdr_callback_t
+    .llvm-libc-macros.link_macros
+)
+
+add_gen_header(
+  elf
+  DEF_FILE elf.h.def
+  GEN_HDR elf.h
+  DEPENDS
+    .llvm-libc-macros.elf_macros
+)
+
 # TODO: Not all platforms will have a include/sys directory. Add the sys
 # directory and the targets for sys/*.h files conditional to the OS requiring
 # them.
diff --git a/libc/include/dlfcn.h.def b/libc/include/dlfcn.h.def
new file mode 100644
index 0000000000000..31395871c6b97
--- /dev/null
+++ b/libc/include/dlfcn.h.def
@@ -0,0 +1,17 @@
+//===-- C standard library header dlfcn.h ---------------------------------===//
+//
+// 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_DLFCN_H
+#define LLVM_LIBC_DLFCN_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-macros/dlfcn-macros.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_DLFCN_H
diff --git a/libc/include/elf.h.def b/libc/include/elf.h.def
new file mode 100644
index 0000000000000..1c9d11929029f
--- /dev/null
+++ b/libc/include/elf.h.def
@@ -0,0 +1,14 @@
+//===-- C standard library header elf.h -----------------------------------===//
+//
+// 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_ELF_H
+#define LLVM_LIBC_ELF_H
+
+#include "llvm-libc-macros/elf-macros.h"
+
+#endif // LLVM_LIBC_ELF_H
diff --git a/libc/include/link.h.def b/libc/include/link.h.def
new file mode 100644
index 0000000000000..353398e4f3c88
--- /dev/null
+++ b/libc/include/link.h.def
@@ -0,0 +1,16 @@
+//===-- C standard library header link.h ----------------------------------===//
+//
+// 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_LINK_H
+#define LLVM_LIBC_LINK_H
+
+#include "llvm-libc-macros/link-macros.h"
+
+%%public_api()
+
+#endif // LLVM_LIBC_LINK_H
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index f6af11abd4dd7..60c8f5a9cd3de 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -277,3 +277,15 @@ add_macro_header(
   HDR
     stdckdint-macros.h
 )
+
+add_macro_header(
+  dlfcn_macros
+  HDR
+    dlfcn-macros.h
+)
+
+add_macro_header(
+  elf_macros
+  HDR
+    elf-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/dlfcn-macros.h b/libc/include/llvm-libc-macros/dlfcn-macros.h
new file mode 100644
index 0000000000000..dcd202b9ab435
--- /dev/null
+++ b/libc/include/llvm-libc-macros/dlfcn-macros.h
@@ -0,0 +1,23 @@
+//===-- Definition of macros from dlfcn.h ---------------------------------===//
+//
+// 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_MACROS_DLFCN_MACROS_H
+#define LLVM_LIBC_MACROS_DLFCN_MACROS_H
+
+#define RTLD_LAZY 0x00001
+#define RTLD_NOW 0x00002
+#define RTLD_GLOBAL 0x00100
+#define RTLD_LOCAL 0
+
+// Non-standard stuff here
+#define RTLD_BINDING_MASK 0x3
+#define RTLD_NOLOAD 0x00004
+#define RTLD_DEEPBIND 0x00008
+#define RTLD_NODELETE 0x01000
+
+#endif // LLVM_LIBC_MACROS_DLFCN_MACROS_H
diff --git a/libc/include/llvm-libc-macros/elf-macros.h b/libc/include/llvm-libc-macros/elf-macros.h
new file mode 100644
index 0000000000000..fa4442abf0f5c
--- /dev/null
+++ b/libc/include/llvm-libc-macros/elf-macros.h
@@ -0,0 +1,18 @@
+//===-- Definition of macros from elf.h -----------------------------------===//
+//
+// 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_MACROS_ELF_MACROS_H
+#define LLVM_LIBC_MACROS_ELF_MACROS_H
+
+#if __has_include(<linux/elf.h>)
+#include <linux/elf.h>
+#else
+#error "cannot use <sys/elf.h> without proper system headers."
+#endif
+
+#endif // LLVM_LIBC_MACROS_ELF_MACROS_H
diff --git a/libc/include/llvm-libc-macros/link-macros.h b/libc/include/llvm-libc-macros/link-macros.h
index 5c8cadab8e71c..f7461d9527a47 100644
--- a/libc/include/llvm-libc-macros/link-macros.h
+++ b/libc/include/llvm-libc-macros/link-macros.h
@@ -6,8 +6,30 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef LLVM_LIBC_MACROS_LINK_MACROS_H
+#define LLVM_LIBC_MACROS_LINK_MACROS_H
+
+#include "elf-macros.h"
+
 #ifdef __LP64__
-#define ElfW(type) Elf64_ ## type
+#define ElfW(type) Elf64_##type
 #else
-#define ElfW(type) Elf32_ ## type
+#define ElfW(type) Elf32_##type
+#endif
+
+struct link_map {
+  ElfW(Addr) l_addr;
+  char *l_name;
+  ElfW(Dyn) * l_ld;
+  struct link_map *l_next, *l_prev;
+};
+
+struct r_debug {
+  int r_version;
+  struct link_map *r_map;
+  ElfW(Addr) r_brk;
+  enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;
+  ElfW(Addr) r_ldbase;
+};
+
 #endif
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index d8b975572e0dd..016ec14b077e8 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -89,6 +89,9 @@ add_header(thrd_t HDR thrd_t.h DEPENDS .__thread_type)
 add_header(tss_t HDR tss_t.h)
 add_header(tss_dtor_t HDR tss_dtor_t.h)
 add_header(__atexithandler_t HDR __atexithandler_t.h)
+add_header(Dl_info HDR Dl_info.h)
+add_header(struct_dl_phdr_info HDR struct_dl_phdr_info.h)
+add_header(__dl_iterate_phdr_callback_t HDR __dl_iterate_phdr_callback_t.h)
 add_header(speed_t HDR speed_t.h)
 add_header(tcflag_t HDR tcflag_t.h)
 add_header(struct_termios HDR struct_termios.h DEPENDS .cc_t .speed_t .tcflag_t)
diff --git a/libc/include/llvm-libc-types/Dl_info.h b/libc/include/llvm-libc-types/Dl_info.h
new file mode 100644
index 0000000000000..bee32015c4008
--- /dev/null
+++ b/libc/include/llvm-libc-types/Dl_info.h
@@ -0,0 +1,19 @@
+//===-- Definition of type Dl_info ----------------------------------------===//
+//
+// 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_TYPES_DL_INFO_H
+#define LLVM_LIBC_TYPES_DL_INFO_H
+
+typedef struct {
+	const char *dli_fname;
+	void *dli_fbase;
+	const char *dli_sname;
+	void *dli_saddr;
+} Dl_info;
+
+#endif // LLVM_LIBC_TYPES_DL_INFO_H
diff --git a/libc/include/llvm-libc-types/__dl_iterate_phdr_callback_t.h b/libc/include/llvm-libc-types/__dl_iterate_phdr_callback_t.h
new file mode 100644
index 0000000000000..9d73e88076e00
--- /dev/null
+++ b/libc/include/llvm-libc-types/__dl_iterate_phdr_callback_t.h
@@ -0,0 +1,17 @@
+//===-- Definition of __dl_iterate_phdr_callback_t type -------------------===//
+//
+// 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_TYPES___DL_ITERATE_PHDR_CALLBACK_T_H
+#define LLVM_LIBC_TYPES___DL_ITERATE_PHDR_CALLBACK_T_H
+
+#include "llvm-libc-types/size_t.h"
+
+typedef int (*__dl_iterate_phdr_callback_t)(struct dl_phdr_info *info,
+                                            size_t size, void *data);
+
+#endif // LLVM_LIBC_TYPES___DL_ITERATE_PHDR_CALLBACK_T_H
diff --git a/libc/include/llvm-libc-types/struct_dl_phdr_info.h b/libc/include/llvm-libc-types/struct_dl_phdr_info.h
new file mode 100644
index 0000000000000..8bbd7811bbe2a
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_dl_phdr_info.h
@@ -0,0 +1,26 @@
+//===-- Definition of type struct dl_phdr_info ----------------------------===//
+//
+// 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_TYPES_STRUCT_DL_PHDR_INFO_H
+#define LLVM_LIBC_TYPES_STRUCT_DL_PHDR_INFO_H
+
+#include "llvm-libc-types/size_t.h"
+#include "llvm-libc-macros/link-macros.h"
+
+struct dl_phdr_info {
+  ElfW(Addr) dlpi_addr;
+  const char *dlpi_name;
+  const ElfW(Phdr) * dlpi_phdr;
+  ElfW(Half) dlpi_phnum;
+  unsigned long long int dlpi_adds;
+  unsigned long long int dlpi_subs;
+  size_t dlpi_tls_modid;
+  void *dlpi_tls_data;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_DL_PHDR_INFO_H
diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index 82630ff413c73..bd13dd17a85cd 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -3,6 +3,9 @@ def StructEpollEventPtr : PtrType<StructEpollEvent>;
 
 def StructEpollData : NamedType<"struct epoll_data">;
 
+def StructDlPhdrInfo : NamedType<"struct dl_phdr_info">;
+def DlIteratePhdrCallback : NamedType<"__dl_iterate_phdr_callback_t">;
+
 def Linux : StandardSpec<"Linux"> {
   HeaderSpec Errno = HeaderSpec<
       "errno.h",
@@ -264,8 +267,35 @@ def Linux : StandardSpec<"Linux"> {
       ]
   >;
 
+  HeaderSpec Link = HeaderSpec<
+     "link.h",
+      [], // Macros
+      [StructDlPhdrInfo, DlIteratePhdrCallback], // Types
+      [], // Enumerations
+      [
+        FunctionSpec<
+          "dl_iterate_phdr",
+          RetValSpec<IntType>,
+          [
+            ArgSpec<DlIteratePhdrCallback>,
+            ArgSpec<VoidPtr>
+          ]
+        >,
+      ]  // Functions
+  >;
+
+  HeaderSpec Elf = HeaderSpec<
+     "elf.h",
+      [], // Macros
+      [], // Types
+      [], // Enumerations
+      []  // Functions
+  >;
+
   let Headers = [
+    Elf,
     Errno,
+    Link,
     SysEpoll,
     SysMMan,
     SysPrctl,
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index d14047548e104..1a829704c0667 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -21,6 +21,9 @@ def PThreadOnceT : NamedType<"pthread_once_t">;
 def PThreadOnceTPtr : PtrType<PThreadOnceT>;
 def PThreadOnceCallback : NamedType<"__pthread_once_func_t">;
 
+def DlInfo : NamedType<"Dl_info">;
+def DlInfoPtr : PtrType<DlInfo>;
+
 def InoT : NamedType<"ino_t">;
 def UidT : NamedType<"uid_t">;
 def GidT : NamedType<"gid_t">;
@@ -222,6 +225,45 @@ def POSIX : StandardSpec<"POSIX"> {
       []  // Functions
   >;
 
+  HeaderSpec DlFcn = HeaderSpec<
+    "dlfcn.h",
+    [
+      Macro<"RTLD_LAZY">,
+      Macro<"RTLD_NOW">,
+      Macro<"RTLD_GLOBAL">,
+      Macro<"RTLD_LOCAL">,
+    ],
+    [DlInfo],  // Types
+    [], // Enumerations
+    [
+      FunctionSpec<
+          "dladdr",
+          RetValSpec<IntType>,
+          [ArgSpec<ConstVoidPtr>, ArgSpec<DlInfoPtr>]
+      >,
+      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 +1732,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..9ff88cffc487c 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -11,6 +11,8 @@ add_subdirectory(stdio)
 add_subdirectory(stdlib)
 add_subdirectory(string)
 add_subdirectory(wchar)
+add_subdirectory(dlfcn)
+add_subdirectory(link)
 
 if(${LIBC_TARGET_OS} STREQUAL "linux")
   add_subdirectory(dirent)
diff --git a/libc/src/dlfcn/CMakeLists.txt b/libc/src/dlfcn/CMakeLists.txt
new file mode 100644
index 0000000000000..5321499b2e334
--- /dev/null
+++ b/libc/src/dlfcn/CMakeLists.txt
@@ -0,0 +1,54 @@
+add_entrypoint_object(
+  dladdr
+  SRCS
+    dladdr.cpp
+  HDRS
+    dladdr.h
+  DEPENDS
+    libc.include.dlfcn
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  dlclose
+  SRCS
+    dlclose.cpp
+  HDRS
+    dlclose.h
+  DEPENDS
+    libc.include.dlfcn
+    libc.src.errno.errno
+)
+
+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/dladdr.cpp b/libc/src/dlfcn/dladdr.cpp
new file mode 100644
index 0000000000000..00ff1845fbe3e
--- /dev/null
+++ b/libc/src/dlfcn/dladdr.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of dladdr -----------------------------------------===//
+//
+// 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 "dladdr.h"
+
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, dladdr, (const void *, Dl_info *)) { return 0; }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/dlfcn/dladdr.h b/libc/src/dlfcn/dladdr.h
new file mode 100644
index 0000000000000..be9a7fec7a5ef
--- /dev/null
+++ b/libc/src/dlfcn/dladdr.h
@@ -0,0 +1,20 @@
+//===-- Implementation header of dladdr ------------------------*- 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_DLADDR_H
+#define LLVM_LIBC_SRC_DLFCN_DLADDR_H
+
+namespace LIBC_NAMESPACE {
+
+#include "include/llvm-libc-types/Dl_info.h"
+
+int dladdr(const void *,Dl_info *);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLADDR_H
diff --git a/libc/src/dlfcn/dlclose.cpp b/libc/src/dlfcn/dlclose.cpp
new file mode 100644
index 0000000000000..6dc1892120ddd
--- /dev/null
+++ b/libc/src/dlfcn/dlclose.cpp
@@ -0,0 +1,17 @@
+//===-- 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 {
+
+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 000000000...
[truncated]

@izaakschroeder
Copy link
Contributor Author

@izaakschroeder izaakschroeder mentioned this pull request Jul 3, 2024
39 tasks
Copy link

github-actions bot commented Jul 3, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@SchrodingerZhu SchrodingerZhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but need a small fix

@izaakschroeder izaakschroeder changed the title [libc] Add link.h and elf.h [libc] Add link.h and elf.h placeholder Jul 6, 2024
SchrodingerZhu pushed a commit that referenced this pull request Jul 7, 2024

namespace LIBC_NAMESPACE {

// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97929
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format I've seen more commonly used in LLVM is TODO(#97929): More details....

@nickdesaulniers
Copy link
Member

What's the status of this PR? Should it be closed?

@michaelrj-google
Copy link
Contributor

Closing as not superseded, link and elf headers are available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants