aboutsummaryrefslogtreecommitdiff
path: root/ELF
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-02-05 19:38:00 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-02-05 19:38:00 +0000
commita863509cdddf90a3ec3b23a5b2da6d65b68c4800 (patch)
tree3b7aece88aa1d94d3de2b633050e43f3fa030f05 /ELF
parent63b9abd1dbe002d940a818f51dd9d6e585e41c84 (diff)
Notes
Diffstat (limited to 'ELF')
-rw-r--r--ELF/Config.h1
-rw-r--r--ELF/Driver.cpp2
-rw-r--r--ELF/Options.td13
-rw-r--r--ELF/Symbols.cpp2
-rw-r--r--ELF/SyntheticSections.cpp15
-rw-r--r--ELF/Writer.cpp14
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;
}