blob: de3960d54f4862acdfc9059a8cb630d7fb422e93 [file] [log] [blame]
Bill Wendling841056a2007-01-24 03:36:05 +00001//===-- PPCMachOWriterInfo.cpp - Mach-O Writer Info for the PowerPC -------===//
2//
3// The LLVM Compiler Infrastructure
4//
Bill Wendling2f5bcb52007-02-08 06:05:08 +00005// This file was developed by Bill Wendling and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
Bill Wendling841056a2007-01-24 03:36:05 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements Mach-O writer information for the PowerPC backend.
11//
12//===----------------------------------------------------------------------===//
13
14#include "PPCMachOWriterInfo.h"
Bill Wendling736610c2007-02-03 02:41:58 +000015#include "PPCRelocations.h"
Bill Wendling841056a2007-01-24 03:36:05 +000016#include "PPCTargetMachine.h"
Bill Wendling736610c2007-02-03 02:41:58 +000017#include "llvm/CodeGen/MachORelocation.h"
18#include "llvm/Support/OutputBuffer.h"
Bill Wendling841056a2007-01-24 03:36:05 +000019using namespace llvm;
20
21PPCMachOWriterInfo::PPCMachOWriterInfo(const PPCTargetMachine &TM)
22 : TargetMachOWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64 ?
23 HDR_CPU_TYPE_POWERPC64 :
24 HDR_CPU_TYPE_POWERPC,
25 HDR_CPU_SUBTYPE_POWERPC_ALL) {}
Bill Wendling736610c2007-02-03 02:41:58 +000026PPCMachOWriterInfo::~PPCMachOWriterInfo() {}
27
Bill Wendling736610c2007-02-03 02:41:58 +000028/// GetTargetRelocation - For the MachineRelocation MR, convert it to one or
29/// more PowerPC MachORelocation(s), add the new relocations to the
30/// MachOSection, and rewrite the instruction at the section offset if required
31/// by that relocation type.
32unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR,
33 unsigned FromIdx,
34 unsigned ToAddr,
35 unsigned ToIdx,
36 OutputBuffer &RelocOut,
37 OutputBuffer &SecOut,
38 bool Scattered) const {
39 unsigned NumRelocs = 0;
40 uint64_t Addr = 0;
41
42 // Keep track of whether or not this is an externally defined relocation.
43 bool isExtern = false;
44
45 // Get the address of whatever it is we're relocating, if possible.
46 if (!isExtern)
47 Addr = (uintptr_t)MR.getResultPointer() + ToAddr;
48
49 switch ((PPC::RelocationType)MR.getRelocationType()) {
50 default: assert(0 && "Unknown PPC relocation type!");
51 case PPC::reloc_absolute_low_ix:
52 assert(0 && "Unhandled PPC relocation type!");
53 break;
54 case PPC::reloc_vanilla:
55 {
56 // FIXME: need to handle 64 bit vanilla relocs
57 MachORelocation VANILLA(MR.getMachineCodeOffset(), ToIdx,
58 false, 2, isExtern,
59 PPC_RELOC_VANILLA,
60 Scattered, (intptr_t)MR.getResultPointer());
61 ++NumRelocs;
62
63 if (Scattered) {
64 RelocOut.outword(VANILLA.getPackedFields());
65 RelocOut.outword(VANILLA.getAddress());
66 } else {
67 RelocOut.outword(VANILLA.getAddress());
68 RelocOut.outword(VANILLA.getPackedFields());
69 }
70
71 intptr_t SymbolOffset;
72
73 if (Scattered)
74 SymbolOffset = Addr + MR.getConstantVal();
75 else
76 SymbolOffset = Addr;
77
78 printf("vanilla fixup: sec_%x[%x] = %x\n", FromIdx,
79 unsigned(MR.getMachineCodeOffset()),
80 unsigned(SymbolOffset));
81 SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset());
82 }
83 break;
84 case PPC::reloc_pcrel_bx:
85 {
86 Addr -= MR.getMachineCodeOffset();
87 Addr >>= 2;
88 Addr &= 0xFFFFFF;
89 Addr <<= 2;
90 Addr |= (SecOut[MR.getMachineCodeOffset()] << 24);
91
92 SecOut.fixword(Addr, MR.getMachineCodeOffset());
93 break;
94 }
95 case PPC::reloc_pcrel_bcx:
96 {
97 Addr -= MR.getMachineCodeOffset();
98 Addr &= 0xFFFC;
99
100 SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
101 break;
102 }
103 case PPC::reloc_absolute_high:
104 {
105 MachORelocation HA16(MR.getMachineCodeOffset(), ToIdx, false, 2,
106 isExtern, PPC_RELOC_HA16);
107 MachORelocation PAIR(Addr & 0xFFFF, 0xFFFFFF, false, 2, isExtern,
108 PPC_RELOC_PAIR);
109 NumRelocs = 2;
110
111 RelocOut.outword(HA16.getRawAddress());
112 RelocOut.outword(HA16.getPackedFields());
113 RelocOut.outword(PAIR.getRawAddress());
114 RelocOut.outword(PAIR.getPackedFields());
115
116 Addr += 0x8000;
117
118 SecOut.fixhalf(Addr >> 16, MR.getMachineCodeOffset() + 2);
119 break;
120 }
121 case PPC::reloc_absolute_low:
122 {
123 MachORelocation LO16(MR.getMachineCodeOffset(), ToIdx, false, 2,
124 isExtern, PPC_RELOC_LO16);
125 MachORelocation PAIR(Addr >> 16, 0xFFFFFF, false, 2, isExtern,
126 PPC_RELOC_PAIR);
127 NumRelocs = 2;
128
129 RelocOut.outword(LO16.getRawAddress());
130 RelocOut.outword(LO16.getPackedFields());
131 RelocOut.outword(PAIR.getRawAddress());
132 RelocOut.outword(PAIR.getPackedFields());
133
134 SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2);
135 break;
136 }
137 }
138
139 return NumRelocs;
140}