LLVM API Documentation

PPCMachOWriterInfo.cpp

Go to the documentation of this file.
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 }