Index | Thread | Search

From:
"Kirill A. Korinsky" <kirill@korins.ky>
Subject:
llvm/sparc64: match BFD -N alignment
To:
Sebastien Marie <semarie@online.fr>, Robert Nagy <robert@openbsd.org>
Cc:
OpenBSD tech <tech@openbsd.org>
Date:
Tue, 18 Aug 2026 15:18:01 +0200

Download raw body.

Thread
Robert, Sebastien,

BFD aligns nonpaged PT_LOAD segments to their maximum contained section
alignment. Do the same for SPARCV9 instead of retaining the 1 MiB maximum
page alignment.

This removes roughly 1 MiB of leading padding from ofwboot without changing
its load address or memory layout.

Here diff for the base and llvm/22 in ports.

Ok?

Index: src/gnu/llvm/lld/ELF/Driver.cpp
===================================================================
RCS file: /home/cvs/src/gnu/llvm/lld/ELF/Driver.cpp,v
diff -u -p -r1.25 Driver.cpp
--- src/gnu/llvm/lld/ELF/Driver.cpp	30 Jul 2026 19:28:37 -0000	1.25
+++ src/gnu/llvm/lld/ELF/Driver.cpp	18 Aug 2026 13:01:23 -0000
@@ -3496,6 +3496,12 @@ template <class ELFT> void LinkerDriver:
   // sections are non-aligned (maxPageSize set to 1) but text sections are aligned
   // to the target page size.
   ctx.arg.textAlignPageSize = ctx.arg.omagic ? getRealMaxPageSize(ctx, args) : ctx.arg.maxPageSize;
+#ifdef __OpenBSD__
+  // Match BFD -N semantics for SPARCV9: use the maximum contained section
+  // alignment for PT_LOAD segments instead of the 1 MiB page alignment.
+  if (ctx.arg.omagic && ctx.arg.emachine == EM_SPARCV9)
+    ctx.arg.textAlignPageSize = ctx.arg.maxPageSize;
+#endif
 
   ctx.arg.imageBase = getImageBase(ctx, args);
 
Index: src/gnu/llvm/lld/ELF/Writer.cpp
===================================================================
RCS file: /home/cvs/src/gnu/llvm/lld/ELF/Writer.cpp,v
diff -u -p -r1.11 Writer.cpp
--- src/gnu/llvm/lld/ELF/Writer.cpp	30 Jul 2026 19:28:37 -0000	1.11
+++ src/gnu/llvm/lld/ELF/Writer.cpp	18 Aug 2026 13:01:23 -0000
@@ -2701,6 +2701,16 @@ template <class ELFT> void Writer<ELFT>:
   ctx.out.programHeaders->offset = ctx.out.elfHeader->size;
   uint64_t off = ctx.out.elfHeader->size + ctx.out.programHeaders->size;
 
+#ifdef __OpenBSD__
+  // BFD's implicit script reserves 0x200 bytes before fixed-address SPARCV9
+  // -N payloads consumed by OpenFirmware.
+  if (!ctx.arg.relocatable && ctx.arg.omagic &&
+      ctx.arg.emachine == EM_SPARCV9 &&
+      ctx.arg.sectionStartMap.count(".text") &&
+      !ctx.script->hasSectionsCommand && !ctx.script->hasPhdrsCommands())
+    off = std::max<uint64_t>(off, 0x200);
+#endif
+
   PhdrEntry *lastRX = nullptr;
   for (Partition &part : ctx.partitions)
     for (auto &p : part.phdrs)
Index: ports/devel/llvm/22/Makefile
===================================================================
RCS file: /home/cvs/ports/devel/llvm/22/Makefile,v
diff -u -p -r1.22 Makefile
--- ports/devel/llvm/22/Makefile	30 Jul 2026 19:28:03 -0000	1.22
+++ ports/devel/llvm/22/Makefile	18 Aug 2026 13:17:33 -0000
@@ -2,7 +2,7 @@ LLVM_MAJOR =	22
 LLVM_VERSION =	${LLVM_MAJOR}.1.8
 LLVM_PKGSPEC =	>=22,<23
 
-REVISION =	4
+REVISION =	5
 
 SHARED_LIBS +=	LLVM		0.0 \
 		LTO		0.0 \
