For PC relative relocations where symbols are defined in the same section they
[oota-llvm.git] / lib / Target / X86 / X86ELFWriterInfo.cpp
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/ErrorHandling.h"
18 #include "llvm/Target/TargetData.h"
19 #include "llvm/Target/TargetMachine.h"
20
21 using namespace llvm;
22
23 //===----------------------------------------------------------------------===//
24 //  Implementation of the X86ELFWriterInfo class
25 //===----------------------------------------------------------------------===//
26
27 X86ELFWriterInfo::X86ELFWriterInfo(TargetMachine &TM)
28   : TargetELFWriterInfo(TM) {
29     bool is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
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 R_X86_64_PC32;
40     case X86::reloc_absolute_word:
41       return R_X86_64_32;
42     case X86::reloc_absolute_dword:
43       return R_X86_64_64;
44     case X86::reloc_picrel_word:
45     default:
46       llvm_unreachable("unknown x86_64 machine relocation type");
47     }
48   } else {
49     switch(MachineRelTy) {
50     case X86::reloc_pcrel_word:
51       return R_386_PC32;
52     case X86::reloc_absolute_word:
53       return R_386_32;
54     case X86::reloc_absolute_dword:
55     case X86::reloc_picrel_word:
56     default:
57       llvm_unreachable("unknown x86 machine relocation type");
58     }
59   }
60   return 0;
61 }
62
63 long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy) const {
64   if (is64Bit) {
65     switch(RelTy) {
66     case R_X86_64_PC32: return -4;
67     case R_X86_64_32: return 0;
68     default:
69       llvm_unreachable("unknown x86_64 relocation type");
70     }
71   } else {
72     switch(RelTy) {
73       case R_386_PC32: return -4;
74       case R_386_32: return 0;
75     default:
76       llvm_unreachable("unknown x86 relocation type");
77     }
78   }
79   return 0;
80 }
81
82 unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
83   if (is64Bit) {
84     switch(RelTy) {
85       case R_X86_64_PC32:
86       case R_X86_64_32:
87       case R_X86_64_32S:
88         return 32;
89       case R_X86_64_64:
90         return 64;
91     default:
92       llvm_unreachable("unknown x86_64 relocation type");
93     }
94   } else {
95     switch(RelTy) {
96       case R_386_PC32:
97       case R_386_32:
98         return 32;
99     default:
100       llvm_unreachable("unknown x86 relocation type");
101     }
102   }
103   return 0;
104 }
105
106 bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
107   if (is64Bit) {
108     switch(RelTy) {
109       case R_X86_64_PC32:
110         return true;
111       case R_X86_64_32:
112       case R_X86_64_32S:
113       case R_X86_64_64:
114         return false;
115     default:
116       llvm_unreachable("unknown x86_64 relocation type");
117     }
118   } else {
119     switch(RelTy) {
120       case R_386_PC32:
121         return true;
122       case R_386_32:
123         return false;
124     default:
125       llvm_unreachable("unknown x86 relocation type");
126     }
127   }
128   return 0;
129 }
130
131 unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
132   return is64Bit ?
133     X86::reloc_absolute_dword : X86::reloc_absolute_word;
134 }
135
136 long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
137                                              unsigned RelOffset,
138                                              unsigned RelTy) const {
139
140   if (RelTy == R_X86_64_PC32 || RelTy == R_386_PC32)
141     return SymOffset - (RelOffset + 4);
142   else
143     assert("computeRelocation unknown for this relocation type");
144
145   return 0;
146 }