Add strings to .dynstr early.

Previously, we added strings from DynamicSection::finalize().
It was a bit tricky because finalize() is supposed to fix the final
size of the section, but adding new strings would change the size of
.dynstr section. So there was a dependency between finalize functions
of .dynamic and .dynstr.

However, I noticed that we can elimiante the dependency by simply
add strings early; we don't have to do that in finalize() but can do
from DynamicSection's ctor.

This patch defines a new function, DynamicSection::addEntries, to
add .dynamic entries that doesn't depend on other sections.

llvm-svn: 285784
This commit is contained in:
Rui Ueyama 2016-11-02 02:18:01 +00:00
parent b4f6ebf806
commit a959393a15
7 changed files with 54 additions and 49 deletions

View File

@ -722,19 +722,15 @@ DynamicSection<ELFT>::DynamicSection()
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
if (Config->EMachine == EM_MIPS)
Header.sh_flags = SHF_ALLOC;
addEntries();
}
template <class ELFT> void DynamicSection<ELFT>::finalize() {
if (this->Header.sh_size)
return; // Already finalized.
Elf_Shdr &Header = this->Header;
Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
auto Add = [=](Entry E) { Entries.push_back(E); };
// Add strings. We know that these are the last strings to be added to
// DynStrTab and doing this here allows this function to set DT_STRSZ.
// There are some dynamic entries that don't depend on other sections.
// Such entries can be set early.
template <class ELFT> void DynamicSection<ELFT>::addEntries() {
// Add strings to .dynstr early so that .dynstr's size will be
// fixed early.
for (StringRef S : Config->AuxiliaryList)
Add({DT_AUXILIARY, Out<ELFT>::DynStrTab->addString(S)});
if (!Config->RPath.empty())
@ -746,7 +742,37 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
if (!Config->SoName.empty())
Add({DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName)});
Out<ELFT>::DynStrTab->finalize();
// Set DT_FLAGS and DT_FLAGS_1.
uint32_t DtFlags = 0;
uint32_t DtFlags1 = 0;
if (Config->Bsymbolic)
DtFlags |= DF_SYMBOLIC;
if (Config->ZNodelete)
DtFlags1 |= DF_1_NODELETE;
if (Config->ZNow) {
DtFlags |= DF_BIND_NOW;
DtFlags1 |= DF_1_NOW;
}
if (Config->ZOrigin) {
DtFlags |= DF_ORIGIN;
DtFlags1 |= DF_1_ORIGIN;
}
if (DtFlags)
Add({DT_FLAGS, DtFlags});
if (DtFlags1)
Add({DT_FLAGS_1, DtFlags1});
if (!Config->Entry.empty())
Add({DT_DEBUG, (uint64_t)0});
}
// Add remaining entries to complete .dynamic contents.
template <class ELFT> void DynamicSection<ELFT>::finalize() {
if (this->Header.sh_size)
return; // Already finalized.
this->Header.sh_link = Out<ELFT>::DynStrTab->SectionIndex;
if (Out<ELFT>::RelaDyn->hasRelocs()) {
bool IsRela = Config->Rela;
@ -799,29 +825,6 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
Add({DT_FINI, B});
uint32_t DtFlags = 0;
uint32_t DtFlags1 = 0;
if (Config->Bsymbolic)
DtFlags |= DF_SYMBOLIC;
if (Config->ZNodelete)
DtFlags1 |= DF_1_NODELETE;
if (Config->ZNow) {
DtFlags |= DF_BIND_NOW;
DtFlags1 |= DF_1_NOW;
}
if (Config->ZOrigin) {
DtFlags |= DF_ORIGIN;
DtFlags1 |= DF_1_ORIGIN;
}
if (DtFlags)
Add({DT_FLAGS, DtFlags});
if (DtFlags1)
Add({DT_FLAGS_1, DtFlags1});
if (!Config->Entry.empty())
Add({DT_DEBUG, (uint64_t)0});
bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0;
if (HasVerNeed || Out<ELFT>::VerDef)
Add({DT_VERSYM, Out<ELFT>::VerSym});
@ -850,7 +853,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
}
// +1 for DT_NULL
Header.sh_size = (Entries.size() + 1) * Header.sh_entsize;
this->Header.sh_size = (Entries.size() + 1) * this->Header.sh_entsize;
}
template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {

View File

@ -640,11 +640,15 @@ class DynamicSection final : public OutputSectionBase<ELFT> {
std::vector<Entry> Entries;
public:
explicit DynamicSection();
DynamicSection();
void finalize() override;
void writeTo(uint8_t *Buf) override;
typename Base::Kind getKind() const override { return Base::Dynamic; }
static bool classof(const Base *B) { return B->getKind() == Base::Dynamic; }
private:
void addEntries();
void Add(Entry E) { Entries.push_back(E); }
};
template <class ELFT>

View File

@ -218,6 +218,7 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
// Create singleton output sections.
Out<ELFT>::Bss =
make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
Out<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
Out<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
Out<ELFT>::Got = make<GotSection<ELFT>>();
@ -237,7 +238,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
Out<ELFT>::Interp = make<InterpSection<ELFT>>();
if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
Out<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
Out<ELFT>::DynSymTab =
make<SymbolTableSection<ELFT>>(*Out<ELFT>::DynStrTab);
}
@ -837,11 +837,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Fill other section headers. The dynamic table is finalized
// at the end because some tags like RELSZ depend on result
// of finalizing other sections. The dynamic string table is
// finalized once the .dynamic finalizer has added a few last
// strings. See DynamicSection::finalize()
// of finalizing other sections.
for (OutputSectionBase<ELFT> *Sec : OutputSections)
if (Sec != Out<ELFT>::DynStrTab && Sec != Out<ELFT>::Dynamic)
if (Sec != Out<ELFT>::Dynamic)
Sec->finalize();
if (Out<ELFT>::DynSymTab)

