[llvm] [llvm-objcopy] Stream ELF output to reduce peak memory usage (PR #217706)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 01:11:39 PDT 2026


================
@@ -982,18 +1065,27 @@ static void writeRel(const RelRange &Relocations, T *Buf, bool IsMips64EL) {
 
 template <class ELFT>
 Error ELFSectionWriter<ELFT>::visit(const RelocationSection &Sec) {
-  uint8_t *Buf = reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
   if (Sec.Type == SHT_CREL) {
     auto Content = encodeCrel<ELFT::Is64Bits>(Sec.Relocations);
-    memcpy(Buf, Content.data(), Content.size());
-  } else if (Sec.Type == SHT_REL) {
-    writeRel(Sec.Relocations, reinterpret_cast<Elf_Rel *>(Buf),
-             Sec.getObject().IsMips64EL);
-  } else {
-    writeRel(Sec.Relocations, reinterpret_cast<Elf_Rela *>(Buf),
-             Sec.getObject().IsMips64EL);
-  }
-  return Error::success();
+    return writeSectionContents(
+        ArrayRef(reinterpret_cast<const uint8_t *>(Content.data()),
+                 Content.size()),
+        Sec.Offset);
+  }
+  if (Sec.Type == SHT_REL) {
+    SmallVector<Elf_Rel, 0> Relocations(Sec.Relocations.size());
+    writeRel(Sec.Relocations, Relocations.data(), Sec.getObject().IsMips64EL);
+    return writeSectionContents(
+        ArrayRef(reinterpret_cast<const uint8_t *>(Relocations.data()),
+                 Relocations.size() * sizeof(Elf_Rel)),
+        Sec.Offset);
----------------
jh7370 wrote:

This sort of pattern makes me really sad. What was previously was a relatively simple single-line function call has turned into (basically) that same function call plus three more lines, duplicated between the SHT_REL and SHT_RELA case.

It also seems bizarre to me that we're going from "write directly to output" to "write to local vector, then wrap that vector in an ArrayRef, then write that to the output via another function". I don't think this is the most effective way we could do things, in my opinion. `writeRel` should probably just write directly to the output stream. I see similar patterns in other places, which suggests to me there is more scope for designing the implementation better to simplify the code (and possibly even get more small performance wins).

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


More information about the llvm-commits mailing list