[ELF] - Change way how we handle --noinhibit-exec

Previously we handled this option implicitly, only
for infering unresolved symbols handling policy.

ld man says: "--noinhibit-exec Retain the executable
output file whenever it is still usable",
and we may want to handle other cases too.

Differential revision: https://reviews.llvm.org/D35793

llvm-svn: 309091
This commit is contained in:
George Rimar 2017-07-26 09:46:59 +00:00
parent b1fd784936
commit 84941ef158
5 changed files with 24 additions and 14 deletions

View File

@ -44,7 +44,7 @@ enum class DiscardPolicy { Default, All, Locals, None };
enum class StripPolicy { None, All, Debug }; enum class StripPolicy { None, All, Debug };
// For --unresolved-symbols. // For --unresolved-symbols.
enum class UnresolvedPolicy { ReportError, Warn, WarnAll, Ignore, IgnoreAll }; enum class UnresolvedPolicy { ReportError, Warn, Ignore, IgnoreAll };
// For --sort-section and linkerscript sorting rules. // For --sort-section and linkerscript sorting rules.
enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };
@ -128,6 +128,7 @@ struct Configuration {
bool ICF; bool ICF;
bool MipsN32Abi = false; bool MipsN32Abi = false;
bool NoGnuUnique; bool NoGnuUnique;
bool NoinhibitExec;
bool NoUndefinedVersion; bool NoUndefinedVersion;
bool Nostdlib; bool Nostdlib;
bool OFormatBinary; bool OFormatBinary;

View File

@ -418,9 +418,6 @@ static std::string getRpath(opt::InputArgList &Args) {
// Determines what we should do if there are remaining unresolved // Determines what we should do if there are remaining unresolved
// symbols after the name resolution. // symbols after the name resolution.
static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) { static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
// -noinhibit-exec or -r imply some default values.
if (Args.hasArg(OPT_noinhibit_exec))
return UnresolvedPolicy::WarnAll;
if (Args.hasArg(OPT_relocatable)) if (Args.hasArg(OPT_relocatable))
return UnresolvedPolicy::IgnoreAll; return UnresolvedPolicy::IgnoreAll;
@ -648,6 +645,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->MapFile = Args.getLastArgValue(OPT_Map); Config->MapFile = Args.getLastArgValue(OPT_Map);
Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique); Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique);
Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version); Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version);
Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
Config->Nostdlib = Args.hasArg(OPT_nostdlib); Config->Nostdlib = Args.hasArg(OPT_nostdlib);
Config->OFormatBinary = isOutputFormatBinary(Args); Config->OFormatBinary = isOutputFormatBinary(Args);
Config->Omagic = Args.hasArg(OPT_omagic); Config->Omagic = Args.hasArg(OPT_omagic);

View File

@ -535,6 +535,13 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
In<ELFT>::RelaDyn->addReloc({Target->CopyRel, Sec, Off, false, SS, 0}); In<ELFT>::RelaDyn->addReloc({Target->CopyRel, Sec, Off, false, SS, 0});
} }
static void errorOrWarn(const Twine &Msg) {
if (!Config->NoinhibitExec)
error(Msg);
else
warn(Msg);
}
template <class ELFT> template <class ELFT>
static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type, static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type,
const uint8_t *Data, InputSectionBase &S, const uint8_t *Data, InputSectionBase &S,
@ -609,8 +616,8 @@ static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type,
return toPlt(Expr); return toPlt(Expr);
} }
error("symbol '" + toString(Body) + "' defined in " + toString(Body.File) + errorOrWarn("symbol '" + toString(Body) + "' defined in " +
" has no type"); toString(Body.File) + " has no type");
return Expr; return Expr;
} }
@ -691,12 +698,10 @@ static void reportUndefined(SymbolBody &Sym, InputSectionBase &S,
Msg += Src + "\n>>> "; Msg += Src + "\n>>> ";
Msg += S.getObjMsg<ELFT>(Offset); Msg += S.getObjMsg<ELFT>(Offset);
if (Config->UnresolvedSymbols == UnresolvedPolicy::WarnAll || if (Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal)
(Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal)) {
warn(Msg); warn(Msg);
} else { else
error(Msg); errorOrWarn(Msg);
}
} }
template <class RelTy> template <class RelTy>
@ -905,9 +910,10 @@ static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
// We don't know anything about the finaly symbol. Just ask the dynamic // We don't know anything about the finaly symbol. Just ask the dynamic
// linker to handle the relocation for us. // linker to handle the relocation for us.
if (!Target->isPicRel(Type)) if (!Target->isPicRel(Type))
error("relocation " + toString(Type) + errorOrWarn(
" cannot be used against shared object; recompile with -fPIC" + "relocation " + toString(Type) +
getLocation<ELFT>(Sec, Body, Offset)); " cannot be used against shared object; recompile with -fPIC" +
getLocation<ELFT>(Sec, Body, Offset));
In<ELFT>::RelaDyn->addReloc( In<ELFT>::RelaDyn->addReloc(
{Target->getDynRel(Type), &Sec, Offset, false, &Body, Addend}); {Target->getDynRel(Type), &Sec, Offset, false, &Body, Addend});

View File

@ -9,6 +9,9 @@
// CHECK: >>> referenced by {{.*}}.o:(.text+0x1) // CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
// CHECK: symbol 'zed' defined in {{.*}}.so has no type // CHECK: symbol 'zed' defined in {{.*}}.so has no type
// RUN: not ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s --check-prefix=NOINHIBIT
// NOINHIBIT: warning: symbol 'zed' defined in {{.*}}.so has no type
.global _start .global _start
_start: _start:
call bar call bar

View File

@ -10,3 +10,5 @@ _start:
.long bar .long bar
// CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC // CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC
// RUN: ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s