LLVM API Documentation

SystemZMCObjectWriter.cpp
Go to the documentation of this file.
00001 //===-- SystemZMCObjectWriter.cpp - SystemZ ELF writer --------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "MCTargetDesc/SystemZMCTargetDesc.h"
00011 #include "MCTargetDesc/SystemZMCFixups.h"
00012 #include "llvm/MC/MCELFObjectWriter.h"
00013 #include "llvm/MC/MCExpr.h"
00014 #include "llvm/MC/MCValue.h"
00015 
00016 using namespace llvm;
00017 
00018 namespace {
00019 class SystemZObjectWriter : public MCELFObjectTargetWriter {
00020 public:
00021   SystemZObjectWriter(uint8_t OSABI);
00022 
00023   virtual ~SystemZObjectWriter();
00024 
00025 protected:
00026   // Override MCELFObjectTargetWriter.
00027   unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
00028                         bool IsPCRel) const override;
00029 };
00030 } // end anonymous namespace
00031 
00032 SystemZObjectWriter::SystemZObjectWriter(uint8_t OSABI)
00033   : MCELFObjectTargetWriter(/*Is64Bit=*/true, OSABI, ELF::EM_S390,
00034                             /*HasRelocationAddend=*/ true) {}
00035 
00036 SystemZObjectWriter::~SystemZObjectWriter() {
00037 }
00038 
00039 // Return the relocation type for an absolute value of MCFixupKind Kind.
00040 static unsigned getAbsoluteReloc(unsigned Kind) {
00041   switch (Kind) {
00042   case FK_Data_1: return ELF::R_390_8;
00043   case FK_Data_2: return ELF::R_390_16;
00044   case FK_Data_4: return ELF::R_390_32;
00045   case FK_Data_8: return ELF::R_390_64;
00046   }
00047   llvm_unreachable("Unsupported absolute address");
00048 }
00049 
00050 // Return the relocation type for a PC-relative value of MCFixupKind Kind.
00051 static unsigned getPCRelReloc(unsigned Kind) {
00052   switch (Kind) {
00053   case FK_Data_2:                return ELF::R_390_PC16;
00054   case FK_Data_4:                return ELF::R_390_PC32;
00055   case FK_Data_8:                return ELF::R_390_PC64;
00056   case SystemZ::FK_390_PC16DBL:  return ELF::R_390_PC16DBL;
00057   case SystemZ::FK_390_PC32DBL:  return ELF::R_390_PC32DBL;
00058   case SystemZ::FK_390_PLT16DBL: return ELF::R_390_PLT16DBL;
00059   case SystemZ::FK_390_PLT32DBL: return ELF::R_390_PLT32DBL;
00060   }
00061   llvm_unreachable("Unsupported PC-relative address");
00062 }
00063 
00064 // Return the R_390_TLS_LE* relocation type for MCFixupKind Kind.
00065 static unsigned getTLSLEReloc(unsigned Kind) {
00066   switch (Kind) {
00067   case FK_Data_4: return ELF::R_390_TLS_LE32;
00068   case FK_Data_8: return ELF::R_390_TLS_LE64;
00069   }
00070   llvm_unreachable("Unsupported absolute address");
00071 }
00072 
00073 // Return the PLT relocation counterpart of MCFixupKind Kind.
00074 static unsigned getPLTReloc(unsigned Kind) {
00075   switch (Kind) {
00076   case SystemZ::FK_390_PC16DBL: return ELF::R_390_PLT16DBL;
00077   case SystemZ::FK_390_PC32DBL: return ELF::R_390_PLT32DBL;
00078   }
00079   llvm_unreachable("Unsupported absolute address");
00080 }
00081 
00082 unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target,
00083                                            const MCFixup &Fixup,
00084                                            bool IsPCRel) const {
00085   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
00086   unsigned Kind = Fixup.getKind();
00087   switch (Modifier) {
00088   case MCSymbolRefExpr::VK_None:
00089     if (IsPCRel)
00090       return getPCRelReloc(Kind);
00091     return getAbsoluteReloc(Kind);
00092 
00093   case MCSymbolRefExpr::VK_NTPOFF:
00094     assert(!IsPCRel && "NTPOFF shouldn't be PC-relative");
00095     return getTLSLEReloc(Kind);
00096 
00097   case MCSymbolRefExpr::VK_GOT:
00098     if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
00099       return ELF::R_390_GOTENT;
00100     llvm_unreachable("Only PC-relative GOT accesses are supported for now");
00101 
00102   case MCSymbolRefExpr::VK_PLT:
00103     assert(IsPCRel && "@PLT shouldt be PC-relative");
00104     return getPLTReloc(Kind);
00105 
00106   default:
00107     llvm_unreachable("Modifier not supported");
00108   }
00109 }
00110 
00111 MCObjectWriter *llvm::createSystemZObjectWriter(raw_ostream &OS,
00112                                                 uint8_t OSABI) {
00113   MCELFObjectTargetWriter *MOTW = new SystemZObjectWriter(OSABI);
00114   return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false);
00115 }