1 //===- MCMachOStreamer.cpp - MachO Streamer -------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/DenseMap.h" 10 #include "llvm/ADT/SmallString.h" 11 #include "llvm/ADT/SmallVector.h" 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/BinaryFormat/MachO.h" 14 #include "llvm/MC/MCAsmBackend.h" 15 #include "llvm/MC/MCAssembler.h" 16 #include "llvm/MC/MCCodeEmitter.h" 17 #include "llvm/MC/MCContext.h" 18 #include "llvm/MC/MCDirectives.h" 19 #include "llvm/MC/MCExpr.h" 20 #include "llvm/MC/MCFixup.h" 21 #include "llvm/MC/MCFragment.h" 22 #include "llvm/MC/MCLinkerOptimizationHint.h" 23 #include "llvm/MC/MCMachObjectWriter.h" 24 #include "llvm/MC/MCObjectFileInfo.h" 25 #include "llvm/MC/MCObjectStreamer.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCSection.h" 28 #include "llvm/MC/MCSectionMachO.h" 29 #include "llvm/MC/MCSymbol.h" 30 #include "llvm/MC/MCSymbolMachO.h" 31 #include "llvm/MC/MCValue.h" 32 #include "llvm/MC/SectionKind.h" 33 #include "llvm/MC/TargetRegistry.h" 34 #include "llvm/Support/Casting.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include <cassert> 37 #include <vector> 38 39 namespace llvm { 40 class MCInst; 41 class MCStreamer; 42 class MCSubtargetInfo; 43 class Triple; 44 } // namespace llvm 45 46 using namespace llvm; 47 48 namespace { 49 50 class MCMachOStreamer : public MCObjectStreamer { 51 private: 52 /// LabelSections - true if each section change should emit a linker local 53 /// label for use in relocations for assembler local references. Obviates the 54 /// need for local relocations. False by default. 55 bool LabelSections; 56 57 /// HasSectionLabel - map of which sections have already had a non-local 58 /// label emitted to them. Used so we don't emit extraneous linker local 59 /// labels in the middle of the section. 60 DenseMap<const MCSection*, bool> HasSectionLabel; 61 62 void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override; 63 64 void emitDataRegion(MachO::DataRegionType Kind); 65 void emitDataRegionEnd(); 66 67 public: 68 MCMachOStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, 69 std::unique_ptr<MCObjectWriter> OW, 70 std::unique_ptr<MCCodeEmitter> Emitter, bool label) 71 : MCObjectStreamer(Context, std::move(MAB), std::move(OW), 72 std::move(Emitter)), 73 LabelSections(label) {} 74 75 /// state management 76 void reset() override { 77 HasSectionLabel.clear(); 78 MCObjectStreamer::reset(); 79 } 80 81 MachObjectWriter &getWriter() { 82 return static_cast<MachObjectWriter &>(getAssembler().getWriter()); 83 } 84 85 /// @name MCStreamer Interface 86 /// @{ 87 88 void changeSection(MCSection *Sect, uint32_t Subsection = 0) override; 89 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; 90 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; 91 void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; 92 void emitAssemblerFlag(MCAssemblerFlag Flag) override; 93 void emitLinkerOptions(ArrayRef<std::string> Options) override; 94 void emitDataRegion(MCDataRegionType Kind) override; 95 void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor, 96 unsigned Update, VersionTuple SDKVersion) override; 97 void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, 98 unsigned Update, VersionTuple SDKVersion) override; 99 void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, 100 unsigned Minor, unsigned Update, 101 VersionTuple SDKVersion) override; 102 void emitThumbFunc(MCSymbol *Func) override; 103 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; 104 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; 105 void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 106 Align ByteAlignment) override; 107 108 void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 109 Align ByteAlignment) override; 110 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, 111 uint64_t Size = 0, Align ByteAlignment = Align(1), 112 SMLoc Loc = SMLoc()) override; 113 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, 114 Align ByteAlignment = Align(1)) override; 115 116 void emitIdent(StringRef IdentString) override { 117 llvm_unreachable("macho doesn't support this directive"); 118 } 119 120 void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override { 121 getWriter().getLOHContainer().addDirective(Kind, Args); 122 } 123 void emitCGProfileEntry(const MCSymbolRefExpr *From, 124 const MCSymbolRefExpr *To, uint64_t Count) override { 125 if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary()) 126 getWriter().getCGProfile().push_back({From, To, Count}); 127 } 128 129 void finishImpl() override; 130 131 void finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE); 132 void finalizeCGProfile(); 133 void createAddrSigSection(); 134 }; 135 136 } // end anonymous namespace. 137 138 void MCMachOStreamer::changeSection(MCSection *Section, uint32_t Subsection) { 139 // Change the section normally. 140 changeSectionImpl(Section, Subsection); 141 142 // Output a linker-local symbol so we don't need section-relative local 143 // relocations. The linker hates us when we do that. 144 if (LabelSections && !HasSectionLabel[Section] && 145 !Section->getBeginSymbol()) { 146 MCSymbol *Label = getContext().createLinkerPrivateTempSymbol(); 147 Section->setBeginSymbol(Label); 148 HasSectionLabel[Section] = true; 149 } 150 } 151 152 void MCMachOStreamer::emitEHSymAttributes(const MCSymbol *Symbol, 153 MCSymbol *EHSymbol) { 154 auto *Sym = cast<MCSymbolMachO>(Symbol); 155 getAssembler().registerSymbol(*Symbol); 156 if (Symbol->isExternal()) 157 emitSymbolAttribute(EHSymbol, MCSA_Global); 158 if (Sym->isWeakDefinition()) 159 emitSymbolAttribute(EHSymbol, MCSA_WeakDefinition); 160 if (Sym->isPrivateExtern()) 161 emitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); 162 } 163 164 void MCMachOStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { 165 // We have to create a new fragment if this is an atom defining symbol, 166 // fragments cannot span atoms. 167 if (cast<MCSymbolMachO>(Symbol)->isSymbolLinkerVisible()) 168 insert(getContext().allocFragment<MCDataFragment>()); 169 170 MCObjectStreamer::emitLabel(Symbol, Loc); 171 172 // This causes the reference type flag to be cleared. Darwin 'as' was "trying" 173 // to clear the weak reference and weak definition bits too, but the 174 // implementation was buggy. For now we just try to match 'as', for 175 // diffability. 176 // 177 // FIXME: Cleanup this code, these bits should be emitted based on semantic 178 // properties, not on the order of definition, etc. 179 cast<MCSymbolMachO>(Symbol)->clearReferenceType(); 180 } 181 182 void MCMachOStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 183 MCValue Res; 184 185 if (Value->evaluateAsRelocatable(Res, nullptr, nullptr)) { 186 if (const MCSymbolRefExpr *SymAExpr = Res.getSymA()) { 187 const MCSymbol &SymA = SymAExpr->getSymbol(); 188 if (!Res.getSymB() && (SymA.getName() == "" || Res.getConstant() != 0)) 189 cast<MCSymbolMachO>(Symbol)->setAltEntry(); 190 } 191 } 192 MCObjectStreamer::emitAssignment(Symbol, Value); 193 } 194 195 void MCMachOStreamer::emitDataRegion(MachO::DataRegionType Kind) { 196 // Create a temporary label to mark the start of the data region. 197 MCSymbol *Start = getContext().createTempSymbol(); 198 emitLabel(Start); 199 // Record the region for the object writer to use. 200 getWriter().getDataRegions().push_back({Kind, Start, nullptr}); 201 } 202 203 void MCMachOStreamer::emitDataRegionEnd() { 204 auto &Regions = getWriter().getDataRegions(); 205 assert(!Regions.empty() && "Mismatched .end_data_region!"); 206 auto &Data = Regions.back(); 207 assert(!Data.End && "Mismatched .end_data_region!"); 208 // Create a temporary label to mark the end of the data region. 209 Data.End = getContext().createTempSymbol(); 210 emitLabel(Data.End); 211 } 212 213 void MCMachOStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { 214 // Let the target do whatever target specific stuff it needs to do. 215 getAssembler().getBackend().handleAssemblerFlag(Flag); 216 // Do any generic stuff we need to do. 217 switch (Flag) { 218 case MCAF_SyntaxUnified: return; // no-op here. 219 case MCAF_Code16: return; // Change parsing mode; no-op here. 220 case MCAF_Code32: return; // Change parsing mode; no-op here. 221 case MCAF_Code64: return; // Change parsing mode; no-op here. 222 case MCAF_SubsectionsViaSymbols: 223 getWriter().setSubsectionsViaSymbols(true); 224 return; 225 } 226 } 227 228 void MCMachOStreamer::emitLinkerOptions(ArrayRef<std::string> Options) { 229 getWriter().getLinkerOptions().push_back(Options); 230 } 231 232 void MCMachOStreamer::emitDataRegion(MCDataRegionType Kind) { 233 switch (Kind) { 234 case MCDR_DataRegion: 235 emitDataRegion(MachO::DataRegionType::DICE_KIND_DATA); 236 return; 237 case MCDR_DataRegionJT8: 238 emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE8); 239 return; 240 case MCDR_DataRegionJT16: 241 emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE16); 242 return; 243 case MCDR_DataRegionJT32: 244 emitDataRegion(MachO::DataRegionType::DICE_KIND_JUMP_TABLE32); 245 return; 246 case MCDR_DataRegionEnd: 247 emitDataRegionEnd(); 248 return; 249 } 250 } 251 252 void MCMachOStreamer::emitVersionMin(MCVersionMinType Kind, unsigned Major, 253 unsigned Minor, unsigned Update, 254 VersionTuple SDKVersion) { 255 getWriter().setVersionMin(Kind, Major, Minor, Update, SDKVersion); 256 } 257 258 void MCMachOStreamer::emitBuildVersion(unsigned Platform, unsigned Major, 259 unsigned Minor, unsigned Update, 260 VersionTuple SDKVersion) { 261 getWriter().setBuildVersion((MachO::PlatformType)Platform, Major, Minor, 262 Update, SDKVersion); 263 } 264 265 void MCMachOStreamer::emitDarwinTargetVariantBuildVersion( 266 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, 267 VersionTuple SDKVersion) { 268 getWriter().setTargetVariantBuildVersion((MachO::PlatformType)Platform, Major, 269 Minor, Update, SDKVersion); 270 } 271 272 void MCMachOStreamer::emitThumbFunc(MCSymbol *Symbol) { 273 // Remember that the function is a thumb function. Fixup and relocation 274 // values will need adjusted. 275 getAssembler().setIsThumbFunc(Symbol); 276 cast<MCSymbolMachO>(Symbol)->setThumbFunc(); 277 } 278 279 bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym, 280 MCSymbolAttr Attribute) { 281 MCSymbolMachO *Symbol = cast<MCSymbolMachO>(Sym); 282 283 // Indirect symbols are handled differently, to match how 'as' handles 284 // them. This makes writing matching .o files easier. 285 if (Attribute == MCSA_IndirectSymbol) { 286 // Note that we intentionally cannot use the symbol data here; this is 287 // important for matching the string table that 'as' generates. 288 getWriter().getIndirectSymbols().push_back( 289 {Symbol, getCurrentSectionOnly()}); 290 return true; 291 } 292 293 // Adding a symbol attribute always introduces the symbol, note that an 294 // important side effect of calling registerSymbol here is to register 295 // the symbol with the assembler. 296 getAssembler().registerSymbol(*Symbol); 297 298 // The implementation of symbol attributes is designed to match 'as', but it 299 // leaves much to desired. It doesn't really make sense to arbitrarily add and 300 // remove flags, but 'as' allows this (in particular, see .desc). 301 // 302 // In the future it might be worth trying to make these operations more well 303 // defined. 304 switch (Attribute) { 305 case MCSA_Invalid: 306 case MCSA_ELF_TypeFunction: 307 case MCSA_ELF_TypeIndFunction: 308 case MCSA_ELF_TypeObject: 309 case MCSA_ELF_TypeTLS: 310 case MCSA_ELF_TypeCommon: 311 case MCSA_ELF_TypeNoType: 312 case MCSA_ELF_TypeGnuUniqueObject: 313 case MCSA_Extern: 314 case MCSA_Hidden: 315 case MCSA_IndirectSymbol: 316 case MCSA_Internal: 317 case MCSA_Protected: 318 case MCSA_Weak: 319 case MCSA_Local: 320 case MCSA_LGlobal: 321 case MCSA_Exported: 322 case MCSA_Memtag: 323 case MCSA_WeakAntiDep: 324 return false; 325 326 case MCSA_Global: 327 Symbol->setExternal(true); 328 // This effectively clears the undefined lazy bit, in Darwin 'as', although 329 // it isn't very consistent because it implements this as part of symbol 330 // lookup. 331 // 332 // FIXME: Cleanup this code, these bits should be emitted based on semantic 333 // properties, not on the order of definition, etc. 334 Symbol->setReferenceTypeUndefinedLazy(false); 335 break; 336 337 case MCSA_LazyReference: 338 // FIXME: This requires -dynamic. 339 Symbol->setNoDeadStrip(); 340 if (Symbol->isUndefined()) 341 Symbol->setReferenceTypeUndefinedLazy(true); 342 break; 343 344 // Since .reference sets the no dead strip bit, it is equivalent to 345 // .no_dead_strip in practice. 346 case MCSA_Reference: 347 case MCSA_NoDeadStrip: 348 Symbol->setNoDeadStrip(); 349 break; 350 351 case MCSA_SymbolResolver: 352 Symbol->setSymbolResolver(); 353 break; 354 355 case MCSA_AltEntry: 356 Symbol->setAltEntry(); 357 break; 358 359 case MCSA_PrivateExtern: 360 Symbol->setExternal(true); 361 Symbol->setPrivateExtern(true); 362 break; 363 364 case MCSA_WeakReference: 365 // FIXME: This requires -dynamic. 366 if (Symbol->isUndefined()) 367 Symbol->setWeakReference(); 368 break; 369 370 case MCSA_WeakDefinition: 371 // FIXME: 'as' enforces that this is defined and global. The manual claims 372 // it has to be in a coalesced section, but this isn't enforced. 373 Symbol->setWeakDefinition(); 374 break; 375 376 case MCSA_WeakDefAutoPrivate: 377 Symbol->setWeakDefinition(); 378 Symbol->setWeakReference(); 379 break; 380 381 case MCSA_Cold: 382 Symbol->setCold(); 383 break; 384 } 385 386 return true; 387 } 388 389 void MCMachOStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 390 // Encode the 'desc' value into the lowest implementation defined bits. 391 getAssembler().registerSymbol(*Symbol); 392 cast<MCSymbolMachO>(Symbol)->setDesc(DescValue); 393 } 394 395 void MCMachOStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 396 Align ByteAlignment) { 397 // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. 398 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 399 400 getAssembler().registerSymbol(*Symbol); 401 Symbol->setExternal(true); 402 Symbol->setCommon(Size, ByteAlignment); 403 } 404 405 void MCMachOStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 406 Align ByteAlignment) { 407 // '.lcomm' is equivalent to '.zerofill'. 408 return emitZerofill(getContext().getObjectFileInfo()->getDataBSSSection(), 409 Symbol, Size, ByteAlignment); 410 } 411 412 void MCMachOStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol, 413 uint64_t Size, Align ByteAlignment, 414 SMLoc Loc) { 415 // On darwin all virtual sections have zerofill type. Disallow the usage of 416 // .zerofill in non-virtual functions. If something similar is needed, use 417 // .space or .zero. 418 if (!Section->isVirtualSection()) { 419 getContext().reportError( 420 Loc, "The usage of .zerofill is restricted to sections of " 421 "ZEROFILL type. Use .zero or .space instead."); 422 return; // Early returning here shouldn't harm. EmitZeros should work on any 423 // section. 424 } 425 426 pushSection(); 427 switchSection(Section); 428 429 // The symbol may not be present, which only creates the section. 430 if (Symbol) { 431 emitValueToAlignment(ByteAlignment, 0, 1, 0); 432 emitLabel(Symbol); 433 emitZeros(Size); 434 } 435 popSection(); 436 } 437 438 // This should always be called with the thread local bss section. Like the 439 // .zerofill directive this doesn't actually switch sections on us. 440 void MCMachOStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, 441 uint64_t Size, Align ByteAlignment) { 442 emitZerofill(Section, Symbol, Size, ByteAlignment); 443 } 444 445 void MCMachOStreamer::emitInstToData(const MCInst &Inst, 446 const MCSubtargetInfo &STI) { 447 MCDataFragment *DF = getOrCreateDataFragment(); 448 449 SmallVector<MCFixup, 4> Fixups; 450 SmallString<256> Code; 451 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); 452 453 // Add the fixups and data. 454 for (MCFixup &Fixup : Fixups) { 455 Fixup.setOffset(Fixup.getOffset() + DF->getContents().size()); 456 DF->getFixups().push_back(Fixup); 457 } 458 DF->setHasInstructions(STI); 459 DF->getContents().append(Code.begin(), Code.end()); 460 } 461 462 void MCMachOStreamer::finishImpl() { 463 emitFrames(&getAssembler().getBackend()); 464 465 // We have to set the fragment atom associations so we can relax properly for 466 // Mach-O. 467 468 // First, scan the symbol table to build a lookup table from fragments to 469 // defining symbols. 470 DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap; 471 for (const MCSymbol &Symbol : getAssembler().symbols()) { 472 auto &Sym = cast<MCSymbolMachO>(Symbol); 473 if (Sym.isSymbolLinkerVisible() && Sym.isInSection() && !Sym.isVariable() && 474 !Sym.isAltEntry()) { 475 // An atom defining symbol should never be internal to a fragment. 476 assert(Symbol.getOffset() == 0 && 477 "Invalid offset in atom defining symbol!"); 478 DefiningSymbolMap[Symbol.getFragment()] = &Symbol; 479 } 480 } 481 482 // Set the fragment atom associations by tracking the last seen atom defining 483 // symbol. 484 for (MCSection &Sec : getAssembler()) { 485 cast<MCSectionMachO>(Sec).allocAtoms(); 486 const MCSymbol *CurrentAtom = nullptr; 487 size_t I = 0; 488 for (MCFragment &Frag : Sec) { 489 if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag)) 490 CurrentAtom = Symbol; 491 cast<MCSectionMachO>(Sec).setAtom(I++, CurrentAtom); 492 } 493 } 494 495 finalizeCGProfile(); 496 497 createAddrSigSection(); 498 this->MCObjectStreamer::finishImpl(); 499 } 500 501 void MCMachOStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) { 502 const MCSymbol *S = &SRE->getSymbol(); 503 if (getAssembler().registerSymbol(*S)) 504 S->setExternal(true); 505 } 506 507 void MCMachOStreamer::finalizeCGProfile() { 508 MCAssembler &Asm = getAssembler(); 509 MCObjectWriter &W = getWriter(); 510 if (W.getCGProfile().empty()) 511 return; 512 for (auto &E : W.getCGProfile()) { 513 finalizeCGProfileEntry(E.From); 514 finalizeCGProfileEntry(E.To); 515 } 516 // We can't write the section out until symbol indices are finalized which 517 // doesn't happen until after section layout. We need to create the section 518 // and set its size now so that it's accounted for in layout. 519 MCSection *CGProfileSection = Asm.getContext().getMachOSection( 520 "__LLVM", "__cg_profile", 0, SectionKind::getMetadata()); 521 changeSection(CGProfileSection); 522 // For each entry, reserve space for 2 32-bit indices and a 64-bit count. 523 size_t SectionBytes = 524 W.getCGProfile().size() * (2 * sizeof(uint32_t) + sizeof(uint64_t)); 525 cast<MCDataFragment>(*CGProfileSection->begin()) 526 .getContents() 527 .resize(SectionBytes); 528 } 529 530 MCStreamer *llvm::createMachOStreamer(MCContext &Context, 531 std::unique_ptr<MCAsmBackend> &&MAB, 532 std::unique_ptr<MCObjectWriter> &&OW, 533 std::unique_ptr<MCCodeEmitter> &&CE, 534 bool DWARFMustBeAtTheEnd, 535 bool LabelSections) { 536 MCMachOStreamer *S = new MCMachOStreamer( 537 Context, std::move(MAB), std::move(OW), std::move(CE), LabelSections); 538 const Triple &Target = Context.getTargetTriple(); 539 S->emitVersionForTarget( 540 Target, Context.getObjectFileInfo()->getSDKVersion(), 541 Context.getObjectFileInfo()->getDarwinTargetVariantTriple(), 542 Context.getObjectFileInfo()->getDarwinTargetVariantSDKVersion()); 543 return S; 544 } 545 546 // The AddrSig section uses a series of relocations to refer to the symbols that 547 // should be considered address-significant. The only interesting content of 548 // these relocations is their symbol; the type, length etc will be ignored by 549 // the linker. The reason we are not referring to the symbol indices directly is 550 // that those indices will be invalidated by tools that update the symbol table. 551 // Symbol relocations OTOH will have their indices updated by e.g. llvm-strip. 552 void MCMachOStreamer::createAddrSigSection() { 553 MCAssembler &Asm = getAssembler(); 554 MCObjectWriter &writer = Asm.getWriter(); 555 if (!writer.getEmitAddrsigSection()) 556 return; 557 // Create the AddrSig section and first data fragment here as its layout needs 558 // to be computed immediately after in order for it to be exported correctly. 559 MCSection *AddrSigSection = 560 Asm.getContext().getObjectFileInfo()->getAddrSigSection(); 561 changeSection(AddrSigSection); 562 auto *Frag = cast<MCDataFragment>(AddrSigSection->curFragList()->Head); 563 // We will generate a series of pointer-sized symbol relocations at offset 564 // 0x0. Set the section size to be large enough to contain a single pointer 565 // (instead of emitting a zero-sized section) so these relocations are 566 // technically valid, even though we don't expect these relocations to 567 // actually be applied by the linker. 568 Frag->getContents().resize(8); 569 } 570