ARMMachObjectWriter.cpp revision be74029f44c32efc09274a16cbff588ad10dc5ea
1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===// 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// The LLVM Compiler Infrastructure 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// This file is distributed under the University of Illinois Open Source 6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// License. See LICENSE.TXT for details. 7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch//===----------------------------------------------------------------------===// 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "MCTargetDesc/ARMBaseInfo.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "MCTargetDesc/ARMFixupKinds.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/ADT/Twine.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCAssembler.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCAsmLayout.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCMachObjectWriter.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "llvm/MC/MCExpr.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "llvm/MC/MCFixup.h" 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCFixupKindInfo.h" 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/MC/MCValue.h" 20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/Object/MachOFormat.h" 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/Support/ErrorHandling.h" 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "llvm/Target/TargetAsmBackend.h" 23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing namespace llvm; 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing namespace llvm::object; 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace { 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass ARMMachObjectWriter : public MCMachObjectTargetWriter { 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch void RecordARMScatteredRelocation(MachObjectWriter *Writer, 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCAssembler &Asm, 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCAsmLayout &Layout, 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCFragment *Fragment, 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCFixup &Fixup, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MCValue Target, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned Log2Size, 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint64_t &FixedValue); 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void RecordARMMovwMovtRelocation(MachObjectWriter *Writer, 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCAssembler &Asm, 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCAsmLayout &Layout, 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const MCFragment *Fragment, 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const MCFixup &Fixup, MCValue Target, 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64_t &FixedValue); 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccipublic: 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32_t CPUSubtype) 46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype, 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch /*UseAggressiveSymbolFolding=*/true) {} 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch void RecordRelocation(MachObjectWriter *Writer, 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const MCAssembler &Asm, const MCAsmLayout &Layout, 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const MCFragment *Fragment, const MCFixup &Fixup, 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch MCValue Target, uint64_t &FixedValue); 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType, 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch unsigned &Log2Size) { 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RelocType = unsigned(macho::RIT_Vanilla); 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = ~0U; 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (Kind) { 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case FK_Data_1: 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(1); 67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case FK_Data_2: 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(2); 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case FK_Data_4: 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(4); 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case FK_Data_8: 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(8); 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Handle 24-bit branch kinds. 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_ldst_pcrel_12: 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case ARM::fixup_arm_pcrel_10: 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_adr_pcrel_12: 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case ARM::fixup_arm_condbranch: 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_uncondbranch: 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RelocType = unsigned(macho::RIT_ARM_Branch24Bit); 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Report as 'long', even though that is not quite accurate. 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(4); 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Handle Thumb branches. 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_thumb_br: 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(2); 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_t2_uncondbranch: 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_thumb_bl: 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_thumb_blx: 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit); 99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(4); 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_movt_hi16: 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_movt_hi16_pcrel: 104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_t2_movt_hi16: 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) case ARM::fixup_t2_movt_hi16_pcrel: 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) RelocType = unsigned(macho::RIT_ARM_HalfDifference); 107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Report as 'long', even though that is not quite accurate. 108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(4); 109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_movw_lo16: 112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_arm_movw_lo16_pcrel: 113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_t2_movw_lo16: 114ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ARM::fixup_t2_movw_lo16_pcrel: 115ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RelocType = unsigned(macho::RIT_ARM_Half); 116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Report as 'long', even though that is not quite accurate. 117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Log2Size = llvm::Log2_32(4); 118ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 119ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 120} 121 122void ARMMachObjectWriter:: 123RecordARMMovwMovtRelocation(MachObjectWriter *Writer, 124 const MCAssembler &Asm, 125 const MCAsmLayout &Layout, 126 const MCFragment *Fragment, 127 const MCFixup &Fixup, 128 MCValue Target, 129 uint64_t &FixedValue) { 130 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); 131 unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); 132 unsigned Type = macho::RIT_ARM_Half; 133 134 // See <reloc.h>. 135 const MCSymbol *A = &Target.getSymA()->getSymbol(); 136 MCSymbolData *A_SD = &Asm.getSymbolData(*A); 137 138 if (!A_SD->getFragment()) 139 report_fatal_error("symbol '" + A->getName() + 140 "' can not be undefined in a subtraction expression"); 141 142 uint32_t Value = Writer->getSymbolAddress(A_SD, Layout); 143 uint32_t Value2 = 0; 144 uint64_t SecAddr = 145 Writer->getSectionAddress(A_SD->getFragment()->getParent()); 146 FixedValue += SecAddr; 147 148 if (const MCSymbolRefExpr *B = Target.getSymB()) { 149 MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); 150 151 if (!B_SD->getFragment()) 152 report_fatal_error("symbol '" + B->getSymbol().getName() + 153 "' can not be undefined in a subtraction expression"); 154 155 // Select the appropriate difference relocation type. 156 Type = macho::RIT_ARM_HalfDifference; 157 Value2 = Writer->getSymbolAddress(B_SD, Layout); 158 FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent()); 159 } 160 161 // Relocations are written out in reverse order, so the PAIR comes first. 162 // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field: 163 // 164 // For these two r_type relocations they always have a pair following them and 165 // the r_length bits are used differently. The encoding of the r_length is as 166 // follows: 167 // low bit of r_length: 168 // 0 - :lower16: for movw instructions 169 // 1 - :upper16: for movt instructions 170 // high bit of r_length: 171 // 0 - arm instructions 172 // 1 - thumb instructions 173 // the other half of the relocated expression is in the following pair 174 // relocation entry in the the low 16 bits of r_address field. 175 unsigned ThumbBit = 0; 176 unsigned MovtBit = 0; 177 switch ((unsigned)Fixup.getKind()) { 178 default: break; 179 case ARM::fixup_arm_movt_hi16: 180 case ARM::fixup_arm_movt_hi16_pcrel: 181 MovtBit = 1; 182 break; 183 case ARM::fixup_t2_movt_hi16: 184 case ARM::fixup_t2_movt_hi16_pcrel: 185 MovtBit = 1; 186 // Fallthrough 187 case ARM::fixup_t2_movw_lo16: 188 case ARM::fixup_t2_movw_lo16_pcrel: 189 ThumbBit = 1; 190 break; 191 } 192 193 194 if (Type == macho::RIT_ARM_HalfDifference) { 195 uint32_t OtherHalf = MovtBit 196 ? (FixedValue & 0xffff) : ((FixedValue & 0xffff0000) >> 16); 197 198 macho::RelocationEntry MRE; 199 MRE.Word0 = ((OtherHalf << 0) | 200 (macho::RIT_Pair << 24) | 201 (MovtBit << 28) | 202 (ThumbBit << 29) | 203 (IsPCRel << 30) | 204 macho::RF_Scattered); 205 MRE.Word1 = Value2; 206 Writer->addRelocation(Fragment->getParent(), MRE); 207 } 208 209 macho::RelocationEntry MRE; 210 MRE.Word0 = ((FixupOffset << 0) | 211 (Type << 24) | 212 (MovtBit << 28) | 213 (ThumbBit << 29) | 214 (IsPCRel << 30) | 215 macho::RF_Scattered); 216 MRE.Word1 = Value; 217 Writer->addRelocation(Fragment->getParent(), MRE); 218} 219 220void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer, 221 const MCAssembler &Asm, 222 const MCAsmLayout &Layout, 223 const MCFragment *Fragment, 224 const MCFixup &Fixup, 225 MCValue Target, 226 unsigned Log2Size, 227 uint64_t &FixedValue) { 228 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); 229 unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); 230 unsigned Type = macho::RIT_Vanilla; 231 232 // See <reloc.h>. 233 const MCSymbol *A = &Target.getSymA()->getSymbol(); 234 MCSymbolData *A_SD = &Asm.getSymbolData(*A); 235 236 if (!A_SD->getFragment()) 237 report_fatal_error("symbol '" + A->getName() + 238 "' can not be undefined in a subtraction expression"); 239 240 uint32_t Value = Writer->getSymbolAddress(A_SD, Layout); 241 uint64_t SecAddr = Writer->getSectionAddress(A_SD->getFragment()->getParent()); 242 FixedValue += SecAddr; 243 uint32_t Value2 = 0; 244 245 if (const MCSymbolRefExpr *B = Target.getSymB()) { 246 MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); 247 248 if (!B_SD->getFragment()) 249 report_fatal_error("symbol '" + B->getSymbol().getName() + 250 "' can not be undefined in a subtraction expression"); 251 252 // Select the appropriate difference relocation type. 253 Type = macho::RIT_Difference; 254 Value2 = Writer->getSymbolAddress(B_SD, Layout); 255 FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent()); 256 } 257 258 // Relocations are written out in reverse order, so the PAIR comes first. 259 if (Type == macho::RIT_Difference || 260 Type == macho::RIT_Generic_LocalDifference) { 261 macho::RelocationEntry MRE; 262 MRE.Word0 = ((0 << 0) | 263 (macho::RIT_Pair << 24) | 264 (Log2Size << 28) | 265 (IsPCRel << 30) | 266 macho::RF_Scattered); 267 MRE.Word1 = Value2; 268 Writer->addRelocation(Fragment->getParent(), MRE); 269 } 270 271 macho::RelocationEntry MRE; 272 MRE.Word0 = ((FixupOffset << 0) | 273 (Type << 24) | 274 (Log2Size << 28) | 275 (IsPCRel << 30) | 276 macho::RF_Scattered); 277 MRE.Word1 = Value; 278 Writer->addRelocation(Fragment->getParent(), MRE); 279} 280 281void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer, 282 const MCAssembler &Asm, 283 const MCAsmLayout &Layout, 284 const MCFragment *Fragment, 285 const MCFixup &Fixup, 286 MCValue Target, 287 uint64_t &FixedValue) { 288 unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); 289 unsigned Log2Size; 290 unsigned RelocType = macho::RIT_Vanilla; 291 if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) { 292 report_fatal_error("unknown ARM fixup kind!"); 293 return; 294 } 295 296 // If this is a difference or a defined symbol plus an offset, then we need a 297 // scattered relocation entry. Differences always require scattered 298 // relocations. 299 if (Target.getSymB()) { 300 if (RelocType == macho::RIT_ARM_Half || 301 RelocType == macho::RIT_ARM_HalfDifference) 302 return RecordARMMovwMovtRelocation(Writer, Asm, Layout, Fragment, Fixup, 303 Target, FixedValue); 304 return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, 305 Target, Log2Size, FixedValue); 306 } 307 308 // Get the symbol data, if any. 309 MCSymbolData *SD = 0; 310 if (Target.getSymA()) 311 SD = &Asm.getSymbolData(Target.getSymA()->getSymbol()); 312 313 // FIXME: For other platforms, we need to use scattered relocations for 314 // internal relocations with offsets. If this is an internal relocation with 315 // an offset, it also needs a scattered relocation entry. 316 // 317 // Is this right for ARM? 318 uint32_t Offset = Target.getConstant(); 319 if (IsPCRel && RelocType == macho::RIT_Vanilla) 320 Offset += 1 << Log2Size; 321 if (Offset && SD && !Writer->doesSymbolRequireExternRelocation(SD)) 322 return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, 323 Target, Log2Size, FixedValue); 324 325 // See <reloc.h>. 326 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); 327 unsigned Index = 0; 328 unsigned IsExtern = 0; 329 unsigned Type = 0; 330 331 if (Target.isAbsolute()) { // constant 332 // FIXME! 333 report_fatal_error("FIXME: relocations to absolute targets " 334 "not yet implemented"); 335 } else { 336 // Resolve constant variables. 337 if (SD->getSymbol().isVariable()) { 338 int64_t Res; 339 if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute( 340 Res, Layout, Writer->getSectionAddressMap())) { 341 FixedValue = Res; 342 return; 343 } 344 } 345 346 // Check whether we need an external or internal relocation. 347 if (Writer->doesSymbolRequireExternRelocation(SD)) { 348 IsExtern = 1; 349 Index = SD->getIndex(); 350 351 // For external relocations, make sure to offset the fixup value to 352 // compensate for the addend of the symbol address, if it was 353 // undefined. This occurs with weak definitions, for example. 354 if (!SD->Symbol->isUndefined()) 355 FixedValue -= Layout.getSymbolOffset(SD); 356 } else { 357 // The index is the section ordinal (1-based). 358 const MCSectionData &SymSD = Asm.getSectionData( 359 SD->getSymbol().getSection()); 360 Index = SymSD.getOrdinal() + 1; 361 FixedValue += Writer->getSectionAddress(&SymSD); 362 } 363 if (IsPCRel) 364 FixedValue -= Writer->getSectionAddress(Fragment->getParent()); 365 366 // The type is determined by the fixup kind. 367 Type = RelocType; 368 } 369 370 // struct relocation_info (8 bytes) 371 macho::RelocationEntry MRE; 372 MRE.Word0 = FixupOffset; 373 MRE.Word1 = ((Index << 0) | 374 (IsPCRel << 24) | 375 (Log2Size << 25) | 376 (IsExtern << 27) | 377 (Type << 28)); 378 Writer->addRelocation(Fragment->getParent(), MRE); 379} 380 381MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS, 382 bool Is64Bit, 383 uint32_t CPUType, 384 uint32_t CPUSubtype) { 385 return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit, 386 CPUType, 387 CPUSubtype), 388 OS, /*IsLittleEndian=*/true); 389} 390