diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-18 20:30:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-06 20:11:55 +0000 |
commit | 5f757f3ff9144b609b3c433dfd370cc6bdc191ad (patch) | |
tree | 1b4e980b866cd26a00af34c0a653eb640bd09caf /contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp | |
parent | 3e1c8a35f741a5d114d0ba670b15191355711fe9 (diff) | |
parent | 312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp index 697afab2a617..5352736bdcb9 100644 --- a/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp +++ b/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp @@ -1987,8 +1987,9 @@ template <class ELFT> void ELFWriter<ELFT>::writeEhdr() { Ehdr.e_ident[EI_MAG2] = 'L'; Ehdr.e_ident[EI_MAG3] = 'F'; Ehdr.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; - Ehdr.e_ident[EI_DATA] = - ELFT::TargetEndianness == support::big ? ELFDATA2MSB : ELFDATA2LSB; + Ehdr.e_ident[EI_DATA] = ELFT::TargetEndianness == llvm::endianness::big + ? ELFDATA2MSB + : ELFDATA2LSB; Ehdr.e_ident[EI_VERSION] = EV_CURRENT; Ehdr.e_ident[EI_OSABI] = Obj.OSABI; Ehdr.e_ident[EI_ABIVERSION] = Obj.ABIVersion; @@ -2089,7 +2090,7 @@ template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() { Size); } - for (auto it : Obj.getUpdatedSections()) { + for (const auto &it : Obj.getUpdatedSections()) { SectionBase *Sec = it.first; ArrayRef<uint8_t> Data = it.second; @@ -2635,9 +2636,36 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() { } Error BinaryWriter::write() { - for (const SectionBase &Sec : Obj.allocSections()) + SmallVector<const SectionBase *, 30> SectionsToWrite; + for (const SectionBase &Sec : Obj.allocSections()) { + if (Sec.Type != SHT_NOBITS) + SectionsToWrite.push_back(&Sec); + } + + if (SectionsToWrite.empty()) + return Error::success(); + + llvm::stable_sort(SectionsToWrite, + [](const SectionBase *LHS, const SectionBase *RHS) { + return LHS->Offset < RHS->Offset; + }); + + assert(SectionsToWrite.front()->Offset == 0); + + for (size_t i = 0; i != SectionsToWrite.size(); ++i) { + const SectionBase &Sec = *SectionsToWrite[i]; if (Error Err = Sec.accept(*SecWriter)) return Err; + if (GapFill == 0) + continue; + uint64_t PadOffset = (i < SectionsToWrite.size() - 1) + ? SectionsToWrite[i + 1]->Offset + : Buf->getBufferSize(); + assert(PadOffset <= Buf->getBufferSize()); + assert(Sec.Offset + Sec.Size <= PadOffset); + std::fill(Buf->getBufferStart() + Sec.Offset + Sec.Size, + Buf->getBufferStart() + PadOffset, GapFill); + } // TODO: Implement direct writing to the output stream (without intermediate // memory buffer Buf). @@ -2663,7 +2691,7 @@ Error BinaryWriter::finalize() { // file size. This might not be the same as the offset returned by // layoutSections, because we want to truncate the last segment to the end of // its last non-empty section, to match GNU objcopy's behaviour. - TotalSize = 0; + TotalSize = PadTo > MinAddr ? PadTo - MinAddr : 0; for (SectionBase &Sec : Obj.allocSections()) if (Sec.Type != SHT_NOBITS && Sec.Size > 0) { Sec.Offset = Sec.Addr - MinAddr; @@ -2695,11 +2723,11 @@ uint64_t IHexWriter::writeEntryPointRecord(uint8_t *Buf) { if (Obj.Entry <= 0xFFFFFU) { Data[0] = ((Obj.Entry & 0xF0000U) >> 12) & 0xFF; support::endian::write(&Data[2], static_cast<uint16_t>(Obj.Entry), - support::big); + llvm::endianness::big); HexData = IHexRecord::getLine(IHexRecord::StartAddr80x86, 0, Data); } else { support::endian::write(Data, static_cast<uint32_t>(Obj.Entry), - support::big); + llvm::endianness::big); HexData = IHexRecord::getLine(IHexRecord::StartAddr, 0, Data); } memcpy(Buf, HexData.data(), HexData.size()); |