View File

@ -44,6 +44,7 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000017 JMPREL
// CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes)
// CHECK-NEXT: 0x0000000000000003 PLTGOT
@ -53,7 +54,6 @@
// CHECK-NEXT: 0x0000000000000005 STRTAB
// CHECK-NEXT: 0x000000000000000A STRSZ
// CHECK-NEXT: 0x0000000000000004 HASH
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]

View File

@ -22,11 +22,11 @@
// CHECK-NEXT: Tag Type Name/Value
// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar
// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]]
// CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes)
// CHECK: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000000 NULL 0x0
// CHECK: 0x0000000000000000 NULL 0x0
// CHECK-NEXT: ]
.global _start

View File

@ -255,6 +255,7 @@
// CHECK-NEXT: Tag Type Name/Value
// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
// CHECK-NEXT: 0x00000015 DEBUG 0x0
// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
// CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes)
// CHECK-NEXT: 0x00000013 RELENT [[RELENT]] (bytes)
@ -263,7 +264,6 @@
// CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]]
// CHECK-NEXT: 0x0000000A STRSZ
// CHECK-NEXT: 0x00000004 HASH [[HASHADDR]]
// CHECK-NEXT: 0x00000015 DEBUG 0x0
// CHECK-NEXT: 0x00000000 NULL 0x0
// CHECK-NEXT: ]

View File

@ -60,9 +60,9 @@
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 00663100 7665726E 65656431 2E736F2E |.f1.verneed1.so.|
# CHECK-NEXT: 0010: 30007633 00663200 76320067 31007665 |0.v3.f2.v2.g1.ve|
# CHECK-NEXT: 0020: 726E6565 64322E73 6F2E3000 763100 |rneed2.so.0.v1.|
# CHECK-NEXT: 0000: 00766572 6E656564 312E736F 2E300076 |.verneed1.so.0.v|
# CHECK-NEXT: 0010: 65726E65 6564322E 736F2E30 00663100 |erneed2.so.0.f1.|
# CHECK-NEXT: 0020: 76330066 32007632 00673100 763100 |v3.f2.v2.g1.v1.|
# CHECK-NEXT: )
# CHECK-NEXT: }