aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-05-22 00:13:04 +0000
committerRui Ueyama <ruiu@google.com>2016-05-22 00:13:04 +0000
commit51af09a76fe107b4d05b78d432a45633cd945d44 (patch)
treeadf76ddec11b51b6cd278d7b63c1082eae977de0
parentc23cb216df75f354752259e63aba9c3f643939af (diff)
Define SectionPiece and use it instead of std::pair<uint_t, uint_t>.
We were using std::pair to represents pieces of splittable section contents. It hurt readability because "first" and "second" are not meaningful. This patch give them names. One more thing is that piecewise liveness information is stored to the second element of the pair as a special value of output section offset. It was confusing, so I defiend a new bit, "Live", in the new struct. git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@270340 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--ELF/InputSection.cpp50
-rw-r--r--ELF/InputSection.h31
-rw-r--r--ELF/MarkLive.cpp5
-rw-r--r--ELF/OutputSections.cpp43
-rw-r--r--ELF/Writer.cpp3
5 files changed, 56 insertions, 76 deletions
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 835e8c512..58e8e63bf 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -414,13 +414,12 @@ typename ELFT::uint EHInputSection<ELFT>::getOffset(uintX_t Offset) {
// identify the start of the output .eh_frame. Handle this special case.
if (this->getSectionHdr()->sh_size == 0)
return Offset;
- std::pair<uintX_t, uintX_t> *I = this->getRangeAndSize(Offset).first;
- uintX_t Base = I->second;
- if (Base == uintX_t(-1))
+ SectionPiece *Piece = this->getRangeAndSize(Offset).first;
+ if (Piece->OutputOff == size_t(-1))
return -1; // Not in the output
- uintX_t Addend = Offset - I->first;
- return Base + Addend;
+ uintX_t Addend = Offset - Piece->InputOff;
+ return Piece->OutputOff + Addend;
}
static size_t findNull(StringRef S, size_t EntSize) {
@@ -443,17 +442,14 @@ MergeInputSection<ELFT>::MergeInputSection(elf::ObjectFile<ELFT> *F,
uintX_t EntSize = Header->sh_entsize;
ArrayRef<uint8_t> D = this->getSectionData();
StringRef Data((const char *)D.data(), D.size());
- std::vector<std::pair<uintX_t, uintX_t>> &Offsets = this->Offsets;
- uintX_t V = Config->GcSections ? MergeInputSection<ELFT>::PieceDead
- : MergeInputSection<ELFT>::PieceLive;
if (Header->sh_flags & SHF_STRINGS) {
uintX_t Offset = 0;
while (!Data.empty()) {
size_t End = findNull(Data, EntSize);
if (End == StringRef::npos)
fatal("string is not null terminated");
- Offsets.push_back(std::make_pair(Offset, V));
+ this->Pieces.emplace_back(Offset);
uintX_t Size = End + EntSize;
Data = Data.substr(Size);
Offset += Size;
@@ -465,7 +461,7 @@ MergeInputSection<ELFT>::MergeInputSection(elf::ObjectFile<ELFT> *F,
size_t Size = Data.size();
assert((Size % EntSize) == 0);
for (unsigned I = 0, N = Size; I != N; I += EntSize)
- Offsets.push_back(std::make_pair(I, V));
+ this->Pieces.emplace_back(I);
}
template <class ELFT>
@@ -474,8 +470,7 @@ bool MergeInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
}
template <class ELFT>
-std::pair<std::pair<typename ELFT::uint, typename ELFT::uint> *,
- typename ELFT::uint>
+std::pair<SectionPiece *, typename ELFT::uint>
SplitInputSection<ELFT>::getRangeAndSize(uintX_t Offset) {
ArrayRef<uint8_t> D = this->getSectionData();
StringRef Data((const char *)D.data(), D.size());
@@ -485,37 +480,32 @@ SplitInputSection<ELFT>::getRangeAndSize(uintX_t Offset) {
// Find the element this offset points to.
auto I = std::upper_bound(
- Offsets.begin(), Offsets.end(), Offset,
- [](const uintX_t &A, const std::pair<uintX_t, uintX_t> &B) {
- return A < B.first;
- });
- uintX_t End = I == Offsets.end() ? Data.size() : I->first;
+ Pieces.begin(), Pieces.end(), Offset,
+ [](const uintX_t &A, const SectionPiece &B) { return A < B.InputOff; });
+ uintX_t End = (I == Pieces.end()) ? Data.size() : I->InputOff;
--I;
- return std::make_pair(&*I, End);
+ return {&*I, End};
}
template <class ELFT>
typename ELFT::uint MergeInputSection<ELFT>::getOffset(uintX_t Offset) {
- std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> T =
- this->getRangeAndSize(Offset);
- std::pair<uintX_t, uintX_t> *I = T.first;
+ std::pair<SectionPiece *, uintX_t> T = this->getRangeAndSize(Offset);
+ SectionPiece &Piece = *T.first;
uintX_t End = T.second;
- uintX_t Start = I->first;
+ assert(Piece.Live);
// Compute the Addend and if the Base is cached, return.
- uintX_t Addend = Offset - Start;
- uintX_t &Base = I->second;
- assert(Base != MergeInputSection<ELFT>::PieceDead);
- if (Base != MergeInputSection<ELFT>::PieceLive)
- return Base + Addend;
+ uintX_t Addend = Offset - Piece.InputOff;
+ if (Piece.OutputOff != size_t(-1))
+ return Piece.OutputOff + Addend;
// Map the base to the offset in the output section and cache it.
ArrayRef<uint8_t> D = this->getSectionData();
StringRef Data((const char *)D.data(), D.size());
- StringRef Entry = Data.substr(Start, End - Start);
+ StringRef Entry = Data.substr(Piece.InputOff, End - Piece.InputOff);
auto *MOS = static_cast<MergeOutputSection<ELFT> *>(this->OutSec);
- Base = MOS->getOffset(Entry);
- return Base + Addend;
+ Piece.OutputOff = MOS->getOffset(Entry);
+ return Piece.OutputOff + Addend;
}
template <class ELFT>
diff --git a/ELF/InputSection.h b/ELF/InputSection.h
index 84a48dcfb..f2458592b 100644
--- a/ELF/InputSection.h
+++ b/ELF/InputSection.h
@@ -130,6 +130,14 @@ public:
template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;
+// SectionPiece represents a piece of splittable section contents.
+struct SectionPiece {
+ SectionPiece(size_t I) : InputOff(I), Live(!Config->GcSections) {}
+ size_t InputOff;
+ size_t OutputOff = -1;
+ bool Live;
+};
+
// Usually sections are copied to the output as atomic chunks of data,
// but some special types of sections are split into small pieces of data
// and each piece is copied to a different place in the output.
@@ -142,24 +150,11 @@ public:
SplitInputSection(ObjectFile<ELFT> *File, const Elf_Shdr *Header,
typename InputSectionBase<ELFT>::Kind SectionKind);
- // For each piece of data, we maintain the offsets in the input section and
- // in the output section.
- std::vector<std::pair<uintX_t, uintX_t>> Offsets;
-
- // Merge input sections may use the following special values as the output
- // section offset:
- enum {
- // The piece is dead.
- PieceDead = uintX_t(-1),
- // The piece is live, but an offset has not yet been assigned. After offsets
- // have been assigned, if the output section uses tail merging, the field
- // will still have this value and the output section offset is computed
- // lazilly.
- PieceLive = uintX_t(-2),
- };
-
- std::pair<std::pair<uintX_t, uintX_t> *, uintX_t>
- getRangeAndSize(uintX_t Offset);
+ // Splittable sections are handled as a sequence of data
+ // rather than a single large blob of data.
+ std::vector<SectionPiece> Pieces;
+
+ std::pair<SectionPiece *, uintX_t> getRangeAndSize(uintX_t Offset);
};
// This corresponds to a SHF_MERGE section of an input file.
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index dc653d969..6680f6950 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -143,9 +143,8 @@ template <class ELFT> void elf::markLive() {
if (!R.Sec)
return;
if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(R.Sec)) {
- std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> T =
- MS->getRangeAndSize(R.Offset);
- T.first->second = MergeInputSection<ELFT>::PieceLive;
+ std::pair<SectionPiece *, uintX_t> T = MS->getRangeAndSize(R.Offset);
+ T.first->Live = true;
}
if (R.Sec->Live)
return;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index b16035bfa..e02411a7e 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -978,10 +978,9 @@ EHRegion<ELFT>::EHRegion(EHInputSection<ELFT> *S, unsigned Index)
template <class ELFT> StringRef EHRegion<ELFT>::data() const {
ArrayRef<uint8_t> SecData = S->getSectionData();
- ArrayRef<std::pair<uintX_t, uintX_t>> Offsets = S->Offsets;
- size_t Start = Offsets[Index].first;
- size_t End =
- Index == Offsets.size() - 1 ? SecData.size() : Offsets[Index + 1].first;
+ size_t Start = S->Pieces[Index].InputOff;
+ size_t End = (Index == S->Pieces.size() - 1) ? SecData.size()
+ : S->Pieces[Index + 1].InputOff;
return StringRef((const char *)SecData.data() + Start, End - Start);
}
@@ -1142,8 +1141,8 @@ void EHOutputSection<ELFT>::addSectionAux(EHInputSection<ELFT> *S,
DenseMap<uintX_t, uintX_t> OffsetToIndex;
while (!D.empty()) {
- unsigned Index = S->Offsets.size();
- S->Offsets.push_back(std::make_pair(Offset, -1));
+ unsigned Index = S->Pieces.size();
+ S->Pieces.emplace_back(Offset);
uintX_t Length = readEntryLength<ELFT>(D);
// If CIE/FDE data length is zero then Length is 4, this
@@ -1227,11 +1226,11 @@ template <class ELFT> void EHOutputSection<ELFT>::finalize() {
size_t Offset = 0;
for (const Cie<ELFT> &C : Cies) {
- C.S->Offsets[C.Index].second = Offset;
+ C.S->Pieces[C.Index].OutputOff = Offset;
Offset += alignTo(C.data().size(), sizeof(uintX_t));
for (const EHRegion<ELFT> &F : C.Fdes) {
- F.S->Offsets[F.Index].second = Offset;
+ F.S->Pieces[F.Index].OutputOff = Offset;
Offset += alignTo(F.data().size(), sizeof(uintX_t));
}
}
@@ -1240,11 +1239,11 @@ template <class ELFT> void EHOutputSection<ELFT>::finalize() {
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;
+ size_t CieOffset = C.S->Pieces[C.Index].OutputOff;
writeCieFde<ELFT>(Buf + CieOffset, C.data());
for (const EHRegion<ELFT> &F : C.Fdes) {
- size_t Offset = F.S->Offsets[F.Index].second;
+ size_t Offset = F.S->Pieces[F.Index].OutputOff;
writeCieFde<ELFT>(Buf + Offset, F.data());
write32<E>(Buf + Offset + 4, Offset + 4 - CieOffset); // Pointer
@@ -1284,32 +1283,30 @@ void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
StringRef Data((const char *)D.data(), D.size());
uintX_t EntSize = S->getSectionHdr()->sh_entsize;
this->Header.sh_entsize = EntSize;
- MutableArrayRef<std::pair<uintX_t, uintX_t>> Offsets = S->Offsets;
// If this is of type string, the contents are null-terminated strings.
if (this->Header.sh_flags & SHF_STRINGS) {
- for (unsigned I = 0, N = Offsets.size(); I != N; ++I) {
- auto &P = Offsets[I];
- if (P.second == MergeInputSection<ELFT>::PieceDead)
+ for (unsigned I = 0, N = S->Pieces.size(); I != N; ++I) {
+ SectionPiece &Piece = S->Pieces[I];
+ if (!Piece.Live)
continue;
- uintX_t Start = P.first;
- uintX_t End = (I == N - 1) ? Data.size() : Offsets[I + 1].first;
+ uintX_t Start = Piece.InputOff;
+ uintX_t End = (I == N - 1) ? Data.size() : S->Pieces[I + 1].InputOff;
StringRef Entry = Data.substr(Start, End - Start);
uintX_t OutputOffset = Builder.add(Entry);
- if (shouldTailMerge())
- OutputOffset = MergeInputSection<ELFT>::PieceLive;
- P.second = OutputOffset;
+ if (!shouldTailMerge())
+ Piece.OutputOff = OutputOffset;
}
return;
}
// If this is not of type string, every entry has the same size.
- for (auto &P : Offsets) {
- if (P.second == (uintX_t)-1)
+ for (SectionPiece &Piece : S->Pieces) {
+ if (!Piece.Live)
continue;
- StringRef Entry = Data.substr(P.first, EntSize);
- P.second = Builder.add(Entry);
+ StringRef Entry = Data.substr(Piece.InputOff, EntSize);
+ Piece.OutputOff = Builder.add(Entry);
}
}
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 60181c962..0105991f8 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -855,8 +855,7 @@ template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
if (!D->Section->Live)
return false;
if (auto *S = dyn_cast<MergeInputSection<ELFT>>(D->Section))
- if (S->getRangeAndSize(D->Value).first->second ==
- MergeInputSection<ELFT>::PieceDead)
+ if (!S->getRangeAndSize(D->Value).first->Live)
return false;
}
return true;