1 //===-- PPCMachOWriterInfo.cpp - Mach-O Writer Info for the PowerPC -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements Mach-O writer information for the PowerPC backend.
12 //===----------------------------------------------------------------------===//
14 #include "PPCMachOWriterInfo.h"
15 #include "PPCRelocations.h"
16 #include "PPCTargetMachine.h"
17 #include "llvm/CodeGen/MachORelocation.h"
18 #include "llvm/Support/OutputBuffer.h"
22 PPCMachOWriterInfo::PPCMachOWriterInfo(const PPCTargetMachine
&TM
)
23 : TargetMachOWriterInfo(TM
.getTargetData()->getPointerSizeInBits() == 64 ?
24 HDR_CPU_TYPE_POWERPC64
:
26 HDR_CPU_SUBTYPE_POWERPC_ALL
) {}
27 PPCMachOWriterInfo::~PPCMachOWriterInfo() {}
29 /// GetTargetRelocation - For the MachineRelocation MR, convert it to one or
30 /// more PowerPC MachORelocation(s), add the new relocations to the
31 /// MachOSection, and rewrite the instruction at the section offset if required
32 /// by that relocation type.
33 unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation
&MR
,
37 OutputBuffer
&RelocOut
,
40 bool isExtern
) const {
41 unsigned NumRelocs
= 0;
44 // Get the address of whatever it is we're relocating, if possible.
46 Addr
= (uintptr_t)MR
.getResultPointer() + ToAddr
;
48 switch ((PPC::RelocationType
)MR
.getRelocationType()) {
49 default: assert(0 && "Unknown PPC relocation type!");
50 case PPC::reloc_absolute_low_ix
:
51 assert(0 && "Unhandled PPC relocation type!");
53 case PPC::reloc_vanilla
:
55 // FIXME: need to handle 64 bit vanilla relocs
56 MachORelocation
VANILLA(MR
.getMachineCodeOffset(), ToIdx
,
59 Scattered
, (intptr_t)MR
.getResultPointer());
63 RelocOut
.outword(VANILLA
.getPackedFields());
64 RelocOut
.outword(VANILLA
.getAddress());
66 RelocOut
.outword(VANILLA
.getAddress());
67 RelocOut
.outword(VANILLA
.getPackedFields());
70 intptr_t SymbolOffset
;
73 SymbolOffset
= Addr
+ MR
.getConstantVal();
77 printf("vanilla fixup: sec_%x[%x] = %x\n", FromIdx
,
78 unsigned(MR
.getMachineCodeOffset()),
79 unsigned(SymbolOffset
));
80 SecOut
.fixword(SymbolOffset
, MR
.getMachineCodeOffset());
83 case PPC::reloc_pcrel_bx
:
85 // FIXME: Presumably someday we will need to branch to other, non-extern
86 // functions too. Need to figure out some way to distinguish between
87 // target is BB and target is function.
89 MachORelocation
BR24(MR
.getMachineCodeOffset(), ToIdx
, true, 2,
90 isExtern
, PPC_RELOC_BR24
, Scattered
,
91 (intptr_t)MR
.getMachineCodeOffset());
92 RelocOut
.outword(BR24
.getAddress());
93 RelocOut
.outword(BR24
.getPackedFields());
97 Addr
-= MR
.getMachineCodeOffset();
101 Addr
|= (SecOut
[MR
.getMachineCodeOffset()] << 24);
102 Addr
|= (SecOut
[MR
.getMachineCodeOffset()+3] & 0x3);
103 SecOut
.fixword(Addr
, MR
.getMachineCodeOffset());
106 case PPC::reloc_pcrel_bcx
:
108 Addr
-= MR
.getMachineCodeOffset();
111 SecOut
.fixhalf(Addr
, MR
.getMachineCodeOffset() + 2);
114 case PPC::reloc_absolute_high
:
116 MachORelocation
HA16(MR
.getMachineCodeOffset(), ToIdx
, false, 2,
117 isExtern
, PPC_RELOC_HA16
);
118 MachORelocation
PAIR(Addr
& 0xFFFF, 0xFFFFFF, false, 2, isExtern
,
122 RelocOut
.outword(HA16
.getRawAddress());
123 RelocOut
.outword(HA16
.getPackedFields());
124 RelocOut
.outword(PAIR
.getRawAddress());
125 RelocOut
.outword(PAIR
.getPackedFields());
129 SecOut
.fixhalf(Addr
>> 16, MR
.getMachineCodeOffset() + 2);
132 case PPC::reloc_absolute_low
:
134 MachORelocation
LO16(MR
.getMachineCodeOffset(), ToIdx
, false, 2,
135 isExtern
, PPC_RELOC_LO16
);
136 MachORelocation
PAIR(Addr
>> 16, 0xFFFFFF, false, 2, isExtern
,
140 RelocOut
.outword(LO16
.getRawAddress());
141 RelocOut
.outword(LO16
.getPackedFields());
142 RelocOut
.outword(PAIR
.getRawAddress());
143 RelocOut
.outword(PAIR
.getPackedFields());
145 SecOut
.fixhalf(Addr
, MR
.getMachineCodeOffset() + 2);