Skip to content

Conversation

@petrhosek
Copy link
Member

Some of the baremetal users of libc use elf.h to generate coredumps and we would like to support this use case without needing Linux elf.h.

We plan to expand the implementation in the future.

@llvmbot
Copy link
Member

llvmbot commented Dec 18, 2025

@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-libc

Author: Petr Hosek (petrhosek)

Changes

Some of the baremetal users of libc use elf.h to generate coredumps and we would like to support this use case without needing Linux elf.h.

We plan to expand the implementation in the future.


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

25 Files Affected:

  • (modified) libc/config/baremetal/aarch64/headers.txt (+1)
  • (modified) libc/config/baremetal/arm/headers.txt (+1)
  • (modified) libc/config/baremetal/riscv/headers.txt (+1)
  • (modified) libc/include/elf.yaml (+159-3)
  • (modified) libc/include/llvm-libc-macros/elf-macros.h (+1-5)
  • (added) libc/include/llvm-libc-types/Elf32_Addr.h (+16)
  • (added) libc/include/llvm-libc-types/Elf32_Ehdr.h (+35)
  • (added) libc/include/llvm-libc-types/Elf32_Half.h (+16)
  • (added) libc/include/llvm-libc-types/Elf32_Lword.h (+16)
  • (added) libc/include/llvm-libc-types/Elf32_Nhdr.h (+20)
  • (added) libc/include/llvm-libc-types/Elf32_Off.h (+16)
  • (added) libc/include/llvm-libc-types/Elf32_Phdr.h (+27)
  • (added) libc/include/llvm-libc-types/Elf32_Sword.h (+16)
  • (added) libc/include/llvm-libc-types/Elf32_Word.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Addr.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Ehdr.h (+35)
  • (added) libc/include/llvm-libc-types/Elf64_Half.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Lword.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Nhdr.h (+20)
  • (added) libc/include/llvm-libc-types/Elf64_Off.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Phdr.h (+28)
  • (added) libc/include/llvm-libc-types/Elf64_Sword.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Sxword.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Word.h (+16)
  • (added) libc/include/llvm-libc-types/Elf64_Xword.h (+16)
diff --git a/libc/config/baremetal/aarch64/headers.txt b/libc/config/baremetal/aarch64/headers.txt
index 5666ef7e0012d..31cc04d849109 100644
--- a/libc/config/baremetal/aarch64/headers.txt
+++ b/libc/config/baremetal/aarch64/headers.txt
@@ -2,6 +2,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.assert
     libc.include.complex
     libc.include.ctype
+    libc.include.elf
     libc.include.errno
     libc.include.features
     libc.include.fenv
diff --git a/libc/config/baremetal/arm/headers.txt b/libc/config/baremetal/arm/headers.txt
index 1f64afebdaaa7..a259c3a4d834b 100644
--- a/libc/config/baremetal/arm/headers.txt
+++ b/libc/config/baremetal/arm/headers.txt
@@ -2,6 +2,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.assert
     libc.include.complex
     libc.include.ctype
+    libc.include.elf
     libc.include.errno
     libc.include.features
     libc.include.fenv
diff --git a/libc/config/baremetal/riscv/headers.txt b/libc/config/baremetal/riscv/headers.txt
index 1f64afebdaaa7..a259c3a4d834b 100644
--- a/libc/config/baremetal/riscv/headers.txt
+++ b/libc/config/baremetal/riscv/headers.txt
@@ -2,6 +2,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.assert
     libc.include.complex
     libc.include.ctype
+    libc.include.elf
     libc.include.errno
     libc.include.features
     libc.include.fenv
diff --git a/libc/include/elf.yaml b/libc/include/elf.yaml
index f78ae82c77850..c433b9d495c9c 100644
--- a/libc/include/elf.yaml
+++ b/libc/include/elf.yaml
@@ -1,9 +1,165 @@
 header: elf.h
 header_template: elf.h.def
 standards:
