Index: lld/trunk/ELF/Config.h =================================================================== --- lld/trunk/ELF/Config.h +++ lld/trunk/ELF/Config.h @@ -184,6 +184,7 @@ bool ZGlobal; bool ZHazardplt; bool ZInitfirst; + bool ZInterpose; bool ZKeepTextSectionPrefix; bool ZNodelete; bool ZNodlopen; Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -341,9 +341,10 @@ 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 @@ 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"); Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -1268,6 +1268,8 @@ 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) Index: lld/trunk/docs/ld.lld.1 =================================================================== --- lld/trunk/docs/ld.lld.1 +++ lld/trunk/docs/ld.lld.1 @@ -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 @@ 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. Index: lld/trunk/test/ELF/dt_flags.s =================================================================== --- lld/trunk/test/ELF/dt_flags.s +++ lld/trunk/test/ELF/dt_flags.s @@ -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 [