[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


================
@@ -33,10 +35,72 @@ using namespace llvm::objcopy::elf;
 using namespace llvm::object;
 using namespace llvm::support;
 
-template <class ELFT> void ELFWriter<ELFT>::writePhdr(const Segment &Seg) {
-  uint8_t *B = reinterpret_cast<uint8_t *>(Buf->getBufferStart()) +
-               Obj.ProgramHdrSegment.Offset + Seg.Index * sizeof(Elf_Phdr);
-  Elf_Phdr &Phdr = *reinterpret_cast<Elf_Phdr *>(B);
+Error ELFWriterOutput::write(ArrayRef<uint8_t> Data, uint64_t Offset) {
+  if (Data.empty())
+    return Error::success();
+  if (Buffer) {
+    llvm::copy(Data, Buffer->getBufferStart() + Offset);
+    return Error::success();
+  }
+  Stream->pwrite(reinterpret_cast<const char *>(Data.data()), Data.size(),
+                 StartOffset + Offset);
+  if (Error E = Stream->takeError())
+    return E;
+  return Error::success();
+}
+
+Error ELFWriterOutput::writeZerosImpl(uint64_t Offset, uint64_t Size) {
+  if (!Size)
+    return Error::success();
+
+  const uint64_t Pos = Stream->tell();
+  Stream->seek(StartOffset + Offset);
+  if (Error E = Stream->takeError())
+    return E;
+  // raw_ostream::write_zeros is intended for small, unsigned-sized padding;
+  // ELF gaps can be larger, so write them using reasonably sized chunks.
----------------
jh7370 wrote:

This comment makes me uncomfortable. It seems to me like this is leaking internal details of `raw_ostream` into a higher-level library (in this case llvm-objcopy). If the underlying implementation were to change, this could go stale very quickly. In my opinion, if handling zeros in large numbers is required, a new function in the stream should be added and this handle it. Better yet, `Stream->seek` should just automatically add zeros to fill gaps after the end of its current internal buffer/output location, if seeking past the end, so instead of something like:
```
Stream->write(someData);
Stream->writeZeros(10000);
Stream->write(moreData);
```
You'd have something like:
```
Stream->write(someData);
Stream->seek(10000, Stream.getOffset());
Stream->write(moreData);
```

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


More information about the llvm-commits mailing list