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"
21 PPCMachOWriterInfo::PPCMachOWriterInfo(const PPCTargetMachine
&TM
)
22 : TargetMachOWriterInfo(TM
.getTargetData()->getPointerSizeInBits() == 64 ?
23 HDR_CPU_TYPE_POWERPC64
:
25 HDR_CPU_SUBTYPE_POWERPC_ALL
) {}
26 PPCMachOWriterInfo::~PPCMachOWriterInfo() {}
28 /// 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.
32 unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation
&MR
,
36 OutputBuffer
&RelocOut
,
39 bool isExtern
) const {
40 unsigned NumRelocs
= 0;
43 // Get the address of whatever it is we're relocating, if possible.
45 Addr
= (uintptr_t)MR
.getResultPointer() + ToAddr
;
47 switch ((PPC::RelocationType
)MR
.getRelocationType()) {
48 default: assert(0 && "Unknown PPC relocation type!");
49 case PPC::reloc_absolute_low_ix
:
50 assert(0 && "Unhandled PPC relocation type!");
52 case PPC::reloc_vanilla
:
54 // FIXME: need to handle 64 bit vanilla relocs
55 MachORelocation
VANILLA(MR
.getMachineCodeOffset(), ToIdx
,
58 Scattered
, (intptr_t)MR
.getResultPointer());
62 RelocOut
.outword(VANILLA
.getPackedFields());
63 RelocOut
.outword(VANILLA
.getAddress());
65 RelocOut
.outword(VANILLA
.getAddress());
66 RelocOut
.outword(VANILLA
.getPackedFields());
69 intptr_t SymbolOffset
;
72 SymbolOffset
= Addr
+ MR
.getConstantVal();
76 printf("vanilla fixup: sec_%x[%x] = %x\n", FromIdx
,
77 unsigned(MR
.getMachineCodeOffset()),
78 unsigned(SymbolOffset
));
79 SecOut
.fixword(SymbolOffset
, MR
.getMachineCodeOffset());
82 case PPC::reloc_pcrel_bx
:
84 // FIXME: Presumably someday we will need to branch to other, non-extern
85 // functions too. Need to figure out some way to distinguish between
86 // target is BB and target is function.
88 MachORelocation
BR24(MR
.getMachineCodeOffset(), ToIdx
, true, 2,
89 isExtern
, PPC_RELOC_BR24
, Scattered
,
90 (intptr_t)MR
.getMachineCodeOffset());
91 RelocOut
.outword(BR24
.getAddress());
92 RelocOut
.outword(BR24
.getPackedFields());
96 Addr
-= MR
.getMachineCodeOffset();
100 Addr
|= (SecOut
[MR
.getMachineCodeOffset()] << 24);
101 Addr
|= (SecOut
[MR
.getMachineCodeOffset()+3] & 0x3);
102 SecOut
.fixword(Addr
, MR
.getMachineCodeOffset());
105 case PPC::reloc_pcrel_bcx
:
107 Addr
-= MR
.getMachineCodeOffset();
110 SecOut
.fixhalf(Addr
, MR
.getMachineCodeOffset() + 2);
113 case PPC::reloc_absolute_high
:
115 MachORelocation
HA16(MR
.getMachineCodeOffset(), ToIdx
, false, 2,
116 isExtern
, PPC_RELOC_HA16
);
117 MachORelocation
PAIR(Addr
& 0xFFFF, 0xFFFFFF, false, 2, isExtern
,
121 RelocOut
.outword(HA16
.getRawAddress());
122 RelocOut
.outword(HA16
.getPackedFields());
123 RelocOut
.outword(PAIR
.getRawAddress());
124 RelocOut
.outword(PAIR
.getPackedFields());
128 SecOut
.fixhalf(Addr
>> 16, MR
.getMachineCodeOffset() + 2);
131 case PPC::reloc_absolute_low
:
133 MachORelocation
LO16(MR
.getMachineCodeOffset(), ToIdx
, false, 2,
134 isExtern
, PPC_RELOC_LO16
);
135 MachORelocation
PAIR(Addr
>> 16, 0xFFFFFF, false, 2, isExtern
,
139 RelocOut
.outword(LO16
.getRawAddress());
140 RelocOut
.outword(LO16
.getPackedFields());
141 RelocOut
.outword(PAIR
.getRawAddress());
142 RelocOut
.outword(PAIR
.getPackedFields());
144 SecOut
.fixhalf(Addr
, MR
.getMachineCodeOffset() + 2);