11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZMCObjectWriter.cpp - SystemZ ELF writer --------------------===// 21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The LLVM Compiler Infrastructure 41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source 61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details. 71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "MCTargetDesc/SystemZMCTargetDesc.h" 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "MCTargetDesc/SystemZMCFixups.h" 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCELFObjectWriter.h" 131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCExpr.h" 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCValue.h" 151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandnamespace { 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandclass SystemZObjectWriter : public MCELFObjectTargetWriter { 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandpublic: 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZObjectWriter(uint8_t OSABI); 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand virtual ~SystemZObjectWriter(); 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandprotected: 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Override MCELFObjectTargetWriter. 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsPCRel) const override; 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}; 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end anonymous namespace 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZObjectWriter::SystemZObjectWriter(uint8_t OSABI) 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : MCELFObjectTargetWriter(/*Is64Bit=*/true, OSABI, ELF::EM_S390, 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand /*HasRelocationAddend=*/ true) {} 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZObjectWriter::~SystemZObjectWriter() { 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return the relocation type for an absolute value of MCFixupKind Kind. 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic unsigned getAbsoluteReloc(unsigned Kind) { 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Kind) { 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_1: return ELF::R_390_8; 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_2: return ELF::R_390_16; 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_4: return ELF::R_390_32; 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_8: return ELF::R_390_64; 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported absolute address"); 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return the relocation type for a PC-relative value of MCFixupKind Kind. 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic unsigned getPCRelReloc(unsigned Kind) { 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Kind) { 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_2: return ELF::R_390_PC16; 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_4: return ELF::R_390_PC32; 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_8: return ELF::R_390_PC64; 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::FK_390_PC16DBL: return ELF::R_390_PC16DBL; 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::FK_390_PC32DBL: return ELF::R_390_PC32DBL; 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::FK_390_PLT16DBL: return ELF::R_390_PLT16DBL; 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::FK_390_PLT32DBL: return ELF::R_390_PLT32DBL; 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported PC-relative address"); 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return the R_390_TLS_LE* relocation type for MCFixupKind Kind. 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic unsigned getTLSLEReloc(unsigned Kind) { 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Kind) { 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_4: return ELF::R_390_TLS_LE32; 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case FK_Data_8: return ELF::R_390_TLS_LE64; 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported absolute address"); 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return the PLT relocation counterpart of MCFixupKind Kind. 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic unsigned getPLTReloc(unsigned Kind) { 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Kind) { 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::FK_390_PC16DBL: return ELF::R_390_PLT16DBL; 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::FK_390_PC32DBL: return ELF::R_390_PLT32DBL; 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported absolute address"); 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZObjectWriter::GetRelocType(const MCValue &Target, 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCFixup &Fixup, 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsPCRel) const { 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Kind = Fixup.getKind(); 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Modifier) { 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MCSymbolRefExpr::VK_None: 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsPCRel) 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return getPCRelReloc(Kind); 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return getAbsoluteReloc(Kind); 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MCSymbolRefExpr::VK_NTPOFF: 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(!IsPCRel && "NTPOFF shouldn't be PC-relative"); 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return getTLSLEReloc(Kind); 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MCSymbolRefExpr::VK_GOT: 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL) 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return ELF::R_390_GOTENT; 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Only PC-relative GOT accesses are supported for now"); 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MCSymbolRefExpr::VK_PLT: 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(IsPCRel && "@PLT shouldt be PC-relative"); 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return getPLTReloc(Kind); 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Modifier not supported"); 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMCObjectWriter *llvm::createSystemZObjectWriter(raw_ostream &OS, 1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint8_t OSABI) { 1131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MCELFObjectTargetWriter *MOTW = new SystemZObjectWriter(OSABI); 1141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false); 1151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 116