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
|
//===-- X86ELFWriterInfo.cpp - ELF Writer Info for the X86 backend --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements ELF writer information for the X86 backend.
//
//===----------------------------------------------------------------------===//
#include "X86ELFWriterInfo.h"
#include "X86Relocations.h"
#include "llvm/Function.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// Implementation of the X86ELFWriterInfo class
//===----------------------------------------------------------------------===//
X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_)
: TargetELFWriterInfo(is64Bit_, isLittleEndian_) {
EMachine = is64Bit ? EM_X86_64 : EM_386;
}
X86ELFWriterInfo::~X86ELFWriterInfo() {}
unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
if (is64Bit) {
switch(MachineRelTy) {
case X86::reloc_pcrel_word:
return ELF::R_X86_64_PC32;
case X86::reloc_absolute_word:
return ELF::R_X86_64_32;
case X86::reloc_absolute_word_sext:
return ELF::R_X86_64_32S;
case X86::reloc_absolute_dword:
return ELF::R_X86_64_64;
case X86::reloc_picrel_word:
default:
llvm_unreachable("unknown x86_64 machine relocation type");
}
} else {
switch(MachineRelTy) {
case X86::reloc_pcrel_word:
return ELF::R_386_PC32;
case X86::reloc_absolute_word:
return ELF::R_386_32;
case X86::reloc_absolute_word_sext:
case X86::reloc_absolute_dword:
case X86::reloc_picrel_word:
default:
llvm_unreachable("unknown x86 machine relocation type");
}
}
return 0;
}
long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
long int Modifier) const {
if (is64Bit) {
switch(RelTy) {
case ELF::R_X86_64_PC32: return Modifier - 4;
case ELF::R_X86_64_32:
case ELF::R_X86_64_32S:
case ELF::R_X86_64_64:
return Modifier;
default:
llvm_unreachable("unknown x86_64 relocation type");
}
} else {
switch(RelTy) {
case ELF::R_386_PC32: return Modifier - 4;
case ELF::R_386_32: return Modifier;
default:
llvm_unreachable("unknown x86 relocation type");
}
}
return 0;
}
unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
if (is64Bit) {
switch(RelTy) {
case ELF::R_X86_64_PC32:
case ELF::R_X86_64_32:
case ELF::R_X86_64_32S:
return 32;
case ELF::R_X86_64_64:
return 64;
default:
llvm_unreachable("unknown x86_64 relocation type");
}
} else {
switch(RelTy) {
case ELF::R_386_PC32:
case ELF::R_386_32:
return 32;
default:
llvm_unreachable("unknown x86 relocation type");
}
}
return 0;
}
bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
if (is64Bit) {
switch(RelTy) {
case ELF::R_X86_64_PC32:
return true;
case ELF::R_X86_64_32:
case ELF::R_X86_64_32S:
case ELF::R_X86_64_64:
return false;
default:
llvm_unreachable("unknown x86_64 relocation type");
}
} else {
switch(RelTy) {
case ELF::R_386_PC32:
return true;
case ELF::R_386_32:
return false;
default:
llvm_unreachable("unknown x86 relocation type");
}
}
return 0;
}
unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
return is64Bit ?
X86::reloc_absolute_dword : X86::reloc_absolute_word;
}
long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
unsigned RelOffset,
unsigned RelTy) const {
if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32)
return SymOffset - (RelOffset + 4);
else
assert(0 && "computeRelocation unknown for this relocation type");
return 0;
}
|