lld: add -z interpose support

-z interpose sets the DF_1_INTERPOSE flag, marking the object as an
interposer.

Via FreeBSD PR 230604, linking Valgrind with lld failed.

Differential Revision:	https://reviews.llvm.org/D52094

llvm-svn: 342239
This commit is contained in:
Ed Maste 2018-09-14 14:25:37 +00:00
parent 3c011e1e3c
commit c0b474f67a
5 changed files with 18 additions and 7 deletions

View File

@ -184,6 +184,7 @@ struct Configuration {
bool ZGlobal;
bool ZHazardplt;
bool ZInitfirst;
bool ZInterpose;
bool ZKeepTextSectionPrefix;
bool ZNodelete;
bool ZNodlopen;

View File

@ -341,9 +341,10 @@ static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2,
static bool isKnown(StringRef S) {
return S == "combreloc" || S == "copyreloc" || S == "defs" ||
S == "execstack" || S == "global" || S == "hazardplt" ||
S == "initfirst" || S == "keep-text-section-prefix" || S == "lazy" ||
S == "muldefs" || S == "nocombreloc" || S == "nocopyreloc" ||
S == "nodelete" || S == "nodlopen" || S == "noexecstack" ||
S == "initfirst" || S == "interpose" ||
S == "keep-text-section-prefix" || S == "lazy" || S == "muldefs" ||
S == "nocombreloc" || S == "nocopyreloc" || S == "nodelete" ||
S == "nodlopen" || S == "noexecstack" ||
S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
S == "rodynamic" || S == "text" || S == "wxneeded" ||
@ -836,6 +837,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->ZGlobal = hasZOption(Args, "global");
Config->ZHazardplt = hasZOption(Args, "hazardplt");
Config->ZInitfirst = hasZOption(Args, "initfirst");
Config->ZInterpose = hasZOption(Args, "interpose");
Config->ZKeepTextSectionPrefix = getZFlag(
Args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
Config->ZNodelete = hasZOption(Args, "nodelete");

View File

@ -1268,6 +1268,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
DtFlags1 |= DF_1_GLOBAL;
if (Config->ZInitfirst)
DtFlags1 |= DF_1_INITFIRST;
if (Config->ZInterpose)
DtFlags1 |= DF_1_INTERPOSE;
if (Config->ZNodelete)
DtFlags1 |= DF_1_NODELETE;
if (Config->ZNodlopen)

View File

@ -3,7 +3,7 @@
.\"
.\" This man page documents only lld's ELF linking support, obtained originally
.\" from FreeBSD.
.Dd July 30, 2018
.Dd September 14, 2018
.Dt LD.LLD 1
.Os
.Sh NAME
@ -446,6 +446,12 @@ segment.
Sets the
.Dv DF_1_INITFIRST
flag to indicate the module should be initialized first.
.It Cm interpose
Set the
.Dv DF_1_INTERPOSE
flag to indicate to the runtime linker that the object is an interposer.
During symbol resolution interposers are searched after the application
but before other dependencies.
.It Cm muldefs
Do not error if a symbol is defined multiple times.
The first definition will be used.

View File

@ -3,8 +3,8 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: ld.lld -shared %t -o %t.so
# RUN: ld.lld -z global -z initfirst -z now -z nodelete -z nodlopen -z origin \
# RUN: -Bsymbolic %t %t.so -o %t1
# RUN: ld.lld -z global -z initfirst -z interpose -z now -z nodelete \
# RUN: -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
# RUN: ld.lld %t %t.so -o %t2
@ -15,7 +15,7 @@
# FLAGS: DynamicSection [
# FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW GLOBAL NODELETE INITFIRST NOOPEN ORIGIN
# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW GLOBAL NODELETE INITFIRST NOOPEN ORIGIN INTERPOSE
# FLAGS: ]
# CHECK: DynamicSection [