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 22 using namespace llvm; 23 24 //===----------------------------------------------------------------------===// 25 // Implementation of the X86ELFWriterInfo class 26 //===----------------------------------------------------------------------===// 27 28 X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_) 29 : TargetELFWriterInfo(is64Bit_, isLittleEndian_) { 30 EMachine = is64Bit ? EM_X86_64 : EM_386; 31 } 32 33 X86ELFWriterInfo::~X86ELFWriterInfo() {} 34 35 unsigned 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 66 long 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 89 unsigned 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 113 bool 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 138 unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const { 139 return is64Bit ? 140 X86::reloc_absolute_dword : X86::reloc_absolute_word; 141 } 142 143 long 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