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 }