Index: llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp =================================================================== --- llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp +++ llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp @@ -150,7 +150,7 @@ uint64_t PaddingSize = offsetToAlignment(SegFileSize, Align(1ull << Sec.Align)); Sec.Offset = SegOffset + SegFileSize + PaddingSize; - Sec.Size = Sec.Content.size(); + Sec.Size = Sec.getContents().size(); SegFileSize += PaddingSize + Sec.Size; } VMSize = std::max(VMSize, Sec.Addr + Sec.Size); @@ -161,7 +161,7 @@ } else { uint32_t SectOffset = Sec.Addr - SegmentVmAddr; Sec.Offset = SegOffset + SectOffset; - Sec.Size = Sec.Content.size(); + Sec.Size = Sec.getContents().size(); SegFileSize = std::max(SegFileSize, SectOffset + Sec.Size); VMSize = std::max(VMSize, SegFileSize); } Index: llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -90,11 +90,11 @@ for (Section &Sec : LC.Sections) { if (Sec.CanonicalName == SecName) { Expected> BufferOrErr = - FileOutputBuffer::create(Filename, Sec.Content.size()); + FileOutputBuffer::create(Filename, Sec.getContents().size()); if (!BufferOrErr) return BufferOrErr.takeError(); std::unique_ptr Buf = std::move(*BufferOrErr); - llvm::copy(Sec.Content, Buf->getBufferStart()); + llvm::copy(Sec.getContents(), Buf->getBufferStart()); if (Error E = Buf->commit()) return E; Index: llvm/tools/llvm-objcopy/MachO/MachOReader.cpp =================================================================== --- llvm/tools/llvm-objcopy/MachO/MachOReader.cpp +++ llvm/tools/llvm-objcopy/MachO/MachOReader.cpp @@ -29,12 +29,9 @@ template Section constructSectionCommon(SectionType Sec) { - Section S; - S.Sectname = - StringRef(Sec.sectname, strnlen(Sec.sectname, sizeof(Sec.sectname))) - .str(); - S.Segname = - StringRef(Sec.segname, strnlen(Sec.segname, sizeof(Sec.sectname))).str(); + StringRef Segname(Sec.segname, strnlen(Sec.segname, sizeof(Sec.segname))); + StringRef Sectname(Sec.sectname, strnlen(Sec.sectname, sizeof(Sec.sectname))); + Section S(Segname, Sectname); S.CanonicalName = (Twine(S.Segname) + "," + S.Sectname).str(); S.Addr = Sec.addr; S.Size = Sec.size; @@ -90,8 +87,7 @@ if (Expected> E = MachOObj.getSectionContents(SecRef->getRawDataRefImpl())) - S.Content = - StringRef(reinterpret_cast(E->data()), E->size()); + S.setContentsRef(*E); else reportError(MachOObj.getFileName(), E.takeError()); Index: llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp =================================================================== --- llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp +++ llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp @@ -235,9 +235,9 @@ continue; assert(Sec.Offset && "Section offset can not be zero"); - assert((Sec.Size == Sec.Content.size()) && "Incorrect section size"); - memcpy(B.getBufferStart() + Sec.Offset, Sec.Content.data(), - Sec.Content.size()); + assert((Sec.Size == Sec.getContents().size()) && "Incorrect section size"); + memcpy(B.getBufferStart() + Sec.Offset, Sec.getContents().data(), + Sec.getContents().size()); for (size_t Index = 0; Index < Sec.Relocations.size(); ++Index) { auto RelocInfo = Sec.Relocations[Index]; if (!RelocInfo.Scattered) { Index: llvm/tools/llvm-objcopy/MachO/Object.h =================================================================== --- llvm/tools/llvm-objcopy/MachO/Object.h +++ llvm/tools/llvm-objcopy/MachO/Object.h @@ -9,6 +9,7 @@ #ifndef LLVM_OBJCOPY_MACHO_OBJECT_H #define LLVM_OBJCOPY_MACHO_OBJECT_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/MachO.h" @@ -36,24 +37,48 @@ struct RelocationInfo; struct Section { +private: + Optional> OwnedContents; + ArrayRef ContentsRef; + +public: std::string Sectname; std::string Segname; // CanonicalName is a string formatted as “,". std::string CanonicalName; - uint64_t Addr; - uint64_t Size; - uint32_t Offset; - uint32_t Align; - uint32_t RelOff; - uint32_t NReloc; - uint32_t Flags; - uint32_t Reserved1; - uint32_t Reserved2; - uint32_t Reserved3; + uint64_t Addr = 0; + uint64_t Size = 0; + uint32_t Offset = 0; + uint32_t Align = 0; + uint32_t RelOff = 0; + uint32_t NReloc = 0; + uint32_t Flags = 0; + uint32_t Reserved1 = 0; + uint32_t Reserved2 = 0; + uint32_t Reserved3 = 0; - StringRef Content; std::vector Relocations; + Section(StringRef SegName, StringRef SectName) + : Sectname(SectName), Segname(SegName), + CanonicalName((Twine(SegName) + Twine(',') + SectName).str()) {} + + Section(StringRef SegName, StringRef SectName, ArrayRef Content) + : ContentsRef(Content), Sectname(SectName), Segname(SegName), + CanonicalName((Twine(SegName) + Twine(',') + SectName).str()) {} + + void setContentsRef(ArrayRef Data) { ContentsRef = Data; } + + void setOwnedContents(std::vector &&Data) { + OwnedContents = std::move(Data); + } + + ArrayRef getContents() const { + if (OwnedContents) + return *OwnedContents; + return ContentsRef; + } + MachO::SectionType getType() const { return static_cast(Flags & MachO::SECTION_TYPE); }