1//===-- X86ELFWriterInfo.cpp - ELF Writer Info for the X86 backend --------===// 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// This file implements ELF writer information for the X86 backend. 11// 12//===----------------------------------------------------------------------===// 13 14#include "X86ELFWriterInfo.h" 15#include "X86Relocations.h" 16#include "llvm/Function.h" 17#include "llvm/Support/ELF.h" 18#include "llvm/Support/ErrorHandling.h" 19#include "llvm/Target/TargetData.h" 20#include "llvm/Target/TargetMachine.h" 21 22using namespace llvm; 23 24//===----------------------------------------------------------------------===// 25// Implementation of the X86ELFWriterInfo class 26//===----------------------------------------------------------------------===// 27 28X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_) 29 : TargetELFWriterInfo(is64Bit_, isLittleEndian_) { 30 EMachine = is64Bit ? EM_X86_64 : EM_386; 31 } 32 33X86ELFWriterInfo::~X86ELFWriterInfo() {} 34 35unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { 36 if (is64Bit) { 37 switch(MachineRelTy) { 38 case X86::reloc_pcrel_word: 39 return ELF::R_X86_64_PC32; 40 case X86::reloc_absolute_word: 41 return ELF::R_X86_64_32; 42 case X86::reloc_absolute_word_sext: 43 return ELF::R_X86_64_32S; 44 case X86::reloc_absolute_dword: 45 return ELF::R_X86_64_64; 46 case X86::reloc_picrel_word: 47 default: 48 llvm_unreachable("unknown x86_64 machine relocation type"); 49 } 50 } else { 51 switch(MachineRelTy) { 52 case X86::reloc_pcrel_word: 53 return ELF::R_386_PC32; 54 case X86::reloc_absolute_word: 55 return ELF::R_386_32; 56 case X86::reloc_absolute_word_sext: 57 case X86::reloc_absolute_dword: 58 case X86::reloc_picrel_word: 59 default: 60 llvm_unreachable("unknown x86 machine relocation type"); 61 } 62 } 63 return 0; 64} 65 66long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, 67 long int Modifier) const { 68 if (is64Bit) { 69 switch(RelTy) { 70 case ELF::R_X86_64_PC32: return Modifier - 4; 71 case ELF::R_X86_64_32: 72 case ELF::R_X86_64_32S: 73 case ELF::R_X86_64_64: 74 return Modifier; 75 default: 76 llvm_unreachable("unknown x86_64 relocation type"); 77 } 78 } else { 79 switch(RelTy) { 80 case ELF::R_386_PC32: return Modifier - 4; 81 case ELF::R_386_32: return Modifier; 82 default: 83 llvm_unreachable("unknown x86 relocation type"); 84 } 85 } 86 return 0; 87} 88 89unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const { 90 if (is64Bit) { 91 switch(RelTy) { 92 case ELF::R_X86_64_PC32: 93 case ELF::R_X86_64_32: 94 case ELF::R_X86_64_32S: 95 return 32; 96 case ELF::R_X86_64_64: 97 return 64; 98 default: 99 llvm_unreachable("unknown x86_64 relocation type"); 100 } 101 } else { 102 switch(RelTy) { 103 case ELF::R_386_PC32: 104 case ELF::R_386_32: 105 return 32; 106 default: 107 llvm_unreachable("unknown x86 relocation type"); 108 } 109 } 110 return 0; 111} 112 113bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { 114 if (is64Bit) { 115 switch(RelTy) { 116 case ELF::R_X86_64_PC32: 117 return true; 118 case ELF::R_X86_64_32: 119 case ELF::R_X86_64_32S: 120 case ELF::R_X86_64_64: 121 return false; 122 default: 123 llvm_unreachable("unknown x86_64 relocation type"); 124 } 125 } else { 126 switch(RelTy) { 127 case ELF::R_386_PC32: 128 return true; 129 case ELF::R_386_32: 130 return false; 131 default: 132 llvm_unreachable("unknown x86 relocation type"); 133 } 134 } 135 return 0; 136} 137 138unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const { 139 return is64Bit ? 140 X86::reloc_absolute_dword : X86::reloc_absolute_word; 141} 142 143long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset, 144 unsigned RelOffset, 145 unsigned RelTy) const { 146 147 if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32) 148 return SymOffset - (RelOffset + 4); 149 else 150 assert(0 && "computeRelocation unknown for this relocation type"); 151 152 return 0; 153} 154