Index: ports/devel/llvm/22/patches/patch-lld_ELF_Driver_cpp
===================================================================
RCS file: /home/cvs/ports/devel/llvm/22/patches/patch-lld_ELF_Driver_cpp,v
diff -u -p -r1.3 patch-lld_ELF_Driver_cpp
--- ports/devel/llvm/22/patches/patch-lld_ELF_Driver_cpp	30 Jul 2026 19:28:03 -0000	1.3
+++ ports/devel/llvm/22/patches/patch-lld_ELF_Driver_cpp	18 Aug 2026 13:14:56 -0000
@@ -169,7 +169,7 @@ Index: lld/ELF/Driver.cpp
  // Parses --image-base option.
  static std::optional<uint64_t> getImageBase(Ctx &ctx, opt::InputArgList &args) {
    // Because we are using `ctx.arg.maxPageSize` here, this function has to be
-@@ -3435,6 +3491,11 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
+@@ -3435,6 +3491,17 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
    // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it
    // is limited to writing trap instructions on the last executable segment.
    ctx.arg.commonPageSize = getCommonPageSize(ctx, args);
@@ -178,6 +178,12 @@ Index: lld/ELF/Driver.cpp
 +  // sections are non-aligned (maxPageSize set to 1) but text sections are aligned
 +  // to the target page size.
 +  ctx.arg.textAlignPageSize = ctx.arg.omagic ? getRealMaxPageSize(ctx, args) : ctx.arg.maxPageSize;
++#ifdef __OpenBSD__
++  // Match BFD -N semantics for SPARCV9: use the maximum contained section
++  // alignment for PT_LOAD segments instead of the 1 MiB page alignment.
++  if (ctx.arg.omagic && ctx.arg.emachine == EM_SPARCV9)
++    ctx.arg.textAlignPageSize = ctx.arg.maxPageSize;
++#endif
  
    ctx.arg.imageBase = getImageBase(ctx, args);
  
Index: ports/devel/llvm/22/patches/patch-lld_ELF_Writer_cpp
===================================================================
RCS file: /home/cvs/ports/devel/llvm/22/patches/patch-lld_ELF_Writer_cpp,v
diff -u -p -r1.2 patch-lld_ELF_Writer_cpp
--- ports/devel/llvm/22/patches/patch-lld_ELF_Writer_cpp	30 Jul 2026 19:28:03 -0000	1.2
+++ ports/devel/llvm/22/patches/patch-lld_ELF_Writer_cpp	18 Aug 2026 13:14:56 -0000
@@ -183,11 +183,10 @@ Index: lld/ELF/Writer.cpp
    if (OutputSection *cmd = findSection(ctx, ".note.gnu.property", partNo))
      addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd);
  
-@@ -2586,6 +2610,31 @@ template <class ELFT> void Writer<ELFT>::fixSectionAli
-         };
+@@ -2587,6 +2611,31 @@ template <class ELFT> void Writer<ELFT>::fixSectionAli
      }
    };
-+
+ 
 +#ifndef __OpenBSD__
 +  // On i386, produce binaries that are compatible with our W^X implementation
 +  if (ctx.arg.emachine == EM_386) {
@@ -212,6 +211,24 @@ Index: lld/ELF/Writer.cpp
 +    }
 +  }
 +#endif
- 
++
    for (Partition &part : ctx.partitions) {
      prev = nullptr;
+     for (auto &p : part.phdrs)
+@@ -2651,6 +2700,16 @@ static std::string rangeToString(uint64_t addr, uint64
+ template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
+   ctx.out.programHeaders->offset = ctx.out.elfHeader->size;
+   uint64_t off = ctx.out.elfHeader->size + ctx.out.programHeaders->size;
++
++#ifdef __OpenBSD__
++  // BFD's implicit script reserves 0x200 bytes before fixed-address SPARCV9
++  // -N payloads consumed by OpenFirmware.
++  if (!ctx.arg.relocatable && ctx.arg.omagic &&
++      ctx.arg.emachine == EM_SPARCV9 &&
++      ctx.arg.sectionStartMap.count(".text") &&
++      !ctx.script->hasSectionsCommand && !ctx.script->hasPhdrsCommands())
++    off = std::max<uint64_t>(off, 0x200);
++#endif
+ 
+   PhdrEntry *lastRX = nullptr;
+   for (Partition &part : ctx.partitions)



-- 
wbr, Kirill