diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -148,6 +148,7 @@ bool emitLLVM; bool emitRelocs; bool enableNewDtags; + bool errorCallLacksNop; bool executeOnly; bool exportDynamic; bool fixCortexA53Errata843419; @@ -163,6 +164,7 @@ bool hasDynSymTab; bool ignoreDataAddressEquality; bool ignoreFunctionAddressEquality; + bool laxCallLacksNop; bool ltoCSProfileGenerate; bool ltoDebugPassManager; bool ltoNewPassManager; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -887,6 +887,7 @@ config->ignoreFunctionAddressEquality = args.hasArg(OPT_ignore_function_address_equality); config->init = args.getLastArgValue(OPT_init, "_init"); + config->laxCallLacksNop = args.hasArg(OPT_lax_call_lacks_nop); config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline); config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate); config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file); diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -975,9 +975,9 @@ // gcc/gfortran 5.4, 6.3 and earlier versions do not add nop for // recursive calls even if the function is preemptible. This is not // wrong in the common case where the function is not preempted at - // runtime. Just ignore. + // runtime. Just ignore if --lax-call-lacks-nop is specified. if ((bufLoc + 8 > bufEnd || read32(bufLoc + 4) != 0x60000000) && - rel.sym->file != file) { + !(config->laxCallLacksNop && rel.sym->file == file)) { // Use substr(6) to remove the "__plt_" prefix. errorOrWarn(getErrorLocation(bufLoc) + "call to " + lld::toString(*rel.sym).substr(6) + diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -220,6 +220,10 @@ defm keep_unique: Eq<"keep-unique", "Do not fold this symbol during ICF">; +def lax_call_lacks_nop : F<"lax-call-lacks-nop">, + HelpText<"(PowerPC64) Don't error on b/bl not followed by nop, if the target is " + "defined in the same file. This is for compatibility with GCC<5.4 and GCC<6.4">; + defm library: Eq<"library", "Root name of library to use">, MetaVarName<"">;