| Bill Wendling | 2bab162 | 2007-01-27 02:54:30 +0000 | [diff] [blame] | 1 | //===-- X86ELFWriterInfo.cpp - ELF Writer Info for the X86 backend --------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Bill Wendling | 2bab162 | 2007-01-27 02:54:30 +0000 | [diff] [blame] | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file implements ELF writer information for the X86 backend. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "X86ELFWriterInfo.h" | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 15 | #include "X86Relocations.h" | 
| Bruno Cardoso Lopes | 6618950 | 2009-06-11 22:13:00 +0000 | [diff] [blame] | 16 | #include "llvm/Function.h" | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 17 | #include "llvm/Support/ELF.h" | 
| Torok Edwin | 56d0659 | 2009-07-11 20:10:48 +0000 | [diff] [blame] | 18 | #include "llvm/Support/ErrorHandling.h" | 
| Bruno Cardoso Lopes | 6618950 | 2009-06-11 22:13:00 +0000 | [diff] [blame] | 19 | #include "llvm/Target/TargetData.h" | 
| Bruno Cardoso Lopes | 1656366 | 2009-06-11 19:16:03 +0000 | [diff] [blame] | 20 | #include "llvm/Target/TargetMachine.h" | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 21 |  | 
| Bill Wendling | 2bab162 | 2007-01-27 02:54:30 +0000 | [diff] [blame] | 22 | using namespace llvm; | 
|  | 23 |  | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 24 | //===----------------------------------------------------------------------===// | 
|  | 25 | //  Implementation of the X86ELFWriterInfo class | 
|  | 26 | //===----------------------------------------------------------------------===// | 
|  | 27 |  | 
| Rafael Espindola | 66e08d4 | 2010-10-03 18:59:45 +0000 | [diff] [blame] | 28 | X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_) | 
|  | 29 | : TargetELFWriterInfo(is64Bit_, isLittleEndian_) { | 
| Bruno Cardoso Lopes | 1656366 | 2009-06-11 19:16:03 +0000 | [diff] [blame] | 30 | EMachine = is64Bit ? EM_X86_64 : EM_386; | 
|  | 31 | } | 
|  | 32 |  | 
| Bill Wendling | fa663ee | 2007-01-27 11:40:32 +0000 | [diff] [blame] | 33 | X86ELFWriterInfo::~X86ELFWriterInfo() {} | 
| Bruno Cardoso Lopes | 1656366 | 2009-06-11 19:16:03 +0000 | [diff] [blame] | 34 |  | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 35 | unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { | 
|  | 36 | if (is64Bit) { | 
|  | 37 | switch(MachineRelTy) { | 
|  | 38 | case X86::reloc_pcrel_word: | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 39 | return ELF::R_X86_64_PC32; | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 40 | case X86::reloc_absolute_word: | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 41 | return ELF::R_X86_64_32; | 
| Bruno Cardoso Lopes | 2b1dc9a | 2009-08-05 06:57:03 +0000 | [diff] [blame] | 42 | case X86::reloc_absolute_word_sext: | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 43 | return ELF::R_X86_64_32S; | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 44 | case X86::reloc_absolute_dword: | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 45 | return ELF::R_X86_64_64; | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 46 | case X86::reloc_picrel_word: | 
|  | 47 | default: | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 48 | llvm_unreachable("unknown x86_64 machine relocation type"); | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 49 | } | 
|  | 50 | } else { | 
|  | 51 | switch(MachineRelTy) { | 
|  | 52 | case X86::reloc_pcrel_word: | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 53 | return ELF::R_386_PC32; | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 54 | case X86::reloc_absolute_word: | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 55 | return ELF::R_386_32; | 
| Bruno Cardoso Lopes | 2b1dc9a | 2009-08-05 06:57:03 +0000 | [diff] [blame] | 56 | case X86::reloc_absolute_word_sext: | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 57 | case X86::reloc_absolute_dword: | 
|  | 58 | case X86::reloc_picrel_word: | 
|  | 59 | default: | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 60 | llvm_unreachable("unknown x86 machine relocation type"); | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 61 | } | 
|  | 62 | } | 
|  | 63 | return 0; | 
|  | 64 | } | 
|  | 65 |  | 
| Bruno Cardoso Lopes | 2b1dc9a | 2009-08-05 06:57:03 +0000 | [diff] [blame] | 66 | long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, | 
|  | 67 | long int Modifier) const { | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 68 | if (is64Bit) { | 
|  | 69 | switch(RelTy) { | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 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: | 
| Bruno Cardoso Lopes | 2b1dc9a | 2009-08-05 06:57:03 +0000 | [diff] [blame] | 74 | return Modifier; | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 75 | default: | 
|  | 76 | llvm_unreachable("unknown x86_64 relocation type"); | 
|  | 77 | } | 
|  | 78 | } else { | 
|  | 79 | switch(RelTy) { | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 80 | case ELF::R_386_PC32: return Modifier - 4; | 
|  | 81 | case ELF::R_386_32: return Modifier; | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 82 | default: | 
| Torok Edwin | fbcc663 | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 83 | llvm_unreachable("unknown x86 relocation type"); | 
| Bruno Cardoso Lopes | a040566 | 2009-06-22 19:16:16 +0000 | [diff] [blame] | 84 | } | 
|  | 85 | } | 
|  | 86 | return 0; | 
|  | 87 | } | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 88 |  | 
|  | 89 | unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const { | 
|  | 90 | if (is64Bit) { | 
|  | 91 | switch(RelTy) { | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 92 | case ELF::R_X86_64_PC32: | 
|  | 93 | case ELF::R_X86_64_32: | 
|  | 94 | case ELF::R_X86_64_32S: | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 95 | return 32; | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 96 | case ELF::R_X86_64_64: | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 97 | return 64; | 
|  | 98 | default: | 
|  | 99 | llvm_unreachable("unknown x86_64 relocation type"); | 
|  | 100 | } | 
|  | 101 | } else { | 
|  | 102 | switch(RelTy) { | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 103 | case ELF::R_386_PC32: | 
|  | 104 | case ELF::R_386_32: | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 105 | return 32; | 
|  | 106 | default: | 
|  | 107 | llvm_unreachable("unknown x86 relocation type"); | 
|  | 108 | } | 
|  | 109 | } | 
|  | 110 | return 0; | 
|  | 111 | } | 
|  | 112 |  | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 113 | bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { | 
|  | 114 | if (is64Bit) { | 
|  | 115 | switch(RelTy) { | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 116 | case ELF::R_X86_64_PC32: | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 117 | return true; | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 118 | case ELF::R_X86_64_32: | 
|  | 119 | case ELF::R_X86_64_32S: | 
|  | 120 | case ELF::R_X86_64_64: | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 121 | return false; | 
|  | 122 | default: | 
|  | 123 | llvm_unreachable("unknown x86_64 relocation type"); | 
|  | 124 | } | 
|  | 125 | } else { | 
|  | 126 | switch(RelTy) { | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 127 | case ELF::R_386_PC32: | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 128 | return true; | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 129 | case ELF::R_386_32: | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 130 | return false; | 
|  | 131 | default: | 
|  | 132 | llvm_unreachable("unknown x86 relocation type"); | 
|  | 133 | } | 
|  | 134 | } | 
|  | 135 | return 0; | 
|  | 136 | } | 
|  | 137 |  | 
| Bruno Cardoso Lopes | e376b53 | 2009-07-18 20:52:11 +0000 | [diff] [blame] | 138 | unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const { | 
|  | 139 | return is64Bit ? | 
|  | 140 | X86::reloc_absolute_dword : X86::reloc_absolute_word; | 
| Bruno Cardoso Lopes | 484e90b | 2009-07-18 19:30:09 +0000 | [diff] [blame] | 141 | } | 
|  | 142 |  | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 143 | long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset, | 
|  | 144 | unsigned RelOffset, | 
|  | 145 | unsigned RelTy) const { | 
|  | 146 |  | 
| Rafael Espindola | 6e39a50 | 2010-11-22 21:49:05 +0000 | [diff] [blame] | 147 | if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32) | 
| Bruno Cardoso Lopes | 447b7fd | 2009-07-20 08:52:02 +0000 | [diff] [blame] | 148 | return SymOffset - (RelOffset + 4); | 
|  | 149 | else | 
|  | 150 | assert("computeRelocation unknown for this relocation type"); | 
|  | 151 |  | 
|  | 152 | return 0; | 
|  | 153 | } |