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 X86ELFWriterInfo(bool is64Bit_,bool isLittleEndian_)28X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_) 29 : TargetELFWriterInfo(is64Bit_, isLittleEndian_) { 30 EMachine = is64Bit ? EM_X86_64 : EM_386; 31 } 32 ~X86ELFWriterInfo()33X86ELFWriterInfo::~X86ELFWriterInfo() {} 34 getRelocationType(unsigned MachineRelTy) const35unsigned 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 } 64 getDefaultAddendForRelTy(unsigned RelTy,long int Modifier) const65long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, 66 long int Modifier) const { 67 if (is64Bit) { 68 switch(RelTy) { 69 case ELF::R_X86_64_PC32: return Modifier - 4; 70 case ELF::R_X86_64_32: 71 case ELF::R_X86_64_32S: 72 case ELF::R_X86_64_64: 73 return Modifier; 74 default: 75 llvm_unreachable("unknown x86_64 relocation type"); 76 } 77 } else { 78 switch(RelTy) { 79 case ELF::R_386_PC32: return Modifier - 4; 80 case ELF::R_386_32: return Modifier; 81 default: 82 llvm_unreachable("unknown x86 relocation type"); 83 } 84 } 85 } 86 getRelocationTySize(unsigned RelTy) const87unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const { 88 if (is64Bit) { 89 switch(RelTy) { 90 case ELF::R_X86_64_PC32: 91 case ELF::R_X86_64_32: 92 case ELF::R_X86_64_32S: 93 return 32; 94 case ELF::R_X86_64_64: 95 return 64; 96 default: 97 llvm_unreachable("unknown x86_64 relocation type"); 98 } 99 } else { 100 switch(RelTy) { 101 case ELF::R_386_PC32: 102 case ELF::R_386_32: 103 return 32; 104 default: 105 llvm_unreachable("unknown x86 relocation type"); 106 } 107 } 108 } 109 isPCRelativeRel(unsigned RelTy) const110bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { 111 if (is64Bit) { 112 switch(RelTy) { 113 case ELF::R_X86_64_PC32: 114 return true; 115 case ELF::R_X86_64_32: 116 case ELF::R_X86_64_32S: 117 case ELF::R_X86_64_64: 118 return false; 119 default: 120 llvm_unreachable("unknown x86_64 relocation type"); 121 } 122 } else { 123 switch(RelTy) { 124 case ELF::R_386_PC32: 125 return true; 126 case ELF::R_386_32: 127 return false; 128 default: 129 llvm_unreachable("unknown x86 relocation type"); 130 } 131 } 132 } 133 getAbsoluteLabelMachineRelTy() const134unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const { 135 return is64Bit ? 136 X86::reloc_absolute_dword : X86::reloc_absolute_word; 137 } 138 computeRelocation(unsigned SymOffset,unsigned RelOffset,unsigned RelTy) const139long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset, 140 unsigned RelOffset, 141 unsigned RelTy) const { 142 143 if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32) 144 return SymOffset - (RelOffset + 4); 145 146 llvm_unreachable("computeRelocation unknown for this relocation type"); 147 } 148