/usr/include/llvm-3.9/llvm/MC/MCMachObjectWriter.h is in llvm-3.9-dev 1:3.9.1-19ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | //===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCMACHOBJECTWRITER_H
#define LLVM_MC_MCMACHOBJECTWRITER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MachO.h"
#include <vector>
namespace llvm {
class MachObjectWriter;
class MCMachObjectTargetWriter {
const unsigned Is64Bit : 1;
const uint32_t CPUType;
const uint32_t CPUSubtype;
unsigned LocalDifference_RIT;
protected:
MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
uint32_t CPUSubtype_);
void setLocalDifferenceRelocationType(unsigned Type) {
LocalDifference_RIT = Type;
}
public:
virtual ~MCMachObjectTargetWriter();
/// \name Lifetime Management
/// @{
virtual void reset() {}
/// @}
/// \name Accessors
/// @{
bool is64Bit() const { return Is64Bit; }
uint32_t getCPUType() const { return CPUType; }
uint32_t getCPUSubtype() const { return CPUSubtype; }
unsigned getLocalDifferenceRelocationType() const {
return LocalDifference_RIT;
}
/// @}
/// \name API
/// @{
virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
uint64_t &FixedValue) = 0;
/// @}
};
class MachObjectWriter : public MCObjectWriter {
/// Helper struct for containing some precomputed information on symbols.
struct MachSymbolData {
const MCSymbol *Symbol;
uint64_t StringIndex;
uint8_t SectionIndex;
// Support lexicographic sorting.
bool operator<(const MachSymbolData &RHS) const;
};
/// The target specific Mach-O writer instance.
std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
/// \name Relocation Data
/// @{
struct RelAndSymbol {
const MCSymbol *Sym;
MachO::any_relocation_info MRE;
RelAndSymbol(const MCSymbol *Sym, const MachO::any_relocation_info &MRE)
: Sym(Sym), MRE(MRE) {}
};
llvm::DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
llvm::DenseMap<const MCSection *, unsigned> IndirectSymBase;
SectionAddrMap SectionAddress;
/// @}
/// \name Symbol Table Data
/// @{
StringTableBuilder StringTable{StringTableBuilder::MachO};
std::vector<MachSymbolData> LocalSymbolData;
std::vector<MachSymbolData> ExternalSymbolData;
std::vector<MachSymbolData> UndefinedSymbolData;
/// @}
MachSymbolData *findSymbolData(const MCSymbol &Sym);
public:
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
bool IsLittleEndian)
: MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
/// \name Lifetime management Methods
/// @{
void reset() override;
/// @}
/// \name Utility Methods
/// @{
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
uint64_t getSectionAddress(const MCSection *Sec) const {
return SectionAddress.lookup(Sec);
}
uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const;
uint64_t getFragmentAddress(const MCFragment *Fragment,
const MCAsmLayout &Layout) const;
uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const;
bool doesSymbolRequireExternRelocation(const MCSymbol &S);
/// @}
/// \name Target Writer Proxy Accessors
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool isX86_64() const {
uint32_t CPUType = TargetObjectWriter->getCPUType();
return CPUType == MachO::CPU_TYPE_X86_64;
}
/// @}
void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
/// Write a segment load command.
///
/// \param NumSections The number of sections in this segment.
/// \param SectionDataSize The total size of the sections.
void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
uint64_t VMAddr, uint64_t VMSize,
uint64_t SectionDataStartOffset,
uint64_t SectionDataSize, uint32_t MaxProt,
uint32_t InitProt);
void writeSection(const MCAsmLayout &Layout, const MCSection &Sec,
uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
uint64_t RelocationsStart, unsigned NumRelocations);
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
uint32_t StringTableOffset,
uint32_t StringTableSize);
void writeDysymtabLoadCommand(
uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
uint32_t DataSize);
void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
// entry as the linker would, and verifies that the resultant fixup value is
// exactly what the encoder wanted. This will catch several classes of
// problems:
//
// - Relocation entry bugs, the two algorithms are unlikely to have the same
// exact bug.
//
// - Relaxation issues, where we forget to relax something.
//
// - Input errors, where something cannot be correctly encoded. 'as' allows
// these through in many cases.
// Add a relocation to be output in the object file. At the time this is
// called, the symbol indexes are not know, so if the relocation refers
// to a symbol it should be passed as \p RelSymbol so that it can be updated
// afterwards. If the relocation doesn't refer to a symbol, nullptr should be
// used.
void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec,
MachO::any_relocation_info &MRE) {
RelAndSymbol P(RelSymbol, MRE);
Relocations[Sec].push_back(P);
}
void recordScatteredRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
unsigned Log2Size, uint64_t &FixedValue);
void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue);
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
uint64_t &FixedValue) override;
void bindIndirectSymbols(MCAssembler &Asm);
/// Compute the symbol table data.
void computeSymbolTable(MCAssembler &Asm,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
std::vector<MachSymbolData> &UndefinedSymbolData);
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
void executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &A,
const MCSymbol &B,
bool InSet) const override;
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &SymA,
const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
/// Construct a new Mach-O writer instance.
///
/// This routine takes ownership of the target writer subclass.
///
/// \param MOTW - The target specific Mach-O writer subclass.
/// \param OS - The stream to write to.
/// \returns The constructed object writer.
MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
raw_pwrite_stream &OS,
bool IsLittleEndian);
} // End llvm namespace
#endif
|