Index: include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/ELFLinkingContext.h +++ include/lld/ReaderWriter/ELFLinkingContext.h @@ -97,6 +97,12 @@ OMAGIC, }; + /// \brief ELF DT_FLAGS. + enum DTFlag : uint32_t { + DT_NOW = 1 << 1, + DT_ORIGIN = 1 << 2, + }; + llvm::Triple getTriple() const { return _triple; } uint64_t getPageSize() const { return _maxPageSize; } @@ -329,6 +335,10 @@ // --wrap option. void addWrapForSymbol(StringRef sym) { _wrapCalls.insert(sym); } + // \brief Set DT_FLAGS flag. + void setDTFlag(DTFlag f) { _dtFlags |= f; }; + bool getDTFlag(DTFlag f) { return (_dtFlags & f); }; + const llvm::StringSet<> &wrapCalls() const { return _wrapCalls; } void setUndefinesResolver(std::unique_ptr resolver); @@ -383,6 +393,7 @@ bool _armTarget1Rel = false; bool _mipsPcRelEhRel = false; uint64_t _maxPageSize = 0x1000; + uint32_t _dtFlags = 0; OutputMagic _outputMagic = OutputMagic::DEFAULT; StringRefVector _inputSearchPaths; Index: lib/Driver/GnuLdDriver.cpp =================================================================== --- lib/Driver/GnuLdDriver.cpp +++ lib/Driver/GnuLdDriver.cpp @@ -584,9 +584,13 @@ for (auto *arg : parsedArgs->filtered(OPT_z)) { StringRef opt = arg->getValue(); - if (opt == "muldefs") { + if (opt == "muldefs") ctx->setAllowDuplicates(true); - } else if (opt.startswith("max-page-size")) { + else if (opt == "now") + ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_NOW); + else if (opt == "origin") + ctx->setDTFlag(ELFLinkingContext::DTFlag::DT_ORIGIN); + else if (opt.startswith("max-page-size")) { // Parse -z max-page-size option. // The default page size is considered the minimum page size the user // can set, check the user input if its atleast the minimum page size Index: lib/ReaderWriter/ELF/OutputELFWriter.cpp =================================================================== --- lib/ReaderWriter/ELF/OutputELFWriter.cpp +++ lib/ReaderWriter/ELF/OutputELFWriter.cpp @@ -140,6 +140,21 @@ if (!soname.empty() && _ctx.getOutputELFType() == llvm::ELF::ET_DYN) _dynamicTable->addEntry(DT_SONAME, _dynamicStringTable->addString(soname)); + // Add DT_FLAGS/DT_FLAGS_1 entries if necessary. + uint32_t dtflags = 0, dt1flags = 0; + if (_ctx.getDTFlag(ELFLinkingContext::DTFlag::DT_NOW)) { + dtflags |= DF_BIND_NOW; + dt1flags |= DF_1_NOW; + } + if (_ctx.getDTFlag(ELFLinkingContext::DTFlag::DT_ORIGIN)) { + dtflags |= DF_ORIGIN; + dt1flags |= DF_1_ORIGIN; + } + if (dtflags != 0) + _dynamicTable->addEntry(DT_FLAGS, dtflags); + if (dt1flags != 0) + _dynamicTable->addEntry(DT_FLAGS_1, dt1flags); + // The dynamic symbol table need to be sorted earlier because the hash // table needs to be built using the dynamic symbol table. It would be // late to sort the symbols due to that in finalize. In the dynamic symbol