blob: 7410c9395bc618ac0154ed6401f54de376935d53 [file] [log] [blame]
Venkatraman Govindarajub73aeca2014-01-06 01:22:54 +00001//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MCTargetDesc/SparcMCTargetDesc.h"
11#include "MCTargetDesc/SparcFixupKinds.h"
12#include "llvm/ADT/STLExtras.h"
13#include "llvm/MC/MCELFObjectWriter.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCValue.h"
16#include "llvm/Support/ErrorHandling.h"
17
18using namespace llvm;
19
20namespace {
21 class SparcELFObjectWriter : public MCELFObjectTargetWriter {
22 public:
23 SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
24 : MCELFObjectTargetWriter(Is64Bit, OSABI,
25 Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC,
26 /*HasRelocationAddend*/ true) {}
27
28 virtual ~SparcELFObjectWriter() {}
29 protected:
30 virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
31 bool IsPCRel, bool IsRelocWithSymbol,
32 int64_t Addend) const;
33
34 };
35}
36
37
38unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
39 const MCFixup &Fixup,
40 bool IsPCRel,
41 bool IsRelocWithSymbol,
42 int64_t Addend) const {
43 if (IsPCRel) {
44 switch((unsigned)Fixup.getKind()) {
45 default:
46 llvm_unreachable("Unimplemented fixup -> relocation");
47 case FK_Data_1: return ELF::R_SPARC_DISP8;
48 case FK_Data_2: return ELF::R_SPARC_DISP16;
49 case FK_Data_4: return ELF::R_SPARC_DISP32;
50 case FK_Data_8: return ELF::R_SPARC_DISP64;
51 case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30;
52 case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22;
53 case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
54 }
55 }
56
57 switch((unsigned)Fixup.getKind()) {
58 default:
59 llvm_unreachable("Unimplemented fixup -> relocation");
60 case FK_Data_1: return ELF::R_SPARC_8;
61 case FK_Data_2: return ((Fixup.getOffset() % 2)
62 ? ELF::R_SPARC_UA16
63 : ELF::R_SPARC_16);
64 case FK_Data_4: return ((Fixup.getOffset() % 4)
65 ? ELF::R_SPARC_UA32
66 : ELF::R_SPARC_32);
67 case FK_Data_8: return ((Fixup.getOffset() % 8)
68 ? ELF::R_SPARC_UA64
69 : ELF::R_SPARC_64);
70 case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22;
71 case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10;
72 case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44;
73 case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M44;
74 case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44;
75 case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22;
76 case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
77 }
78 return ELF::R_SPARC_NONE;
79}
80
81MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
82 bool Is64Bit,
83 uint8_t OSABI) {
84 MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI);
85 return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false);
86}