aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/WinCOFFObjectWriter.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-08-21MC: Avoid MCSymbol::isExportedFangrui Song1-19/+20
This bit is only used by COFF/MachO. The upcoming change will move isExported/setExported to MCSymbolCOFF/MCSymbolMachO.
2025-08-03MCSymbolCOFF: Remove classofFangrui Song1-5/+8
The object file format specific derived classes are used in context where the type is statically known. We don't use isa/dyn_cast and we want to eliminate MCSymbol::Kind in the base class.
2025-07-25MCSectionCOFF: Remove classofFangrui Song1-2/+3
The object file format specific derived classes are used in context like MCStreamer and MCObjectTargetWriter where the type is statically known. We don't use isa/dyn_cast and we want to eliminate MCSection::SectionVariant in the base class.
2025-07-20MCFragment: Remove clearContents and uses of non-streaming doneAppendingFangrui Song1-10/+10
Make the fixed-size part of MCFragment append-only to support allocating content as trailing data. The `doneAppending` API is reserved by MCStreamer API before finish and should not be used by the addrsig and call-graph-profile features.
2025-07-20MC: Optimize emitInstruction and simplify fragment-in-BSS checkFangrui Song1-4/+7
Move the FT_Relaxable-in-BSS check from frequently-called MCObjectStreamer::emitInstruction to MCAssembler::writeSectionData, along with existing checks for other fragment types. For the uncommon diagnostics, losing the location information is acceptable.
2025-07-15MC: Restructure MCFragment as a fixed part and a variable tailFangrui Song1-2/+2
Refactor the fragment representation of `push rax; jmp foo; nop; jmp foo`, previously encoded as `MCDataFragment(nop); MCRelaxableFragment(jmp foo); MCDataFragment(nop); MCRelaxableFragment(jmp foo)`, to ``` MCFragment(fixed: push rax, variable: jmp foo) MCFragment(fixed: nop, variable: jmp foo) ``` Changes: * Eliminate MCEncodedFragment, moving content and fixup storage to MCFragment. * The new MCFragment contains a fixed-size content (similar to previous MCDataFragment) and an optional variable-size tail. * The variable-size tail supports FT_Relaxable, FT_LEB, FT_Dwarf, and FT_DwarfFrame, with plans to extend to other fragment types. dyn_cast/isa should be avoided for the converted fragment subclasses. * In `setVarFixups`, source fixup offsets are relative to the variable part's start. Stored fixup (in `FixupStorage`) offsets are relative to the fixed part's start. A lot of code does `getFragmentOffset(Frag) + Fixup.getOffset()`, expecting the fixup offset to be relative to the fixed part's start. * HexagonAsmBackend::fixupNeedsRelaxationAdvanced needs to know the associated instruction for a fixup. We have to add a `const MCFragment &` parameter. * In MCObjectStreamer, extend `absoluteSymbolDiff` to apply to FT_Relaxable as otherwise there would be many more FT_DwarfFrame fragments in -g compilations. https://llvm-compile-time-tracker.com/compare.php?from=28e1473e8e523150914e8c7ea50b44fb0d2a8d65&to=778d68ad1d48e7f111ea853dd249912c601bee89&stat=instructions:u ``` stage2-O0-g instructins:u geomeon (-0.07%) stage1-ReleaseLTO-g (link only) max-rss geomean (-0.39%) ``` ``` % /t/clang-old -g -c sqlite3.i -w -mllvm -debug-only=mc-dump &| awk '/^[0-9]+/{s[$2]++;tot++} END{print "Total",tot; n=asorti(s, si); for(i=1;i<=n;i++) print si[i],s[si[i]]}' Total 59675 Align 2215 Data 29700 Dwarf 12044 DwarfCallFrame 4216 Fill 92 LEB 12 Relaxable 11396 % /t/clang-new -g -c sqlite3.i -w -mllvm -debug-only=mc-dump &| awk '/^[0-9]+/{s[$2]++;tot++} END{print "Total",tot; n=asorti(s, si); for(i=1;i<=n;i++) print si[i],s[si[i]]}' Total 32287 Align 2215 Data 2312 Dwarf 12044 DwarfCallFrame 4216 Fill 92 LEB 12 Relaxable 11396 ``` Pull Request: https://github.com/llvm/llvm-project/pull/148544
2025-07-01MC: Store fragment content and fixups out-of-lineFangrui Song1-2/+4
Moved `Contents` and `Fixups` SmallVector storage to MCSection, enabling trivial destructors for most fragment subclasses and eliminating the need for MCFragment::destroy in ~MCSection. For appending content to the current section, use getContentsForAppending. During assembler relaxation, prefer setContents/setFixups, which may involve copying and reduce the benefits of https://reviews.llvm.org/D145791. Moving only Contents out-of-line caused a slight performance regression (Alexis Engelke's 2024 prototype). By also moving Fragments out-of-line, fragment destructors become trivial, resulting in neglgible instructions:u increase for "stage2-O0-g" and [large max-rss decrease](https://llvm-compile-time-tracker.com/compare.php?from=84e82746c3ff63ec23a8b85e9efd4f7fccf92590&to=555a28c0b2f8250a9cf86fd267a04b0460283e15&stat=max-rss&linkStats=on) for the "stage1-ReleaseLTO-g (link only)" benchmark. ( An older version using fewer inline functions: https://llvm-compile-time-tracker.com/compare.php?from=bb982e733cfcda7e4cfb0583544f68af65211ed1&to=f12d55f97c47717d438951ecddecf8ebd28c296b&linkStats=on ) Now using plain SmallVector in MCSection for storage, with potential for future allocator optimizations, such as allocating `Contents` as the trailing object of MCDataFragment. (GNU Assembler uses gnulib's obstack for fragment management.) Co-authored-by: Alexis Engelke <engelke@in.tum.de> Pull Request: https://github.com/llvm/llvm-project/pull/146307
2025-06-30MC: Merge MCFragment.h into MCSection.hFangrui Song1-1/+0
... due to their close relationship. MCSection's inline functions (e.g. iterator) access MCFragment, and we want MCFragment's inline functions to access MCSection similarly (#146307). Pull Request: https://github.com/llvm/llvm-project/pull/146315
2025-05-25WinCOFFObjectWriter: Simplify code with member MCAssembler *Fangrui Song1-52/+56
Similar to b65760bc7fcdee8179bf1e57fce3786737528dd8 for ELF.
2025-05-24MCObjectWriter: Remove the MCAssembler argument from writeObjectFangrui Song1-3/+3
2025-05-24MC: Simplify recordRelocationFangrui Song1-12/+8
* Remove the MCAssembler * argument. Change subclasses to use MCAssembler *MCObjectWriter::Asm. * Remove pure specifier and add an empty implementation * Change MCFragment * to MCFragment &
2025-05-24MCObjectwriter: Add getContext and simplify codeFangrui Song1-14/+14
2025-05-24MCObjectwriter: Add member variable MCAssembler * and simplify codeFangrui Song1-5/+5
2025-04-05[MC] Replace getSymA()->getSymbol() with getAddSym. NFCFangrui Song1-2/+2
We will replace the MCSymbolRefExpr member in MCValue with MCSymbol. This change reduces dependence on MCSymbolRefExpr.
2025-03-23MCValue: Simplify code with getSubSymFangrui Song1-5/+2
MCValue::SymB is a MCSymbolRefExpr *, which might become MCSymbol * in the future. Simplify some code that uses MCValue::SymB.
2025-01-20[MC][Mips] Generate required IMAGE_REL_MIPS_PAIR relocation (#120876)Hervé Poussineau1-2/+15
Add the required IMAGE_REL_MIPS_PAIR relocation after IMAGE_REL_MIPS_REFHI/IMAGE_REL_MIPS_SECRELHI Microsoft PE/COFF specification says that the IMAGE_REL_MIPS_REFHI relocation contains "the high 16 bits of the target's 32-bit virtual address. [...] This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a 16-bit displacement which is added to the upper 16 bits taken from the location being relocated." Microsoft PE/COFF specification says that the IMAGE_REL_MIPS_SECRELHI relocation contains "the high 16 bits of the 32-bit offset of the target from the beginning of its section. A PAIR relocation must immediately follow this on. The SymbolTableIndex of the PAIR relocation contains a 16-bit displacement, which is added to the upper 16 bits taken from the location being relocated." Behavior has been checked against Microsoft C compiler for MIPS.
2025-01-15[coff] Don't try to write the obj if the assembler has errors (#123007)Daniel Paoliello1-0/+5
The ASAN and MSAN tests have been failing after #122777 because some fields are now set in `executePostLayoutBinding` which is skipped by the assembler if it had errors but read in `writeObject` Since the compilation has failed anyway, skip `writeObject` if the assembler had errors.
2025-01-13Reapply "[aarch64][win] Add support for import call optimization (equivalent ↵Daniel Paoliello1-9/+18
to MSVC /d2ImportCallOptimization) (#121516)" (#122777) This reverts commit 2f7ade4b5e399962e18f5f9a0ab0b7335deece51. Fix is available in #122762
2025-01-13Revert "[aarch64][win] Add support for import call optimization (equivalent ↵Kirill Stoimenov1-18/+9
to MSVC /d2ImportCallOptimization) (#121516)" Breaks sanitizer build: https://lab.llvm.org/buildbot/#/builders/52/builds/5179 This reverts commits: 5ee0a71df919a328c714e25f0935c21e586cc18b d997a722c194feec5f3a94dec5acdce59ac5e55b
2025-01-11[aarch64][win] Add support for import call optimization (equivalent to MSVC ↵Daniel Paoliello1-9/+18
/d2ImportCallOptimization) (#121516) This change implements import call optimization for AArch64 Windows (equivalent to the undocumented MSVC `/d2ImportCallOptimization` flag). Import call optimization adds additional data to the binary which can be used by the Windows kernel loader to rewrite indirect calls to imported functions as direct calls. It uses the same [Dynamic Value Relocation Table mechanism that was leveraged on x64 to implement `/d2GuardRetpoline`](https://techcommunity.microsoft.com/blog/windowsosplatform/mitigating-spectre-variant-2-with-retpoline-on-windows/295618). The change to the obj file is to add a new `.impcall` section with the following layout: ```cpp // Per section that contains calls to imported functions: // uint32_t SectionSize: Size in bytes for information in this section. // uint32_t Section Number // Per call to imported function in section: // uint32_t Kind: the kind of imported function. // uint32_t BranchOffset: the offset of the branch instruction in its // parent section. // uint32_t TargetSymbolId: the symbol id of the called function. ``` NOTE: If the import call optimization feature is enabled, then the `.impcall` section must be emitted, even if there are no calls to imported functions. The implementation is split across a few parts of LLVM: * During AArch64 instruction selection, the `GlobalValue` for each call to a global is recorded into the Extra Information for that node. * During lowering to machine instructions, the called global value for each call is noted in its containing `MachineFunction`. * During AArch64 asm printing, if the import call optimization feature is enabled: - A (new) `.impcall` directive is emitted for each call to an imported function. - The `.impcall` section is emitted with its magic header (but is not filled in). * During COFF object writing, the `.impcall` section is filled in based on each `.impcall` directive that were encountered. The `.impcall` section can only be filled in when we are writing the COFF object as it requires the actual section numbers, which are only assigned at that point (i.e., they don't exist during asm printing). I had tried to avoid using the Extra Information during instruction selection and instead implement this either purely during asm printing or in a `MachineFunctionPass` (as suggested in [on the forums](https://discourse.llvm.org/t/design-gathering-locations-of-instructions-to-emit-into-a-section/83729/3)) but this was not possible due to how loading and calling an imported function works on AArch64. Specifically, they are emitted as `ADRP` + `LDR` (to load the symbol) then a `BR` (to do the call), so at the point when we have machine instructions, we would have to work backwards through the instructions to discover what is being called. An initial prototype did work by inspecting instructions; however, it didn't correctly handle the case where the same function was called twice in a row, which caused LLVM to elide the `ADRP` + `LDR` and reuse the previously loaded address. Worse than that, sometimes for the double-call case LLVM decided to spill the loaded address to the stack and then reload it before making the second call. So, instead of trying to implement logic to discover where the value in a register came from, I instead recorded the symbol being called at the last place where it was easy to do: instruction selection.
2024-12-21[MC] Remove redundant MCSection::empty check. NFCFangrui Song1-1/+1
The section cannot be empty due to allocInitialFragment.
2024-11-15[MC] Remove unused includes (NFC) (#116317)Kazu Hirata1-1/+0
Identified with misc-include-cleaner.
2024-07-22MCAssembler: Move CGProfile to MCObjectWriterFangrui Song1-2/+2
2024-07-22MCAssembler: Move FileNames and CompilerVersion to MCObjectWriterFangrui Song1-1/+1
2024-07-21[MC] Export llvm::WinCOFFObjectWriter and access it from MCWinCOFFStreamerFangrui Song1-39/+17
Similar to commit 28fcafb50274be2520117eacb0a886adafefe59d (2011) for MachObjectWriter. MCWinCOFFStreamer can now access WinCOFFObjectWriter directly without holding object file format specific inforamtion in MCAssembler (e.g. IncrementalLinkerCompatible).
2024-07-05MCAssembler: Remove unneeded non-const iterators for Sections and misleading ↵Fangrui Song1-2/+2
size() The pointers cannot be mutated even if the dereferenced MCSection can.
2024-07-01WinCOFFObjectWriter: replace the MCAsmLayout parameter with MCAssemblerFangrui Song1-14/+8
2024-07-01[MC] Remove MCAsmLayout::{getSymbolOffset,getBaseSymbol}Fangrui Song1-8/+6
The MCAsmLayout::* forwarders added by 67957a45ee1ec42ae1671cdbfa0d73127346cc95 have all been removed.
2024-07-01[MC] Remove MCAsmLayout::{getSectionFileSize,getSectionAddressSize}Fangrui Song1-7/+7
2024-07-01[MC] Remove the MCAsmLayout parameter from ↵Fangrui Song1-9/+7
MCObjectWriter::executePostLayoutBinding
2024-07-01[MC] Remove the MCAsmLayout parameter from ↵Fangrui Song1-12/+10
MCObjectWriter::{writeObject,writeSectionData}
2024-06-30[MC] Remove the MCAsmLayout parameter from MCObjectWriter::recordRelocationFangrui Song1-13/+11
2024-06-30[MC] Start merging MCAsmLayout into MCAssemblerFangrui Song1-4/+3
Follow-up to 10c894cffd0f4bef21b54a43b5780240532e44cf. MCAsmLayout, introduced by ac8a95498a99eb16dff9d3d0186616645d200b6e (2010), provides APIs to compute fragment/symbol/section offsets. The separate class is cumbersome and passing it around has overhead. Let's remove it as the underlying implementation is tightly coupled with MCAsmLayout anyway. Some forwarders are added to ease migration.
2024-06-29[MC] Simplify isSymbolRefDifferenceFullyResolvedImpl overloads. NFCFangrui Song1-2/+1
The base implementation is simple. Just inline it.
2024-06-25[MC,COFF] Change how we handle section symbolsFangrui Song1-4/+8
13a79bbfe583e1d8cc85d241b580907260065eb8 (2017) unified `BeginSymbol` and section symbol for ELF. This patch does the same for COFF. * In getCOFFSection, all sections now have a `BeginSymbol` (section symbol). We do not need a dummy symbol name when `getBeginSymbol` is needed (used by AsmParser::Run and DWARF generation). * Section symbols are in the global symbol table. `call .text` will reference the section symbol instead of an undefined symbol. This matches GNU assembler. Unlike GNU, redefining the section symbol will cause a "symbol 'foo0' is already defined" error (see `section-sym-err.s`). Pull Request: https://github.com/llvm/llvm-project/pull/96459
2024-06-23[MC,COFF] Register .llvm.call-graph-profile in finalizeImplFangrui Song1-23/+8
All sections should have been created before MCAssembler::layout so that every section has an ordinal. Registering the section in WinCOFFObjectWriter::executePostLayoutBinding is a hack.
2024-06-20[MC] Remove SectionKind from MCSection (#96067)aengelke1-4/+2
There are only three actual uses of the section kind in MCSection: isText(), XCOFF, and WebAssembly. Store isText() in the MCSection, and store other info in the actual section variants where required. ELF and COFF flags also encode all relevant information, so for these two section variants, remove the SectionKind parameter entirely. This allows to remove the string switch (which is unnecessary and inaccurate) from createELFSectionImpl. This was introduced in [D133456](https://reviews.llvm.org/D133456), but apparently, it was never hit for non-writable sections anyway and the resulting kind was never used.
2024-06-14[MC] Add MCFragment allocation helpersFangrui Song1-4/+6
`allocFragment` might be changed to a placement new when the allocation strategy changes. `allocInitialFragment` is to deduplicate the following pattern ``` auto *F = new MCDataFragment(); Result->addFragment(*F); F->setParent(Result); ``` Pull Request: https://github.com/llvm/llvm-project/pull/95197
2024-06-10[MC] Remove getFragmentList uses. NFCFangrui Song1-1/+1
2024-03-22[MC][COFF][AArch64] Treat ARM64EC/X as ARM64 for relocations (#86019)Billy Laws1-2/+2
Since ARM64EC/X objects use regular ARM64 relocations, any special handling must be done for them too.
2023-12-11[llvm] Use StringRef::{starts,ends}_with (NFC) (#74956)Kazu Hirata1-1/+1
This patch replaces uses of StringRef::{starts,ends}with with StringRef::{starts,ends}_with for consistency with std::{string,string_view}::{starts,ends}_with in C++20. I'm planning to deprecate and eventually remove StringRef::{starts,ends}with.
2023-10-12Use llvm::endianness::{big,little,native} (NFC)Kazu Hirata1-1/+1
Note that llvm::support::endianness has been renamed to llvm::endianness while becoming an enum class as opposed to an enum. This patch replaces support::{big,little,native} with llvm::endianness::{big,little,native}.
2023-08-17[MC][COFF][AArch64] Avoid incorrect IMAGE_REL_ARM64_BRANCH26 relocations.Hiroshi Yamauchi1-2/+4
For a b/bl instruction that branches a temporary symbol (private assembly label), an IMAGE_REL_ARM64_BRANCH26 relocation to another symbol + a non-zero offset could be emitted but the linkers don't support this type of relocation and cause incorrect relocations and crashes. Avoid emitting this type of relocations. Differential Revision: https://reviews.llvm.org/D155732
2023-06-26Reland [COFF] Support -gsplit-dwarf for COFF on WindowsHaohai Wen1-15/+61
This relands 3eee5aa528abd67bb6d057e25ce1980d0d38c445 with fixes.
2023-06-25Revert "[COFF] Support -gsplit-dwarf for COFF on Windows"Nico Weber1-61/+15
This reverts commit 3eee5aa528abd67bb6d057e25ce1980d0d38c445. Breaks tests on mac, see https://reviews.llvm.org/D152785#4447118
2023-06-25[COFF] Support -gsplit-dwarf for COFF on WindowsHaohai Wen1-15/+61
D152340 has split WinCOFFObjectWriter to WinCOFFWriter. This patch adds another WinCOFFWriter as DwoWriter to write Dwo sections to dwo file. Driver options are also updated accordingly to support -gsplit-dwarf in CL mode. e.g. $ clang-cl -c -gdwarf -gsplit-dwarf foo.c Like what -gsplit-dwarf did in ELF, using this option will create DWARF object (.dwo) file. DWARF debug info is split between COFF object and DWARF object file. It can reduce the executable file size especially for large project. Reviewed By: skan, MaskRay Differential Revision: https://reviews.llvm.org/D152785
2023-06-09[NFC][COFF] Split WinCOFFObjectWriter to WinCOFFWriterHaohai Wen1-107/+148
We'd like to support -gsplit-dwarf for Windows COFF. It requires to write Dwo and NonDwo sections to different output streams.The original implementation is not designed to do that and there can be only one MCObjectWriter. This patch split WinCOFFObjectWriter to WinCOFFWriter so that: 1. WinCOFFObjectWriter can create multiple WinCOFFWriter. 2. Each WinCOFFWriter can separately collect sections it is interested. 3. Each WinCOFFWriter can write to it's own output stream. Reviewed By: skan Differential Revision: https://reviews.llvm.org/D152340
2023-06-07[COFF] Add MC support for emitting IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY symbolsEli Friedman1-3/+3
This is mostly useful for ARM64EC, which uses such symbols extensively. One interesting quirk of ARM64EC is that we need to be able to emit weak symbols that point at each other (so if either symbol is defined elsewhere, both symbols point at the definition). This handling is currently restricted to weak_anti_dep symbols, because we depend on the current behavior of resolving weak symbols in some cases. Differential Revision: https://reviews.llvm.org/D145208
2023-06-06[NFC][COFF] Refine access specifiers for WinCOFFObjectWriterHaohai Wen1-176/+173
Set public specifiers only for constructor and inherited methods from MCObjectWriter and leave others as private. Also change the order of MCObjectWriter methods' definition according to it's declaration order. Reviewed By: skan Differential Revision: https://reviews.llvm.org/D152229
2023-06-05[NFC][COFF] clang-format WinCOFFObjectWriter and MCWinCOFFObjectWriterHaohai Wen1-15/+12
Reviewed By: skan Differential Revision: https://reviews.llvm.org/D152119