blob: c1a49a764614dd0c8b354c9a3a9576e36d9b8ba6 [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 }
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000063}
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) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +000069 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:
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) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +000079 case ELF::R_386_PC32: return Modifier - 4;
80 case ELF::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 }
Bruno Cardoso Lopes0d3193e2009-06-22 19:16:16 +000085}
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000086
87unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
88 if (is64Bit) {
89 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +000090 case ELF::R_X86_64_PC32:
91 case ELF::R_X86_64_32:
92 case ELF::R_X86_64_32S:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000093 return 32;
Rafael Espindolad80f8d02010-11-22 21:49:05 +000094 case ELF::R_X86_64_64:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +000095 return 64;
96 default:
97 llvm_unreachable("unknown x86_64 relocation type");
98 }
99 } else {
100 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000101 case ELF::R_386_PC32:
102 case ELF::R_386_32:
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +0000103 return 32;
104 default:
105 llvm_unreachable("unknown x86 relocation type");
106 }
107 }
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +0000108}
109
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000110bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
111 if (is64Bit) {
112 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000113 case ELF::R_X86_64_PC32:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000114 return true;
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000115 case ELF::R_X86_64_32:
116 case ELF::R_X86_64_32S:
117 case ELF::R_X86_64_64:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000118 return false;
119 default:
120 llvm_unreachable("unknown x86_64 relocation type");
121 }
122 } else {
123 switch(RelTy) {
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000124 case ELF::R_386_PC32:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000125 return true;
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000126 case ELF::R_386_32:
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000127 return false;
128 default:
129 llvm_unreachable("unknown x86 relocation type");
130 }
131 }
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000132}
133
Bruno Cardoso Lopes617dd7b2009-07-18 20:52:11 +0000134unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
135 return is64Bit ?
136 X86::reloc_absolute_dword : X86::reloc_absolute_word;
Bruno Cardoso Lopes171375f2009-07-18 19:30:09 +0000137}
138
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000139long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
140 unsigned RelOffset,
141 unsigned RelTy) const {
142
Rafael Espindolad80f8d02010-11-22 21:49:05 +0000143 if (RelTy == ELF::R_X86_64_PC32 || RelTy == ELF::R_386_PC32)
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000144 return SymOffset - (RelOffset + 4);
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000145
Craig Topper6d1263a2012-02-05 05:38:58 +0000146 llvm_unreachable("computeRelocation unknown for this relocation type");
Bruno Cardoso Lopes0a38dc52009-07-20 08:52:02 +0000147}