aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp38
1 files changed, 30 insertions, 8 deletions
diff --git a/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp
index ea6dadabace6..697afab2a617 100644
--- a/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ b/contrib/llvm-project/llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -429,6 +429,13 @@ Error Section::accept(MutableSectionVisitor &Visitor) {
return Visitor.visit(*this);
}
+void Section::restoreSymTabLink(SymbolTableSection &SymTab) {
+ if (HasSymTabLink) {
+ assert(LinkSection == nullptr);
+ LinkSection = &SymTab;
+ }
+}
+
Error SectionWriter::visit(const OwnedDataSection &Sec) {
llvm::copy(Sec.Data, Out.getBufferStart() + Sec.Offset);
return Error::success();
@@ -680,8 +687,11 @@ bool Symbol::isCommon() const { return getShndx() == SHN_COMMON; }
void SymbolTableSection::assignIndices() {
uint32_t Index = 0;
- for (auto &Sym : Symbols)
+ for (auto &Sym : Symbols) {
+ if (Sym->Index != Index)
+ IndicesChanged = true;
Sym->Index = Index++;
+ }
}
void SymbolTableSection::addSymbol(Twine Name, uint8_t Bind, uint8_t Type,
@@ -741,7 +751,10 @@ Error SymbolTableSection::removeSymbols(
std::remove_if(std::begin(Symbols) + 1, std::end(Symbols),
[ToRemove](const SymPtr &Sym) { return ToRemove(*Sym); }),
std::end(Symbols));
+ auto PrevSize = Size;
Size = Symbols.size() * EntrySize;
+ if (Size < PrevSize)
+ IndicesChanged = true;
assignIndices();
return Error::success();
}
@@ -1106,8 +1119,10 @@ Error Section::initialize(SectionTableRef SecTable) {
LinkSection = *Sec;
- if (LinkSection->Type == ELF::SHT_SYMTAB)
+ if (LinkSection->Type == ELF::SHT_SYMTAB) {
+ HasSymTabLink = true;
LinkSection = nullptr;
+ }
return Error::success();
}
@@ -1704,6 +1719,10 @@ Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
else
return Data.takeError();
case SHT_SYMTAB: {
+ // Multiple SHT_SYMTAB sections are forbidden by the ELF gABI.
+ if (Obj.SymbolTable != nullptr)
+ return createStringError(llvm::errc::invalid_argument,
+ "found multiple SHT_SYMTAB sections");
auto &SymTab = Obj.addSection<SymbolTableSection>();
Obj.SymbolTable = &SymTab;
return SymTab;
@@ -2298,7 +2317,7 @@ static uint64_t layoutSections(Range Sections, uint64_t Offset) {
for (auto &Sec : Sections) {
Sec.Index = Index++;
if (Sec.ParentSegment != nullptr) {
- auto Segment = *Sec.ParentSegment;
+ const Segment &Segment = *Sec.ParentSegment;
Sec.Offset =
Segment.Offset + (Sec.OriginalOffset - Segment.OriginalOffset);
} else
@@ -2511,6 +2530,12 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
if (Error E = removeUnneededSections(Obj))
return E;
+ // If the .symtab indices have not been changed, restore the sh_link to
+ // .symtab for sections that were linked to .symtab.
+ if (Obj.SymbolTable && !Obj.SymbolTable->indicesChanged())
+ for (SectionBase &Sec : Obj.sections())
+ Sec.restoreSymTabLink(*Obj.SymbolTable);
+
// We need to assign indexes before we perform layout because we need to know
// if we need large indexes or not. We can assign indexes first and check as
// we go to see if we will actully need large indexes.
@@ -2627,12 +2652,9 @@ Error BinaryWriter::finalize() {
// MinAddr will be skipped.
uint64_t MinAddr = UINT64_MAX;
for (SectionBase &Sec : Obj.allocSections()) {
- // If Sec's type is changed from SHT_NOBITS due to --set-section-flags,
- // Offset may not be aligned. Align it to max(Align, 1).
if (Sec.ParentSegment != nullptr)
- Sec.Addr = alignTo(Sec.Offset - Sec.ParentSegment->Offset +
- Sec.ParentSegment->PAddr,
- std::max(Sec.Align, uint64_t(1)));
+ Sec.Addr =
+ Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr;
if (Sec.Type != SHT_NOBITS && Sec.Size > 0)
MinAddr = std::min(MinAddr, Sec.Addr);
}