LLVM API Documentation
00001 //===-- PPCMachOWriterInfo.cpp - Mach-O Writer Info for the PowerPC -------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements Mach-O writer information for the PowerPC backend. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "PPCMachOWriterInfo.h" 00015 #include "PPCRelocations.h" 00016 #include "PPCTargetMachine.h" 00017 #include "llvm/CodeGen/MachORelocation.h" 00018 #include "llvm/Support/OutputBuffer.h" 00019 #include <cstdio> 00020 using namespace llvm; 00021 00022 PPCMachOWriterInfo::PPCMachOWriterInfo(const PPCTargetMachine &TM) 00023 : TargetMachOWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64 ? 00024 HDR_CPU_TYPE_POWERPC64 : 00025 HDR_CPU_TYPE_POWERPC, 00026 HDR_CPU_SUBTYPE_POWERPC_ALL) {} 00027 PPCMachOWriterInfo::~PPCMachOWriterInfo() {} 00028 00029 /// GetTargetRelocation - For the MachineRelocation MR, convert it to one or 00030 /// more PowerPC MachORelocation(s), add the new relocations to the 00031 /// MachOSection, and rewrite the instruction at the section offset if required 00032 /// by that relocation type. 00033 unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR, 00034 unsigned FromIdx, 00035 unsigned ToAddr, 00036 unsigned ToIdx, 00037 OutputBuffer &RelocOut, 00038 OutputBuffer &SecOut, 00039 bool Scattered, 00040 bool isExtern) const { 00041 unsigned NumRelocs = 0; 00042 uint64_t Addr = 0; 00043 00044 // Get the address of whatever it is we're relocating, if possible. 00045 if (!isExtern) 00046 Addr = (uintptr_t)MR.getResultPointer() + ToAddr; 00047 00048 switch ((PPC::RelocationType)MR.getRelocationType()) { 00049 default: assert(0 && "Unknown PPC relocation type!"); 00050 case PPC::reloc_absolute_low_ix: 00051 assert(0 && "Unhandled PPC relocation type!"); 00052 break; 00053 case PPC::reloc_vanilla: 00054 { 00055 // FIXME: need to handle 64 bit vanilla relocs 00056 MachORelocation VANILLA(MR.getMachineCodeOffset(), ToIdx, 00057 false, 2, isExtern, 00058 PPC_RELOC_VANILLA, 00059 Scattered, (intptr_t)MR.getResultPointer()); 00060 ++NumRelocs; 00061 00062 if (Scattered) { 00063 RelocOut.outword(VANILLA.getPackedFields()); 00064 RelocOut.outword(VANILLA.getAddress()); 00065 } else { 00066 RelocOut.outword(VANILLA.getAddress()); 00067 RelocOut.outword(VANILLA.getPackedFields()); 00068 } 00069 00070 intptr_t SymbolOffset; 00071 00072 if (Scattered) 00073 SymbolOffset = Addr + MR.getConstantVal(); 00074 else 00075 SymbolOffset = Addr; 00076 00077 printf("vanilla fixup: sec_%x[%x] = %x\n", FromIdx, 00078 unsigned(MR.getMachineCodeOffset()), 00079 unsigned(SymbolOffset)); 00080 SecOut.fixword(SymbolOffset, MR.getMachineCodeOffset()); 00081 } 00082 break; 00083 case PPC::reloc_pcrel_bx: 00084 { 00085 // FIXME: Presumably someday we will need to branch to other, non-extern 00086 // functions too. Need to figure out some way to distinguish between 00087 // target is BB and target is function. 00088 if (isExtern) { 00089 MachORelocation BR24(MR.getMachineCodeOffset(), ToIdx, true, 2, 00090 isExtern, PPC_RELOC_BR24, Scattered, 00091 (intptr_t)MR.getMachineCodeOffset()); 00092 RelocOut.outword(BR24.getAddress()); 00093 RelocOut.outword(BR24.getPackedFields()); 00094 ++NumRelocs; 00095 } 00096 00097 Addr -= MR.getMachineCodeOffset(); 00098 Addr >>= 2; 00099 Addr &= 0xFFFFFF; 00100 Addr <<= 2; 00101 Addr |= (SecOut[MR.getMachineCodeOffset()] << 24); 00102 Addr |= (SecOut[MR.getMachineCodeOffset()+3] & 0x3); 00103 SecOut.fixword(Addr, MR.getMachineCodeOffset()); 00104 break; 00105 } 00106 case PPC::reloc_pcrel_bcx: 00107 { 00108 Addr -= MR.getMachineCodeOffset(); 00109 Addr &= 0xFFFC; 00110 00111 SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2); 00112 break; 00113 } 00114 case PPC::reloc_absolute_high: 00115 { 00116 MachORelocation HA16(MR.getMachineCodeOffset(), ToIdx, false, 2, 00117 isExtern, PPC_RELOC_HA16); 00118 MachORelocation PAIR(Addr & 0xFFFF, 0xFFFFFF, false, 2, isExtern, 00119 PPC_RELOC_PAIR); 00120 NumRelocs = 2; 00121 00122 RelocOut.outword(HA16.getRawAddress()); 00123 RelocOut.outword(HA16.getPackedFields()); 00124 RelocOut.outword(PAIR.getRawAddress()); 00125 RelocOut.outword(PAIR.getPackedFields()); 00126 00127 Addr += 0x8000; 00128 00129 SecOut.fixhalf(Addr >> 16, MR.getMachineCodeOffset() + 2); 00130 break; 00131 } 00132 case PPC::reloc_absolute_low: 00133 { 00134 MachORelocation LO16(MR.getMachineCodeOffset(), ToIdx, false, 2, 00135 isExtern, PPC_RELOC_LO16); 00136 MachORelocation PAIR(Addr >> 16, 0xFFFFFF, false, 2, isExtern, 00137 PPC_RELOC_PAIR); 00138 NumRelocs = 2; 00139 00140 RelocOut.outword(LO16.getRawAddress()); 00141 RelocOut.outword(LO16.getPackedFields()); 00142 RelocOut.outword(PAIR.getRawAddress()); 00143 RelocOut.outword(PAIR.getPackedFields()); 00144 00145 SecOut.fixhalf(Addr, MR.getMachineCodeOffset() + 2); 00146 break; 00147 } 00148 } 00149 00150 return NumRelocs; 00151 }