diff options
author | Reid Kleckner <rnk@google.com> | 2020-09-18 13:43:13 -0700 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2020-09-18 14:31:01 -0700 |
commit | 9932561b4892b6e9bbb0c2369272dfff2305fdb9 (patch) | |
tree | f7dc6a6c92310b40e00c8a2406ea79b7f1d41c9f /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | |
parent | 3c731ba5f1b604c873e96ac137bfea723690ba95 (diff) | |
download | llvm-9932561b4892b6e9bbb0c2369272dfff2305fdb9.zip llvm-9932561b4892b6e9bbb0c2369272dfff2305fdb9.tar.gz llvm-9932561b4892b6e9bbb0c2369272dfff2305fdb9.tar.bz2 |
[COFF] Move per-global .drective emission from AsmPrinter to TLOFCOFF
This changes the order of output sections and the output assembly, but
is otherwise NFC.
It simplifies the TLOF interface by removing two COFF-only methods.
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 85 |
1 files changed, 60 insertions, 25 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 08dfbd1..0c43ec8 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1551,21 +1551,7 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { - if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { - // Emit the linker options to the linker .drectve section. According to the - // spec, this section is a space-separated string containing flags for - // linker. - MCSection *Sec = getDrectveSection(); - Streamer.SwitchSection(Sec); - for (const auto *Option : LinkerOptions->operands()) { - for (const auto &Piece : cast<MDNode>(Option)->operands()) { - // Lead with a space for consistency with our dllexport implementation. - std::string Directive(" "); - Directive.append(std::string(cast<MDString>(Piece)->getString())); - Streamer.emitBytes(Directive); - } - } - } + emitLinkerDirectives(Streamer, M); unsigned Version = 0; unsigned Flags = 0; @@ -1588,6 +1574,65 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, emitCGProfile(Streamer, M); } +void TargetLoweringObjectFileCOFF::emitLinkerDirectives( + MCStreamer &Streamer, Module &M) const { + if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { + // Emit the linker options to the linker .drectve section. According to the + // spec, this section is a space-separated string containing flags for + // linker. + MCSection *Sec = getDrectveSection(); + Streamer.SwitchSection(Sec); + for (const auto *Option : LinkerOptions->operands()) { + for (const auto &Piece : cast<MDNode>(Option)->operands()) { + // Lead with a space for consistency with our dllexport implementation. + std::string Directive(" "); + Directive.append(std::string(cast<MDString>(Piece)->getString())); + Streamer.emitBytes(Directive); + } + } + } + + // Emit /EXPORT: flags for each exported global as necessary. + std::string Flags; + for (const GlobalValue &GV : M.global_values()) { + raw_string_ostream OS(Flags); + emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler()); + OS.flush(); + if (!Flags.empty()) { + Streamer.SwitchSection(getDrectveSection()); + Streamer.emitBytes(Flags); + } + Flags.clear(); + } + + // Emit /INCLUDE: flags for each used global as necessary. + if (const auto *LU = M.getNamedGlobal("llvm.used")) { + assert(LU->hasInitializer() && "expected llvm.used to have an initializer"); + assert(isa<ArrayType>(LU->getValueType()) && + "expected llvm.used to be an array type"); + if (const auto *A = cast<ConstantArray>(LU->getInitializer())) { + for (const Value *Op : A->operands()) { + const auto *GV = cast<GlobalValue>(Op->stripPointerCasts()); + // Global symbols with internal or private linkage are not visible to + // the linker, and thus would cause an error when the linker tried to + // preserve the symbol due to the `/include:` directive. + if (GV->hasLocalLinkage()) + continue; + + raw_string_ostream OS(Flags); + emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler()); + OS.flush(); + + if (!Flags.empty()) { + Streamer.SwitchSection(getDrectveSection()); + Streamer.emitBytes(Flags); + } + Flags.clear(); + } + } + } +} + void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, const TargetMachine &TM) { TargetLoweringObjectFile::Initialize(Ctx, TM); @@ -1665,16 +1710,6 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( cast<MCSectionCOFF>(StaticDtorSection)); } -void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal( - raw_ostream &OS, const GlobalValue *GV) const { - emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler()); -} - -void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed( - raw_ostream &OS, const GlobalValue *GV) const { - emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler()); -} - const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( const GlobalValue *LHS, const GlobalValue *RHS, const TargetMachine &TM) const { |