/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/MC/MCELFObjectWriter.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ----------*- C++ -*-===// |
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 | | #ifndef LLVM_MC_MCELFOBJECTWRITER_H |
11 | | #define LLVM_MC_MCELFOBJECTWRITER_H |
12 | | |
13 | | #include "llvm/ADT/Triple.h" |
14 | | #include "llvm/BinaryFormat/ELF.h" |
15 | | #include "llvm/Support/Casting.h" |
16 | | #include "llvm/Support/raw_ostream.h" |
17 | | #include <cstdint> |
18 | | #include <vector> |
19 | | |
20 | | namespace llvm { |
21 | | |
22 | | class MCAssembler; |
23 | | class MCContext; |
24 | | class MCFixup; |
25 | | class MCObjectWriter; |
26 | | class MCSymbol; |
27 | | class MCSymbolELF; |
28 | | class MCValue; |
29 | | |
30 | | struct ELFRelocationEntry { |
31 | | uint64_t Offset; // Where is the relocation. |
32 | | const MCSymbolELF *Symbol; // The symbol to relocate with. |
33 | | unsigned Type; // The type of the relocation. |
34 | | uint64_t Addend; // The addend to use. |
35 | | const MCSymbolELF *OriginalSymbol; // The original value of Symbol if we changed it. |
36 | | uint64_t OriginalAddend; // The original value of addend. |
37 | | |
38 | | ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type, |
39 | | uint64_t Addend, const MCSymbolELF *OriginalSymbol, |
40 | | uint64_t OriginalAddend) |
41 | | : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend), |
42 | 9.70k | OriginalSymbol(OriginalSymbol), OriginalAddend(OriginalAddend) {} |
43 | | |
44 | 0 | void print(raw_ostream &Out) const { |
45 | 0 | Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type |
46 | 0 | << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol |
47 | 0 | << ", OriginalAddend=" << OriginalAddend; |
48 | 0 | } |
49 | | |
50 | 0 | void dump() const { print(errs()); } |
51 | | }; |
52 | | |
53 | | class MCELFObjectTargetWriter { |
54 | | const uint8_t OSABI; |
55 | | const uint16_t EMachine; |
56 | | const unsigned HasRelocationAddend : 1; |
57 | | const unsigned Is64Bit : 1; |
58 | | |
59 | | protected: |
60 | | MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_, |
61 | | bool HasRelocationAddend); |
62 | | |
63 | | public: |
64 | 2.83k | virtual ~MCELFObjectTargetWriter() = default; |
65 | | |
66 | 11.8k | static uint8_t getOSABI(Triple::OSType OSType) { |
67 | 11.8k | switch (OSType) { |
68 | 4 | case Triple::CloudABI: |
69 | 4 | return ELF::ELFOSABI_CLOUDABI; |
70 | 141 | case Triple::PS4: |
71 | 141 | case Triple::FreeBSD: |
72 | 141 | return ELF::ELFOSABI_FREEBSD; |
73 | 11.7k | default: |
74 | 11.7k | return ELF::ELFOSABI_NONE; |
75 | 11.8k | } |
76 | 11.8k | } |
77 | | |
78 | | virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, |
79 | | const MCFixup &Fixup, bool IsPCRel) const = 0; |
80 | | |
81 | | virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, |
82 | | unsigned Type) const; |
83 | | |
84 | | virtual void sortRelocs(const MCAssembler &Asm, |
85 | | std::vector<ELFRelocationEntry> &Relocs); |
86 | | |
87 | | /// \name Accessors |
88 | | /// @{ |
89 | 2.78k | uint8_t getOSABI() const { return OSABI; } |
90 | 16.7k | uint16_t getEMachine() const { return EMachine; } |
91 | 28.7k | bool hasRelocationAddend() const { return HasRelocationAddend; } |
92 | 2.13M | bool is64Bit() const { return Is64Bit; } |
93 | | /// @} |
94 | | |
95 | | // Instead of changing everyone's API we pack the N64 Type fields |
96 | | // into the existing 32 bit data unsigned. |
97 | 330 | #define R_TYPE_SHIFT 0 |
98 | 57 | #define R_TYPE_MASK 0xffffff00 |
99 | 1.24k | #define R_TYPE2_SHIFT 8 |
100 | 57 | #define R_TYPE2_MASK 0xffff00ff |
101 | 1.24k | #define R_TYPE3_SHIFT 16 |
102 | 57 | #define R_TYPE3_MASK 0xff00ffff |
103 | 273 | #define R_SSYM_SHIFT 24 |
104 | | #define R_SSYM_MASK 0x00ffffff |
105 | | |
106 | | // N64 relocation type accessors |
107 | 273 | uint8_t getRType(uint32_t Type) const { |
108 | 273 | return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff); |
109 | 273 | } |
110 | 1.18k | uint8_t getRType2(uint32_t Type) const { |
111 | 1.18k | return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff); |
112 | 1.18k | } |
113 | 1.18k | uint8_t getRType3(uint32_t Type) const { |
114 | 1.18k | return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff); |
115 | 1.18k | } |
116 | 273 | uint8_t getRSsym(uint32_t Type) const { |
117 | 273 | return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff); |
118 | 273 | } |
119 | | |
120 | | // N64 relocation type setting |
121 | 57 | unsigned setRType(unsigned Value, unsigned Type) const { |
122 | 57 | return ((Type & R_TYPE_MASK57 ) | ((Value & 0xff) << R_TYPE_SHIFT57 )); |
123 | 57 | } |
124 | 57 | unsigned setRType2(unsigned Value, unsigned Type) const { |
125 | 57 | return (Type & R_TYPE2_MASK57 ) | ((Value & 0xff) << R_TYPE2_SHIFT57 ); |
126 | 57 | } |
127 | 57 | unsigned setRType3(unsigned Value, unsigned Type) const { |
128 | 57 | return (Type & R_TYPE3_MASK57 ) | ((Value & 0xff) << R_TYPE3_SHIFT57 ); |
129 | 57 | } |
130 | 0 | unsigned setRSsym(unsigned Value, unsigned Type) const { |
131 | 0 | return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT); |
132 | 0 | } |
133 | | }; |
134 | | |
135 | | /// \brief Construct a new ELF writer instance. |
136 | | /// |
137 | | /// \param MOTW - The target specific ELF writer subclass. |
138 | | /// \param OS - The stream to write to. |
139 | | /// \returns The constructed object writer. |
140 | | MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, |
141 | | raw_pwrite_stream &OS, |
142 | | bool IsLittleEndian); |
143 | | |
144 | | } // end namespace llvm |
145 | | |
146 | | #endif // LLVM_MC_MCELFOBJECTWRITER_H |