blob: 3b721b4fe0eb8ff047f96c3cebf94bc1c726457d [file] [log] [blame]
Bill Wendling40d77642007-01-27 02:54:30 +00001//===-- X86ELFWriterInfo.cpp - ELF Writer Info for the X86 backend --------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Bill Wendling40d77642007-01-27 02:54:30 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements ELF writer information for the X86 backend.
11//
12//===----------------------------------------------------------------------===//
13
14#include "X86ELFWriterInfo.h"
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000015#include "X86Relocations.h"
Bruno Cardoso Lopesd00d4152009-06-11 22:13:00 +000016#include "llvm/Function.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000017#include "llvm/Support/ErrorHandling.h"
Bruno Cardoso Lopesd00d4152009-06-11 22:13:00 +000018#include "llvm/Target/TargetData.h"
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000019#include "llvm/Target/TargetMachine.h"
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000020
Bill Wendling40d77642007-01-27 02:54:30 +000021using namespace llvm;
22
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000023//===----------------------------------------------------------------------===//
24// Implementation of the X86ELFWriterInfo class
25//===----------------------------------------------------------------------===//
26
Rafael Espindola0febc462010-10-03 18:59:45 +000027X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_)
28 : TargetELFWriterInfo(is64Bit_, isLittleEndian_) {
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000029 EMachine = is64Bit ? EM_X86_64 : EM_386;
30 }
31
Bill Wendling0db1f0b2007-01-27 11:40:32 +000032X86ELFWriterInfo::~X86ELFWriterInfo() {}
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000033
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000034unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
35 if (is64Bit) {
36 switch(MachineRelTy) {
37 case X86::reloc_pcrel_word:
38 return R_X86_64_PC32;
39 case X86::reloc_absolute_word:
40 return R_X86_64_32;
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000041 case X86::reloc_absolute_word_sext:
42 return R_X86_64_32S;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000043 case X86::reloc_absolute_dword:
44 return R_X86_64_64;
45 case X86::reloc_picrel_word:
46 default:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000047 llvm_unreachable("unknown x86_64 machine relocation type");
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000048 }
49 } else {
50 switch(MachineRelTy) {
51 case X86::reloc_pcrel_word:
52 return R_386_PC32;
53 case X86::reloc_absolute_word:
54 return R_386_32;
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000055 case X86::reloc_absolute_word_sext:
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000056 case X86::reloc_absolute_dword:
57 case X86::reloc_picrel_word:
58 default:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000059 llvm_unreachable("unknown x86 machine relocation type");
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000060 }
61 }
62 return 0;
63}
64
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000065long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
66 long int Modifier) const {
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000067 if (is64Bit) {
68 switch(RelTy) {
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000069 case R_X86_64_PC32: return Modifier - 4;
Bruno Cardoso Lopes68491c12009-07-21 06:51:32 +000070 case R_X86_64_32:
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000071 case R_X86_64_32S:
Bruno Cardoso Lopes68491c12009-07-21 06:51:32 +000072 case R_X86_64_64:
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000073 return Modifier;
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000074 default:
75 llvm_unreachable("unknown x86_64 relocation type");
76 }
77 } else {
78 switch(RelTy) {
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000079 case R_386_PC32: return Modifier - 4;
80 case R_386_32: return Modifier;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000081 default:
Torok Edwinc23197a2009-07-14 16:55:14 +000082 llvm_unreachable("unknown x86 relocation type");
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000083 }
84 }
85 return 0;
86}
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000087
88unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
89 if (is64Bit) {
90 switch(RelTy) {
91 case R_X86_64_PC32:
92 case R_X86_64_32:
Bruno Cardoso Lopese2b0ecd2009-07-18 23:24:01 +000093 case R_X86_64_32S:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000094 return 32;
95 case R_X86_64_64:
96 return 64;
97 default:
98 llvm_unreachable("unknown x86_64 relocation type");
99 }
100 } else {
101 switch(RelTy) {
102 case R_386_PC32:
103 case R_386_32:
104 return 32;
105 default:
106 llvm_unreachable("unknown x86 relocation type");
107 }
108 }
109 return 0;
110}
111
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000112bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
113 if (is64Bit) {
114 switch(RelTy) {
115 case R_X86_64_PC32:
116 return true;
117 case R_X86_64_32:
118 case R_X86_64_32S:
119 case R_X86_64_64:
120 return false;
121 default:
122 llvm_unreachable("unknown x86_64 relocation type");
123 }
124 } else {
125 switch(RelTy) {
126 case R_386_PC32:
127 return true;
128 case R_386_32:
129 return false;
130 default:
131 llvm_unreachable("unknown x86 relocation type");
132 }
133 }
134 return 0;
135}
136
Bruno Cardoso Lopes617dd7b2009-07-18 20:52:11 +0000137unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
138 return is64Bit ?
139 X86::reloc_absolute_dword : X86::reloc_absolute_word;
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +0000140}
141
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000142long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
143 unsigned RelOffset,
144 unsigned RelTy) const {
145
146 if (RelTy == R_X86_64_PC32 || RelTy == R_386_PC32)
147 return SymOffset - (RelOffset + 4);
148 else
149 assert("computeRelocation unknown for this relocation type");
150
151 return 0;
152}