Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | c2174574ed3a |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "MCTargetDesc/X86FixupKinds.h" | |
10 #include "MCTargetDesc/X86MCTargetDesc.h" | 11 #include "MCTargetDesc/X86MCTargetDesc.h" |
11 #include "MCTargetDesc/X86FixupKinds.h" | |
12 #include "llvm/ADT/Twine.h" | 12 #include "llvm/ADT/Twine.h" |
13 #include "llvm/BinaryFormat/MachO.h" | |
13 #include "llvm/MC/MCAsmInfo.h" | 14 #include "llvm/MC/MCAsmInfo.h" |
14 #include "llvm/MC/MCAsmLayout.h" | 15 #include "llvm/MC/MCAsmLayout.h" |
15 #include "llvm/MC/MCAssembler.h" | 16 #include "llvm/MC/MCAssembler.h" |
16 #include "llvm/MC/MCContext.h" | 17 #include "llvm/MC/MCContext.h" |
17 #include "llvm/MC/MCMachObjectWriter.h" | 18 #include "llvm/MC/MCMachObjectWriter.h" |
18 #include "llvm/MC/MCSectionMachO.h" | 19 #include "llvm/MC/MCSectionMachO.h" |
19 #include "llvm/MC/MCValue.h" | 20 #include "llvm/MC/MCValue.h" |
20 #include "llvm/Support/ErrorHandling.h" | 21 #include "llvm/Support/ErrorHandling.h" |
21 #include "llvm/Support/Format.h" | 22 #include "llvm/Support/Format.h" |
22 #include "llvm/Support/MachO.h" | |
23 | 23 |
24 using namespace llvm; | 24 using namespace llvm; |
25 | 25 |
26 namespace { | 26 namespace { |
27 class X86MachObjectWriter : public MCMachObjectTargetWriter { | 27 class X86MachObjectWriter : public MCMachObjectTargetWriter { |
151 if (B->isTemporary()) | 151 if (B->isTemporary()) |
152 B = &Writer->findAliasedSymbol(*B); | 152 B = &Writer->findAliasedSymbol(*B); |
153 const MCSymbol *B_Base = Asm.getAtom(*B); | 153 const MCSymbol *B_Base = Asm.getAtom(*B); |
154 | 154 |
155 // Neither symbol can be modified. | 155 // Neither symbol can be modified. |
156 if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || | 156 if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None) { |
157 Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) { | |
158 Asm.getContext().reportError(Fixup.getLoc(), | 157 Asm.getContext().reportError(Fixup.getLoc(), |
159 "unsupported relocation of modified symbol"); | 158 "unsupported relocation of modified symbol"); |
160 return; | 159 return; |
161 } | 160 } |
162 | 161 |
395 const MCSymbol *SB = &B->getSymbol(); | 394 const MCSymbol *SB = &B->getSymbol(); |
396 | 395 |
397 if (!SB->getFragment()) { | 396 if (!SB->getFragment()) { |
398 Asm.getContext().reportError( | 397 Asm.getContext().reportError( |
399 Fixup.getLoc(), | 398 Fixup.getLoc(), |
400 "symbol '" + B->getSymbol().getName() + | 399 "symbol '" + SB->getName() + |
401 "' can not be undefined in a subtraction expression"); | 400 "' can not be undefined in a subtraction expression"); |
402 return false; | 401 return false; |
403 } | 402 } |
404 | 403 |
405 // Select the appropriate difference relocation type. | 404 // Select the appropriate difference relocation type. |
407 // Note that there is no longer any semantic difference between these two | 406 // Note that there is no longer any semantic difference between these two |
408 // relocation types from the linkers point of view, this is done solely for | 407 // relocation types from the linkers point of view, this is done solely for |
409 // pedantic compatibility with 'as'. | 408 // pedantic compatibility with 'as'. |
410 Type = A->isExternal() ? (unsigned)MachO::GENERIC_RELOC_SECTDIFF | 409 Type = A->isExternal() ? (unsigned)MachO::GENERIC_RELOC_SECTDIFF |
411 : (unsigned)MachO::GENERIC_RELOC_LOCAL_SECTDIFF; | 410 : (unsigned)MachO::GENERIC_RELOC_LOCAL_SECTDIFF; |
412 Value2 = Writer->getSymbolAddress(B->getSymbol(), Layout); | 411 Value2 = Writer->getSymbolAddress(*SB, Layout); |
413 FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent()); | 412 FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent()); |
414 } | 413 } |
415 | 414 |
416 // Relocations are written out in reverse order, so the PAIR comes first. | 415 // Relocations are written out in reverse order, so the PAIR comes first. |
417 if (Type == MachO::GENERIC_RELOC_SECTDIFF || | 416 if (Type == MachO::GENERIC_RELOC_SECTDIFF || |
467 const MCAsmLayout &Layout, | 466 const MCAsmLayout &Layout, |
468 const MCFragment *Fragment, | 467 const MCFragment *Fragment, |
469 const MCFixup &Fixup, | 468 const MCFixup &Fixup, |
470 MCValue Target, | 469 MCValue Target, |
471 uint64_t &FixedValue) { | 470 uint64_t &FixedValue) { |
472 assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP && | 471 const MCSymbolRefExpr *SymA = Target.getSymA(); |
473 !is64Bit() && | 472 assert(SymA->getKind() == MCSymbolRefExpr::VK_TLVP && !is64Bit() && |
474 "Should only be called with a 32-bit TLVP relocation!"); | 473 "Should only be called with a 32-bit TLVP relocation!"); |
475 | 474 |
476 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); | 475 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); |
477 uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); | 476 uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); |
478 unsigned IsPCRel = 0; | 477 unsigned IsPCRel = 0; |
479 | 478 |
480 // We're only going to have a second symbol in pic mode and it'll be a | 479 // We're only going to have a second symbol in pic mode and it'll be a |
481 // subtraction from the picbase. For 32-bit pic the addend is the difference | 480 // subtraction from the picbase. For 32-bit pic the addend is the difference |
482 // between the picbase and the next address. For 32-bit static the addend is | 481 // between the picbase and the next address. For 32-bit static the addend is |
483 // zero. | 482 // zero. |
484 if (Target.getSymB()) { | 483 if (auto *SymB = Target.getSymB()) { |
485 // If this is a subtraction then we're pcrel. | 484 // If this is a subtraction then we're pcrel. |
486 uint32_t FixupAddress = | 485 uint32_t FixupAddress = |
487 Writer->getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); | 486 Writer->getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); |
488 IsPCRel = 1; | 487 IsPCRel = 1; |
489 FixedValue = | 488 FixedValue = FixupAddress - |
490 FixupAddress - | 489 Writer->getSymbolAddress(SymB->getSymbol(), Layout) + |
491 Writer->getSymbolAddress(Target.getSymB()->getSymbol(), Layout) + | 490 Target.getConstant(); |
492 Target.getConstant(); | |
493 FixedValue += 1ULL << Log2Size; | 491 FixedValue += 1ULL << Log2Size; |
494 } else { | 492 } else { |
495 FixedValue = 0; | 493 FixedValue = 0; |
496 } | 494 } |
497 | 495 |
498 // struct relocation_info (8 bytes) | 496 // struct relocation_info (8 bytes) |
499 MachO::any_relocation_info MRE; | 497 MachO::any_relocation_info MRE; |
500 MRE.r_word0 = Value; | 498 MRE.r_word0 = Value; |
501 MRE.r_word1 = | 499 MRE.r_word1 = |
502 (IsPCRel << 24) | (Log2Size << 25) | (MachO::GENERIC_RELOC_TLV << 28); | 500 (IsPCRel << 24) | (Log2Size << 25) | (MachO::GENERIC_RELOC_TLV << 28); |
503 Writer->addRelocation(&Target.getSymA()->getSymbol(), Fragment->getParent(), | 501 Writer->addRelocation(&SymA->getSymbol(), Fragment->getParent(), MRE); |
504 MRE); | |
505 } | 502 } |
506 | 503 |
507 void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer, | 504 void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer, |
508 const MCAssembler &Asm, | 505 const MCAssembler &Asm, |
509 const MCAsmLayout &Layout, | 506 const MCAsmLayout &Layout, |
598 MRE.r_word1 = | 595 MRE.r_word1 = |
599 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); | 596 (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); |
600 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE); | 597 Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE); |
601 } | 598 } |
602 | 599 |
603 MCObjectWriter *llvm::createX86MachObjectWriter(raw_pwrite_stream &OS, | 600 std::unique_ptr<MCObjectWriter> |
604 bool Is64Bit, uint32_t CPUType, | 601 llvm::createX86MachObjectWriter(raw_pwrite_stream &OS, bool Is64Bit, |
605 uint32_t CPUSubtype) { | 602 uint32_t CPUType, uint32_t CPUSubtype) { |
606 return createMachObjectWriter(new X86MachObjectWriter(Is64Bit, | 603 return createMachObjectWriter( |
607 CPUType, | 604 llvm::make_unique<X86MachObjectWriter>(Is64Bit, CPUType, CPUSubtype), OS, |
608 CPUSubtype), | 605 /*IsLittleEndian=*/true); |
609 OS, /*IsLittleEndian=*/true); | 606 } |
610 } |