[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