summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-04-07 14:22:09 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-04-07 14:22:09 +0000
commit56004c577a05b7cfe504a2251731ebdb4fb0803f (patch)
tree7f12686c5c829350e68dd276646ef871ece685a5 /lld/ELF/OutputSections.cpp
parent0ab420570500273e2814a21f65075257b319b59b (diff)
downloadbcm5719-llvm-56004c577a05b7cfe504a2251731ebdb4fb0803f.tar.gz
bcm5719-llvm-56004c577a05b7cfe504a2251731ebdb4fb0803f.zip
Don't create dynamic relocs for discarded .eh_frame entries.
This requires knowing input section offsets in output sections before scanRelocs. This is generally a good thing and should allow further simplifications in the creation of dynamic relocations. llvm-svn: 265673
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp58
1 files changed, 36 insertions, 22 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 18d1ed47350..feaff820d86 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -307,7 +307,7 @@ typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
case Off_LTlsIndex:
return Out<ELFT>::Got->getTlsIndexVA();
case Off_Sec:
- return OffsetSec->getOffset(OffsetInSec) + OffsetSec->OutSec->getVA();
+ return OffsetInSec + OffsetSec->getVA();
case Off_Bss:
return cast<SharedSymbol<ELFT>>(Sym)->OffsetInBss + Out<ELFT>::Bss->getVA();
case Off_Got:
@@ -836,16 +836,11 @@ static int getPriority(StringRef S) {
return V;
}
-// This function is called after we sort input sections
-// and scan relocations to setup sections' offsets.
-template <class ELFT> void OutputSection<ELFT>::assignOffsets() {
- uintX_t Off = this->Header.sh_size;
- for (InputSection<ELFT> *S : Sections) {
- Off = alignTo(Off, S->Align);
- S->OutSecOff = Off;
- Off += S->getSize();
- }
- this->Header.sh_size = Off;
+template <class ELFT>
+void OutputSection<ELFT>::forEachInputSection(
+ std::function<void(InputSectionBase<ELFT> *S)> F) {
+ for (InputSection<ELFT> *S : Sections)
+ F(S);
}
// Sorts input sections by section name suffixes, so that .foo.N comes
@@ -956,6 +951,13 @@ EHOutputSection<ELFT>::EHOutputSection(StringRef Name, uint32_t Type,
}
template <class ELFT>
+void EHOutputSection<ELFT>::forEachInputSection(
+ std::function<void(InputSectionBase<ELFT> *)> F) {
+ for (EHInputSection<ELFT> *S : Sections)
+ F(S);
+}
+
+template <class ELFT>
EHRegion<ELFT>::EHRegion(EHInputSection<ELFT> *S, unsigned Index)
: S(S), Index(Index) {}
@@ -1186,31 +1188,43 @@ void EHOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
}
template <class ELFT>
-static typename ELFT::uint writeAlignedCieOrFde(StringRef Data, uint8_t *Buf) {
+static void writeAlignedCieOrFde(StringRef Data, uint8_t *Buf) {
typedef typename ELFT::uint uintX_t;
const endianness E = ELFT::TargetEndianness;
uint64_t Len = alignTo(Data.size(), sizeof(uintX_t));
write32<E>(Buf, Len - 4);
memcpy(Buf + 4, Data.data() + 4, Data.size() - 4);
- return Len;
}
-template <class ELFT> void EHOutputSection<ELFT>::writeTo(uint8_t *Buf) {
- const endianness E = ELFT::TargetEndianness;
+template <class ELFT> void EHOutputSection<ELFT>::finalize() {
+ if (Finalized)
+ return;
+ Finalized = true;
+
size_t Offset = 0;
for (const Cie<ELFT> &C : Cies) {
- size_t CieOffset = Offset;
-
- uintX_t CIELen = writeAlignedCieOrFde<ELFT>(C.data(), Buf + Offset);
C.S->Offsets[C.Index].second = Offset;
- Offset += CIELen;
+ Offset += alignTo(C.data().size(), sizeof(uintX_t));
for (const EHRegion<ELFT> &F : C.Fdes) {
- uintX_t Len = writeAlignedCieOrFde<ELFT>(F.data(), Buf + Offset);
- write32<E>(Buf + Offset + 4, Offset + 4 - CieOffset); // Pointer
F.S->Offsets[F.Index].second = Offset;
+ Offset += alignTo(F.data().size(), sizeof(uintX_t));
+ }
+ }
+}
+
+template <class ELFT> void EHOutputSection<ELFT>::writeTo(uint8_t *Buf) {
+ const endianness E = ELFT::TargetEndianness;
+ for (const Cie<ELFT> &C : Cies) {
+ size_t CieOffset = C.S->Offsets[C.Index].second;
+ writeAlignedCieOrFde<ELFT>(C.data(), Buf + CieOffset);
+
+ for (const EHRegion<ELFT> &F : C.Fdes) {
+ size_t Offset = F.S->Offsets[F.Index].second;
+ writeAlignedCieOrFde<ELFT>(F.data(), Buf + Offset);
+ write32<E>(Buf + Offset + 4, Offset + 4 - CieOffset); // Pointer
+
Out<ELFT>::EhFrameHdr->addFde(C.FdeEncoding, Offset, Buf + Offset + 8);
- Offset += Len;
}
}
OpenPOWER on IntegriCloud