Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ----------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_MC_MCELFOBJECTWRITER_H
10
#define LLVM_MC_MCELFOBJECTWRITER_H
11
 
12
#include "llvm/ADT/Triple.h"
13
#include "llvm/BinaryFormat/ELF.h"
14
#include "llvm/MC/MCObjectWriter.h"
15
#include "llvm/MC/MCSectionELF.h"
16
#include "llvm/Support/Casting.h"
17
#include "llvm/Support/raw_ostream.h"
18
#include <cstdint>
19
#include <vector>
20
 
21
namespace llvm {
22
 
23
class MCAssembler;
24
class MCContext;
25
class MCFixup;
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
        OriginalSymbol(OriginalSymbol), OriginalAddend(OriginalAddend) {}
43
 
44
  void print(raw_ostream &Out) const {
45
    Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type
46
        << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol
47
        << ", OriginalAddend=" << OriginalAddend;
48
  }
49
 
50
  LLVM_DUMP_METHOD void dump() const { print(errs()); }
51
};
52
 
53
class MCELFObjectTargetWriter : public MCObjectTargetWriter {
54
  const uint8_t OSABI;
55
  const uint8_t ABIVersion;
56
  const uint16_t EMachine;
57
  const unsigned HasRelocationAddend : 1;
58
  const unsigned Is64Bit : 1;
59
 
60
protected:
61
  MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_,
62
                          bool HasRelocationAddend_, uint8_t ABIVersion_ = 0);
63
 
64
public:
65
  virtual ~MCELFObjectTargetWriter() = default;
66
 
67
  Triple::ObjectFormatType getFormat() const override { return Triple::ELF; }
68
  static bool classof(const MCObjectTargetWriter *W) {
69
    return W->getFormat() == Triple::ELF;
70
  }
71
 
72
  static uint8_t getOSABI(Triple::OSType OSType) {
73
    switch (OSType) {
74
      case Triple::CloudABI:
75
        return ELF::ELFOSABI_CLOUDABI;
76
      case Triple::HermitCore:
77
        return ELF::ELFOSABI_STANDALONE;
78
      case Triple::PS4:
79
      case Triple::FreeBSD:
80
        return ELF::ELFOSABI_FREEBSD;
81
      case Triple::Solaris:
82
        return ELF::ELFOSABI_SOLARIS;
83
      default:
84
        return ELF::ELFOSABI_NONE;
85
    }
86
  }
87
 
88
  virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
89
                                const MCFixup &Fixup, bool IsPCRel) const = 0;
90
 
91
  virtual bool needsRelocateWithSymbol(const MCSymbol &Sym,
92
                                       unsigned Type) const;
93
 
94
  virtual void sortRelocs(const MCAssembler &Asm,
95
                          std::vector<ELFRelocationEntry> &Relocs);
96
 
97
  virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec);
98
 
99
  /// \name Accessors
100
  /// @{
101
  uint8_t getOSABI() const { return OSABI; }
102
  uint8_t getABIVersion() const { return ABIVersion; }
103
  uint16_t getEMachine() const { return EMachine; }
104
  bool hasRelocationAddend() const { return HasRelocationAddend; }
105
  bool is64Bit() const { return Is64Bit; }
106
  /// @}
107
 
108
  // Instead of changing everyone's API we pack the N64 Type fields
109
  // into the existing 32 bit data unsigned.
110
#define R_TYPE_SHIFT 0
111
#define R_TYPE_MASK 0xffffff00
112
#define R_TYPE2_SHIFT 8
113
#define R_TYPE2_MASK 0xffff00ff
114
#define R_TYPE3_SHIFT 16
115
#define R_TYPE3_MASK 0xff00ffff
116
#define R_SSYM_SHIFT 24
117
#define R_SSYM_MASK 0x00ffffff
118
 
119
  // N64 relocation type accessors
120
  uint8_t getRType(uint32_t Type) const {
121
    return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
122
  }
123
  uint8_t getRType2(uint32_t Type) const {
124
    return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
125
  }
126
  uint8_t getRType3(uint32_t Type) const {
127
    return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
128
  }
129
  uint8_t getRSsym(uint32_t Type) const {
130
    return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
131
  }
132
 
133
  // N64 relocation type setting
134
  static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3) {
135
    return ((Value1 & 0xff) << R_TYPE_SHIFT) |
136
           ((Value2 & 0xff) << R_TYPE2_SHIFT) |
137
           ((Value3 & 0xff) << R_TYPE3_SHIFT);
138
  }
139
  unsigned setRSsym(unsigned Value, unsigned Type) const {
140
    return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
141
  }
142
 
143
  // On AArch64, return a new section to be added to the ELF object that
144
  // contains relocations used to describe every symbol that should have memory
145
  // tags applied. Returns nullptr if no such section is necessary (i.e. there's
146
  // no tagged globals).
147
  virtual MCSectionELF *getMemtagRelocsSection(MCContext &Ctx) const {
148
    return nullptr;
149
  }
150
};
151
 
152
/// Construct a new ELF writer instance.
153
///
154
/// \param MOTW - The target specific ELF writer subclass.
155
/// \param OS - The stream to write to.
156
/// \returns The constructed object writer.
157
std::unique_ptr<MCObjectWriter>
158
createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
159
                      raw_pwrite_stream &OS, bool IsLittleEndian);
160
 
161
std::unique_ptr<MCObjectWriter>
162
createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
163
                         raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
164
                         bool IsLittleEndian);
165
 
166
} // end namespace llvm
167
 
168
#endif // LLVM_MC_MCELFOBJECTWRITER_H