1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#include <mach/machine.h> 24#include <mach-o/reloc.h> 25#include <mach-o/m88k/reloc.h> 26#include <mach-o/ppc/reloc.h> 27#include <mach-o/i860/reloc.h> 28#include <mach-o/hppa/reloc.h> 29#include <mach-o/sparc/reloc.h> 30#include <mach-o/x86_64/reloc.h> 31#include <mach-o/arm/reloc.h> 32#include "stuff/bool.h" 33#include "stuff/errors.h" 34#include "stuff/reloc.h" 35 36/* 37 * reloc_pair_r_type() returns the PAIR constant for the specific cputype for 38 * a paired relocation entry. 39 */ 40__private_extern__ 41uint32_t 42reloc_pair_r_type( 43cpu_type_t cputype) 44{ 45 switch(cputype){ 46 case CPU_TYPE_MC680x0: 47 case CPU_TYPE_I386: 48 return(GENERIC_RELOC_PAIR); 49 break; 50 case CPU_TYPE_X86_64: 51 /* 52 * We should never hit this case for x86-64, so drop down to the 53 * fatal error below. 54 */ 55 break; 56 case CPU_TYPE_MC88000: 57 return(M88K_RELOC_PAIR); 58 break; 59 case CPU_TYPE_I860: 60 return(I860_RELOC_PAIR); 61 break; 62 case CPU_TYPE_POWERPC: 63 case CPU_TYPE_POWERPC64: 64 case CPU_TYPE_VEO: 65 return(PPC_RELOC_PAIR); 66 break; 67 case CPU_TYPE_HPPA: 68 return(HPPA_RELOC_PAIR); 69 break; 70 case CPU_TYPE_SPARC: 71 return(SPARC_RELOC_PAIR); 72 break; 73 case CPU_TYPE_ARM: 74 return(ARM_RELOC_PAIR); 75 break; 76 } 77 fatal("internal error: reloc_pair_r_type() called with unknown " 78 "cputype (%u)", cputype); 79 /* can't get here but to shut up the compiler warning ... */ 80 return(0); 81} 82 83/* 84 * reloc_has_pair() returns TRUE if the specified r_type for the specified 85 * cputype for has a paired relocation entry. 86 */ 87__private_extern__ 88enum bool 89reloc_has_pair( 90cpu_type_t cputype, 91uint32_t r_type) 92{ 93 switch(cputype){ 94 case CPU_TYPE_MC680x0: 95 case CPU_TYPE_I386: 96 if(r_type == GENERIC_RELOC_SECTDIFF || 97 r_type == GENERIC_RELOC_LOCAL_SECTDIFF) 98 return(TRUE); 99 break; 100 case CPU_TYPE_X86_64: 101 return(FALSE); 102 break; 103 case CPU_TYPE_MC88000: 104 if(r_type == M88K_RELOC_HI16 || 105 r_type == M88K_RELOC_LO16 || 106 r_type == M88K_RELOC_SECTDIFF) 107 return(TRUE); 108 break; 109 case CPU_TYPE_I860: 110 if(r_type == I860_RELOC_HIGH || 111 r_type == I860_RELOC_HIGHADJ || 112 r_type == I860_RELOC_SECTDIFF) 113 return(TRUE); 114 break; 115 case CPU_TYPE_POWERPC: 116 case CPU_TYPE_POWERPC64: 117 case CPU_TYPE_VEO: 118 if(r_type == PPC_RELOC_HI16 || 119 r_type == PPC_RELOC_LO16 || 120 r_type == PPC_RELOC_HA16 || 121 r_type == PPC_RELOC_LO14 || 122 r_type == PPC_RELOC_SECTDIFF || 123 r_type == PPC_RELOC_LOCAL_SECTDIFF || 124 r_type == PPC_RELOC_HI16_SECTDIFF || 125 r_type == PPC_RELOC_LO16_SECTDIFF || 126 r_type == PPC_RELOC_LO14_SECTDIFF || 127 r_type == PPC_RELOC_HA16_SECTDIFF || 128 r_type == PPC_RELOC_JBSR) 129 return(TRUE); 130 break; 131 case CPU_TYPE_HPPA: 132 if(r_type == HPPA_RELOC_HI21 || 133 r_type == HPPA_RELOC_LO14 || 134 r_type == HPPA_RELOC_BR17 || 135 r_type == HPPA_RELOC_JBSR || 136 r_type == HPPA_RELOC_SECTDIFF || 137 r_type == HPPA_RELOC_HI21_SECTDIFF || 138 r_type == HPPA_RELOC_LO14_SECTDIFF) 139 return(TRUE); 140 break; 141 case CPU_TYPE_SPARC: 142 if (r_type == SPARC_RELOC_HI22 || 143 r_type == SPARC_RELOC_LO10 || 144 r_type == SPARC_RELOC_HI22_SECTDIFF || 145 r_type == SPARC_RELOC_LO10_SECTDIFF || 146 r_type == SPARC_RELOC_SECTDIFF) 147 return(TRUE); 148 break; 149 case CPU_TYPE_ARM: 150 if(r_type == ARM_RELOC_SECTDIFF || 151 r_type == ARM_RELOC_LOCAL_SECTDIFF || 152 r_type == ARM_RELOC_HALF || 153 r_type == ARM_RELOC_HALF_SECTDIFF) 154 return(TRUE); 155 break; 156 default: 157 fatal("internal error: reloc_has_pair() called with unknown " 158 "cputype (%u)", cputype); 159 } 160 return(FALSE); 161} 162 163/* 164 * reloc_is_sectdiff() returns TRUE if the specified r_type for the specified 165 * cputype is a section difference relocation type. 166 */ 167__private_extern__ 168enum bool 169reloc_is_sectdiff( 170cpu_type_t cputype, 171uint32_t r_type) 172{ 173 switch(cputype){ 174 case CPU_TYPE_MC680x0: 175 case CPU_TYPE_I386: 176 if(r_type == GENERIC_RELOC_SECTDIFF || 177 r_type == GENERIC_RELOC_LOCAL_SECTDIFF) 178 return(TRUE); 179 break; 180 case CPU_TYPE_X86_64: 181 /* No sectdiff relocs for x86-64. */ 182 return(FALSE); 183 break; 184 case CPU_TYPE_MC88000: 185 if(r_type == M88K_RELOC_SECTDIFF) 186 return(TRUE); 187 break; 188 case CPU_TYPE_I860: 189 if(r_type == I860_RELOC_SECTDIFF) 190 return(TRUE); 191 break; 192 case CPU_TYPE_POWERPC: 193 case CPU_TYPE_VEO: 194 if(r_type == PPC_RELOC_SECTDIFF || 195 r_type == PPC_RELOC_LOCAL_SECTDIFF || 196 r_type == PPC_RELOC_HI16_SECTDIFF || 197 r_type == PPC_RELOC_LO16_SECTDIFF || 198 r_type == PPC_RELOC_LO14_SECTDIFF || 199 r_type == PPC_RELOC_HA16_SECTDIFF) 200 return(TRUE); 201 break; 202 case CPU_TYPE_HPPA: 203 if(r_type == HPPA_RELOC_SECTDIFF || 204 r_type == HPPA_RELOC_HI21_SECTDIFF || 205 r_type == HPPA_RELOC_LO14_SECTDIFF) 206 return(TRUE); 207 break; 208 case CPU_TYPE_SPARC: 209 if(r_type == SPARC_RELOC_SECTDIFF || 210 r_type == SPARC_RELOC_HI22_SECTDIFF || 211 r_type == SPARC_RELOC_LO10_SECTDIFF) 212 return(TRUE); 213 break; 214 case CPU_TYPE_ARM: 215 if(r_type == ARM_RELOC_SECTDIFF || 216 r_type == ARM_RELOC_LOCAL_SECTDIFF || 217 r_type == ARM_RELOC_HALF_SECTDIFF) 218 return(TRUE); 219 break; 220 default: 221 fatal("internal error: reloc_is_sectdiff() called with unknown " 222 "cputype (%u)", cputype); 223 } 224 return(FALSE); 225} 226