diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp @@ -17,7 +17,7 @@ uint32_t MachOLayoutBuilder::computeSizeOfCmds() const { uint32_t Size = 0; - for (const auto &LC : O.LoadCommands) { + for (const LoadCommand &LC : O.LoadCommands) { const MachO::macho_load_command &MLC = LC.MachOLoadCommand; auto cmd = MLC.load_command_data.cmd; switch (cmd) { @@ -107,7 +107,7 @@ const bool IsObjectFile = O.Header.FileType == MachO::HeaderFileType::MH_OBJECT; uint64_t Offset = IsObjectFile ? (HeaderSize + O.Header.SizeOfCmds) : 0; - for (auto &LC : O.LoadCommands) { + for (LoadCommand &LC : O.LoadCommands) { auto &MLC = LC.MachOLoadCommand; StringRef Segname; uint64_t SegmentVmAddr; @@ -142,27 +142,27 @@ uint64_t SegOffset = Offset; uint64_t SegFileSize = 0; uint64_t VMSize = 0; - for (auto &Sec : LC.Sections) { + for (std::unique_ptr
&Sec : LC.Sections) { if (IsObjectFile) { - if (Sec.isVirtualSection()) { - Sec.Offset = 0; + if (Sec->isVirtualSection()) { + Sec->Offset = 0; } else { uint64_t PaddingSize = - offsetToAlignment(SegFileSize, Align(1ull << Sec.Align)); - Sec.Offset = SegOffset + SegFileSize + PaddingSize; - Sec.Size = Sec.Content.size(); - SegFileSize += PaddingSize + Sec.Size; + offsetToAlignment(SegFileSize, Align(1ull << Sec->Align)); + Sec->Offset = SegOffset + SegFileSize + PaddingSize; + Sec->Size = Sec->Content.size(); + SegFileSize += PaddingSize + Sec->Size; } - VMSize = std::max(VMSize, Sec.Addr + Sec.Size); + VMSize = std::max(VMSize, Sec->Addr + Sec->Size); } else { - if (Sec.isVirtualSection()) { - Sec.Offset = 0; - VMSize += Sec.Size; + if (Sec->isVirtualSection()) { + Sec->Offset = 0; + VMSize += Sec->Size; } else { - uint32_t SectOffset = Sec.Addr - SegmentVmAddr; - Sec.Offset = SegOffset + SectOffset; - Sec.Size = Sec.Content.size(); - SegFileSize = std::max(SegFileSize, SectOffset + Sec.Size); + uint32_t SectOffset = Sec->Addr - SegmentVmAddr; + Sec->Offset = SegOffset + SectOffset; + Sec->Size = Sec->Content.size(); + SegFileSize = std::max(SegFileSize, SectOffset + Sec->Size); VMSize = std::max(VMSize, SegFileSize); } } @@ -204,11 +204,11 @@ } uint64_t MachOLayoutBuilder::layoutRelocations(uint64_t Offset) { - for (auto &LC : O.LoadCommands) - for (auto &Sec : LC.Sections) { - Sec.RelOff = Sec.Relocations.empty() ? 0 : Offset; - Sec.NReloc = Sec.Relocations.size(); - Offset += sizeof(MachO::any_relocation_info) * Sec.NReloc; + for (LoadCommand &LC : O.LoadCommands) + for (std::unique_ptr
&Sec : LC.Sections) { + Sec->RelOff = Sec->Relocations.empty() ? 0 : Offset; + Sec->NReloc = Sec->Relocations.size(); + Offset += sizeof(MachO::any_relocation_info) * Sec->NReloc; } return Offset; @@ -260,7 +260,7 @@ } } - for (auto &LC : O.LoadCommands) { + for (LoadCommand &LC : O.LoadCommands) { auto &MLC = LC.MachOLoadCommand; auto cmd = MLC.load_command_data.cmd; switch (cmd) { diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -18,21 +18,21 @@ namespace macho { using namespace object; -using SectionPred = std::function; +using SectionPred = std::function &Sec)>; static void removeSections(const CopyConfig &Config, Object &Obj) { - SectionPred RemovePred = [](const Section &) { return false; }; + SectionPred RemovePred = [](const std::unique_ptr
&) { return false; }; if (!Config.ToRemove.empty()) { - RemovePred = [&Config, RemovePred](const Section &Sec) { - return Config.ToRemove.matches(Sec.CanonicalName); + RemovePred = [&Config, RemovePred](const std::unique_ptr
&Sec) { + return Config.ToRemove.matches(Sec->CanonicalName); }; } if (Config.StripAll || Config.StripDebug) { // Remove all debug sections. - RemovePred = [RemovePred](const Section &Sec) { - if (Sec.Segname == "__DWARF") + RemovePred = [RemovePred](const std::unique_ptr
&Sec) { + if (Sec->Segname == "__DWARF") return true; return RemovePred(Sec); @@ -41,8 +41,8 @@ if (!Config.OnlySection.empty()) { // Overwrite RemovePred because --only-section takes priority. - RemovePred = [&Config](const Section &Sec) { - return !Config.OnlySection.matches(Sec.CanonicalName); + RemovePred = [&Config](const std::unique_ptr
&Sec) { + return !Config.OnlySection.matches(Sec->CanonicalName); }; } @@ -87,14 +87,14 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename, Object &Obj) { for (LoadCommand &LC : Obj.LoadCommands) - for (Section &Sec : LC.Sections) { - if (Sec.CanonicalName == SecName) { + for (const std::unique_ptr
&Sec : LC.Sections) { + if (Sec->CanonicalName == SecName) { Expected> BufferOrErr = - FileOutputBuffer::create(Filename, Sec.Content.size()); + FileOutputBuffer::create(Filename, Sec->Content.size()); if (!BufferOrErr) return BufferOrErr.takeError(); std::unique_ptr Buf = std::move(*BufferOrErr); - llvm::copy(Sec.Content, Buf->getBufferStart()); + llvm::copy(Sec->Content, Buf->getBufferStart()); if (Error E = Buf->commit()) return E; @@ -122,7 +122,7 @@ for (LoadCommand &LC : Obj.LoadCommands) { Optional SegName = LC.getSegmentName(); if (SegName && SegName == TargetSegName) { - LC.Sections.push_back(Sec); + LC.Sections.push_back(std::make_unique
(Sec)); return Error::success(); } } @@ -130,7 +130,7 @@ // There's no segment named TargetSegName. Create a new load command and // Insert a new section into it. LoadCommand &NewSegment = Obj.addSegment(TargetSegName); - NewSegment.Sections.push_back(Sec); + NewSegment.Sections.push_back(std::make_unique
(Sec)); return Error::success(); } @@ -187,8 +187,8 @@ if (Config.StripAll) for (LoadCommand &LC : Obj.LoadCommands) - for (Section &Sec : LC.Sections) - Sec.Relocations.clear(); + for (std::unique_ptr
&Sec : LC.Sections) + Sec->Relocations.clear(); for (const StringRef &Flag : Config.DumpSection) { std::pair SecPair = Flag.split("="); diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp @@ -59,25 +59,25 @@ // TODO: get rid of reportError and make MachOReader return Expected<> instead. template -std::vector
+std::vector> extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd, const object::MachOObjectFile &MachOObj, size_t &NextSectionIndex) { auto End = LoadCmd.Ptr + LoadCmd.C.cmdsize; const SectionType *Curr = reinterpret_cast(LoadCmd.Ptr + sizeof(SegmentType)); - std::vector
Sections; + std::vector> Sections; for (; reinterpret_cast(Curr) < End; Curr++) { if (MachOObj.isLittleEndian() != sys::IsLittleEndianHost) { SectionType Sec; memcpy((void *)&Sec, Curr, sizeof(SectionType)); MachO::swapStruct(Sec); - Sections.push_back(constructSection(Sec)); + Sections.push_back(std::make_unique
(constructSection(Sec))); } else { - Sections.push_back(constructSection(*Curr)); + Sections.push_back(std::make_unique
(constructSection(*Curr))); } - Section &S = Sections.back(); + Section &S = *Sections.back(); Expected SecRef = MachOObj.getSection(NextSectionIndex++); @@ -201,9 +201,9 @@ } void MachOReader::setSymbolInRelocationInfo(Object &O) const { - for (auto &LC : O.LoadCommands) - for (auto &Sec : LC.Sections) - for (auto &Reloc : Sec.Relocations) + for (LoadCommand &LC : O.LoadCommands) + for (std::unique_ptr
&Sec : LC.Sections) + for (auto &Reloc : Sec->Relocations) if (!Reloc.Scattered) { auto *Info = reinterpret_cast(&Reloc.Info); Reloc.Symbol = O.SymTable.getSymbolByIndex(Info->r_symbolnum); diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp @@ -110,12 +110,12 @@ } // Otherwise, use the last section / reloction. - for (const auto &LC : O.LoadCommands) - for (const auto &S : LC.Sections) { - Ends.push_back(S.Offset + S.Size); - if (S.RelOff) - Ends.push_back(S.RelOff + - S.NReloc * sizeof(MachO::any_relocation_info)); + for (const LoadCommand &LC : O.LoadCommands) + for (const std::unique_ptr
&S : LC.Sections) { + Ends.push_back(S->Offset + S->Size); + if (S->RelOff) + Ends.push_back(S->RelOff + + S->NReloc * sizeof(MachO::any_relocation_info)); } if (!Ends.empty()) @@ -147,7 +147,7 @@ void MachOWriter::writeLoadCommands() { uint8_t *Begin = B.getBufferStart() + headerSize(); - for (const auto &LC : O.LoadCommands) { + for (const LoadCommand &LC : O.LoadCommands) { // Construct a load command. MachO::macho_load_command MLC = LC.MachOLoadCommand; switch (MLC.load_command_data.cmd) { @@ -157,8 +157,8 @@ memcpy(Begin, &MLC.segment_command_data, sizeof(MachO::segment_command)); Begin += sizeof(MachO::segment_command); - for (const auto &Sec : LC.Sections) - writeSectionInLoadCommand(Sec, Begin); + for (const std::unique_ptr
&Sec : LC.Sections) + writeSectionInLoadCommand(*Sec, Begin); continue; case MachO::LC_SEGMENT_64: if (IsLittleEndian != sys::IsLittleEndianHost) @@ -167,8 +167,8 @@ sizeof(MachO::segment_command_64)); Begin += sizeof(MachO::segment_command_64); - for (const auto &Sec : LC.Sections) - writeSectionInLoadCommand(Sec, Begin); + for (const std::unique_ptr
&Sec : LC.Sections) + writeSectionInLoadCommand(*Sec, Begin); continue; } @@ -229,17 +229,17 @@ } void MachOWriter::writeSections() { - for (const auto &LC : O.LoadCommands) - for (const auto &Sec : LC.Sections) { - if (Sec.isVirtualSection()) + for (const LoadCommand &LC : O.LoadCommands) + for (const std::unique_ptr
&Sec : LC.Sections) { + if (Sec->isVirtualSection()) 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()); - for (size_t Index = 0; Index < Sec.Relocations.size(); ++Index) { - auto RelocInfo = Sec.Relocations[Index]; + 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()); + for (size_t Index = 0; Index < Sec->Relocations.size(); ++Index) { + auto RelocInfo = Sec->Relocations[Index]; if (!RelocInfo.Scattered) { auto *Info = reinterpret_cast(&RelocInfo.Info); @@ -249,7 +249,7 @@ if (IsLittleEndian != sys::IsLittleEndianHost) MachO::swapStruct( reinterpret_cast(RelocInfo.Info)); - memcpy(B.getBufferStart() + Sec.RelOff + + memcpy(B.getBufferStart() + Sec->RelOff + Index * sizeof(MachO::any_relocation_info), &RelocInfo.Info, sizeof(RelocInfo.Info)); } diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/tools/llvm-objcopy/MachO/Object.h @@ -89,7 +89,7 @@ // though the contents of the sections are stored separately. The struct // Section describes only sections' metadata and where to find the // corresponding content inside the binary. - std::vector
Sections; + std::vector> Sections; // Returns the segment name if the load command is a segment command. Optional getSegmentName() const; @@ -292,7 +292,7 @@ Object() : NewSectionsContents(Alloc) {} - void removeSections(function_ref ToRemove); + void removeSections(function_ref &)> ToRemove); void addLoadCommand(LoadCommand LC); /// Creates a new segment load command in the object and returns a reference diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp --- a/llvm/tools/llvm-objcopy/MachO/Object.cpp +++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp @@ -22,7 +22,7 @@ std::end(Symbols)); } -void Object::removeSections(function_ref ToRemove) { +void Object::removeSections(function_ref &)> ToRemove) { for (LoadCommand &LC : LoadCommands) LC.Sections.erase(std::remove_if(std::begin(LC.Sections), std::end(LC.Sections), ToRemove), @@ -52,7 +52,7 @@ constructSegment(LC.MachOLoadCommand.segment_command_data, MachO::LC_SEGMENT, SegName); - LoadCommands.push_back(LC); + LoadCommands.push_back(std::move(LC)); return LoadCommands.back(); }