diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-02-05 19:38:00 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-02-05 19:38:00 +0000 |
| commit | a863509cdddf90a3ec3b23a5b2da6d65b68c4800 (patch) | |
| tree | 3b7aece88aa1d94d3de2b633050e43f3fa030f05 /ELF | |
| parent | 63b9abd1dbe002d940a818f51dd9d6e585e41c84 (diff) | |
Notes
Diffstat (limited to 'ELF')
| -rw-r--r-- | ELF/Config.h | 1 | ||||
| -rw-r--r-- | ELF/Driver.cpp | 2 | ||||
| -rw-r--r-- | ELF/Options.td | 13 | ||||
| -rw-r--r-- | ELF/Symbols.cpp | 2 | ||||
| -rw-r--r-- | ELF/SyntheticSections.cpp | 15 | ||||
| -rw-r--r-- | ELF/Writer.cpp | 14 |
6 files changed, 38 insertions, 9 deletions
diff --git a/ELF/Config.h b/ELF/Config.h index b828cdb25047..b7706205a5b6 100644 --- a/ELF/Config.h +++ b/ELF/Config.h @@ -98,6 +98,7 @@ struct Configuration { bool Bsymbolic; bool BsymbolicFunctions; bool ColorDiagnostics = false; + bool DefineCommon; bool Demangle = true; bool DisableVerify; bool EhFrameHdr; diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp index b4544d78f725..50b701175d3e 100644 --- a/ELF/Driver.cpp +++ b/ELF/Driver.cpp @@ -496,6 +496,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->Pie = getArg(Args, OPT_pie, OPT_nopie, false); Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections); Config->Relocatable = Args.hasArg(OPT_relocatable); + Config->DefineCommon = getArg(Args, OPT_define_common, OPT_no_define_common, + !Config->Relocatable); Config->Discard = getDiscardOption(Args); Config->SaveTemps = Args.hasArg(OPT_save_temps); Config->SingleRoRx = Args.hasArg(OPT_no_rosegment); diff --git a/ELF/Options.td b/ELF/Options.td index d436f056d013..77ed4c7e466f 100644 --- a/ELF/Options.td +++ b/ELF/Options.td @@ -45,6 +45,9 @@ def color_diagnostics: F<"color-diagnostics">, def color_diagnostics_eq: J<"color-diagnostics=">, HelpText<"Use colors in diagnostics">; +def define_common: F<"define-common">, + HelpText<"Assign space to common symbols">; + def disable_new_dtags: F<"disable-new-dtags">, HelpText<"Disable new dynamic tags">; @@ -130,6 +133,9 @@ def no_as_needed: F<"no-as-needed">, def no_color_diagnostics: F<"no-color-diagnostics">, HelpText<"Do not use colors in diagnostics">; +def no_define_common: F<"no-define-common">, + HelpText<"Do not assign space to common symbols">; + def no_demangle: F<"no-demangle">, HelpText<"Do not demangle symbol names">; @@ -255,6 +261,9 @@ def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>; def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>; def alias_Bstatic_static: F<"static">, Alias<Bstatic>; def alias_L__library_path: J<"library-path=">, Alias<L>; +def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>; +def alias_define_common_dc: F<"dc">, Alias<define_common>; +def alias_define_common_dp: F<"dp">, Alias<define_common>; def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>; def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>; def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>; @@ -320,7 +329,6 @@ def plugin_opt_eq: J<"plugin-opt=">; // Options listed below are silently ignored for now for compatibility. def allow_shlib_undefined: F<"allow-shlib-undefined">; def cref: Flag<["--"], "cref">; -def define_common: F<"define-common">; def demangle: F<"demangle">; def detect_odr_violations: F<"detect-odr-violations">; def g: Flag<["-"], "g">; @@ -347,9 +355,6 @@ def G: JoinedOrSeparate<["-"], "G">; def Qy : F<"Qy">; // Aliases for ignored options -def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>; -def alias_define_common_dc: F<"dc">, Alias<define_common>; -def alias_define_common_dp: F<"dp">, Alias<define_common>; def alias_Map_eq: J<"Map=">, Alias<Map>; def alias_version_script_version_script: J<"version-script=">, Alias<version_script>; diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp index 0fe42be250cf..43af44ec4b84 100644 --- a/ELF/Symbols.cpp +++ b/ELF/Symbols.cpp @@ -73,6 +73,8 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, return VA; } case SymbolBody::DefinedCommonKind: + if (!Config->DefineCommon) + return 0; return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff + cast<DefinedCommon>(Body).Offset; case SymbolBody::SharedKind: { diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp index 204b5993a62a..b673a4ece1d2 100644 --- a/ELF/SyntheticSections.cpp +++ b/ELF/SyntheticSections.cpp @@ -59,6 +59,9 @@ template <class ELFT> InputSection<ELFT> *elf::createCommonSection() { ArrayRef<uint8_t>(), "COMMON"); Ret->Live = true; + if (!Config->DefineCommon) + return Ret; + // Sort the common symbols by alignment as an heuristic to pack them better. std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>(); std::stable_sort(Syms.begin(), Syms.end(), @@ -434,7 +437,7 @@ template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) { template <class ELFT> MipsGotSection<ELFT>::MipsGotSection() : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, - SHT_PROGBITS, Target->GotEntrySize, ".got") {} + SHT_PROGBITS, 16, ".got") {} template <class ELFT> void MipsGotSection<ELFT>::addEntry(SymbolBody &Sym, uintX_t Addend, @@ -1168,10 +1171,14 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) { ESym->setVisibility(Body->symbol()->Visibility); ESym->st_value = Body->getVA<ELFT>(); - if (const OutputSectionBase *OutSec = getOutputSection(Body)) + if (const OutputSectionBase *OutSec = getOutputSection(Body)) { ESym->st_shndx = OutSec->SectionIndex; - else if (isa<DefinedRegular<ELFT>>(Body)) + } else if (isa<DefinedRegular<ELFT>>(Body)) { ESym->st_shndx = SHN_ABS; + } else if (isa<DefinedCommon>(Body)) { + ESym->st_shndx = SHN_COMMON; + ESym->st_value = cast<DefinedCommon>(Body)->Alignment; + } if (Config->EMachine == EM_MIPS) { // On MIPS we need to mark symbol which has a PLT entry and requires @@ -1203,6 +1210,8 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) { break; } case SymbolBody::DefinedCommonKind: + if (!Config->DefineCommon) + return nullptr; return In<ELFT>::Common->OutSec; case SymbolBody::SharedKind: { auto &SS = cast<SharedSymbol<ELFT>>(*Sym); diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index f00fb6d11ea5..b004a4f0d7f7 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -476,6 +476,16 @@ static int getPPC64SectionRank(StringRef SectionName) { .Default(1); } +// All sections with SHF_MIPS_GPREL flag should be grouped together +// because data in these sections is addressable with a gp relative address. +static int getMipsSectionRank(const OutputSectionBase *S) { + if ((S->Flags & SHF_MIPS_GPREL) == 0) + return 0; + if (S->getName() == ".got") + return 1; + return 2; +} + template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { if (!Config->ZRelro) return false; @@ -494,8 +504,6 @@ template <class ELFT> bool elf::isRelroSection(const OutputSectionBase *Sec) { return true; if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec) return true; - if (In<ELFT>::MipsGot && Sec == In<ELFT>::MipsGot->OutSec) - return true; if (Sec == Out<ELFT>::BssRelRo) return true; StringRef S = Sec->getName(); @@ -595,6 +603,8 @@ static bool compareSectionsNonScript(const OutputSectionBase *A, if (Config->EMachine == EM_PPC64) return getPPC64SectionRank(A->getName()) < getPPC64SectionRank(B->getName()); + if (Config->EMachine == EM_MIPS) + return getMipsSectionRank(A) < getMipsSectionRank(B); return false; } |
