[llvm] [Object,ELF] Implement PN_XNUM extension for program headers (PR #162288)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 20 00:40:12 PDT 2025


================
@@ -889,7 +887,31 @@ Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
   return 0;
 }
 
-template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
+template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
+  const Elf_Ehdr &Header = getHeader();
+  RealPhNum = Header.e_phnum;
+  RealShNum = Header.e_shnum;
+  RealShStrNdx = Header.e_shstrndx;
+  if (!Header.hasPhdrNumExtension())
+    return;
+
+  // An ELF binary may report `hasExtendedHeader` as true but not actually
----------------
jh7370 wrote:

> A question is that should we consume up the error or report it back when the caller is inside the class?

I'd propagate it as far as possible until you have to change an API, then consume the error with a TODO comment to highlight we'd like to propagate it further. We've taken this approach in other cases. A future change could be made to propagate it further, where we'd evaluate what should be done on a case-by-case basis.

As I understand it, with my suggested approach, the only time we'd see an error is if e_phnum is PN_XNUM/e_shstrndx is SHN_XINDEX/e_shnum is 0 and the section header table can't be read (or there are no section headers in it). As a result, this should preserve the existing behaviour for all current test cases.

Regarding testing, strictly-speaking, I expect the final gABI wording to match that of the Oracle document, which technically means the extension should only be used if there are more than 65534 program headers. However, fundamentally I don't see any reason we'd enforce this in the binary tools (possibly with the exception in llvm-objcopy when writing an object out that used the extension unnecessarily), so if we used yaml2obj to specify e_phnum to be PN_XNUM and to manually populate section header 0, we could show that it correctly reads this in one test and then in a different test case (or cases) we could have it fail because e.g. the section header table is missing (there's a yaml2obj feature that allows you to suppress the table).

https://github.com/llvm/llvm-project/pull/162288


More information about the llvm-commits mailing list