blob: f1d7edea7210a909762025dfe5eef5d6c869a755 [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"
Rafael Espindolad80f8d02010-11-22 21:49:05 +000017#include "llvm/Support/ELF.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000018#include "llvm/Support/ErrorHandling.h"
Bruno Cardoso Lopesd00d4152009-06-11 22:13:00 +000019#include "llvm/Target/TargetData.h"
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000020#include "llvm/Target/TargetMachine.h"
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000021
Bill Wendling40d77642007-01-27 02:54:30 +000022using namespace llvm;
23
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000024//===----------------------------------------------------------------------===//
25// Implementation of the X86ELFWriterInfo class
26//===----------------------------------------------------------------------===//
27
Rafael Espindola0febc462010-10-03 18:59:45 +000028X86ELFWriterInfo::X86ELFWriterInfo(bool is64Bit_, bool isLittleEndian_)
29 : TargetELFWriterInfo(is64Bit_, isLittleEndian_) {
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000030 EMachine = is64Bit ? EM_X86_64 : EM_386;
31 }
32
Bill Wendling0db1f0b2007-01-27 11:40:32 +000033X86ELFWriterInfo::~X86ELFWriterInfo() {}
Bruno Cardoso Lopesc997d452009-06-11 19:16:03 +000034
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000035unsigned X86ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
36 if (is64Bit) {
37 switch(MachineRelTy) {
38 case X86::reloc_pcrel_word:
Rafael Espindolad80f8d02010-11-22 21:49:05 +000039 return ELF::R_X86_64_PC32;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000040 case X86::reloc_absolute_word:
Rafael Espindolad80f8d02010-11-22 21:49:05 +000041 return ELF::R_X86_64_32;
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000042 case X86::reloc_absolute_word_sext:
Rafael Espindolad80f8d02010-11-22 21:49:05 +000043 return ELF::R_X86_64_32S;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000044 case X86::reloc_absolute_dword:
Rafael Espindolad80f8d02010-11-22 21:49:05 +000045 return ELF::R_X86_64_64;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000046 case X86::reloc_picrel_word:
47 default:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000048 llvm_unreachable("unknown x86_64 machine relocation type");
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000049 }
50 } else {
51 switch(MachineRelTy) {
52 case X86::reloc_pcrel_word:
Rafael Espindolad80f8d02010-11-22 21:49:05 +000053 return ELF::R_386_PC32;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000054 case X86::reloc_absolute_word:
Rafael Espindolad80f8d02010-11-22 21:49:05 +000055 return ELF::R_386_32;
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000056 case X86::reloc_absolute_word_sext:
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000057 case X86::reloc_absolute_dword:
58 case X86::reloc_picrel_word:
59 default:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000060 llvm_unreachable("unknown x86 machine relocation type");
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000061 }
62 }
63 return 0;
64}
65
Bruno Cardoso Lopes52d08512009-08-05 06:57:03 +000066long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
67 long int Modifier) const {
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000068 if (is64Bit) {
69 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +000070 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 Lopes52d08512009-08-05 06:57:03 +000074 return Modifier;
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000075 default:
76 llvm_unreachable("unknown x86_64 relocation type");
77 }
78 } else {
79 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +000080 case ELF::R_386_PC32: return Modifier - 4;
81 case ELF::R_386_32: return Modifier;
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000082 default:
Torok Edwinc23197a2009-07-14 16:55:14 +000083 llvm_unreachable("unknown x86 relocation type");
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000084 }
85 }
86 return 0;
87}
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000088
89unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
90 if (is64Bit) {
91 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +000092 case ELF::R_X86_64_PC32:
93 case ELF::R_X86_64_32:
94 case ELF::R_X86_64_32S:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000095 return 32;
Rafael Espindolad80f8d02010-11-22 21:49:05 +000096 case ELF::R_X86_64_64:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000097 return 64;
98 default:
99 llvm_unreachable("unknown x86_64 relocation type");
100 }
101 } else {
102 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000103 case ELF::R_386_PC32:
104 case ELF::R_386_32:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +0000105 return 32;
106 default:
107 llvm_unreachable("unknown x86 relocation type");
108 }
109 }
110 return 0;
111}
112
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000113bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
114 if (is64Bit) {
115 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000116 case ELF::R_X86_64_PC32:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000117 return true;
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000118 case ELF::R_X86_64_32:
119 case ELF::R_X86_64_32S:
120 case ELF::R_X86_64_64:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000121 return false;
122 default:
123 llvm_unreachable("unknown x86_64 relocation type");
124 }
125 } else {
126 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000127 case ELF::R_386_PC32:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000128 return true;
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000129 case ELF::R_386_32:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000130 return false;
131 default:
132 llvm_unreachable("unknown x86 relocation type");
133 }
134 }
135 return 0;
136}
137
Bruno Cardoso Lopes617dd7b2009-07-18 20:52:11 +0000138unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
139 return is64Bit ?
140 X86::reloc_absolute_dword : X86::reloc_absolute_word;
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +0000141}
142
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000143long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
144 unsigned RelOffset,
145 unsigned RelTy) const {
146
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000147 if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32)
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000148 return SymOffset - (RelOffset + 4);
149 else
150 assert("computeRelocation unknown for this relocation type");
151
152 return 0;
153}