[libc-commits] [libc] [libc][linux] add support to parse PT_GNU_PROPERTY (PR #174772)
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Fri Jan 16 14:19:17 PST 2026
================
@@ -0,0 +1,92 @@
+//===-- Header file of gnu_property_section -------------------------------===//
+//
+// 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_STARTUP_LINUX_GNU_PROPERTY_SECTION_H
+#define LLVM_LIBC_STARTUP_LINUX_GNU_PROPERTY_SECTION_H
+
+#include "include/llvm-libc-macros/link-macros.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+#include <linux/elf.h>
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+// The layout of the .note.gnu.property section and the program property is
+// described in "System V Application Binary Interface - Linux Extensions"
+// (https://github.com/hjl-tools/linux-abi/wiki).
+
+// The program property note is basically a note (Elf64_Nhdr) prepended with:
+// * n_name[4]: should always be "GNU\0"
+// * n_desc: an array of n_descsz bytes with program property entries
+// Since we are casting a memory address into this struct, the layout needs to
+// *exactly* match.
+struct Elf64_ProgramPropertyNote {
+ Elf64_Nhdr nhdr;
+ unsigned char n_name[4];
+ unsigned char n_desc[0]; // the size of 'n_desc' depends on n_descsz and is
+ // not known statically.
+};
+
+// 32-bit variant for ProgramPropertyNote.
+struct Elf32_ProgramPropertyNote {
+ Elf32_Nhdr nhdr;
+ unsigned char n_name[4];
+ unsigned char n_desc[0]; // the size of 'n_desc' depends on n_descsz and is
+ // not known statically.
+};
+
+// A program property consists of a type, the data size, followed by the actual
+// data and potential padding (aligning it to 64bit).
+// Since we are casting a memory address into this struct, the layout needs to
+// *exactly* match (The padding is ommited since it doesn't have actual
+// content).
+// pr_data needs to be ElfW_Word aligned, therefore the whole struct needs to be
+// aligned.
+struct Elf64_ProgramProperty {
+ Elf64_Word pr_type;
+ Elf64_Word pr_datasz;
+ unsigned char pr_data[0];
+};
+
+// 32-bit variant for ProgramProperty.
+struct Elf32_ProgramProperty {
+ Elf32_Word pr_type;
+ Elf32_Word pr_datasz;
+ unsigned char pr_data[0];
+};
+
+struct GnuPropertyFeatures {
+#ifdef LIBC_TARGET_ARCH_IS_X86_64
+ // Set if the binary was compiled with SHSTK enabled and declares support.
+ bool shstk_supported = false;
+#endif
+};
+
+// This class parses the .note.gnu.property section within the ELF binary.
+// Currently it only extracts the bit representing SHSTK support but can easily
+// be expanded to other features included in it.
+class GnuPropertySection {
+private:
+ [[maybe_unused]] GnuPropertyFeatures features_;
+
+public:
+ LIBC_INLINE GnuPropertySection() = default;
+
+ bool Parse(const ElfW(Phdr) * gnu_property_phdr, const ElfW(Addr) base);
+
+#ifdef LIBC_TARGET_ARCH_IS_X86_64
+ LIBC_INLINE bool IsSHSTKSupported() const {
+ return features_.shstk_supported;
+ }
+#endif
----------------
michaelrj-google wrote:
if you removed the arch checks from this and the definition of `GnuPropertyFeatures` it seems like it would also default to `is_shstk_supported` returning false. Is there a reason we shouldn't do it that way?
https://github.com/llvm/llvm-project/pull/174772
More information about the libc-commits
mailing list