-  - Linux
-macros: []
-types: []
+  - svid
+macros:
+  - macro_name: EI_MAG0
+    macro_value: 0
+  - macro_name: EI_MAG1
+    macro_value: 1
+  - macro_name: EI_MAG2
+    macro_value: 2
+  - macro_name: EI_MAG3
+    macro_value: 3
+  - macro_name: EI_CLASS
+    macro_value: 4
+  - macro_name: EI_DATA
+    macro_value: 5
+  - macro_name: EI_VERSION
+    macro_value: 6
+  - macro_name: EI_OSABI
+    macro_value: 7
+  - macro_name: EI_ABIVERSION
+    macro_value: 8
+  - macro_name: EI_PAD
+    macro_value: 9
+  - macro_name: EI_NIDENT
+    macro_value: 16
+  - macro_name: ELFMAG0
+    macro_value: '0x7f'
+  - macro_name: ELFMAG1
+    macro_value: "'E'"
+  - macro_name: ELFMAG2
+    macro_value: "'L'"
+  - macro_name: ELFMAG3
+    macro_value: "'F'"
+  - macro_name: ELFMAG
+    macro_value: '"\177ELF"'
+  - macro_name: SELFMAG
+    macro_value: 4
+  - macro_name: ELFCLASSNONE
+    macro_value: 0
+  - macro_name: ELFCLASS32
+    macro_value: 1
+  - macro_name: ELFCLASS64
+    macro_value: 2
+  - macro_name: ELFDATANONE
+    macro_value: 0
+  - macro_name: ELFDATA2LSB
+    macro_value: 1
+  - macro_name: ELFDATA2MSB
+    macro_value: 2
+  - macro_name: ELFOSABI_NONE
+    macro_value: 0
+  - macro_name: ET_NONE
+    macro_value: 0
+  - macro_name: ET_REL
+    macro_value: 1
+  - macro_name: ET_EXEC
+    macro_value: 2
+  - macro_name: ET_DYN
+    macro_value: 3
+  - macro_name: ET_CORE
+    macro_value: 4
+  - macro_name: ET_LOOS
+    macro_value: '0xfe00'
+  - macro_name: ET_HIOS
+    macro_value: '0xfeff'
+  - macro_name: ET_LOPROC
+    macro_value: '0xff00'
+  - macro_name: ET_HIPROC
+    macro_value: '0xffff'
+  - macro_name: EM_NONE
+    macro_value: 0
+  - macro_name: EV_NONE
+    macro_value: 0
+  - macro_name: EV_CURRENT
+    macro_value: 1
+  - macro_name: PT_NULL
+    macro_value: 0
+  - macro_name: PT_LOAD
+    macro_value: 1
+  - macro_name: PT_DYNAMIC
+    macro_value: 2
+  - macro_name: PT_INTERP
+    macro_value: 3
+  - macro_name: PT_NOTE
+    macro_value: 4
+  - macro_name: PT_SHLIB
+    macro_value: 5
+  - macro_name: PT_PHDR
+    macro_value: 6
+  - macro_name: PT_TLS
+    macro_value: 7
+  - macro_name: PT_LOOS
+    macro_value: '0x60000000'
+  - macro_name: PT_HIOS
+    macro_value: '0x6fffffff'
+  - macro_name: PT_LOPROC
+    macro_value: '0x70000000'
+  - macro_name: PT_HIPROC
+    macro_value: '0x7fffffff'
+  - macro_name: PF_X
+    macro_value: '0x1'
+  - macro_name: PF_W
+    macro_value: '0x2'
+  - macro_name: PF_R
+    macro_value: '0x4'
+  - macro_name: PF_MASKOS
+    macro_value: '0x0ff00000'
+  - macro_name: PF_MASKPROC
+    macro_value: '0xf0000000'
+  # Notes used in ET_CORE.
+  - macro_name: NT_PRSTATUS
+    macro_value: 1
+    standards:
+      - linux
+  - macro_name: NT_PRFPREG
+    macro_value: 2
+    standards:
+      - linux
+  - macro_name: NT_PRPSINFO
+    macro_value: 3
+    standards:
+      - linux
+  - macro_name: NT_TASKSTRUCT
+    macro_value: 4
+    standards:
+      - linux
+  - macro_name: NT_PLATFORM
+    macro_value: 5
+    standards:
+      - linux
+  - macro_name: NT_AUXV
+    macro_value: 6
+    standards:
+      - linux
+  # Notes used by GNU toolchain.
+  - macro_name: NT_GNU_BUILD_ID
+    macro_value: 3
+    standards:
+      - gnu
+types:
+  - type_name: Elf32_Addr
+  - type_name: Elf32_Half
+  - type_name: Elf32_Off
+  - type_name: Elf32_Sword
+  - type_name: Elf32_Word
+  - type_name: Elf32_Lword
+  - type_name: Elf32_Ehdr
+  - type_name: Elf32_Phdr
+  - type_name: Elf32_Nhdr
+  - type_name: Elf64_Addr
+  - type_name: Elf64_Half
+  - type_name: Elf64_Off
+  - type_name: Elf64_Sword
+  - type_name: Elf64_Sxword
+  - type_name: Elf64_Word
+  - type_name: Elf64_Lword
+  - type_name: Elf64_Xword
+  - type_name: Elf64_Ehdr
+  - type_name: Elf64_Phdr
+  - type_name: Elf64_Nhdr
 enums: []
 objects: []
 functions: []
diff --git a/libc/include/llvm-libc-macros/elf-macros.h b/libc/include/llvm-libc-macros/elf-macros.h
index fa4442abf0f5c..fffcbb62527a7 100644
--- a/libc/include/llvm-libc-macros/elf-macros.h
+++ b/libc/include/llvm-libc-macros/elf-macros.h
@@ -9,10 +9,6 @@
 #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
+#define EI_NIDENT 16
 
 #endif // LLVM_LIBC_MACROS_ELF_MACROS_H
diff --git a/libc/include/llvm-libc-types/Elf32_Addr.h b/libc/include/llvm-libc-types/Elf32_Addr.h
new file mode 100644
index 0000000000000..16cca621fbd47
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Addr.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf32_Addr 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_ELF32_ADDR_H
+#define LLVM_LIBC_TYPES_ELF32_ADDR_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint32_t Elf32_Addr;
+
+#endif // LLVM_LIBC_TYPES_ELF32_ADDR_H
diff --git a/libc/include/llvm-libc-types/Elf32_Ehdr.h b/libc/include/llvm-libc-types/Elf32_Ehdr.h
new file mode 100644
index 0000000000000..571b234a6ff6b
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Ehdr.h
@@ -0,0 +1,35 @@
+//===-- Definition of Elf32_Ehdr 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_ELF32_EHDR_H
+#define LLVM_LIBC_TYPES_ELF32_EHDR_H
+
+#include "../llvm-libc-macros/elf-macros.h"
+#include "Elf32_Addr.h"
+#include "Elf32_Half.h"
+#include "Elf32_Off.h"
+#include "Elf32_Word.h"
+
+typedef struct {
+  unsigned char e_ident[EI_NIDENT];
+  Elf32_Half e_type;
+  Elf32_Half e_machine;
+  Elf32_Word e_version;
+  Elf32_Addr e_entry;
+  Elf32_Off e_phoff;
+  Elf32_Off e_shoff;
+  Elf32_Word e_flags;
+  Elf32_Half e_ehsize;
+  Elf32_Half e_phentsize;
+  Elf32_Half e_phnum;
+  Elf32_Half e_shentsize;
+  Elf32_Half e_shnum;
+  Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+#endif // LLVM_LIBC_TYPES_ELF32_EHDR_H
diff --git a/libc/include/llvm-libc-types/Elf32_Half.h b/libc/include/llvm-libc-types/Elf32_Half.h
new file mode 100644
index 0000000000000..b614b416d51af
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Half.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf32_Half 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_ELF32_HALF_H
+#define LLVM_LIBC_TYPES_ELF32_HALF_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint16_t Elf32_Half;
+
+#endif // LLVM_LIBC_TYPES_ELF32_HALF_H
diff --git a/libc/include/llvm-libc-types/Elf32_Lword.h b/libc/include/llvm-libc-types/Elf32_Lword.h
new file mode 100644
index 0000000000000..5d1e634a1b9b5
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Lword.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf32_Lword 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_ELF32_LWORD_H
+#define LLVM_LIBC_TYPES_ELF32_LWORD_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint32_t Elf32_Lword;
+
+#endif // LLVM_LIBC_TYPES_ELF32_LWORD_H
diff --git a/libc/include/llvm-libc-types/Elf32_Nhdr.h b/libc/include/llvm-libc-types/Elf32_Nhdr.h
new file mode 100644
index 0000000000000..a15c1f21cd6ca
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Nhdr.h
@@ -0,0 +1,20 @@
+//===-- Definition of Elf32_Nhdr 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_ELF32_NHDR_H
+#define LLVM_LIBC_TYPES_ELF32_NHDR_H
+
+#include "Elf32_Word.h"
+
+typedef struct {
+  Elf32_Word n_namesz;
+  Elf32_Word n_descsz;
+  Elf32_Word n_type;
+} Elf32_Note;
+
+#endif // LLVM_LIBC_TYPES_ELF32_NHDR_H
diff --git a/libc/include/llvm-libc-types/Elf32_Off.h b/libc/include/llvm-libc-types/Elf32_Off.h
new file mode 100644
index 0000000000000..46c7118d95e77
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Off.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf32_Off 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_ELF32_OFF_H
+#define LLVM_LIBC_TYPES_ELF32_OFF_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint32_t Elf32_Off;
+
+#endif // LLVM_LIBC_TYPES_ELF32_OFF_H
diff --git a/libc/include/llvm-libc-types/Elf32_Phdr.h b/libc/include/llvm-libc-types/Elf32_Phdr.h
new file mode 100644
index 0000000000000..1fcb6d0e18108
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Phdr.h
@@ -0,0 +1,27 @@
+//===-- Definition of Elf32_Phdr 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_ELF32_PHDR_H
+#define LLVM_LIBC_TYPES_ELF32_PHDR_H
+
+#include "Elf32_Addr.h"
+#include "Elf32_Off.h"
+#include "Elf32_Word.h"
+
+typedef struct {
+  Elf32_Word p_type;
+  Elf32_Off p_offset;
+  Elf32_Addr p_vaddr;
+  Elf32_Addr p_paddr;
+  Elf32_Word p_filesz;
+  Elf32_Word p_memsz;
+  Elf32_Word p_flags;
+  Elf32_Word p_align;
+} Elf32_Phdr;
+
+#endif // LLVM_LIBC_TYPES_ELF32_EHDR_H
diff --git a/libc/include/llvm-libc-types/Elf32_Sword.h b/libc/include/llvm-libc-types/Elf32_Sword.h
new file mode 100644
index 0000000000000..8adbba727afde
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Sword.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf32_Sword 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_ELF32_SWORD_H
+#define LLVM_LIBC_TYPES_ELF32_SWORD_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef int32_t Elf32_Sword;
+
+#endif // LLVM_LIBC_TYPES_ELF32_SWORD_H
diff --git a/libc/include/llvm-libc-types/Elf32_Word.h b/libc/include/llvm-libc-types/Elf32_Word.h
new file mode 100644
index 0000000000000..7444a8b41ff4b
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf32_Word.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf32_Word 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_ELF32_WORD_H
+#define LLVM_LIBC_TYPES_ELF32_WORD_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint32_t Elf32_Word;
+
+#endif // LLVM_LIBC_TYPES_ELF32_WORD_H
diff --git a/libc/include/llvm-libc-types/Elf64_Addr.h b/libc/include/llvm-libc-types/Elf64_Addr.h
new file mode 100644
index 0000000000000..a186c1b316f40
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Addr.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf64_Addr 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_ELF64_ADDR_H
+#define LLVM_LIBC_TYPES_ELF64_ADDR_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint64_t Elf64_Addr;
+
+#endif // LLVM_LIBC_TYPES_ELF64_ADDR_H
diff --git a/libc/include/llvm-libc-types/Elf64_Ehdr.h b/libc/include/llvm-libc-types/Elf64_Ehdr.h
new file mode 100644
index 0000000000000..59bea9c302f51
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Ehdr.h
@@ -0,0 +1,35 @@
+//===-- Definition of Elf64_Ehdr 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_ELF64_EHDR_H
+#define LLVM_LIBC_TYPES_ELF64_EHDR_H
+
+#include "../llvm-libc-macros/elf-macros.h"
+#include "Elf64_Addr.h"
+#include "Elf64_Half.h"
+#include "Elf64_Off.h"
+#include "Elf64_Word.h"
+
+typedef struct {
+  unsigned char e_ident[EI_NIDENT];
+  Elf64_Half e_type;
+  Elf64_Half e_machine;
+  Elf64_Word e_version;
+  Elf64_Addr e_entry;
+  Elf64_Off e_phoff;
+  Elf64_Off e_shoff;
+  Elf64_Word e_flags;
+  Elf64_Half e_ehsize;
+  Elf64_Half e_phentsize;
+  Elf64_Half e_phnum;
+  Elf64_Half e_shentsize;
+  Elf64_Half e_shnum;
+  Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+#endif // LLVM_LIBC_TYPES_ELF64_EHDR_H
diff --git a/libc/include/llvm-libc-types/Elf64_Half.h b/libc/include/llvm-libc-types/Elf64_Half.h
new file mode 100644
index 0000000000000..2f0bfe88992d0
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Half.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf64_Half 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_ELF64_HALF_H
+#define LLVM_LIBC_TYPES_ELF64_HALF_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint16_t Elf64_Half;
+
+#endif // LLVM_LIBC_TYPES_ELF64_HALF_H
diff --git a/libc/include/llvm-libc-types/Elf64_Lword.h b/libc/include/llvm-libc-types/Elf64_Lword.h
new file mode 100644
index 0000000000000..5435e1d8e5deb
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Lword.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf64_Lword 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_ELF64_LWORD_H
+#define LLVM_LIBC_TYPES_ELF64_LWORD_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint64_t Elf64_Lword;
+
+#endif // LLVM_LIBC_TYPES_ELF64_LWORD_H
diff --git a/libc/include/llvm-libc-types/Elf64_Nhdr.h b/libc/include/llvm-libc-types/Elf64_Nhdr.h
new file mode 100644
index 0000000000000..ed0e12cc03d56
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Nhdr.h
@@ -0,0 +1,20 @@
+//===-- Definition of Elf64_Nhdr 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_ELF64_NHDR_H
+#define LLVM_LIBC_TYPES_ELF64_NHDR_H
+
+#include "Elf64_Word.h"
+
+typedef struct {
+  Elf64_Word n_namesz;
+  Elf64_Word n_descsz;
+  Elf64_Word n_type;
+} Elf64_Note;
+
+#endif // LLVM_LIBC_TYPES_ELF64_NHDR_H
diff --git a/libc/include/llvm-libc-types/Elf64_Off.h b/libc/include/llvm-libc-types/Elf64_Off.h
new file mode 100644
index 0000000000000..e33c47e658152
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Off.h
@@ -0,0 +1,16 @@
+//===-- Definition of Elf64_Off 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_ELF64_OFF_H
+#define LLVM_LIBC_TYPES_ELF64_OFF_H
+
+#include "../llvm-libc-macros/stdint-macros.h"
+
+typedef uint64_t Elf64_Off;
+
+#endif // LLVM_LIBC_TYPES_ELF32_OFF_H
diff --git a/libc/include/llvm-libc-types/Elf64_Phdr.h b/libc/include/llvm-libc-types/Elf64_Phdr.h
new file mode 100644
index 0000000000000..e5c96a56491d9
--- /dev/null
+++ b/libc/include/llvm-libc-types/Elf64_Phdr.h
@@ -0,0 +1,28 @@
+//===-- Definition of Elf64_Phdr 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_ELF64_PHDR_H
+#define LLVM_LIBC_TYPES_ELF64_PHDR_H
+
+#include "Elf64_Addr.h"
+#include "Elf64_Off.h"
+#include "Elf64_Word.h"
+#include "Elf64_Xword.h"
+
+typedef struct {
+  Elf64_Word p_type;
+  Elf64_Word p_flags;
+  Elf64_Off p_offset;
+  Elf64_Addr p_vaddr;
+  Elf64_Addr p_paddr;
+  Elf64_Xword p_filesz;
+  Elf64_Xword p_memsz;
+  Elf64_Xword p_align;
+} Elf64_Phdr;
+
+#endif // LLVM_LIBC_TYPES_ELF64_PHDR_H
diff --git a/libc/include/llvm-libc-types/Elf64_Sword.h b/libc/include/llvm-libc-types/Elf64_Sword....
[truncated]

@vonosmas
Copy link
Contributor

I suspect you'd need to add CMake targets and dependencies for all the new type headers... Happy to see these headers expanded!

Some of the baremetal users of libc use elf.h to generate coredumps and
we would like to support this use case without needing Linux elf.h.

We plan to expand the implementation in the future.
add_header(uint_ulr_t HDR uint_ulr_t.h)
add_header(uint_ur_t HDR uint_ur_t.h)

# ELF
Copy link
Contributor

Choose a reason for hiding this comment

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

I forget why we have a file for every single type separately

Copy link
Contributor

@SchrodingerZhu SchrodingerZhu Dec 18, 2025

Choose a reason for hiding this comment

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

User have a way to disable individual type on their choice.

For example, glibc has the following:

#ifndef __ACTION_FN_T
# define __ACTION_FN_T
typedef void (*__action_fn_t) (const void *__nodep, VISIT __value,
                               int __level);
#endif

For us, user can use the header guard for each type... a bit awkward thou.

Copy link
Contributor

Choose a reason for hiding this comment

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

Updated from the monthly meeting, this is also have to do with the YAML structure we have for headergen.

#else
#error "cannot use <sys/elf.h> without proper system headers."
#endif
#define EI_NIDENT 16
Copy link
Contributor

Choose a reason for hiding this comment

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

how about other macros used in

if (phdr.p_type == PT_DYNAMIC && _DYNAMIC)

Copy link
Member Author

Choose a reason for hiding this comment

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

I originally planned on starting with something more minimal and expand later, but given that we're already using these macro inside libc I don't think that's going to work, so I'm expanding the change to cover these use cases as well.

@petrhosek petrhosek marked this pull request as ready for review December 23, 2025 03:56
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.

Thank you for doing this.

The vDSO/Startup part looks good to me.

@petrhosek
Copy link
Member Author

@michaelrj-google Do you have any concerns?

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

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

Overall LGTM, fine to land after addressing comments.

@@ -0,0 +1,23 @@

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like all of these have a leading newline. It would be good to clean that up.

#include "Elf64_Off.h"
#include "Elf64_Word.h"

#define EI_NIDENT 16
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like this is defined in two separate headers. I understand that including macros from types is problematic so it might be best to just add a comment to both headers so that someone updating one knows to update both.

#include "src/__support/threads/linux/futex_word.h"
#include <linux/auxvec.h>

#include <elf.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't include the public elf header, it should include the proxy headers for the types/macros it's using. Looks like just ElfW?


#include <linux/auxvec.h>
#include <linux/elf.h>
#include <elf.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

same here, this should include the proxy header for ElfW instead of elf.h.

libc.hdr.types.struct_timeval
libc.hdr.types.time_t
libc.hdr.link_macros
libc.include.elf
Copy link
Contributor

Choose a reason for hiding this comment

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

also need to update the build when you update the include.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants