llvm.org GIT mirror llvm / 56afa6e
[MC, COFF] Support link /incremental conditionally Today, we always take into account the possibility that object files produced by MC may be consumed by an incremental linker. This results in us initialing fields which vary with time (TimeDateStamp) which harms hermetic builds (e.g. verifying a self-host went well) and produces sub-optimal code because we cannot assume anything about the relative position of functions within a section (call sites can get redirected through incremental linker thunks). Let's provide an MCTargetOption which controls this behavior so that we can disable this functionality if we know a-priori that the build will not rely on /incremental. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256203 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 4 years ago
18 changed file(s) with 71 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
608608
609609 unsigned RelaxAll : 1;
610610 unsigned SubsectionsViaSymbols : 1;
611 unsigned IncrementalLinkerCompatible : 1;
611612
612613 /// ELF specific e_header flags
613614 // It would be good if there were an MCELFAssembler class to hold this.
749750 bool getSubsectionsViaSymbols() const { return SubsectionsViaSymbols; }
750751 void setSubsectionsViaSymbols(bool Value) { SubsectionsViaSymbols = Value; }
751752
753 bool isIncrementalLinkerCompatible() const {
754 return IncrementalLinkerCompatible;
755 }
756 void setIncrementalLinkerCompatible(bool Value) {
757 IncrementalLinkerCompatible = Value;
758 }
759
752760 bool getRelaxAll() const { return RelaxAll; }
753761 void setRelaxAll(bool Value) { RelaxAll = Value; }
754762
3131 bool MCNoWarn : 1;
3232 bool MCSaveTempLabels : 1;
3333 bool MCUseDwarfDirectory : 1;
34 bool MCIncrementalLinkerCompatible : 1;
3435 bool ShowMCEncoding : 1;
3536 bool ShowMCInst : 1;
3637 bool AsmVerbose : 1;
5253 ARE_EQUAL(MCNoWarn) &&
5354 ARE_EQUAL(MCSaveTempLabels) &&
5455 ARE_EQUAL(MCUseDwarfDirectory) &&
56 ARE_EQUAL(MCIncrementalLinkerCompatible) &&
5557 ARE_EQUAL(ShowMCEncoding) &&
5658 ARE_EQUAL(ShowMCInst) &&
5759 ARE_EQUAL(AsmVerbose) &&
3232 cl::desc("When used with filetype=obj, "
3333 "relax all fixups in the emitted object file"));
3434
35 cl::opt IncrementalLinkerCompatible(
36 "incremental-linker-compatible",
37 cl::desc(
38 "When used with filetype=obj, "
39 "emit an object file which can be used with an incremental linker"));
40
3541 cl::opt DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
3642 cl::init(0));
3743
5561 Options.SanitizeAddress =
5662 (AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
5763 Options.MCRelaxAll = RelaxAll;
64 Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
5865 Options.DwarfVersion = DwarfVersion;
5966 Options.ShowMCInst = ShowMCInst;
6067 Options.ABIName = ABIName;
140140 typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
141141 raw_pwrite_stream &OS,
142142 MCCodeEmitter *Emitter,
143 bool RelaxAll);
143 bool RelaxAll,
144 bool IncrementalLinkerCompatible);
144145 typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
145146 typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)(
146147 MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
436437 MCAsmBackend &TAB, raw_pwrite_stream &OS,
437438 MCCodeEmitter *Emitter,
438439 const MCSubtargetInfo &STI, bool RelaxAll,
440 bool IncrementalLinkerCompatible,
439441 bool DWARFMustBeAtTheEnd) const {
440442 MCStreamer *S;
441443 switch (T.getObjectFormat()) {
443445 llvm_unreachable("Unknown object format");
444446 case Triple::COFF:
445447 assert(T.isOSWindows() && "only Windows COFF is supported");
446 S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll);
448 S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll,
449 IncrementalLinkerCompatible);
447450 break;
448451 case Triple::MachO:
449452 if (MachOStreamerCtorFn)
202202 Triple T(getTargetTriple().str());
203203 AsmStreamer.reset(getTarget().createMCObjectStreamer(
204204 T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
205 Options.MCOptions.MCIncrementalLinkerCompatible,
205206 /*DWARFMustBeAtTheEnd*/ true));
206207 break;
207208 }
254255 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
255256 std::unique_ptr AsmStreamer(getTarget().createMCObjectStreamer(
256257 T, *Ctx, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
258 Options.MCOptions.MCIncrementalLinkerCompatible,
257259 /*DWARFMustBeAtTheEnd*/ true));
258260
259261 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
336336 MCCodeEmitter &Emitter_, MCObjectWriter &Writer_)
337337 : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
338338 BundleAlignSize(0), RelaxAll(false), SubsectionsViaSymbols(false),
339 ELFHeaderEFlags(0) {
339 IncrementalLinkerCompatible(false), ELFHeaderEFlags(0) {
340340 VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
341341 }
342342
354354 BundleAlignSize = 0;
355355 RelaxAll = false;
356356 SubsectionsViaSymbols = false;
357 IncrementalLinkerCompatible = false;
357358 ELFHeaderEFlags = 0;
358359 LOHContainer.reset();
359360 VersionMinInfo.Major = 0;
1414 MCTargetOptions::MCTargetOptions()
1515 : SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false),
1616 MCFatalWarnings(false), MCNoWarn(false), MCSaveTempLabels(false),
17 MCUseDwarfDirectory(false), ShowMCEncoding(false), ShowMCInst(false),
18 AsmVerbose(false), DwarfVersion(0), ABIName() {}
17 MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false),
18 ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
19 DwarfVersion(0), ABIName() {}
1920
2021 StringRef MCTargetOptions::getABIName() const {
2122 return ABIName;
620620 // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
621621 // away any relocations to functions.
622622 uint16_t Type = cast(SymA).getType();
623 if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
623 if (Asm.isIncrementalLinkerCompatible() &&
624 (Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
624625 return false;
625626 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
626627 InSet, IsPCRel);
967968
968969 Header.PointerToSymbolTable = offset;
969970
971 // FIXME: Remove the #else branch and make the #if branch unconditional once
972 // LLVM's self host configuration is aware of /Brepro.
970973 #if (ENABLE_TIMESTAMPS == 1)
971974 // MS LINK expects to be able to use this timestamp to implement their
972975 // /INCREMENTAL feature.
973 std::time_t Now = time(nullptr);
974 if (Now < 0 || !isUInt<32>(Now))
975 Now = UINT32_MAX;
976 Header.TimeDateStamp = Now;
976 if (Asm.isIncrementalLinkerCompatible()) {
977 std::time_t Now = time(nullptr);
978 if (Now < 0 || !isUInt<32>(Now))
979 Now = UINT32_MAX;
980 Header.TimeDateStamp = Now;
981 } else {
982 Header.TimeDateStamp = 0;
983 }
977984 #else
978985 // We want a deterministic output. It looks like GNU as also writes 0 in here.
979986 Header.TimeDateStamp = 0;
8585 // object file.
8686 MCStreamer *createARMWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
8787 raw_pwrite_stream &OS,
88 MCCodeEmitter *Emitter, bool RelaxAll);
88 MCCodeEmitter *Emitter, bool RelaxAll,
89 bool IncrementalLinkerCompatible);
8990
9091 /// Construct an ELF Mach-O object writer.
9192 MCObjectWriter *createARMELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI,
3636 }
3737 }
3838
39 MCStreamer *llvm::createARMWinCOFFStreamer(MCContext &Context,
40 MCAsmBackend &MAB,
41 raw_pwrite_stream &OS,
42 MCCodeEmitter *Emitter,
43 bool RelaxAll) {
44 return new ARMWinCOFFStreamer(Context, MAB, *Emitter, OS);
39 MCStreamer *llvm::createARMWinCOFFStreamer(
40 MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS,
41 MCCodeEmitter *Emitter, bool RelaxAll, bool IncrementalLinkerCompatible) {
42 auto *S = new ARMWinCOFFStreamer(Context, MAB, *Emitter, OS);
43 S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
44 return S;
4545 }
4646
7878 /// Takes ownership of \p AB and \p CE.
7979 MCStreamer *createX86WinCOFFStreamer(MCContext &C, MCAsmBackend &AB,
8080 raw_pwrite_stream &OS, MCCodeEmitter *CE,
81 bool RelaxAll);
81 bool RelaxAll, bool IncrementalLinkerCompatible);
8282
8383 /// Construct an X86 Mach-O object writer.
8484 MCObjectWriter *createX86MachObjectWriter(raw_pwrite_stream &OS, bool Is64Bit,
4949
5050 MCStreamer *llvm::createX86WinCOFFStreamer(MCContext &C, MCAsmBackend &AB,
5151 raw_pwrite_stream &OS,
52 MCCodeEmitter *CE, bool RelaxAll) {
52 MCCodeEmitter *CE, bool RelaxAll,
53 bool IncrementalLinkerCompatible) {
5354 X86WinCOFFStreamer *S = new X86WinCOFFStreamer(C, AB, CE, OS);
5455 S->getAssembler().setRelaxAll(RelaxAll);
56 S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
5557 return S;
5658 }
5759
None # RUN: not llvm-mc -triple thumbv7-windows -filetype obj -o /dev/null 2>&1 %s \
0 # RUN: not llvm-mc -triple thumbv7-windows -incremental-linker-compatible -filetype obj -o /dev/null 2>&1 %s \
11 # RUN: | FileCheck %s
22
33 .def invalid_relocation
11 // references to functions. Failing to do so might cause pointer-to-function
22 // equality to fail if /INCREMENTAL links are used.
33
4 // RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | llvm-readobj -s | FileCheck %s
5 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -s | FileCheck %s
4 // RUN: llvm-mc -filetype=obj -incremental-linker-compatible -triple i686-pc-win32 %s | llvm-readobj -s | FileCheck %s
5 // RUN: llvm-mc -filetype=obj -incremental-linker-compatible -triple x86_64-pc-win32 %s | llvm-readobj -s | FileCheck %s
66
77 .def _foo;
88 .scl 2;
None // RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s -o - | llvm-readobj -h | FileCheck %s
0 // RUN: llvm-mc -filetype=obj -triple i686-pc-win32 -incremental-linker-compatible %s -o - | llvm-readobj -h | FileCheck %s
11 // REQUIRES: timestamps
22
33 // CHECK: ImageFileHeader {
3030 #include "llvm/MC/MCRegisterInfo.h"
3131 #include "llvm/MC/MCStreamer.h"
3232 #include "llvm/MC/MCSubtargetInfo.h"
33 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
3334 #include "llvm/Object/MachO.h"
3435 #include "llvm/Support/Dwarf.h"
3536 #include "llvm/Support/LEB128.h"
617618 if (EC)
618619 return error(Twine(OutputFilename) + ": " + EC.message(), Context);
619620
620 MS = TheTarget->createMCObjectStreamer(TheTriple, *MC, *MAB, *OutFile, MCE,
621 *MSTI, false,
622 /*DWARFMustBeAtTheEnd*/ false);
621 MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
622 MS = TheTarget->createMCObjectStreamer(
623 TheTriple, *MC, *MAB, *OutFile, MCE, *MSTI, MCOptions.MCRelaxAll,
624 MCOptions.MCIncrementalLinkerCompatible,
625 /*DWARFMustBeAtTheEnd*/ false);
623626 if (!MS)
624627 return error("no object streamer for target " + TripleName, Context);
625628
99 #include "llvm/MC/MCRegisterInfo.h"
1010 #include "llvm/MC/MCSectionELF.h"
1111 #include "llvm/MC/MCStreamer.h"
12 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
1213 #include "llvm/Object/ObjectFile.h"
1314 #include "llvm/Support/DataExtractor.h"
1415 #include "llvm/Support/FileSystem.h"
403404 if (EC)
404405 return error(Twine(OutputFilename) + ": " + EC.message(), Context);
405406
407 MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
406408 std::unique_ptr MS(TheTarget->createMCObjectStreamer(
407 TheTriple, MC, *MAB, OutFile, MCE, *MSTI, false,
409 TheTriple, MC, *MAB, OutFile, MCE, *MSTI, MCOptions.MCRelaxAll,
410 MCOptions.MCIncrementalLinkerCompatible,
408411 /*DWARFMustBeAtTheEnd*/ false));
409412 if (!MS)
410413 return error("no object streamer for target " + TripleName, Context);
510510
511511 MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
512512 MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
513 Str.reset(TheTarget->createMCObjectStreamer(TheTriple, Ctx, *MAB, *OS, CE,
514 *STI, RelaxAll,
515 /*DWARFMustBeAtTheEnd*/ false));
513 Str.reset(TheTarget->createMCObjectStreamer(
514 TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll,
515 MCOptions.MCIncrementalLinkerCompatible,
516 /*DWARFMustBeAtTheEnd*/ false));
516517 if (NoExecStack)
517518 Str->InitSections(true);
518519 }