ARMMachObjectWriter.cpp revision 7b25ecf6adbf3c4709c48033acfeb6ebbb4452ab
151125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===//
24241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
34241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//                     The LLVM Compiler Infrastructure
44241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
54241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek// This file is distributed under the University of Illinois Open Source
64241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek// License. See LICENSE.TXT for details.
74241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//
84241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek//===----------------------------------------------------------------------===//
94241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
1051125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek#include "MCTargetDesc/ARMBaseInfo.h"
1151125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek#include "MCTargetDesc/ARMFixupKinds.h"
12b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin#include "llvm/ADT/Twine.h"
13b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin#include "llvm/MC/MCAssembler.h"
14b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin#include "llvm/MC/MCAsmLayout.h"
15b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin#include "llvm/MC/MCMachObjectWriter.h"
164241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/MC/MCContext.h"
174241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/MC/MCExpr.h"
184241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/MC/MCFixup.h"
195a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#include "llvm/MC/MCFixupKindInfo.h"
205a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#include "llvm/MC/MCMachOSymbolFlags.h"
214241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek#include "llvm/MC/MCValue.h"
224a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek#include "llvm/Object/MachOFormat.h"
231309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include "llvm/Support/ErrorHandling.h"
2463bbe5312cd89ce0ceb684bff68c5baef636e93cTed Kremenekusing namespace llvm;
254241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenekusing namespace llvm::object;
264241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
27f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremeneknamespace {
284241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenekclass ARMMachObjectWriter : public MCMachObjectTargetWriter {
29ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek  void RecordARMScatteredRelocation(MachObjectWriter *Writer,
304a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                                    const MCAssembler &Asm,
314a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                                    const MCAsmLayout &Layout,
3263bbe5312cd89ce0ceb684bff68c5baef636e93cTed Kremenek                                    const MCFragment *Fragment,
335fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek                                    const MCFixup &Fixup,
3418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                    MCValue Target,
35626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek                                    unsigned Log2Size,
364241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek                                    uint64_t &FixedValue);
374241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  void RecordARMMovwMovtRelocation(MachObjectWriter *Writer,
384a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                                   const MCAssembler &Asm,
3911062b118476368fa5b294954713e5df97d8599fTed Kremenek                                   const MCAsmLayout &Layout,
405a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis                                   const MCFragment *Fragment,
419ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek                                   const MCFixup &Fixup, MCValue Target,
425a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis                                   uint64_t &FixedValue);
435fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek
4411062b118476368fa5b294954713e5df97d8599fTed Kremenekpublic:
45cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType,
46cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                      uint32_t CPUSubtype)
47cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,
48cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek                               /*UseAggressiveSymbolFolding=*/true) {}
49cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void RecordRelocation(MachObjectWriter *Writer,
51bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu                        const MCAssembler &Asm, const MCAsmLayout &Layout,
52bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu                        const MCFragment *Fragment, const MCFixup &Fixup,
53bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu                        MCValue Target, uint64_t &FixedValue);
54c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu};
5538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu}
56d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis
57a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaksstatic bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
58d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                              unsigned &Log2Size) {
59d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  RelocType = unsigned(macho::RIT_Vanilla);
60d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  Log2Size = ~0U;
61e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  switch (Kind) {
631833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  default:
641833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    return false;
651833d284346b9fa11aae4e6aa07381347c04745cJordan Rose
661833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  case FK_Data_1:
671833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    Log2Size = llvm::Log2_32(1);
681833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    return true;
691833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  case FK_Data_2:
701833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    Log2Size = llvm::Log2_32(2);
711833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    return true;
724c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek  case FK_Data_4:
7346e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose    Log2Size = llvm::Log2_32(4);
7446e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose    return true;
7546e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case FK_Data_8:
761833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    Log2Size = llvm::Log2_32(8);
774c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek    return true;
78d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek
794c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek    // Handle 24-bit branch kinds.
8046e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_arm_ldst_pcrel_12:
8146e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_arm_pcrel_10:
8246e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_arm_adr_pcrel_12:
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case ARM::fixup_arm_condbranch:
8446e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_arm_uncondbranch:
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case ARM::fixup_arm_bl:
8646e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_arm_blx:
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    RelocType = unsigned(macho::RIT_ARM_Branch24Bit);
885d5480380d7b7c3590a0283ddf239220e514e576Ted Kremenek    // Report as 'long', even though that is not quite accurate.
891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Log2Size = llvm::Log2_32(4);
9046e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose    return true;
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
921833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    // Handle Thumb branches.
931833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  case ARM::fixup_arm_thumb_br:
941833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit);
959c378f705405d37f49795d5e915989de774fe11fTed Kremenek    Log2Size = llvm::Log2_32(2);
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return true;
971833d284346b9fa11aae4e6aa07381347c04745cJordan Rose
981833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  case ARM::fixup_t2_uncondbranch:
991833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  case ARM::fixup_arm_thumb_bl:
1001833d284346b9fa11aae4e6aa07381347c04745cJordan Rose  case ARM::fixup_arm_thumb_blx:
1011833d284346b9fa11aae4e6aa07381347c04745cJordan Rose    RelocType = unsigned(macho::RIT_ARM_ThumbBranch22Bit);
102d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek    Log2Size = llvm::Log2_32(4);
103d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek    return true;
1041833d284346b9fa11aae4e6aa07381347c04745cJordan Rose
105b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek  case ARM::fixup_arm_movt_hi16:
10646e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_arm_movt_hi16_pcrel:
107f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek  case ARM::fixup_t2_movt_hi16:
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case ARM::fixup_t2_movt_hi16_pcrel:
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    RelocType = unsigned(macho::RIT_ARM_HalfDifference);
1104a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    // Report as 'long', even though that is not quite accurate.
1114a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    Log2Size = llvm::Log2_32(4);
1124a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    return true;
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1144323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek  case ARM::fixup_arm_movw_lo16:
1158bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  case ARM::fixup_arm_movw_lo16_pcrel:
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  case ARM::fixup_t2_movw_lo16:
1174a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  case ARM::fixup_t2_movw_lo16_pcrel:
1184c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek    RelocType = unsigned(macho::RIT_ARM_Half);
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Report as 'long', even though that is not quite accurate.
1204a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    Log2Size = llvm::Log2_32(4);
1214c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek    return true;
122c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  }
1234a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek}
124c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1258bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekvoid ARMMachObjectWriter::
1266800ba622e4edf287801ac69c42c61e7e294b06bAnna ZaksRecordARMMovwMovtRelocation(MachObjectWriter *Writer,
12746e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose                            const MCAssembler &Asm,
12846e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose                            const MCAsmLayout &Layout,
129e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek                            const MCFragment *Fragment,
130e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek                            const MCFixup &Fixup,
131a5888f61be9f8d76e9b48a453dbced50523bd2e0Argyrios Kyrtzidis                            MCValue Target,
132c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                            uint64_t &FixedValue) {
1334a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
1340f9063c116b7c3b05d8042b5976463c2dae04861Ted Kremenek  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
135c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  unsigned Type = macho::RIT_ARM_Half;
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // See <reloc.h>.
13825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  const MCSymbol *A = &Target.getSymA()->getSymbol();
13925e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  MCSymbolData *A_SD = &Asm.getSymbolData(*A);
140955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks
141955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks  if (!A_SD->getFragment())
142955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks    Asm.getContext().FatalError(Fixup.getLoc(),
143955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks                       "symbol '" + A->getName() +
1445032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu                       "' can not be undefined in a subtraction expression");
1455032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu
1465032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu  uint32_t Value = Writer->getSymbolAddress(A_SD, Layout);
1475032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu  uint32_t Value2 = 0;
148b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu  uint64_t SecAddr =
149b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu    Writer->getSectionAddress(A_SD->getFragment()->getParent());
150a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  FixedValue += SecAddr;
151a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek
152a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek  if (const MCSymbolRefExpr *B = Target.getSymB()) {
153c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
154c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1558bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    if (!B_SD->getFragment())
156b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu      Asm.getContext().FatalError(Fixup.getLoc(),
15752c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek                         "symbol '" + B->getSymbol().getName() +
15852c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek                         "' can not be undefined in a subtraction expression");
159c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Select the appropriate difference relocation type.
1616800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks    Type = macho::RIT_ARM_HalfDifference;
1621831bd29572b6a7243da73d9606209190c0217deBenjamin Kramer    Value2 = Writer->getSymbolAddress(B_SD, Layout);
1636800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks    FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent());
1645fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  }
165a5888f61be9f8d76e9b48a453dbced50523bd2e0Argyrios Kyrtzidis
1666800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks  // Relocations are written out in reverse order, so the PAIR comes first.
1675fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field:
168c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  //
169c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  // For these two r_type relocations they always have a pair following them and
1706800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks  // the r_length bits are used differently.  The encoding of the r_length is as
171c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  // follows:
172c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  //   low bit of r_length:
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  //      0 - :lower16: for movw instructions
174c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  //      1 - :upper16: for movt instructions
1759c378f705405d37f49795d5e915989de774fe11fTed Kremenek  //   high bit of r_length:
176c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  //      0 - arm instructions
1774a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  //      1 - thumb instructions
1784a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  // the other half of the relocated expression is in the following pair
1794a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  // relocation entry in the the low 16 bits of r_address field.
1800e8a3c743b9b3e3039e329a1736122d3b5b5fed9Ted Kremenek  unsigned ThumbBit = 0;
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned MovtBit = 0;
182ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  switch ((unsigned)Fixup.getKind()) {
1834a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  default: break;
1845903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  case ARM::fixup_arm_movt_hi16:
1855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks  case ARM::fixup_arm_movt_hi16_pcrel:
1865903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    MovtBit = 1;
1875903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks    // The thumb bit shouldn't be set in the 'other-half' bit of the
1889c378f705405d37f49795d5e915989de774fe11fTed Kremenek    // relocation, but it will be set in FixedValue if the base symbol
18952c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek    // is a thumb function. Clear it out here.
19052c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek    if (A_SD->getFlags() & SF_ThumbFunc)
1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      FixedValue &= 0xfffffffe;
1929c378f705405d37f49795d5e915989de774fe11fTed Kremenek    break;
19352c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek  case ARM::fixup_t2_movt_hi16:
19452c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek  case ARM::fixup_t2_movt_hi16_pcrel:
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (A_SD->getFlags() & SF_ThumbFunc)
1964a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek      FixedValue &= 0xfffffffe;
19746e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose    MovtBit = 1;
1983148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek    // Fallthrough
19946e778145c56cd9b42cb399795a294b29cb78b62Jordan Rose  case ARM::fixup_t2_movw_lo16:
2003148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  case ARM::fixup_t2_movw_lo16_pcrel:
2014a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    ThumbBit = 1;
202c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    break;
203c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  }
2044a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
2054a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  if (Type == macho::RIT_ARM_HalfDifference) {
2064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    uint32_t OtherHalf = MovtBit
2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ? (FixedValue & 0xffff) : ((FixedValue & 0xffff0000) >> 16);
2084a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
2094a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    macho::RelocationEntry MRE;
2104a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    MRE.Word0 = ((OtherHalf       <<  0) |
2114a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                 (macho::RIT_Pair << 24) |
212c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                 (MovtBit         << 28) |
213c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                 (ThumbBit        << 29) |
2144a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                 (IsPCRel         << 30) |
2154a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                 macho::RF_Scattered);
2164a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    MRE.Word1 = Value2;
2174a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    Writer->addRelocation(Fragment->getParent(), MRE);
2184a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  }
2194a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
2204a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  macho::RelocationEntry MRE;
221c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  MRE.Word0 = ((FixupOffset <<  0) |
222c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu               (Type        << 24) |
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump               (MovtBit     << 28) |
224c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu               (ThumbBit    << 29) |
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump               (IsPCRel     << 30) |
226c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu               macho::RF_Scattered);
227c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  MRE.Word1 = Value;
228c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  Writer->addRelocation(Fragment->getParent(), MRE);
2299c378f705405d37f49795d5e915989de774fe11fTed Kremenek}
230c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer,
232c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                                                    const MCAssembler &Asm,
233d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                                    const MCAsmLayout &Layout,
234d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                                    const MCFragment *Fragment,
235d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                                    const MCFixup &Fixup,
236d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                                    MCValue Target,
237c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                                                    unsigned Log2Size,
238c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                                                    uint64_t &FixedValue) {
23938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
24038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
24199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  unsigned Type = macho::RIT_Vanilla;
24238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // See <reloc.h>.
244c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  const MCSymbol *A = &Target.getSymA()->getSymbol();
24538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  MCSymbolData *A_SD = &Asm.getSymbolData(*A);
2469c378f705405d37f49795d5e915989de774fe11fTed Kremenek
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!A_SD->getFragment())
2487177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar    Asm.getContext().FatalError(Fixup.getLoc(),
24938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                       "symbol '" + A->getName() +
2504a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek                       "' can not be undefined in a subtraction expression");
2514a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek
25238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  uint32_t Value = Writer->getSymbolAddress(A_SD, Layout);
2534241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  uint64_t SecAddr = Writer->getSectionAddress(A_SD->getFragment()->getParent());
254d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  FixedValue += SecAddr;
255e96de2dfde487211fb52f9139cdcae64d051a406Zhongxing Xu  uint32_t Value2 = 0;
2564241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
257626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek  if (const MCSymbolRefExpr *B = Target.getSymB()) {
2581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
259626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek
2604241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek    if (!B_SD->getFragment())
2614241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek      Asm.getContext().FatalError(Fixup.getLoc(),
2624241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek                         "symbol '" + B->getSymbol().getName() +
263626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek                         "' can not be undefined in a subtraction expression");
2644241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
265626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek    // Select the appropriate difference relocation type.
266626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek    Type = macho::RIT_Difference;
267626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek    Value2 = Writer->getSymbolAddress(B_SD, Layout);
26838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu    FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent());
26938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  }
27038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
27138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  // Relocations are written out in reverse order, so the PAIR comes first.
2725fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek  if (Type == macho::RIT_Difference ||
2735fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek      Type == macho::RIT_Generic_LocalDifference) {
2745fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    macho::RelocationEntry MRE;
2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    MRE.Word0 = ((0         <<  0) |
27639b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek                 (macho::RIT_Pair  << 24) |
27739b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek                 (Log2Size  << 28) |
278d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                 (IsPCRel   << 30) |
279d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                 macho::RF_Scattered);
2802ac58b7c09938bb28c51c7cd2deada609b75f94cTed Kremenek    MRE.Word1 = Value2;
281d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek    Writer->addRelocation(Fragment->getParent(), MRE);
282d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  }
283626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek
284d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  macho::RelocationEntry MRE;
2854d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  MRE.Word0 = ((FixupOffset <<  0) |
2864d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose               (Type        << 24) |
2874d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose               (Log2Size    << 28) |
2884d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose               (IsPCRel     << 30) |
2892ac58b7c09938bb28c51c7cd2deada609b75f94cTed Kremenek               macho::RF_Scattered);
2902ac58b7c09938bb28c51c7cd2deada609b75f94cTed Kremenek  MRE.Word1 = Value;
2914d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose  Writer->addRelocation(Fragment->getParent(), MRE);
2924241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek}
29338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
2946800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaksvoid ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,
2956800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks                                           const MCAssembler &Asm,
29638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                                           const MCAsmLayout &Layout,
2976800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks                                           const MCFragment *Fragment,
29838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                                           const MCFixup &Fixup,
2998bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                                           MCValue Target,
3006800ba622e4edf287801ac69c42c61e7e294b06bAnna Zaks                                           uint64_t &FixedValue) {
30138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned Log2Size;
30338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  unsigned RelocType = macho::RIT_Vanilla;
304c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu  if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size))
30538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu    // If we failed to get fixup kind info, it's because there's no legal
3064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    // relocation type for the fixup kind. This happens when it's a fixup that's
3074241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek    // expected to always be resolvable at assembly time and not have any
3089c378f705405d37f49795d5e915989de774fe11fTed Kremenek    // relocations needed.
309ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek    Asm.getContext().FatalError(Fixup.getLoc(),
310ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek                                "unsupported relocation on symbol");
311ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek
3124241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  // If this is a difference or a defined symbol plus an offset, then we need a
3134241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  // scattered relocation entry.  Differences always require scattered
3149c378f705405d37f49795d5e915989de774fe11fTed Kremenek  // relocations.
315ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek  if (Target.getSymB()) {
316ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek    if (RelocType == macho::RIT_ARM_Half ||
317ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek        RelocType == macho::RIT_ARM_HalfDifference)
31838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      return RecordARMMovwMovtRelocation(Writer, Asm, Layout, Fragment, Fixup,
3199d0064e802e81d0833e8ccab8978b17c0bac3625Ted Kremenek                                         Target, FixedValue);
3204a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek    return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
321d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek                                        Target, Log2Size, FixedValue);
322d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  }
3234241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek
3244a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek  // Get the symbol data, if any.
3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  MCSymbolData *SD = 0;
32639b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek  if (Target.getSymA())
32739b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek    SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
328c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu
3294241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek  // FIXME: For other platforms, we need to use scattered relocations for
33038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  // internal relocations with offsets.  If this is an internal relocation with
33138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  // an offset, it also needs a scattered relocation entry.
332626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek  //
333626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek  // Is this right for ARM?
334626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek  uint32_t Offset = Target.getConstant();
335626719bd2c09e27fe7c182724a812d27f59e3819Ted Kremenek  if (IsPCRel && RelocType == macho::RIT_Vanilla)
33638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu    Offset += 1 << Log2Size;
33738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  if (Offset && SD && !Writer->doesSymbolRequireExternRelocation(SD))
3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
33938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu                                        Target, Log2Size, FixedValue);
3407ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek
34138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  // See <reloc.h>.
3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
34338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  unsigned Index = 0;
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned IsExtern = 0;
34538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  unsigned Type = 0;
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  if (Target.isAbsolute()) { // constant
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // FIXME!
34938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu    report_fatal_error("FIXME: relocations to absolute targets "
3501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       "not yet implemented");
35138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  } else {
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Resolve constant variables.
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SD->getSymbol().isVariable()) {
3544241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek      int64_t Res;
35538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute(
3561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Res, Layout, Writer->getSectionAddressMap())) {
35738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu        FixedValue = Res;
3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return;
35938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      }
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
36138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
36238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu    // Check whether we need an external or internal relocation.
3635fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek    if (Writer->doesSymbolRequireExternRelocation(SD)) {
3645fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek      IsExtern = 1;
36538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      Index = SD->getIndex();
36638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu
36738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      // For external relocations, make sure to offset the fixup value to
368c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu      // compensate for the addend of the symbol address, if it was
369fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek      // undefined. This occurs with weak definitions, for example.
37038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      if (!SD->Symbol->isUndefined())
371cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek        FixedValue -= Layout.getSymbolOffset(SD);
37238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu    } else {
37338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      // The index is the section ordinal (1-based).
37438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu      const MCSectionData &SymSD = Asm.getSectionData(
37538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu        SD->getSymbol().getSection());
376d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek      Index = SymSD.getOrdinal() + 1;
377d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek      FixedValue += Writer->getSectionAddress(&SymSD);
3782ac58b7c09938bb28c51c7cd2deada609b75f94cTed Kremenek    }
3794d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose    if (IsPCRel)
3804d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose      FixedValue -= Writer->getSectionAddress(Fragment->getParent());
3814d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose
382d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek    // The type is determined by the fixup kind.
383d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek    Type = RelocType;
384d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek  }
3852ac58b7c09938bb28c51c7cd2deada609b75f94cTed Kremenek
386841c96a885789afea9d32d1d842033768c6d2b19Ted Kremenek  // struct relocation_info (8 bytes)
387841c96a885789afea9d32d1d842033768c6d2b19Ted Kremenek  macho::RelocationEntry MRE;
388841c96a885789afea9d32d1d842033768c6d2b19Ted Kremenek  MRE.Word0 = FixupOffset;
389841c96a885789afea9d32d1d842033768c6d2b19Ted Kremenek  MRE.Word1 = ((Index     <<  0) |
3904241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek               (IsPCRel   << 24) |
391cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek               (Log2Size  << 25) |
392f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek               (IsExtern  << 27) |
393c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu               (Type      << 28));
394f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek  Writer->addRelocation(Fragment->getParent(), MRE);
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
396f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek
3979c378f705405d37f49795d5e915989de774fe11fTed KremenekMCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS,
398c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                                                bool Is64Bit,
399f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek                                                uint32_t CPUType,
400f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek                                                uint32_t CPUSubtype) {
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return createMachObjectWriter(new ARMMachObjectWriter(Is64Bit,
402f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek                                                        CPUType,
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                        CPUSubtype),
4049c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                OS, /*IsLittleEndian=*/true);
405c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu}
406f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek