llvm.org GIT mirror llvm / 5512415
Add r224985 back with two fixes. One is that AArch64 has additional restrictions on when local relocations can be used. We have to take those into consideration when deciding to put a L symbol in the symbol table or not. The other is that ld64 requires the relocations to cstring to use linker visible symbols on AArch64. Thanks to Michael Zolotukhin for testing this! Remove doesSectionRequireSymbols. In an assembly expression like bar: .long L0 + 1 the intended semantics is that bar will contain a pointer one byte past L0. In sections that are merged by content (strings, 4 byte constants, etc), a single position in the section doesn't give the linker enough information. For example, it would not be able to tell a relocation must point to the end of a string, since that would look just like the start of the next. The solution used in ELF to use relocation with symbols if there is a non-zero addend. In MachO before this patch we would just keep all symbols in some sections. This would miss some cases (only cstrings on x86_64 were implemented) and was inefficient since most relocations have an addend of 0 and can be represented without the symbol. This patch implements the non-zero addend logic for MachO too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225644 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 5 years ago
19 changed file(s) with 320 addition(s) and 250 deletion(s). Raw diff Collapse all Expand all
5959 /// hasDataInCodeSupport - Check whether this target implements data-in-code
6060 /// markers. If not, data region directives will be ignored.
6161 bool hasDataInCodeSupport() const { return HasDataInCodeSupport; }
62
63 /// doesSectionRequireSymbols - Check whether the given section requires that
64 /// all symbols (even temporaries) have symbol table entries.
65 virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
66 return false;
67 }
6862
6963 /// @name Target Fixup Interfaces
7064 /// @{
1010 #define LLVM_MC_MCASSEMBLER_H
1111
1212 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/DenseSet.h"
1314 #include "llvm/ADT/PointerIntPair.h"
1415 #include "llvm/ADT/SmallPtrSet.h"
1516 #include "llvm/ADT/SmallString.h"
879880 iplist Sections;
880881
881882 iplist Symbols;
883
884 DenseSet LocalsUsedInReloc;
882885
883886 /// The map of sections to their associated assembler backend data.
884887 //
979982 MCFragment &F, const MCFixup &Fixup);
980983
981984 public:
985 void addLocalUsedInReloc(const MCSymbol &Sym);
986 bool isLocalUsedInReloc(const MCSymbol &Sym) const;
987
982988 /// Compute the effective fragment size assuming it is laid out at the given
983989 /// \p SectionAddress and \p FragmentOffset.
984990 uint64_t computeFragmentSize(const MCAsmLayout &Layout,
6767 /// @name API
6868 /// @{
6969
70 virtual void RecordRelocation(MachObjectWriter *Writer,
71 const MCAssembler &Asm,
70 virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
7271 const MCAsmLayout &Layout,
7372 const MCFragment *Fragment,
74 const MCFixup &Fixup,
75 MCValue Target,
73 const MCFixup &Fixup, MCValue Target,
7674 uint64_t &FixedValue) = 0;
7775
7876 /// @}
9694 /// @name Relocation Data
9795 /// @{
9896
99 llvm::DenseMap
100 std::vector > Relocations;
97 struct RelAndSymbol {
98 const MCSymbolData *Sym;
99 MachO::any_relocation_info MRE;
100 RelAndSymbol(const MCSymbolData *Sym, const MachO::any_relocation_info &MRE)
101 : Sym(Sym), MRE(MRE) {}
102 };
103
104 llvm::DenseMap> Relocations;
101105 llvm::DenseMap IndirectSymBase;
102106
103107 /// @}
212216 // - Input errors, where something cannot be correctly encoded. 'as' allows
213217 // these through in many cases.
214218
215 void addRelocation(const MCSectionData *SD,
219 // Add a relocation to be output in the object file. At the time this is
220 // called, the symbol indexes are not know, so if the relocation refers
221 // to a symbol it should be passed as \p RelSymbol so that it can be updated
222 // afterwards. If the relocation doesn't refer to a symbol, nullptr should be
223 // used.
224 void addRelocation(const MCSymbolData *RelSymbol, const MCSectionData *SD,
216225 MachO::any_relocation_info &MRE) {
217 Relocations[SD].push_back(MRE);
226 RelAndSymbol P(RelSymbol, MRE);
227 Relocations[SD].push_back(P);
218228 }
219229
220230 void RecordScatteredRelocation(const MCAssembler &Asm,
230240 const MCFixup &Fixup, MCValue Target,
231241 uint64_t &FixedValue);
232242
233 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
243 void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
234244 const MCFragment *Fragment, const MCFixup &Fixup,
235245 MCValue Target, bool &IsPCRel,
236246 uint64_t &FixedValue) override;
7575 /// post layout binding. The implementation is responsible for storing
7676 /// information about the relocation so that it can be emitted during
7777 /// WriteObject().
78 virtual void RecordRelocation(const MCAssembler &Asm,
79 const MCAsmLayout &Layout,
78 virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
8079 const MCFragment *Fragment,
8180 const MCFixup &Fixup, MCValue Target,
82 bool &IsPCRel,
83 uint64_t &FixedValue) = 0;
81 bool &IsPCRel, uint64_t &FixedValue) = 0;
8482
8583 /// \brief Check whether the difference (A - B) between two symbol
8684 /// references is fully resolved.
218218 const MCSymbolData *SD, uint64_t C,
219219 unsigned Type) const;
220220
221 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
221 void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
222222 const MCFragment *Fragment, const MCFixup &Fixup,
223223 MCValue Target, bool &IsPCRel,
224224 uint64_t &FixedValue) override;
788788 return nullptr;
789789 }
790790
791 void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
791 void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
792792 const MCAsmLayout &Layout,
793793 const MCFragment *Fragment,
794 const MCFixup &Fixup,
795 MCValue Target,
796 bool &IsPCRel,
797 uint64_t &FixedValue) {
794 const MCFixup &Fixup, MCValue Target,
795 bool &IsPCRel, uint64_t &FixedValue) {
798796 const MCSectionData *FixupSection = Fragment->getParent();
799797 uint64_t C = Target.getConstant();
800798 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
2626 // contain.
2727 // Sections holding 2 byte strings require symbols in order to be atomized.
2828 // There is no dedicated section for 4 byte strings.
29 if (SMO.getKind().isMergeable1ByteCString())
30 return false;
31
32 if (SMO.getSegmentName() == "__TEXT" &&
33 SMO.getSectionName() == "__objc_classname" &&
34 SMO.getType() == MachO::S_CSTRING_LITERALS)
35 return false;
36
37 if (SMO.getSegmentName() == "__TEXT" &&
38 SMO.getSectionName() == "__objc_methname" &&
39 SMO.getType() == MachO::S_CSTRING_LITERALS)
40 return false;
41
42 if (SMO.getSegmentName() == "__TEXT" &&
43 SMO.getSectionName() == "__objc_methtype" &&
44 SMO.getType() == MachO::S_CSTRING_LITERALS)
29 if (SMO.getType() == MachO::S_CSTRING_LITERALS)
4530 return false;
4631
4732 if (SMO.getSegmentName() == "__DATA" && SMO.getSectionName() == "__cfstring")
424424 return true;
425425 }
426426
427 void MCAssembler::addLocalUsedInReloc(const MCSymbol &Sym) {
428 assert(Sym.isTemporary());
429 LocalsUsedInReloc.insert(&Sym);
430 }
431
432 bool MCAssembler::isLocalUsedInReloc(const MCSymbol &Sym) const {
433 assert(Sym.isTemporary());
434 return LocalsUsedInReloc.count(&Sym);
435 }
436
427437 bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
428438 // Non-temporary labels should always be visible to the linker.
429439 if (!Symbol.isTemporary())
433443 if (!Symbol.isInSection())
434444 return false;
435445
436 // Otherwise, check if the section requires symbols even for temporary labels.
437 return getBackend().doesSectionRequireSymbols(Symbol.getSection());
446 if (isLocalUsedInReloc(Symbol))
447 return true;
448
449 return false;
438450 }
439451
440452 const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
447447 assert(OS.tell() - Start == Size);
448448 }
449449
450
451 void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
450 void MachObjectWriter::RecordRelocation(MCAssembler &Asm,
452451 const MCAsmLayout &Layout,
453452 const MCFragment *Fragment,
454 const MCFixup &Fixup,
455 MCValue Target,
456 bool &IsPCRel,
457 uint64_t &FixedValue) {
453 const MCFixup &Fixup, MCValue Target,
454 bool &IsPCRel, uint64_t &FixedValue) {
458455 TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,
459456 Target, FixedValue);
460457 }
615612 ExternalSymbolData[i].SymbolData->setIndex(Index++);
616613 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
617614 UndefinedSymbolData[i].SymbolData->setIndex(Index++);
615
616 for (const MCSectionData &SD : Asm) {
617 std::vector &Relocs = Relocations[&SD];
618 for (RelAndSymbol &Rel : Relocs) {
619 if (!Rel.Sym)
620 continue;
621
622 // Set the Index and the IsExtern bit.
623 unsigned Index = Rel.Sym->getIndex();
624 assert(isInt<24>(Index));
625 if (IsLittleEndian)
626 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (-1 << 24)) | Index | (1 << 27);
627 else
628 Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
629 }
630 }
618631 }
619632
620633 void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
661674 // Mark symbol difference expressions in variables (from .set or = directives)
662675 // as absolute.
663676 markAbsoluteVariableSymbols(Asm, Layout);
664
665 // Compute symbol table information and bind symbol indices.
666 ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData,
667 UndefinedSymbolData);
668677 }
669678
670679 bool MachObjectWriter::
748757
749758 void MachObjectWriter::WriteObject(MCAssembler &Asm,
750759 const MCAsmLayout &Layout) {
760 // Compute symbol table information and bind symbol indices.
761 ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData,
762 UndefinedSymbolData);
763
751764 unsigned NumSections = Asm.size();
752765 const MCAssembler::VersionMinInfoType &VersionInfo =
753766 Layout.getAssembler().getVersionMinInfo();
838851 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
839852 for (MCAssembler::const_iterator it = Asm.begin(),
840853 ie = Asm.end(); it != ie; ++it) {
841 std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
854 std::vector<RelAndSymbol> &Relocs = Relocations[it];
842855 unsigned NumRelocs = Relocs.size();
843856 uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
844857 WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
932945 ie = Asm.end(); it != ie; ++it) {
933946 // Write the section relocation entries, in reverse order to match 'as'
934947 // (approximately, the exact algorithm is more complicated than this).
935 std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
948 std::vector<RelAndSymbol> &Relocs = Relocations[it];
936949 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
937 Write32(Relocs[e - i - 1].r_word0);
938 Write32(Relocs[e - i - 1].r_word1);
950 Write32(Relocs[e - i - 1].MRE.r_word0);
951 Write32(Relocs[e - i - 1].MRE.r_word1);
939952 }
940953 }
941954
174174 const MCFragment &FB, bool InSet,
175175 bool IsPCRel) const override;
176176
177 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
177 void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
178178 const MCFragment *Fragment, const MCFixup &Fixup,
179179 MCValue Target, bool &IsPCRel,
180180 uint64_t &FixedValue) override;
660660 InSet, IsPCRel);
661661 }
662662
663 void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
664 const MCAsmLayout &Layout,
665 const MCFragment *Fragment,
666 const MCFixup &Fixup,
667 MCValue Target,
668 bool &IsPCRel,
669 uint64_t &FixedValue) {
663 void WinCOFFObjectWriter::RecordRelocation(
664 MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment,
665 const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) {
670666 assert(Target.getSymA() && "Relocation must reference a symbol!");
671667
672668 const MCSymbol &Symbol = Target.getSymA()->getSymbol();
316316 MachO::CPU_SUBTYPE_ARM64_ALL);
317317 }
318318
319 bool doesSectionRequireSymbols(const MCSection &Section) const override {
320 // Any section for which the linker breaks things into atoms needs to
321 // preserve symbols, including assembler local symbols, to identify
322 // those atoms. These sections are:
323 // Sections of type:
324 //
325 // S_CSTRING_LITERALS (e.g. __cstring)
326 // S_LITERAL_POINTERS (e.g. objc selector pointers)
327 // S_16BYTE_LITERALS, S_8BYTE_LITERALS, S_4BYTE_LITERALS
328 //
329 // Sections named:
330 //
331 // __TEXT,__eh_frame
332 // __TEXT,__ustring
333 // __DATA,__cfstring
334 // __DATA,__objc_classrefs
335 // __DATA,__objc_catlist
336 //
337 // FIXME: It would be better if the compiler used actual linker local
338 // symbols for each of these sections rather than preserving what
339 // are ostensibly assembler local symbols.
340 const MCSectionMachO &SMO = static_cast(Section);
341 return (SMO.getType() == MachO::S_CSTRING_LITERALS ||
342 SMO.getType() == MachO::S_4BYTE_LITERALS ||
343 SMO.getType() == MachO::S_8BYTE_LITERALS ||
344 SMO.getType() == MachO::S_16BYTE_LITERALS ||
345 SMO.getType() == MachO::S_LITERAL_POINTERS ||
346 (SMO.getSegmentName() == "__TEXT" &&
347 (SMO.getSectionName() == "__eh_frame" ||
348 SMO.getSectionName() == "__ustring")) ||
349 (SMO.getSegmentName() == "__DATA" &&
350 (SMO.getSectionName() == "__cfstring" ||
351 SMO.getSectionName() == "__objc_classrefs" ||
352 SMO.getSectionName() == "__objc_catlist")));
353 }
354
355319 /// \brief Generate the compact unwind encoding from the CFI directives.
356320 uint32_t generateCompactUnwindEncoding(
357321 ArrayRef Instrs) const override {
99 #include "MCTargetDesc/AArch64FixupKinds.h"
1010 #include "MCTargetDesc/AArch64MCTargetDesc.h"
1111 #include "llvm/ADT/Twine.h"
12 #include "llvm/MC/MCAsmInfo.h"
1213 #include "llvm/MC/MCAsmLayout.h"
1314 #include "llvm/MC/MCAssembler.h"
1415 #include "llvm/MC/MCContext.h"
3233 : MCMachObjectTargetWriter(true /* is64Bit */, CPUType, CPUSubtype,
3334 /*UseAggressiveSymbolFolding=*/true) {}
3435
35 void RecordRelocation(MachObjectWriter *Writer, const MCAssembler &Asm,
36 void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
3637 const MCAsmLayout &Layout, const MCFragment *Fragment,
3738 const MCFixup &Fixup, MCValue Target,
3839 uint64_t &FixedValue) override;
111112 }
112113 }
113114
115 static bool canUseLocalRelocation(const MCSectionMachO &Section,
116 const MCSymbol &Symbol, unsigned Log2Size) {
117 // Debug info sections can use local relocations.
118 if (Section.hasAttribute(MachO::S_ATTR_DEBUG))
119 return true;
120
121 // Otherwise, only pointer sized relocations are supported.
122 if (Log2Size != 3)
123 return false;
124
125 // But only if they don't point to a cstring.
126 if (!Symbol.isInSection())
127 return true;
128 const MCSectionMachO &RefSec = cast(Symbol.getSection());
129 return RefSec.getType() != MachO::S_CSTRING_LITERALS;
130 }
131
114132 void AArch64MachObjectWriter::RecordRelocation(
115 MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout,
133 MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout,
116134 const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target,
117135 uint64_t &FixedValue) {
118136 unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
122140 unsigned Log2Size = 0;
123141 int64_t Value = 0;
124142 unsigned Index = 0;
125 unsigned IsExtern = 0;
126143 unsigned Type = 0;
127144 unsigned Kind = Fixup.getKind();
145 const MCSymbolData *RelSymbol = nullptr;
128146
129147 FixupOffset += Fixup.getOffset();
130148
170188 // FIXME: Should this always be extern?
171189 // SymbolNum of 0 indicates the absolute section.
172190 Type = MachO::ARM64_RELOC_UNSIGNED;
173 Index = 0;
174191
175192 if (IsPCRel) {
176 IsExtern = 1;
177193 Asm.getContext().FatalError(Fixup.getLoc(),
178194 "PC relative absolute relocation!");
179195
197213 Layout.getSymbolOffset(&B_SD) ==
198214 Layout.getFragmentOffset(Fragment) + Fixup.getOffset()) {
199215 // SymB is the PC, so use a PC-rel pointer-to-GOT relocation.
200 Index = A_Base->getIndex();
201 IsExtern = 1;
202216 Type = MachO::ARM64_RELOC_POINTER_TO_GOT;
203217 IsPCRel = 1;
204218 MachO::any_relocation_info MRE;
205219 MRE.r_word0 = FixupOffset;
206 MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) |
207 (IsExtern << 27) | (Type << 28));
208 Writer->addRelocation(Fragment->getParent(), MRE);
220 MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
221 Writer->addRelocation(A_Base, Fragment->getParent(), MRE);
209222 return;
210223 } else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None ||
211224 Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None)
251264 ? 0
252265 : Writer->getSymbolAddress(B_Base, Layout));
253266
254 Index = A_Base->getIndex();
255 IsExtern = 1;
256267 Type = MachO::ARM64_RELOC_UNSIGNED;
257268
258269 MachO::any_relocation_info MRE;
259270 MRE.r_word0 = FixupOffset;
260 MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) |
261 (IsExtern << 27) | (Type << 28));
262 Writer->addRelocation(Fragment->getParent(), MRE);
263
264 Index = B_Base->getIndex();
265 IsExtern = 1;
271 MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
272 Writer->addRelocation(A_Base, Fragment->getParent(), MRE);
273
274 RelSymbol = B_Base;
266275 Type = MachO::ARM64_RELOC_SUBTRACTOR;
267276 } else { // A + constant
268277 const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
278 const MCSectionMachO &Section = static_cast(
279 Fragment->getParent()->getSection());
280
281 bool CanUseLocalRelocation =
282 canUseLocalRelocation(Section, *Symbol, Log2Size);
283 if (Symbol->isTemporary() && (Value || !CanUseLocalRelocation)) {
284 const MCSection &Sec = Symbol->getSection();
285 if (!Asm.getContext().getAsmInfo()->isSectionAtomizableBySymbols(Sec))
286 Asm.addLocalUsedInReloc(*Symbol);
287 }
288
269289 const MCSymbolData &SD = Asm.getSymbolData(*Symbol);
270290 const MCSymbolData *Base = Asm.getAtom(&SD);
271 const MCSectionMachO &Section = static_cast(
272 Fragment->getParent()->getSection());
273291
274292 // If the symbol is a variable and we weren't able to get a Base for it
275293 // (i.e., it's not in the symbol table associated with a section) resolve
309327 // sections, and for pointer-sized relocations (.quad), we allow section
310328 // relocations. It's code sections that run into trouble.
311329 if (Base) {
312 Index = Base->getIndex();
313 IsExtern = 1;
330 RelSymbol = Base;
314331
315332 // Add the local offset, if needed.
316333 if (Base != &SD)
317334 Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base);
318335 } else if (Symbol->isInSection()) {
319 // Pointer-sized relocations can use a local relocation. Otherwise,
320 // we have to be in a debug info section.
321 if (!Section.hasAttribute(MachO::S_ATTR_DEBUG) && Log2Size != 3)
336 if (!CanUseLocalRelocation)
322337 Asm.getContext().FatalError(
323338 Fixup.getLoc(),
324339 "unsupported relocation of local symbol '" + Symbol->getName() +
328343 const MCSectionData &SymSD =
329344 Asm.getSectionData(SD.getSymbol().getSection());
330345 Index = SymSD.getOrdinal() + 1;
331 IsExtern = 0;
332346 Value += Writer->getSymbolAddress(&SD, Layout);
333347
334348 if (IsPCRel)
361375
362376 MachO::any_relocation_info MRE;
363377 MRE.r_word0 = FixupOffset;
364 MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) |
365 (IsExtern << 27) | (Type << 28));
366 Writer->addRelocation(Fragment->getParent(), MRE);
378 MRE.r_word1 =
379 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
380 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
367381
368382 // Now set up the Addend relocation.
369383 Type = MachO::ARM64_RELOC_ADDEND;
370384 Index = Value;
385 RelSymbol = nullptr;
371386 IsPCRel = 0;
372387 Log2Size = 2;
373 IsExtern = 0;
374388
375389 // Put zero into the instruction itself. The addend is in the relocation.
376390 Value = 0;
382396 // struct relocation_info (8 bytes)
383397 MachO::any_relocation_info MRE;
384398 MRE.r_word0 = FixupOffset;
385 MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) |
386 (IsExtern << 27) | (Type << 28));
387 Writer->addRelocation(Fragment->getParent(), MRE);
399 MRE.r_word1 =
400 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
401 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
388402 }
389403
390404 MCObjectWriter *llvm::createAArch64MachObjectWriter(raw_ostream &OS,
5353 : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,
5454 /*UseAggressiveSymbolFolding=*/true) {}
5555
56 void RecordRelocation(MachObjectWriter *Writer,
57 const MCAssembler &Asm, const MCAsmLayout &Layout,
58 const MCFragment *Fragment, const MCFixup &Fixup,
59 MCValue Target, uint64_t &FixedValue) override;
56 void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
57 const MCAsmLayout &Layout, const MCFragment *Fragment,
58 const MCFixup &Fixup, MCValue Target,
59 uint64_t &FixedValue) override;
6060 };
6161 }
6262
231231 (IsPCRel << 30) |
232232 MachO::R_SCATTERED);
233233 MRE.r_word1 = Value2;
234 Writer->addRelocation(Fragment->getParent(), MRE);
234 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
235235 }
236236
237237 MachO::any_relocation_info MRE;
242242 (IsPCRel << 30) |
243243 MachO::R_SCATTERED);
244244 MRE.r_word1 = Value;
245 Writer->addRelocation(Fragment->getParent(), MRE);
245 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
246246 }
247247
248248 void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer,
296296 (IsPCRel << 30) |
297297 MachO::R_SCATTERED);
298298 MRE.r_word1 = Value2;
299 Writer->addRelocation(Fragment->getParent(), MRE);
299 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
300300 }
301301
302302 MachO::any_relocation_info MRE;
306306 (IsPCRel << 30) |
307307 MachO::R_SCATTERED);
308308 MRE.r_word1 = Value;
309 Writer->addRelocation(Fragment->getParent(), MRE);
309 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
310310 }
311311
312312 bool ARMMachObjectWriter::requiresExternRelocation(MachObjectWriter *Writer,
350350 }
351351
352352 void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,
353 const MCAssembler &Asm,
353 MCAssembler &Asm,
354354 const MCAsmLayout &Layout,
355355 const MCFragment *Fragment,
356 const MCFixup &Fixup,
357 MCValue Target,
356 const MCFixup &Fixup, MCValue Target,
358357 uint64_t &FixedValue) {
359358 unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
360359 unsigned Log2Size;
400399 // See .
401400 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
402401 unsigned Index = 0;
403 unsigned IsExtern = 0;
404402 unsigned Type = 0;
403 const MCSymbolData *RelSymbol = nullptr;
405404
406405 if (Target.isAbsolute()) { // constant
407406 // FIXME!
421420 // Check whether we need an external or internal relocation.
422421 if (requiresExternRelocation(Writer, Asm, *Fragment, RelocType, SD,
423422 FixedValue)) {
424 IsExtern = 1;
425 Index = SD->getIndex();
423 RelSymbol = SD;
426424
427425 // For external relocations, make sure to offset the fixup value to
428426 // compensate for the addend of the symbol address, if it was
446444 // struct relocation_info (8 bytes)
447445 MachO::any_relocation_info MRE;
448446 MRE.r_word0 = FixupOffset;
449 MRE.r_word1 = ((Index << 0) |
450 (IsPCRel << 24) |
451 (Log2Size << 25) |
452 (IsExtern << 27) |
453 (Type << 28));
447 MRE.r_word1 =
448 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
454449
455450 // Even when it's not a scattered relocation, movw/movt always uses
456451 // a PAIR relocation.
475470 (Log2Size << 25) |
476471 (MachO::ARM_RELOC_PAIR << 28));
477472
478 Writer->addRelocation(Fragment->getParent(), MREPair);
479 }
480
481 Writer->addRelocation(Fragment->getParent(), MRE);
473 Writer->addRelocation(nullptr, Fragment->getParent(), MREPair);
474 }
475
476 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
482477 }
483478
484479 MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS,
4040 : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,
4141 /*UseAggressiveSymbolFolding=*/Is64Bit) {}
4242
43 void RecordRelocation(MachObjectWriter *Writer, const MCAssembler &Asm,
43 void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
4444 const MCAsmLayout &Layout, const MCFragment *Fragment,
4545 const MCFixup &Fixup, MCValue Target,
4646 uint64_t &FixedValue) override {
281281 MachO::any_relocation_info MRE;
282282 makeScatteredRelocationInfo(MRE, other_half, MachO::GENERIC_RELOC_PAIR,
283283 Log2Size, IsPCRel, Value2);
284 Writer->addRelocation(Fragment->getParent(), MRE);
284 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
285285 } else {
286286 // If the offset is more than 24-bits, it won't fit in a scattered
287287 // relocation offset field, so we fall back to using a non-scattered
295295 }
296296 MachO::any_relocation_info MRE;
297297 makeScatteredRelocationInfo(MRE, FixupOffset, Type, Log2Size, IsPCRel, Value);
298 Writer->addRelocation(Fragment->getParent(), MRE);
298 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
299299 return true;
300300 }
301301
330330 // See .
331331 const uint32_t FixupOffset = getFixupOffset(Layout, Fragment, Fixup);
332332 unsigned Index = 0;
333 unsigned IsExtern = 0;
334333 unsigned Type = RelocType;
335334
335 const MCSymbolData *RelSymbol = nullptr;
336336 if (Target.isAbsolute()) { // constant
337337 // SymbolNum of 0 indicates the absolute section.
338338 //
354354
355355 // Check whether we need an external or internal relocation.
356356 if (Writer->doesSymbolRequireExternRelocation(SD)) {
357 IsExtern = 1;
358 Index = SD->getIndex();
357 RelSymbol = SD;
359358 // For external relocations, make sure to offset the fixup value to
360359 // compensate for the addend of the symbol address, if it was
361360 // undefined. This occurs with weak definitions, for example.
374373
375374 // struct relocation_info (8 bytes)
376375 MachO::any_relocation_info MRE;
377 makeRelocationInfo(MRE, FixupOffset, Index, IsPCRel, Log2Size, IsExtern,
378 Type);
379 Writer->addRelocation(Fragment->getParent(), MRE);
376 makeRelocationInfo(MRE, FixupOffset, Index, IsPCRel, Log2Size, false, Type);
377 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
380378 }
381379
382380 MCObjectWriter *llvm::createPPCMachObjectWriter(raw_ostream &OS, bool Is64Bit,
2828 const MCAsmLayout &Layout) override {
2929 //XXX: Implement if necessary.
3030 }
31 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
31 void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
3232 const MCFragment *Fragment, const MCFixup &Fixup,
3333 MCValue Target, bool &IsPCRel,
3434 uint64_t &FixedValue) override {
776776 MachO::CPU_TYPE_X86_64, Subtype);
777777 }
778778
779 bool doesSectionRequireSymbols(const MCSection &Section) const override {
780 // Temporary labels in the string literals sections require symbols. The
781 // issue is that the x86_64 relocation format does not allow symbol +
782 // offset, and so the linker does not have enough information to resolve the
783 // access to the appropriate atom unless an external relocation is used. For
784 // non-cstring sections, we expect the compiler to use a non-temporary label
785 // for anything that could have an addend pointing outside the symbol.
786 //
787 // See .
788 const MCSectionMachO &SMO = static_cast(Section);
789 return SMO.getType() == MachO::S_CSTRING_LITERALS;
790 }
791
792779 /// \brief Generate the compact unwind encoding for the CFI instructions.
793780 uint32_t generateCompactUnwindEncoding(
794781 ArrayRef Instrs) const override {
99 #include "MCTargetDesc/X86MCTargetDesc.h"
1010 #include "MCTargetDesc/X86FixupKinds.h"
1111 #include "llvm/ADT/Twine.h"
12 #include "llvm/MC/MCAsmInfo.h"
1213 #include "llvm/MC/MCAsmLayout.h"
1314 #include "llvm/MC/MCAssembler.h"
1415 #include "llvm/MC/MCContext.h"
4647 const MCFixup &Fixup,
4748 MCValue Target,
4849 uint64_t &FixedValue);
49 void RecordX86_64Relocation(MachObjectWriter *Writer,
50 const MCAssembler &Asm,
50 void RecordX86_64Relocation(MachObjectWriter *Writer, MCAssembler &Asm,
5151 const MCAsmLayout &Layout,
52 const MCFragment *Fragment,
53 const MCFixup &Fixup,
54 MCValue Target,
55 uint64_t &FixedValue);
52 const MCFragment *Fragment, const MCFixup &Fixup,
53 MCValue Target, uint64_t &FixedValue);
54
5655 public:
5756 X86MachObjectWriter(bool Is64Bit, uint32_t CPUType,
5857 uint32_t CPUSubtype)
5958 : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,
6059 /*UseAggressiveSymbolFolding=*/Is64Bit) {}
6160
62 void RecordRelocation(MachObjectWriter *Writer,
63 const MCAssembler &Asm, const MCAsmLayout &Layout,
64 const MCFragment *Fragment, const MCFixup &Fixup,
65 MCValue Target, uint64_t &FixedValue) override {
61 void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
62 const MCAsmLayout &Layout, const MCFragment *Fragment,
63 const MCFixup &Fixup, MCValue Target,
64 uint64_t &FixedValue) override {
6665 if (Writer->is64Bit())
6766 RecordX86_64Relocation(Writer, Asm, Layout, Fragment, Fixup, Target,
6867 FixedValue);
9695 }
9796 }
9897
99 void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,
100 const MCAssembler &Asm,
101 const MCAsmLayout &Layout,
102 const MCFragment *Fragment,
103 const MCFixup &Fixup,
104 MCValue Target,
105 uint64_t &FixedValue) {
98 void X86MachObjectWriter::RecordX86_64Relocation(
99 MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout,
100 const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target,
101 uint64_t &FixedValue) {
106102 unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
107103 unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind());
108104 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
116112 unsigned Index = 0;
117113 unsigned IsExtern = 0;
118114 unsigned Type = 0;
115 const MCSymbolData *RelSymbol = nullptr;
119116
120117 Value = Target.getConstant();
121118
131128 if (Target.isAbsolute()) { // constant
132129 // SymbolNum of 0 indicates the absolute section.
133130 Type = MachO::X86_64_RELOC_UNSIGNED;
134 Index = 0;
135131
136132 // FIXME: I believe this is broken, I don't think the linker can understand
137133 // it. I think it would require a local relocation, but I'm not sure if that
192188 Value -= Writer->getSymbolAddress(&B_SD, Layout) -
193189 (!B_Base ? 0 : Writer->getSymbolAddress(B_Base, Layout));
194190
195 if (A_Base) {
196 Index = A_Base->getIndex();
197 IsExtern = 1;
198 } else {
191 if (!A_Base)
199192 Index = A_SD.getFragment()->getParent()->getOrdinal() + 1;
200 IsExtern = 0;
201 }
202193 Type = MachO::X86_64_RELOC_UNSIGNED;
203194
204195 MachO::any_relocation_info MRE;
205196 MRE.r_word0 = FixupOffset;
206 MRE.r_word1 = ((Index << 0) |
207 (IsPCRel << 24) |
208 (Log2Size << 25) |
209 (IsExtern << 27) |
210 (Type << 28));
211 Writer->addRelocation(Fragment->getParent(), MRE);
212
213 if (B_Base) {
214 Index = B_Base->getIndex();
215 IsExtern = 1;
216 } else {
197 MRE.r_word1 =
198 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
199 Writer->addRelocation(A_Base, Fragment->getParent(), MRE);
200
201 if (B_Base)
202 RelSymbol = B_Base;
203 else
217204 Index = B_SD.getFragment()->getParent()->getOrdinal() + 1;
218 IsExtern = 0;
219 }
220205 Type = MachO::X86_64_RELOC_SUBTRACTOR;
221206 } else {
222207 const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
208 if (Symbol->isTemporary() && Value) {
209 const MCSection &Sec = Symbol->getSection();
210 if (!Asm.getContext().getAsmInfo()->isSectionAtomizableBySymbols(Sec))
211 Asm.addLocalUsedInReloc(*Symbol);
212 }
223213 const MCSymbolData &SD = Asm.getSymbolData(*Symbol);
224 const MCSymbolData *Base = Asm.getAtom(&SD);
214 RelSymbol = Asm.getAtom(&SD);
225215
226216 // Relocations inside debug sections always use local relocations when
227217 // possible. This seems to be done because the debugger doesn't fully
231221 const MCSectionMachO &Section = static_cast(
232222 Fragment->getParent()->getSection());
233223 if (Section.hasAttribute(MachO::S_ATTR_DEBUG))
234 Base = nullptr;
224 RelSymbol = nullptr;
235225 }
236226
237227 // x86_64 almost always uses external relocations, except when there is no
238228 // symbol to use as a base address (a local symbol with no preceding
239229 // non-local symbol).
240 if (Base) {
241 Index = Base->getIndex();
242 IsExtern = 1;
243
230 if (RelSymbol) {
244231 // Add the local offset, if needed.
245 if (Base != &SD)
246 Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base);
232 if (RelSymbol != &SD)
233 Value +=
234 Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(RelSymbol);
247235 } else if (Symbol->isInSection() && !Symbol->isVariable()) {
248236 // The index is the section ordinal (1-based).
249237 Index = SD.getFragment()->getParent()->getOrdinal() + 1;
250 IsExtern = 0;
251238 Value += Writer->getSymbolAddress(&SD, Layout);
252239
253240 if (IsPCRel)
346333 // struct relocation_info (8 bytes)
347334 MachO::any_relocation_info MRE;
348335 MRE.r_word0 = FixupOffset;
349 MRE.r_word1 = ((Index << 0) |
350 (IsPCRel << 24) |
351 (Log2Size << 25) |
352 (IsExtern << 27) |
353 (Type << 28));
354 Writer->addRelocation(Fragment->getParent(), MRE);
336 MRE.r_word1 = (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) |
337 (IsExtern << 27) | (Type << 28);
338 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
355339 }
356340
357341 bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer,
423407 (IsPCRel << 30) |
424408 MachO::R_SCATTERED);
425409 MRE.r_word1 = Value2;
426 Writer->addRelocation(Fragment->getParent(), MRE);
410 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
427411 } else {
428412 // If the offset is more than 24-bits, it won't fit in a scattered
429413 // relocation offset field, so we fall back to using a non-scattered
445429 (IsPCRel << 30) |
446430 MachO::R_SCATTERED);
447431 MRE.r_word1 = Value;
448 Writer->addRelocation(Fragment->getParent(), MRE);
432 Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
449433 return true;
450434 }
451435
466450
467451 // Get the symbol data.
468452 const MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol());
469 unsigned Index = SD_A->getIndex();
470453
471454 // We're only going to have a second symbol in pic mode and it'll be a
472455 // subtraction from the picbase. For 32-bit pic the addend is the difference
489472 // struct relocation_info (8 bytes)
490473 MachO::any_relocation_info MRE;
491474 MRE.r_word0 = Value;
492 MRE.r_word1 = ((Index << 0) |
493 (IsPCRel << 24) |
494 (Log2Size << 25) |
495 (1 << 27) | // r_extern
496 (MachO::GENERIC_RELOC_TLV << 28)); // r_type
497 Writer->addRelocation(Fragment->getParent(), MRE);
475 MRE.r_word1 =
476 (IsPCRel << 24) | (Log2Size << 25) | (MachO::GENERIC_RELOC_TLV << 28);
477 Writer->addRelocation(SD_A, Fragment->getParent(), MRE);
498478 }
499479
500480 void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,
545525 // See .
546526 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
547527 unsigned Index = 0;
548 unsigned IsExtern = 0;
549528 unsigned Type = 0;
529 const MCSymbolData *RelSymbol = nullptr;
550530
551531 if (Target.isAbsolute()) { // constant
552532 // SymbolNum of 0 indicates the absolute section.
567547
568548 // Check whether we need an external or internal relocation.
569549 if (Writer->doesSymbolRequireExternRelocation(SD)) {
570 IsExtern = 1;
571 Index = SD->getIndex();
550 RelSymbol = SD;
572551 // For external relocations, make sure to offset the fixup value to
573552 // compensate for the addend of the symbol address, if it was
574553 // undefined. This occurs with weak definitions, for example.
590569 // struct relocation_info (8 bytes)
591570 MachO::any_relocation_info MRE;
592571 MRE.r_word0 = FixupOffset;
593 MRE.r_word1 = ((Index << 0) |
594 (IsPCRel << 24) |
595 (Log2Size << 25) |
596 (IsExtern << 27) |
597 (Type << 28));
598 Writer->addRelocation(Fragment->getParent(), MRE);
572 MRE.r_word1 =
573 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
574 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
599575 }
600576
601577 MCObjectWriter *llvm::createX86MachObjectWriter(raw_ostream &OS,
0 // RUN: llvm-mc -triple aarch64-apple-darwin14 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s
1
2 // Test that we "S + K" produce a relocation with a symbol, but just S produces
3 // a relocation with the section.
4
5 .section __TEXT,__literal4,4byte_literals
6 L0:
7 .long 42
8
9 .section __TEXT,__cstring,cstring_literals
10 L1:
11 .asciz "42"
12
13 .section __DATA,__data
14 .quad L0
15 .quad L0 + 1
16 .quad L1
17 .quad L1 + 1
18
19 // CHECK: Relocations [
20 // CHECK-NEXT: Section __data {
21 // CHECK-NEXT: Relocation {
22 // CHECK-NEXT: Offset: 0x18
23 // CHECK-NEXT: PCRel: 0
24 // CHECK-NEXT: Length: 3
25 // CHECK-NEXT: Extern: 1
26 // CHECK-NEXT: Type: ARM64_RELOC_UNSIGNED (0)
27 // CHECK-NEXT: Symbol: L1
28 // CHECK-NEXT: Scattered: 0
29 // CHECK-NEXT: }
30 // CHECK-NEXT: Relocation {
31 // CHECK-NEXT: Offset: 0x10
32 // CHECK-NEXT: PCRel: 0
33 // CHECK-NEXT: Length: 3
34 // CHECK-NEXT: Extern: 1
35 // CHECK-NEXT: Type: ARM64_RELOC_UNSIGNED (0)
36 // CHECK-NEXT: Symbol: L1
37 // CHECK-NEXT: Scattered: 0
38 // CHECK-NEXT: }
39 // CHECK-NEXT: Relocation {
40 // CHECK-NEXT: Offset: 0x8
41 // CHECK-NEXT: PCRel: 0
42 // CHECK-NEXT: Length: 3
43 // CHECK-NEXT: Extern: 1
44 // CHECK-NEXT: Type: ARM64_RELOC_UNSIGNED (0)
45 // CHECK-NEXT: Symbol: L0
46 // CHECK-NEXT: Scattered: 0
47 // CHECK-NEXT: }
48 // CHECK-NEXT: Relocation {
49 // CHECK-NEXT: Offset: 0x0
50 // CHECK-NEXT: PCRel: 0
51 // CHECK-NEXT: Length: 3
52 // CHECK-NEXT: Extern: 0
53 // CHECK-NEXT: Type: ARM64_RELOC_UNSIGNED (0)
54 // CHECK-NEXT: Symbol: 0x2
55 // CHECK-NEXT: Scattered: 0
56 // CHECK-NEXT: }
57 // CHECK-NEXT: }
58 // CHECK-NEXT: ]
0 // RUN: llvm-mc -triple x86_64-apple-darwin14 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s
1
2 // Test that we "S + K" produce a relocation with a symbol, but just S produces
3 // a relocation with the section.
4
5 .section __TEXT,__literal4,4byte_literals
6 L0:
7 .long 42
8
9 .section __TEXT,__cstring,cstring_literals
10 L1:
11 .asciz "42"
12
13 .section __DATA,__data
14 .quad L0
15 .quad L0 + 1
16 .quad L1
17 .quad L1 + 1
18
19 // CHECK: Relocations [
20 // CHECK-NEXT: Section __data {
21 // CHECK-NEXT: Relocation {
22 // CHECK-NEXT: Offset: 0x18
23 // CHECK-NEXT: PCRel: 0
24 // CHECK-NEXT: Length: 3
25 // CHECK-NEXT: Extern: 1
26 // CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
27 // CHECK-NEXT: Symbol: L1
28 // CHECK-NEXT: Scattered: 0
29 // CHECK-NEXT: }
30 // CHECK-NEXT: Relocation {
31 // CHECK-NEXT: Offset: 0x10
32 // CHECK-NEXT: PCRel: 0
33 // CHECK-NEXT: Length: 3
34 // CHECK-NEXT: Extern: 0
35 // CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
36 // CHECK-NEXT: Symbol: 0x3
37 // CHECK-NEXT: Scattered: 0
38 // CHECK-NEXT: }
39 // CHECK-NEXT: Relocation {
40 // CHECK-NEXT: Offset: 0x8
41 // CHECK-NEXT: PCRel: 0
42 // CHECK-NEXT: Length: 3
43 // CHECK-NEXT: Extern: 1
44 // CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
45 // CHECK-NEXT: Symbol: L0
46 // CHECK-NEXT: Scattered: 0
47 // CHECK-NEXT: }
48 // CHECK-NEXT: Relocation {
49 // CHECK-NEXT: Offset: 0x0
50 // CHECK-NEXT: PCRel: 0
51 // CHECK-NEXT: Length: 3
52 // CHECK-NEXT: Extern: 0
53 // CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
54 // CHECK-NEXT: Symbol: 0x2
55 // CHECK-NEXT: Scattered: 0
56 // CHECK-NEXT: }
57 // CHECK-NEXT: }
58 // CHECK-NEXT: ]
120120 //L39:
121121 //D39:
122122
123 .section foo, bar
124 .long L4 + 1
125 .long L35 + 1
126 .long L36 + 1
127 .long L37 + 1
128 .long L38 + 1
123129
124130 // CHECK: Symbols [
125131 // CHECK-NEXT: Symbol {