summaryrefslogtreecommitdiffstats
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-11-18 05:05:43 +0000
committerRui Ueyama <ruiu@google.com>2016-11-18 05:05:43 +0000
commit77f2a875759a68c91cb9b2fc82bd6a0ba6eb5581 (patch)
tree44cff9fc887925abd997f81a3b9bb491d0863e5b /lld/ELF/OutputSections.cpp
parent37bf5c6a3f31eee7fd95ead38855b081629cf9ca (diff)
downloadbcm5719-llvm-77f2a875759a68c91cb9b2fc82bd6a0ba6eb5581.tar.gz
bcm5719-llvm-77f2a875759a68c91cb9b2fc82bd6a0ba6eb5581.zip
Simplify MergeOutputSection.
MergeOutputSection class was a bit hard to use because it provdes a series of finalize functions that have to be called in a right way at a right time. It also intereacted with MergeInputSection, and the logic was somewhat entangled between the two classes. This patch simplifies it by providing only one finalize function. Now, all you have to do is to call MergeOutputSection::finalize when you have added all sections to the output section. Then, it internally merges strings and initliazes StringPiece objects. I think this is much easier to understand. This patch also adds comments. llvm-svn: 287314
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp55
1 files changed, 31 insertions, 24 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 6ba25c15c94..c98170dfc42 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -772,42 +772,49 @@ void MergeOutputSection<ELFT>::addSection(InputSectionData *C) {
this->updateAlignment(Sec->Alignment);
this->Entsize = Sec->Entsize;
Sections.push_back(Sec);
-
- auto HashI = Sec->Hashes.begin();
- for (auto I = Sec->Pieces.begin(), E = Sec->Pieces.end(); I != E; ++I) {
- SectionPiece &Piece = *I;
- uint32_t Hash = *HashI;
- ++HashI;
- if (!Piece.Live)
- continue;
- StringRef Data = toStringRef(Sec->getData(I));
- CachedHashStringRef V(Data, Hash);
- uintX_t OutputOffset = Builder.add(V);
- if (!shouldTailMerge())
- Piece.OutputOff = OutputOffset;
- }
-}
-
-template <class ELFT>
-unsigned MergeOutputSection<ELFT>::getOffset(CachedHashStringRef Val) {
- return Builder.getOffset(Val);
}
template <class ELFT> bool MergeOutputSection<ELFT>::shouldTailMerge() const {
- return Config->Optimize >= 2 && this->Flags & SHF_STRINGS;
+ return (this->Flags & SHF_STRINGS) && Config->Optimize >= 2;
}
template <class ELFT> void MergeOutputSection<ELFT>::finalize() {
+ // Add all string pieces to the string table builder to create section
+ // contents. If we are not tail-optimizing, offsets of strings are fixed
+ // when they are added to the builder (string table builder contains a
+ // hash table from strings to offsets), so we record them if available.
+ for (MergeInputSection<ELFT> *Sec : Sections) {
+ for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
+ if (!Sec->Pieces[I].Live)
+ continue;
+ uint32_t OutputOffset = Builder.add(Sec->getData(I));
+
+ // Save the offset in the generated string table.
+ if (!shouldTailMerge())
+ Sec->Pieces[I].OutputOff = OutputOffset;
+ }
+ }
+
+ // Fix the string table content. After this, the contents
+ // will never change.
if (shouldTailMerge())
Builder.finalize();
else
Builder.finalizeInOrder();
this->Size = Builder.getSize();
-}
-template <class ELFT> void MergeOutputSection<ELFT>::finalizePieces() {
- for (MergeInputSection<ELFT> *Sec : Sections)
- Sec->finalizePieces();
+ // finalize() fixed tail-optimized strings, so we can now get
+ // offsets of strings. Get an offset for each string and save it
+ // to a corresponding StringPiece for easy access.
+ if (shouldTailMerge()) {
+ for (MergeInputSection<ELFT> *Sec : Sections) {
+ for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
+ if (!Sec->Pieces[I].Live)
+ continue;
+ Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
+ }
+ }
+ }
}
template <class ELFT>
OpenPOWER on IntegriCloud