MCAssembler.cpp revision 034843ac8bca36d14ef9d83b50596354b5f3420f
1fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// 2fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// 3fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// The LLVM Compiler Infrastructure 4fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// 5fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// License. See LICENSE.TXT for details. 7fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// 8fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//===----------------------------------------------------------------------===// 9fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 100adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar#define DEBUG_TYPE "assembler" 11fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCAssembler.h" 1218ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar#include "llvm/MC/MCAsmLayout.h" 131253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar#include "llvm/MC/MCExpr.h" 14bea2c957046e43622b43bed814dd96d772eb0628Chris Lattner#include "llvm/MC/MCSectionMachO.h" 151253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar#include "llvm/MC/MCSymbol.h" 161253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar#include "llvm/MC/MCValue.h" 173edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar#include "llvm/ADT/DenseMap.h" 18f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar#include "llvm/ADT/SmallString.h" 190adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar#include "llvm/ADT/Statistic.h" 20b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar#include "llvm/ADT/StringExtras.h" 21f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar#include "llvm/ADT/StringMap.h" 22d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar#include "llvm/ADT/Twine.h" 230705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar#include "llvm/Support/ErrorHandling.h" 2445f8c095ad94888716ceff54daf2fdf2f2f668a4Chris Lattner#include "llvm/Support/MachO.h" 25fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/Support/raw_ostream.h" 26b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar#include "llvm/Support/Debug.h" 27ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar#include "llvm/Target/TargetRegistry.h" 28df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar#include "llvm/Target/TargetAsmBackend.h" 29f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar 30f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar// FIXME: Gross. 31f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar#include "../Target/X86/X86FixupKinds.h" 32f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar 3323132b188ba651ba172380cd082cc286df73d440Chris Lattner#include <vector> 34fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarusing namespace llvm; 35fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 36f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbarclass MachObjectWriter; 37f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 380adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel DunbarSTATISTIC(EmittedFragments, "Number of emitted assembler fragments"); 390adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar 408f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar// FIXME FIXME FIXME: There are number of places in this file where we convert 418f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar// what is a 64-bit assembler value used for computation into a value in the 428f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar// object file, which may truncate it. We should detect that truncation where 438f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar// invalid and report errors back. 448f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 45f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbarstatic void WriteFileData(raw_ostream &OS, const MCSectionData &SD, 46f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MachObjectWriter &MOW); 47fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 486e72048add2a6464e038121c6c275da37528aa0aKevin Enderbystatic uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW); 496e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 50d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar/// isVirtualSection - Check if this is a section which does not actually exist 51d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar/// in the object file. 52d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbarstatic bool isVirtualSection(const MCSection &Section) { 53d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // FIXME: Lame. 54d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 5599d22adcadc750b2949283d562bdb4d480b8d11cDaniel Dunbar return (SMO.getType() == MCSectionMachO::S_ZEROFILL); 56d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar} 57d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 589a7795cbed47159566fd8f57b846fcf14ffb0272Duncan Sandsstatic unsigned getFixupKindLog2Size(unsigned Kind) { 592be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar switch (Kind) { 602be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar default: llvm_unreachable("invalid fixup kind!"); 61f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar case X86::reloc_pcrel_1byte: 622be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_1: return 0; 632be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_2: return 1; 64f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar case X86::reloc_pcrel_4byte: 65f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar case X86::reloc_riprel_4byte: 662be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_4: return 2; 672be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_8: return 3; 682be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar } 692be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar} 702be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar 719a7795cbed47159566fd8f57b846fcf14ffb0272Duncan Sandsstatic bool isFixupKindPCRel(unsigned Kind) { 72591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar switch (Kind) { 73591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar default: 74591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar return false; 75591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar case X86::reloc_pcrel_1byte: 76591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar case X86::reloc_pcrel_4byte: 77591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar case X86::reloc_riprel_4byte: 78591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar return true; 79591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar } 80591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar} 81591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar 82fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass MachObjectWriter { 83fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // See <mach-o/loader.h>. 84fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar enum { 85fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Header_Magic32 = 0xFEEDFACE, 86fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Header_Magic64 = 0xFEEDFACF 87fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar }; 887eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 89ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar enum { 90ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Header32Size = 28, 91ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Header64Size = 32, 92ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand32Size = 56, 93ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand64Size = 72, 94ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Section32Size = 68, 95ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Section64Size = 80, 96ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SymtabLoadCommandSize = 24, 97ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar DysymtabLoadCommandSize = 80, 98ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Nlist32Size = 12, 99ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Nlist64Size = 16, 100ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar RelocationInfoSize = 8 101ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar }; 102fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 103fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar enum HeaderFileType { 104fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar HFT_Object = 0x1 105fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar }; 106fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1076009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar enum HeaderFlags { 1086009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar HF_SubsectionsViaSymbols = 0x2000 1096009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar }; 1106009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 111fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar enum LoadCommandType { 112f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar LCT_Segment = 0x1, 113f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar LCT_Symtab = 0x2, 114ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar LCT_Dysymtab = 0xb, 115ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar LCT_Segment64 = 0x19 116fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar }; 117fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1183edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // See <mach-o/nlist.h>. 1193edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar enum SymbolTypeType { 1203edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STT_Undefined = 0x00, 1213edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STT_Absolute = 0x02, 1223edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STT_Section = 0x0e 1233edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar }; 1243edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 1253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar enum SymbolTypeFlags { 1263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // If any of these bits are set, then the entry is a stab entry number (see 1273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // <mach-o/stab.h>. Otherwise the other masks apply. 1283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_StabsEntryMask = 0xe0, 1293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 1303edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_TypeMask = 0x0e, 1313edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_External = 0x01, 1323edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_PrivateExtern = 0x10 1333edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar }; 1343edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 135ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar /// IndirectSymbolFlags - Flags for encoding special values in the indirect 136ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar /// symbol entry. 137ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar enum IndirectSymbolFlags { 138ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar ISF_Local = 0x80000000, 139ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar ISF_Absolute = 0x40000000 140ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar }; 141ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar 1423f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar /// RelocationFlags - Special flags for addresses. 1433f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar enum RelocationFlags { 1443f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RF_Scattered = 0x80000000 1453f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar }; 1463f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 1473f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar enum RelocationInfoType { 1483f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_Vanilla = 0, 1493f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_Pair = 1, 1503f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_Difference = 2, 1513f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_PreboundLazyPointer = 3, 1523f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_LocalDifference = 4 1533f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar }; 1543f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 1553edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar /// MachSymbolData - Helper struct for containing some precomputed information 1563edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar /// on symbols. 1573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar struct MachSymbolData { 1583edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MCSymbolData *SymbolData; 1593edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint64_t StringIndex; 1603edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint8_t SectionIndex; 1613edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 1623edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Support lexicographic sorting. 1633edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar bool operator<(const MachSymbolData &RHS) const { 1643edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar const std::string &Name = SymbolData->getSymbol().getName(); 1653edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar return Name < RHS.SymbolData->getSymbol().getName(); 1663edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 1673edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar }; 1683edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 169fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar raw_ostream &OS; 170ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar unsigned Is64Bit : 1; 171ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar unsigned IsLSB : 1; 172fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 173fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic: 174ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar MachObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool _IsLSB = true) 175ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar : OS(_OS), Is64Bit(_Is64Bit), IsLSB(_IsLSB) { 176fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 177fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 178fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @name Helper Methods 179fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @{ 180fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1810705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar void Write8(uint8_t Value) { 1820705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar OS << char(Value); 1830705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 1840705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1850705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar void Write16(uint16_t Value) { 1860705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar if (IsLSB) { 1870705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 0)); 1880705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 8)); 1890705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } else { 1900705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 8)); 1910705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 0)); 1920705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 1930705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 1940705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 195fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar void Write32(uint32_t Value) { 196fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if (IsLSB) { 1970705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 0)); 1980705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 16)); 1990705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } else { 2000705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 16)); 2010705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 0)); 2020705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 2030705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 2040705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 2050705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar void Write64(uint64_t Value) { 2060705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar if (IsLSB) { 2070705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 0)); 2080705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 32)); 209fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } else { 2100705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 32)); 2110705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 0)); 212fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 213fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 214fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 215fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar void WriteZeros(unsigned N) { 216fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar const char Zeros[16] = { 0 }; 2177eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 218fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar for (unsigned i = 0, e = N / 16; i != e; ++i) 219fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar OS << StringRef(Zeros, 16); 2207eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 221fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar OS << StringRef(Zeros, N % 16); 222fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 223fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 2242928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbar void WriteString(StringRef Str, unsigned ZeroFillSize = 0) { 225fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar OS << Str; 226fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if (ZeroFillSize) 227fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteZeros(ZeroFillSize - Str.size()); 228fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 229fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 230fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @} 2317eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 232ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, 233ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar bool SubsectionsViaSymbols) { 2346009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar uint32_t Flags = 0; 2356009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 2366009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar if (SubsectionsViaSymbols) 2376009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Flags |= HF_SubsectionsViaSymbols; 2386009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 239ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct mach_header (28 bytes) or 240ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct mach_header_64 (32 bytes) 241fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 242fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar uint64_t Start = OS.tell(); 243fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (void) Start; 244fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 245ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(Is64Bit ? Header_Magic64 : Header_Magic32); 246fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 247fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // FIXME: Support cputype. 248ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(Is64Bit ? MachO::CPUTypeX86_64 : MachO::CPUTypeI386); 249fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // FIXME: Support cpusubtype. 25045f8c095ad94888716ceff54daf2fdf2f2f668a4Chris Lattner Write32(MachO::CPUSubType_I386_ALL); 251fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(HFT_Object); 2526009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Write32(NumLoadCommands); // Object files have a single load command, the 2536009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar // segment. 254f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(LoadCommandsSize); 2556009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Write32(Flags); 256ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) 257ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(0); // reserved 258fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 259ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar assert(OS.tell() - Start == Is64Bit ? Header64Size : Header32Size); 260fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 261fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 262ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar /// WriteSegmentLoadCommand - Write a segment load command. 2630705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar /// 2640705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar /// \arg NumSections - The number of sections in this segment. 2650705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar /// \arg SectionDataSize - The total size of the sections. 266ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar void WriteSegmentLoadCommand(unsigned NumSections, 267ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t VMSize, 268ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t SectionDataStartOffset, 269ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t SectionDataSize) { 270ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct segment_command (56 bytes) or 271ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct segment_command_64 (72 bytes) 272fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 273fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar uint64_t Start = OS.tell(); 274fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (void) Start; 275fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 276ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar unsigned SegmentLoadCommandSize = Is64Bit ? SegmentLoadCommand64Size : 277ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand32Size; 278ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(Is64Bit ? LCT_Segment64 : LCT_Segment); 279ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SegmentLoadCommandSize + 280ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar NumSections * (Is64Bit ? Section64Size : Section32Size)); 281fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 282fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteString("", 16); 283ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) { 284ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(0); // vmaddr 285ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(VMSize); // vmsize 286ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SectionDataStartOffset); // file offset 287ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SectionDataSize); // file size 288ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } else { 289ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(0); // vmaddr 290ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(VMSize); // vmsize 291ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SectionDataStartOffset); // file offset 292ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SectionDataSize); // file size 293ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } 294fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0x7); // maxprot 295fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0x7); // initprot 296fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(NumSections); 297fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0); // flags 298fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 299ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar assert(OS.tell() - Start == SegmentLoadCommandSize); 300fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 301fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 302ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar void WriteSection(const MCSectionData &SD, uint64_t FileOffset, 303ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t RelocationsStart, unsigned NumRelocations) { 304d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // The offset is unused for virtual sections. 305d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) { 306d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(SD.getFileSize() == 0 && "Invalid file size!"); 307d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar FileOffset = 0; 308d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 309d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 310ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct section (68 bytes) or 311ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct section_64 (80 bytes) 312fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 313fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar uint64_t Start = OS.tell(); 314fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (void) Start; 315fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 316fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // FIXME: cast<> support! 317fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar const MCSectionMachO &Section = 318fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar static_cast<const MCSectionMachO&>(SD.getSection()); 319fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteString(Section.getSectionName(), 16); 320fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteString(Section.getSegmentName(), 16); 321ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) { 322ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SD.getAddress()); // address 323ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SD.getSize()); // size 324ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } else { 325ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SD.getAddress()); // address 326ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SD.getSize()); // size 327ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } 3282ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar Write32(FileOffset); 329fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 330e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar unsigned Flags = Section.getTypeAndAttributes(); 331e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar if (SD.hasInstructions()) 332e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; 333e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar 334fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); 335fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(Log2_32(SD.getAlignment())); 3363f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(NumRelocations ? RelocationsStart : 0); 3373f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(NumRelocations); 338e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar Write32(Flags); 339fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0); // reserved1 340fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(Section.getStubSize()); // reserved2 341ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) 342ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(0); // reserved3 343fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 344ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar assert(OS.tell() - Start == Is64Bit ? Section64Size : Section32Size); 345fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 3462ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar 347f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, 348f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t StringTableOffset, 349f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t StringTableSize) { 350f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // struct symtab_command (24 bytes) 351f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 352f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint64_t Start = OS.tell(); 353f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar (void) Start; 354f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 355f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(LCT_Symtab); 356f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(SymtabLoadCommandSize); 357f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(SymbolOffset); 358f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumSymbols); 359f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(StringTableOffset); 360f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(StringTableSize); 361f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 362f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(OS.tell() - Start == SymtabLoadCommandSize); 363f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 364f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 365f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, 366f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumLocalSymbols, 367f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t FirstExternalSymbol, 368f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumExternalSymbols, 369f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t FirstUndefinedSymbol, 370f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumUndefinedSymbols, 371f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t IndirectSymbolOffset, 372f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumIndirectSymbols) { 373f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // struct dysymtab_command (80 bytes) 374f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 375f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint64_t Start = OS.tell(); 376f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar (void) Start; 377f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 378f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(LCT_Dysymtab); 379f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(DysymtabLoadCommandSize); 380f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(FirstLocalSymbol); 381f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumLocalSymbols); 382f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(FirstExternalSymbol); 383f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumExternalSymbols); 384f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(FirstUndefinedSymbol); 385f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumUndefinedSymbols); 386f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // tocoff 387f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // ntoc 388f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // modtaboff 389f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nmodtab 390f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // extrefsymoff 391f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nextrefsyms 392f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(IndirectSymbolOffset); 393f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumIndirectSymbols); 394f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // extreloff 395f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nextrel 396f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // locreloff 397f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nlocrel 398f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 399f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(OS.tell() - Start == DysymtabLoadCommandSize); 400f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 401f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 4025691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar void WriteNlist(MachSymbolData &MSD) { 4035e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar MCSymbolData &Data = *MSD.SymbolData; 404cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar const MCSymbol &Symbol = Data.getSymbol(); 4053edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint8_t Type = 0; 4068f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar uint16_t Flags = Data.getFlags(); 4078f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar uint32_t Address = 0; 4083edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4093edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Set the N_TYPE bits. See <mach-o/nlist.h>. 4103edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // 4113edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // FIXME: Are the prebound or indirect fields possible here? 4123edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (Symbol.isUndefined()) 4133edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type = STT_Undefined; 4143edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar else if (Symbol.isAbsolute()) 4153edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type = STT_Absolute; 4163edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar else 4173edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type = STT_Section; 4183edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4193edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // FIXME: Set STAB bits. 4203edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4215e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar if (Data.isPrivateExtern()) 4226aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar Type |= STF_PrivateExtern; 4233edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4243edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Set external bit. 4255e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar if (Data.isExternal() || Symbol.isUndefined()) 4263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type |= STF_External; 4273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4288f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // Compute the symbol address. 4298f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (Symbol.isDefined()) { 4308f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (Symbol.isAbsolute()) { 4318f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar llvm_unreachable("FIXME: Not yet implemented!"); 4328f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } else { 4338f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar Address = Data.getAddress(); 4348f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } 4358f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } else if (Data.isCommon()) { 4368f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // Common symbols are encoded with the size in the address 4378f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // field, and their alignment in the flags. 4388f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Address = Data.getCommonSize(); 4398f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 4408f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // Common alignment is packed into the 'desc' bits. 4418f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (unsigned Align = Data.getCommonAlignment()) { 4428f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar unsigned Log2Size = Log2_32(Align); 4438f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); 4448f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (Log2Size > 15) 4458f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar llvm_report_error("invalid 'common' alignment '" + 4468f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Twine(Align) + "'"); 4478f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // FIXME: Keep this mask with the SymbolFlags enumeration. 4488f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Flags = (Flags & 0xF0FF) | (Log2Size << 8); 4498f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } 4508f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } 4518f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 452f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // struct nlist (12 bytes) 453f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 4543edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Write32(MSD.StringIndex); 455f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write8(Type); 4563edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Write8(MSD.SectionIndex); 4577eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 4586aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' 4596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // value. 4608f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Write16(Flags); 4615691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar if (Is64Bit) 4625691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar Write64(Address); 4635691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar else 4645691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar Write32(Address); 465f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 466f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 4673f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar struct MachRelocationEntry { 4683f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Word0; 4693f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Word1; 4703f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar }; 471cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment, 47227ade18431a3504b412e6359e80c9b88e3b0f932Daniel Dunbar MCAsmFixup &Fixup, 4731253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar const MCValue &Target, 4743f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar std::vector<MachRelocationEntry> &Relocs) { 475cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar uint32_t Address = Fragment.getOffset() + Fixup.Offset; 476e180fa962cc629255bbb0c5f185299c981b042efDaniel Dunbar unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); 477eb3804e39a76a267f13e72a00695f5b18c75b932Daniel Dunbar unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); 4783f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned Type = RIT_Vanilla; 4793f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 4803f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // See <reloc.h>. 4819a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar const MCSymbol *A = &Target.getSymA()->getSymbol(); 4822101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData *A_SD = &Asm.getSymbolData(*A); 4830ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 484a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar if (!A_SD->getFragment()) 4850ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar llvm_report_error("symbol '" + A->getName() + 4860ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar "' can not be undefined in a subtraction expression"); 4870ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 4888f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar uint32_t Value = A_SD->getAddress(); 4893f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Value2 = 0; 4903f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 4919a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar if (const MCSymbolRefExpr *B = Target.getSymB()) { 4929a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); 4930ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 494a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar if (!B_SD->getFragment()) 4959a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar llvm_report_error("symbol '" + B->getSymbol().getName() + 4960ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar "' can not be undefined in a subtraction expression"); 4970ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 49807a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // Select the appropriate difference relocation type. 49907a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // 50007a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // Note that there is no longer any semantic difference between these two 50107a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // relocation types from the linkers point of view, this is done solely 50207a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // for pedantic compatibility with 'as'. 503a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar Type = A_SD->isExternal() ? RIT_Difference : RIT_LocalDifference; 5048f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar Value2 = B_SD->getAddress(); 5053f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5063f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5073f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MachRelocationEntry MRE; 5083f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word0 = ((Address << 0) | 5093f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Type << 24) | 5103f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Log2Size << 28) | 5113f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (IsPCRel << 30) | 5123f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RF_Scattered); 5133f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word1 = Value; 5143f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Relocs.push_back(MRE); 5153f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 516a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar if (Type == RIT_Difference || Type == RIT_LocalDifference) { 5173f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MachRelocationEntry MRE; 5183f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word0 = ((0 << 0) | 519aef9d7af69913740f313c5cc1dfe2a8e1d352227Daniel Dunbar (RIT_Pair << 24) | 5203f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Log2Size << 28) | 521aef9d7af69913740f313c5cc1dfe2a8e1d352227Daniel Dunbar (IsPCRel << 30) | 5223f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RF_Scattered); 5233f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word1 = Value2; 5243f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Relocs.push_back(MRE); 5253f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5263f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5273f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5280bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar void ComputeRelocationInfo(MCAssembler &Asm, MCDataFragment &Fragment, 52927ade18431a3504b412e6359e80c9b88e3b0f932Daniel Dunbar MCAsmFixup &Fixup, 5303f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar std::vector<MachRelocationEntry> &Relocs) { 531f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); 532f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); 533f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar 53418ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar // FIXME: Share layout object. 53518ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar MCAsmLayout Layout(Asm); 53618ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar 537df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // Evaluate the fixup; if the value was resolved, no relocation is needed. 5381253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar MCValue Target; 539df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (Asm.EvaluateFixup(Layout, Fixup, &Fragment, Target, Fixup.FixedValue)) 540df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar return; 5411253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar 542f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar // If this is a difference or a defined symbol plus an offset, then we need 543f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar // a scattered relocation entry. 544f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar uint32_t Offset = Target.getConstant(); 545f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar if (IsPCRel) 546f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar Offset += 1 << Log2Size; 5471253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar if (Target.getSymB() || 5489a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar (Target.getSymA() && !Target.getSymA()->getSymbol().isUndefined() && 549f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar Offset)) 550cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target, 5512101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Relocs); 5527eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 5533f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // See <reloc.h>. 554cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar uint32_t Address = Fragment.getOffset() + Fixup.Offset; 5553f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Value = 0; 5563f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned Index = 0; 5573f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned IsExtern = 0; 5583f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned Type = 0; 5593f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5601253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar if (Target.isAbsolute()) { // constant 5613f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // SymbolNum of 0 indicates the absolute section. 5623a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // 563979ba5b3c7c818b826d06298ee7f79c4234faedbDaniel Dunbar // FIXME: Currently, these are never generated (see code below). I cannot 564979ba5b3c7c818b826d06298ee7f79c4234faedbDaniel Dunbar // find a case where they are actually emitted. 5653f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Type = RIT_Vanilla; 5663f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Value = 0; 5673f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } else { 5689a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); 5692101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData *SD = &Asm.getSymbolData(*Symbol); 5707eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 5713f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar if (Symbol->isUndefined()) { 5723f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar IsExtern = 1; 5733f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Index = SD->getIndex(); 5743f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Value = 0; 5753f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } else { 5763f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // The index is the section ordinal. 5773f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // 5783f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // FIXME: O(N) 5793f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Index = 1; 580591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); 581591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar for (; it != ie; ++it, ++Index) 5823f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar if (&*it == SD->getFragment()->getParent()) 5833f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar break; 584591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar assert(it != ie && "Unable to find section index!"); 5858f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar Value = SD->getAddress(); 5863f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5873f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5883f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Type = RIT_Vanilla; 5893f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5903f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5913f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // struct relocation_info (8 bytes) 5923f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MachRelocationEntry MRE; 5933f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word0 = Address; 5943f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word1 = ((Index << 0) | 5953f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (IsPCRel << 24) | 5963f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Log2Size << 25) | 5973f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (IsExtern << 27) | 5983f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Type << 28)); 5993f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Relocs.push_back(MRE); 6003f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 6017eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 6022101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar void BindIndirectSymbols(MCAssembler &Asm) { 6030c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // This is the point where 'as' creates actual symbols for indirect symbols 6040c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // (in the following two passes). It would be easier for us to do this 6050c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // sooner when we see the attribute, but that makes getting the order in the 6060c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // symbol table much more complicated than it is worth. 6070c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // 6080c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: Revisit this when the dust settles. 6090c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6100c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Bind non lazy symbol pointers first. 6110c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 6120c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 6130c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: cast<> support! 6140c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar const MCSectionMachO &Section = 6150c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 6160c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 61799d22adcadc750b2949283d562bdb4d480b8d11cDaniel Dunbar if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) 6180c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar continue; 6190c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6202101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Asm.getOrCreateSymbolData(*it->Symbol); 6210c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 6220c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6230c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Then lazy symbol pointers and symbol stubs. 6240c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 6250c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 6260c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: cast<> support! 6270c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar const MCSectionMachO &Section = 6280c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 6290c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 63099d22adcadc750b2949283d562bdb4d480b8d11cDaniel Dunbar if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && 63199d22adcadc750b2949283d562bdb4d480b8d11cDaniel Dunbar Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) 6320c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar continue; 6330c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6342101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar // Set the symbol type to undefined lazy, but only on construction. 6352101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar // 6362101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar // FIXME: Do not hardcode. 6372101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar bool Created; 6382101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); 6392101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar if (Created) 6402101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Entry.setFlags(Entry.getFlags() | 0x0001); 6410c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 6420c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 6430c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6443edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar /// ComputeSymbolTable - Compute the symbol table data 645f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// 646f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// \param StringTable [out] - The string table data. 647f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// \param StringIndexMap [out] - Map from symbol names to offsets in the 648f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// string table. 6493edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, 6503edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> &LocalSymbolData, 6513edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> &ExternalSymbolData, 6523edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> &UndefinedSymbolData) { 6533edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Build section lookup table. 6543edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar DenseMap<const MCSection*, uint8_t> SectionIndexMap; 6553edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned Index = 1; 6563edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 6573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ie = Asm.end(); it != ie; ++it, ++Index) 6583edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar SectionIndexMap[&it->getSection()] = Index; 6593edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar assert(Index <= 256 && "Too many sections!"); 660f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 661f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Index 0 is always the empty string. 6623edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringMap<uint64_t> StringIndexMap; 663f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar StringTable += '\x00'; 6643edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 6653edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Build the symbol arrays and the string table, but only for non-local 6663edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // symbols. 6673edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // 6683edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // The particular order that we collect the symbols and create the string 6693edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // table, then sort the symbols is chosen to match 'as'. Even though it 6703edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // doesn't matter for correctness, this is important for letting us diff .o 6713edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // files. 672f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 673f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar ie = Asm.symbol_end(); it != ie; ++it) { 674cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar const MCSymbol &Symbol = it->getSymbol(); 6753edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 676238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar // Ignore non-linker visible symbols. 677238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar if (!Asm.isSymbolLinkerVisible(it)) 678959fd883346384e742fff049327a6815e36017e0Daniel Dunbar continue; 679959fd883346384e742fff049327a6815e36017e0Daniel Dunbar 68050e48b359eb4e3d3e22d6e447583619d1feaeeaeDaniel Dunbar if (!it->isExternal() && !Symbol.isUndefined()) 6813edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar continue; 682f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 6833edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint64_t &Entry = StringIndexMap[Symbol.getName()]; 684f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!Entry) { 685f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Entry = StringTable.size(); 6863edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringTable += Symbol.getName(); 687f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar StringTable += '\x00'; 688f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 6893edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 6903edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MachSymbolData MSD; 6913edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SymbolData = it; 6923edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.StringIndex = Entry; 6933edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 6943edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (Symbol.isUndefined()) { 6953edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = 0; 6963edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar UndefinedSymbolData.push_back(MSD); 6973edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } else if (Symbol.isAbsolute()) { 6983edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = 0; 6993edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ExternalSymbolData.push_back(MSD); 7003edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } else { 7013edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 7023edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar assert(MSD.SectionIndex && "Invalid section index!"); 7033edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ExternalSymbolData.push_back(MSD); 7043edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 705f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 706f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 7073edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Now add the data for local symbols. 7083edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 7093edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ie = Asm.symbol_end(); it != ie; ++it) { 710cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar const MCSymbol &Symbol = it->getSymbol(); 7113edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 712238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar // Ignore non-linker visible symbols. 713238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar if (!Asm.isSymbolLinkerVisible(it)) 714959fd883346384e742fff049327a6815e36017e0Daniel Dunbar continue; 715959fd883346384e742fff049327a6815e36017e0Daniel Dunbar 71650e48b359eb4e3d3e22d6e447583619d1feaeeaeDaniel Dunbar if (it->isExternal() || Symbol.isUndefined()) 7173edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar continue; 7183edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7193edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint64_t &Entry = StringIndexMap[Symbol.getName()]; 7203edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (!Entry) { 7213edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Entry = StringTable.size(); 7223edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringTable += Symbol.getName(); 7233edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringTable += '\x00'; 7243edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 7253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MachSymbolData MSD; 7273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SymbolData = it; 7283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.StringIndex = Entry; 7293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7303edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (Symbol.isAbsolute()) { 7313edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = 0; 7323edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar LocalSymbolData.push_back(MSD); 7333edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } else { 7343edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 7353edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar assert(MSD.SectionIndex && "Invalid section index!"); 7363edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar LocalSymbolData.push_back(MSD); 7373edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 7383edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 7393edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7403edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // External and undefined symbols are required to be in lexicographic order. 7413edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 7423edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 7433edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 744be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar // Set the symbol indices. 745be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar Index = 0; 746be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 747be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar LocalSymbolData[i].SymbolData->setIndex(Index++); 748be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 749be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar ExternalSymbolData[i].SymbolData->setIndex(Index++); 750be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 751be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar UndefinedSymbolData[i].SymbolData->setIndex(Index++); 752be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar 753f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // The string table is padded to a multiple of 4. 754f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar while (StringTable.size() % 4) 755f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar StringTable += '\x00'; 756f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 757f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 758f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar void WriteObject(MCAssembler &Asm) { 7592ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar unsigned NumSections = Asm.size(); 7602ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar 761ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // Create symbol data for any indirect symbols. 7622101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar BindIndirectSymbols(Asm); 7630c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 764f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Compute symbol table information. 765f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SmallString<256> StringTable; 7663edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> LocalSymbolData; 7673edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> ExternalSymbolData; 7683edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> UndefinedSymbolData; 769f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar unsigned NumSymbols = Asm.symbol_size(); 770f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 771f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // No symbol table command is written if there are no symbols. 772f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) 7733edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, 7743edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar UndefinedSymbolData); 7757eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 776f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // The section data starts after the header, the segment load command (and 777f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // section headers) and the symbol table. 778f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar unsigned NumLoadCommands = 1; 779ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t LoadCommandsSize = Is64Bit ? 780ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand64Size + NumSections * Section64Size : 781f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SegmentLoadCommand32Size + NumSections * Section32Size; 782f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 783f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Add the symbol table load command sizes, if used. 784f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) { 785f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar NumLoadCommands += 2; 786f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize; 787f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 788f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 789edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // Compute the total size of the section data, as well as its file size and 790edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // vm size. 791ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t SectionDataStart = (Is64Bit ? Header64Size : Header32Size) 792ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar + LoadCommandsSize; 7932ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar uint64_t SectionDataSize = 0; 794edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar uint64_t SectionDataFileSize = 0; 795edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar uint64_t VMSize = 0; 796edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 797edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar ie = Asm.end(); it != ie; ++it) { 798edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar MCSectionData &SD = *it; 799edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 800edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar VMSize = std::max(VMSize, SD.getAddress() + SD.getSize()); 801edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 802d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) 803d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar continue; 804d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 805edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SectionDataSize = std::max(SectionDataSize, 806edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SD.getAddress() + SD.getSize()); 8077eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar SectionDataFileSize = std::max(SectionDataFileSize, 808edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SD.getAddress() + SD.getFileSize()); 8092ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar } 8102ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar 8116b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // The section data is padded to 4 bytes. 812edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // 813edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // FIXME: Is this machine dependent? 814edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); 815edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SectionDataFileSize += SectionDataPadding; 816edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 8172ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar // Write the prolog, starting with the header and load command... 818ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar WriteHeader(NumLoadCommands, LoadCommandsSize, 819ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Asm.getSubsectionsViaSymbols()); 820ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar WriteSegmentLoadCommand(NumSections, VMSize, 821ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SectionDataStart, SectionDataSize); 8227eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 8232ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar // ... and then the section headers. 8247eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar // 8253f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // We also compute the section relocations while we do this. Note that 8266b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // computing relocation info will also update the fixup to have the correct 8276b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // value; this will overwrite the appropriate data in the fragment when it 8286b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // is written. 8293f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar std::vector<MachRelocationEntry> RelocInfos; 830edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; 831cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 832cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar ie = Asm.end(); it != ie; ++it) { 8333f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MCSectionData &SD = *it; 8343f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 8353f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // The assembler writes relocations in the reverse order they were seen. 8363f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // 8373f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // FIXME: It is probably more complicated than this. 8383f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned NumRelocsStart = RelocInfos.size(); 839cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar for (MCSectionData::reverse_iterator it2 = SD.rbegin(), 840cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar ie2 = SD.rend(); it2 != ie2; ++it2) 8410bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2)) 8420bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i) 8430bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar ComputeRelocationInfo(Asm, *DF, DF->getFixups()[e - i - 1], 8442101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar RelocInfos); 8453f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 8463f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned NumRelocs = RelocInfos.size() - NumRelocsStart; 8473f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint64_t SectionStart = SectionDataStart + SD.getAddress(); 848ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar WriteSection(SD, SectionStart, RelocTableEnd, NumRelocs); 8493f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RelocTableEnd += NumRelocs * RelocationInfoSize; 8503f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 8517eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 852f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the symbol table load command, if used. 853f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) { 854f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar unsigned FirstLocalSymbol = 0; 8553edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned NumLocalSymbols = LocalSymbolData.size(); 8563edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; 8573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned NumExternalSymbols = ExternalSymbolData.size(); 8583edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; 8593edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); 8600c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); 8610c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar unsigned NumSymTabSymbols = 8620c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; 8630c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; 8640c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar uint64_t IndirectSymbolOffset = 0; 8650c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 8660c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // If used, the indirect symbols are written after the section data. 8670c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar if (NumIndirectSymbols) 8683f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar IndirectSymbolOffset = RelocTableEnd; 8690c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 8700c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // The symbol table is written after the indirect symbol data. 8713f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; 8720c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 8730c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // The string table is written after symbol table. 8740c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar uint64_t StringTableOffset = 8755691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar SymbolTableOffset + NumSymTabSymbols * (Is64Bit ? Nlist64Size : 8765691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar Nlist32Size); 8770c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, 8780c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar StringTableOffset, StringTable.size()); 8790c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 880f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, 881f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar FirstExternalSymbol, NumExternalSymbols, 882f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar FirstUndefinedSymbol, NumUndefinedSymbols, 883f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar IndirectSymbolOffset, NumIndirectSymbols); 884f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 885fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 886f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the actual section data. 887f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) 888f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar WriteFileData(OS, *it, *this); 889f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 890edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // Write the extra padding. 891edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar WriteZeros(SectionDataPadding); 892edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 8933f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // Write the relocation entries. 8943f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar for (unsigned i = 0, e = RelocInfos.size(); i != e; ++i) { 8953f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(RelocInfos[i].Word0); 8963f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(RelocInfos[i].Word1); 8973f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 8983f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 899f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the symbol table data, if used. 900f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) { 9010c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Write the indirect symbol entries. 902ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar for (MCAssembler::indirect_symbol_iterator 903ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar it = Asm.indirect_symbol_begin(), 904ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 905ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // Indirect symbols in the non lazy symbol pointer section have some 906ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // special handling. 907ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar const MCSectionMachO &Section = 908ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 90999d22adcadc750b2949283d562bdb4d480b8d11cDaniel Dunbar if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { 910ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // If this symbol is defined and internal, mark it as such. 911ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar if (it->Symbol->isDefined() && 9122101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar !Asm.getSymbolData(*it->Symbol).isExternal()) { 913ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar uint32_t Flags = ISF_Local; 914ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar if (it->Symbol->isAbsolute()) 915ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar Flags |= ISF_Absolute; 916ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar Write32(Flags); 917ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar continue; 918ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar } 919ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar } 920ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar 9212101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Write32(Asm.getSymbolData(*it->Symbol).getIndex()); 922ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar } 923f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 9240c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: Check that offsets match computed ones. 925f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 926f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the symbol table entries. 9273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 9285691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar WriteNlist(LocalSymbolData[i]); 9293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 9305691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar WriteNlist(ExternalSymbolData[i]); 9313edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 9325691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar WriteNlist(UndefinedSymbolData[i]); 933f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 934f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the string table. 935f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar OS << StringTable.str(); 936f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 937f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 9383a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar 9393a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) { 9402be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind); 9412be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar 9423a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // FIXME: Endianness assumption. 9432be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar assert(Fixup.Offset + Size <= DF.getContents().size() && 9442be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar "Invalid fixup offset!"); 9452be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar for (unsigned i = 0; i != Size; ++i) 9463a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8)); 9473a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar } 948f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar}; 949fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 950fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar/* *** */ 951fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 9520705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel DunbarMCFragment::MCFragment() : Kind(FragmentType(~0)) { 9530705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 9540705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 9555e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel DunbarMCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) 9560705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar : Kind(_Kind), 9575e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Parent(_Parent), 9580705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar FileSize(~UINT64_C(0)) 959fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar{ 9605e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar if (Parent) 9615e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Parent->getFragmentList().push_back(this); 962fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 963fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 9640705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel DunbarMCFragment::~MCFragment() { 9650705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 9660705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 9675e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbaruint64_t MCFragment::getAddress() const { 9685e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar assert(getParent() && "Missing Section!"); 9695e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar return getParent()->getAddress() + Offset; 9705e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar} 9715e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar 972fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar/* *** */ 973fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 97481e400092f55c2eba157172bfc0dd0df8317638dDaniel DunbarMCSectionData::MCSectionData() : Section(0) {} 975fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 976fb4a6b397665df011348ade24a8e38d2219f095aDaniel DunbarMCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) 97781e400092f55c2eba157172bfc0dd0df8317638dDaniel Dunbar : Section(&_Section), 978fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Alignment(1), 9795e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Address(~UINT64_C(0)), 9806742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar Size(~UINT64_C(0)), 9813f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar FileSize(~UINT64_C(0)), 982e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar HasInstructions(false) 983fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar{ 984fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if (A) 985fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar A->getSectionList().push_back(this); 986fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 987fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 988fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar/* *** */ 989fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 990efbb5330b8d383a393c83d2da5d631c98b0bb3fdDaniel DunbarMCSymbolData::MCSymbolData() : Symbol(0) {} 991f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 992cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel DunbarMCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, 993f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint64_t _Offset, MCAssembler *A) 994efbb5330b8d383a393c83d2da5d631c98b0bb3fdDaniel Dunbar : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), 9958f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar IsExternal(false), IsPrivateExtern(false), 9968f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar CommonSize(0), CommonAlign(0), Flags(0), Index(0) 997f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar{ 998f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (A) 999f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar A->getSymbolList().push_back(this); 1000f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar} 1001f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 1002f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar/* *** */ 1003f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 10041f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel DunbarMCAssembler::MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, 10051f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar raw_ostream &_OS) 10061f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar : Context(_Context), Backend(_Backend), OS(_OS), SubsectionsViaSymbols(false) 10076009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar{ 10086009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar} 1009fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1010fb4a6b397665df011348ade24a8e38d2219f095aDaniel DunbarMCAssembler::~MCAssembler() { 1011fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 1012fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1013939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbarstatic bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm, 1014939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar const MCAsmFixup &Fixup, 1015939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar const MCDataFragment *DF, 1016939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar const MCValue Target, 1017939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar const MCSection *BaseSection) { 1018939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // The effective fixup address is 1019939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // addr(atom(A)) + offset(A) 1020939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // - addr(atom(B)) - offset(B) 1021939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // - addr(<base symbol>) + <fixup offset from base symbol> 1022939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // and the offsets are not relocatable, so the fixup is fully resolved when 1023939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // addr(atom(A)) - addr(atom(B)) - addr(<base symbol>)) == 0. 1024939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // 1025939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // The simple (Darwin, except on x86_64) way of dealing with this was to 1026939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // assume that any reference to a temporary symbol *must* be a temporary 1027939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // symbol in the same atom, unless the sections differ. Therefore, any PCrel 1028939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // relocation to a temporary symbol (in the same section) is fully 1029939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // resolved. This also works in conjunction with absolutized .set, which 1030939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // requires the compiler to use .set to absolutize the differences between 1031939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // symbols which the compiler knows to be assembly time constants, so we don't 1032939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // need to worry about consider symbol differences fully resolved. 1033939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar 1034939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // Non-relative fixups are only resolved if constant. 1035939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar if (!BaseSection) 1036939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar return Target.isAbsolute(); 1037939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar 1038939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // Otherwise, relative fixups are only resolved if not a difference and the 1039939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // target is a temporary in the same section. 1040939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar if (Target.isAbsolute() || Target.getSymB()) 1041939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar return false; 1042939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar 1043939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar const MCSymbol *A = &Target.getSymA()->getSymbol(); 1044939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar if (!A->isTemporary() || !A->isInSection() || 1045939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar &A->getSection() != BaseSection) 1046939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar return false; 1047939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar 1048939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar return true; 1049939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar} 1050939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar 1051034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbarstatic bool isScatteredFixupFullyResolved(const MCAssembler &Asm, 1052034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar const MCAsmFixup &Fixup, 1053034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar const MCDataFragment *DF, 1054034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar const MCValue Target, 1055034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar const MCSymbolData *BaseSymbol) { 1056034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // The effective fixup address is 1057034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // addr(atom(A)) + offset(A) 1058034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // - addr(atom(B)) - offset(B) 1059034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // - addr(BaseSymbol) + <fixup offset from base symbol> 1060034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // and the offsets are not relocatable, so the fixup is fully resolved when 1061034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0. 1062034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // 1063034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // Note that "false" is almost always conservatively correct (it means we emit 1064034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // a relocation which is unnecessary), except when it would force us to emit a 1065034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // relocation which the target cannot encode. 1066034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1067034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar const MCSymbolData *A_Base = 0, *B_Base = 0; 1068034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (const MCSymbolRefExpr *A = Target.getSymA()) { 1069034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // Modified symbol references cannot be resolved. 1070034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (A->getKind() != MCSymbolRefExpr::VK_None) 1071034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar return false; 1072034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1073034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol())); 1074034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (!A_Base) 1075034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar return false; 1076034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar } 1077034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1078034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (const MCSymbolRefExpr *B = Target.getSymB()) { 1079034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // Modified symbol references cannot be resolved. 1080034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (B->getKind() != MCSymbolRefExpr::VK_None) 1081034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar return false; 1082034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1083034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol())); 1084034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (!B_Base) 1085034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar return false; 1086034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar } 1087034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1088034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // If there is no base, A and B have to be the same atom for this fixup to be 1089034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // fully resolved. 1090034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (!BaseSymbol) 1091034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar return A_Base == B_Base; 1092034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1093034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // Otherwise, B must be missing and A must be the base. 1094034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar return !B_Base && BaseSymbol == A_Base; 1095034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar} 1096034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1097238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbarbool MCAssembler::isSymbolLinkerVisible(const MCSymbolData *SD) const { 1098238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar // Non-temporary labels should always be visible to the linker. 1099238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar if (!SD->getSymbol().isTemporary()) 1100238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar return true; 1101238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar 1102238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar // Absolute temporary labels are never visible. 1103238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar if (!SD->getFragment()) 1104238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar return false; 1105238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar 1106238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar // Otherwise, check if the section requires symbols even for temporary labels. 1107238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar return getBackend().doesSectionRequireSymbols( 1108238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar SD->getFragment()->getParent()->getSection()); 1109238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar} 1110238698566311e9dba4092dfa6c0bfe253279702eDaniel Dunbar 11118ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbarconst MCSymbolData *MCAssembler::getAtomForAddress(const MCSectionData *Section, 11128ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar uint64_t Address) const { 11138ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar const MCSymbolData *Best = 0; 11148ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar for (MCAssembler::const_symbol_iterator it = symbol_begin(), 11158ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar ie = symbol_end(); it != ie; ++it) { 11168ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // Ignore non-linker visible symbols. 11178ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar if (!isSymbolLinkerVisible(it)) 11188ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar continue; 11198ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 11208ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // Ignore symbols not in the same section. 11218ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar if (!it->getFragment() || it->getFragment()->getParent() != Section) 11228ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar continue; 11238ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 11248ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // Otherwise, find the closest symbol preceding this address (ties are 11258ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // resolved in favor of the last defined symbol). 11268ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar if (it->getAddress() <= Address && 11278ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar (!Best || it->getAddress() >= Best->getAddress())) 11288ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar Best = it; 11298ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar } 11308ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 11318ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar return Best; 11328ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar} 11338ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 11348ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbarconst MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { 11358ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // Linker visible symbols define atoms. 11368ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar if (isSymbolLinkerVisible(SD)) 11378ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar return SD; 11388ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 11398ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // Absolute and undefined symbols have no defining atom. 11408ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar if (!SD->getFragment()) 11418ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar return 0; 11428ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 11438ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar // Otherwise, search by address. 11448ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar return getAtomForAddress(SD->getFragment()->getParent(), SD->getAddress()); 11458ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar} 11468ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1bDaniel Dunbar 1147df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbarbool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, MCAsmFixup &Fixup, 1148df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar MCDataFragment *DF, 1149df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar MCValue &Target, uint64_t &Value) const { 1150df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (!Fixup.Value->EvaluateAsRelocatable(Target, &Layout)) 1151df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar llvm_report_error("expected relocatable expression"); 1152df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1153df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // FIXME: How do non-scattered symbols work in ELF? I presume the linker 1154df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // doesn't support small relocations, but then under what criteria does the 1155df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // assembler allow symbol differences? 1156df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1157df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar Value = Target.getConstant(); 1158df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1159df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar bool IsResolved = true, IsPCRel = isFixupKindPCRel(Fixup.Kind); 11609a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar if (const MCSymbolRefExpr *A = Target.getSymA()) { 11619a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar if (A->getSymbol().isDefined()) 11629a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar Value += getSymbolData(A->getSymbol()).getAddress(); 1163df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar else 1164df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar IsResolved = false; 1165df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar } 11669a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar if (const MCSymbolRefExpr *B = Target.getSymB()) { 11679a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar if (B->getSymbol().isDefined()) 11689a1d20042f6a6ec648a3588f9b13264a4570aab0Daniel Dunbar Value -= getSymbolData(B->getSymbol()).getAddress(); 1169df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar else 1170df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar IsResolved = false; 1171939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar } 1172df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1173939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // If we are using scattered symbols, determine whether this value is actually 1174939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar // resolved; scattering may cause atoms to move. 1175939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar if (IsResolved && getBackend().hasScatteredSymbols()) { 1176939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar if (getBackend().hasReliableSymbolDifference()) { 1177034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // If this is a PCrel relocation, find the base atom (identified by its 1178034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar // symbol) that the fixup value is relative to. 1179034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar const MCSymbolData *BaseSymbol = 0; 1180034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (IsPCRel) { 1181034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar BaseSymbol = getAtomForAddress( 1182034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar DF->getParent(), DF->getAddress() + Fixup.Offset); 1183034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (!BaseSymbol) 1184034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar IsResolved = false; 1185034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar } 1186034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar 1187034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar if (IsResolved) 1188034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar IsResolved = isScatteredFixupFullyResolved(*this, Fixup, DF, Target, 1189034843ac8bca36d14ef9d83b50596354b5f3420fDaniel Dunbar BaseSymbol); 1190939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar } else { 1191939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar const MCSection *BaseSection = 0; 1192939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar if (IsPCRel) 1193939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar BaseSection = &DF->getParent()->getSection(); 1194939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar 1195939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar IsResolved = isScatteredFixupFullyResolvedSimple(*this, Fixup, DF, Target, 1196939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar BaseSection); 1197939f8d7ca23b95acdd5d1e71a7579ee8d33e7fd6Daniel Dunbar } 1198df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar } 1199df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1200df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (IsPCRel) 1201da3e9f760ce2328f6dfe69663c2b17da02ece2dbDaniel Dunbar Value -= DF->getAddress() + Fixup.Offset; 1202df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1203df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar return IsResolved; 1204df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar} 1205df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1206edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbarvoid MCAssembler::LayoutSection(MCSectionData &SD) { 120718ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar MCAsmLayout Layout(*this); 12086742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar uint64_t Address = SD.getAddress(); 12090705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12100705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) { 12110705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MCFragment &F = *it; 1212d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 12136742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar F.setOffset(Address - SD.getAddress()); 1214d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1215d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // Evaluate fragment size. 1216d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar switch (F.getKind()) { 1217d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Align: { 1218d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCAlignFragment &AF = cast<MCAlignFragment>(F); 12197eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 1220d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar uint64_t Size = OffsetToAlignment(Address, AF.getAlignment()); 12216742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar if (Size > AF.getMaxBytesToEmit()) 1222d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar AF.setFileSize(0); 1223d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar else 12246742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar AF.setFileSize(Size); 1225d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1226d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1227d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1228d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Data: 1229a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case MCFragment::FT_Fill: 1230d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar F.setFileSize(F.getMaxFileSize()); 1231d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1232d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1233d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Org: { 1234d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCOrgFragment &OF = cast<MCOrgFragment>(F); 1235d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 123618ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar int64_t TargetLocation; 123718ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout)) 123818ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar llvm_report_error("expected assembly-time absolute expression"); 1239d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1240d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // FIXME: We need a way to communicate this error. 124118ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar int64_t Offset = TargetLocation - F.getOffset(); 124218ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar if (Offset < 0) 124318ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar llvm_report_error("invalid .org offset '" + Twine(TargetLocation) + 124418ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar "' (at offset '" + Twine(F.getOffset()) + "'"); 12457eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 124618ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar F.setFileSize(Offset); 1247d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 12487eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar } 1249d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1250d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar case MCFragment::FT_ZeroFill: { 1251d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCZeroFillFragment &ZFF = cast<MCZeroFillFragment>(F); 1252d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1253d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Align the fragment offset; it is safe to adjust the offset freely since 1254d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // this is only in virtual sections. 125537fad5ce4d81fd459fafe1517d6cd17e7ab49958Daniel Dunbar Address = RoundUpToAlignment(Address, ZFF.getAlignment()); 125637fad5ce4d81fd459fafe1517d6cd17e7ab49958Daniel Dunbar F.setOffset(Address - SD.getAddress()); 1257d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1258d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // FIXME: This is misnamed. 1259d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar F.setFileSize(ZFF.getSize()); 1260d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar break; 1261d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 1262d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1263d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 12646742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar Address += F.getFileSize(); 12650705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 12660705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12676742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar // Set the section sizes. 12686742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar SD.setSize(Address - SD.getAddress()); 1269d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) 1270d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setFileSize(0); 1271d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar else 1272d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setFileSize(Address - SD.getAddress()); 12730705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 12740705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12756e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// WriteNopData - Write optimal nops to the output file for the \arg Count 12766e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// bytes. This returns the number of bytes written. It may return 0 if 12776e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// the \arg Count is more than the maximum optimal nops. 12786e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// 12796e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// FIXME this is X86 32-bit specific and should move to a better place. 12806e72048add2a6464e038121c6c275da37528aa0aKevin Enderbystatic uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) { 128176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby static const uint8_t Nops[16][16] = { 128276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nop 128376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x90}, 128476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // xchg %ax,%ax 128576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x90}, 128676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl (%[re]ax) 128776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x00}, 128876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0(%[re]ax) 128976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x40, 0x00}, 129076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0(%[re]ax,%[re]ax,1) 129176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x44, 0x00, 0x00}, 129276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 129376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 129476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 129576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 129676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax,%[re]ax,1) 129776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 129876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0L(%[re]ax,%[re]ax,1) 129976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 130076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw %cs:0L(%[re]ax,%[re]ax,1) 130176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 130276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0(%[re]ax,%[re]ax,1) 130376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 130476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x44, 0x00, 0x00, 130576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 130676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 130776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 130876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00, 130976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 131076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 131176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) */ 131276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00, 131376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 131476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 131576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 131676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 131776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 131876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 131976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax,%[re]ax,1) 132076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 132176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00} 132276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby }; 132376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 132476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby if (Count > 15) 132576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby return 0; 132676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 13276e72048add2a6464e038121c6c275da37528aa0aKevin Enderby for (uint64_t i = 0; i < Count; i++) 132876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby MOW.Write8 (uint8_t(Nops[Count - 1][i])); 13296e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 13306e72048add2a6464e038121c6c275da37528aa0aKevin Enderby return Count; 13316e72048add2a6464e038121c6c275da37528aa0aKevin Enderby} 13326e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 13330705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar/// WriteFileData - Write the \arg F data to the output file. 13340705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbarstatic void WriteFileData(raw_ostream &OS, const MCFragment &F, 13350705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MachObjectWriter &MOW) { 13360705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar uint64_t Start = OS.tell(); 13370705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar (void) Start; 13387eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 13390adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar ++EmittedFragments; 13400adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar 13410705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar // FIXME: Embed in fragments instead? 13420705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar switch (F.getKind()) { 1343d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Align: { 1344d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCAlignFragment &AF = cast<MCAlignFragment>(F); 1345d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar uint64_t Count = AF.getFileSize() / AF.getValueSize(); 1346d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1347d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // FIXME: This error shouldn't actually occur (the front end should emit 1348d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // multiple .align directives to enforce the semantics it wants), but is 1349d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // severe enough that we want to report it. How to handle this? 1350d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar if (Count * AF.getValueSize() != AF.getFileSize()) 13517eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar llvm_report_error("undefined .align directive, value size '" + 13527eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar Twine(AF.getValueSize()) + 1353d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar "' is not a divisor of padding size '" + 1354d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar Twine(AF.getFileSize()) + "'"); 1355d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 13566e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // See if we are aligning with nops, and if so do that first to try to fill 13576e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // the Count bytes. Then if that did not fill any bytes or there are any 13586e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // bytes left to fill use the the Value and ValueSize to fill the rest. 13596e72048add2a6464e038121c6c275da37528aa0aKevin Enderby if (AF.getEmitNops()) { 13606e72048add2a6464e038121c6c275da37528aa0aKevin Enderby uint64_t NopByteCount = WriteNopData(Count, MOW); 13616e72048add2a6464e038121c6c275da37528aa0aKevin Enderby Count -= NopByteCount; 13626e72048add2a6464e038121c6c275da37528aa0aKevin Enderby } 13636e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 1364d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar for (uint64_t i = 0; i != Count; ++i) { 1365d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar switch (AF.getValueSize()) { 1366d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar default: 1367d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar assert(0 && "Invalid size!"); 1368d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 1: MOW.Write8 (uint8_t (AF.getValue())); break; 1369d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 2: MOW.Write16(uint16_t(AF.getValue())); break; 1370d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 4: MOW.Write32(uint32_t(AF.getValue())); break; 1371d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 8: MOW.Write64(uint64_t(AF.getValue())); break; 1372d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1373d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1374d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1375d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 13760705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 13773a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar case MCFragment::FT_Data: { 13783a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar MCDataFragment &DF = cast<MCDataFragment>(F); 13793a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar 13803a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // Apply the fixups. 13813a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // 13823a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // FIXME: Move elsewhere. 13833a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar for (MCDataFragment::const_fixup_iterator it = DF.fixup_begin(), 13843a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar ie = DF.fixup_end(); it != ie; ++it) 13853a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar MOW.ApplyFixup(*it, DF); 13863a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar 13870705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar OS << cast<MCDataFragment>(F).getContents().str(); 13880705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar break; 13893a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar } 13900705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 13910705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar case MCFragment::FT_Fill: { 13920705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MCFillFragment &FF = cast<MCFillFragment>(F); 13930705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) { 13940705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar switch (FF.getValueSize()) { 13950705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar default: 13960705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar assert(0 && "Invalid size!"); 1397a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 1: MOW.Write8 (uint8_t (FF.getValue())); break; 1398a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 2: MOW.Write16(uint16_t(FF.getValue())); break; 1399a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 4: MOW.Write32(uint32_t(FF.getValue())); break; 1400a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 8: MOW.Write64(uint64_t(FF.getValue())); break; 14010705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 14020705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 14030705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar break; 14040705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 14057eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 1406d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Org: { 1407d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCOrgFragment &OF = cast<MCOrgFragment>(F); 1408d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1409d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i) 1410d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MOW.Write8(uint8_t(OF.getValue())); 1411d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1412d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1413d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1414d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1415d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar case MCFragment::FT_ZeroFill: { 1416d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(0 && "Invalid zero fill fragment in concrete section!"); 1417d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar break; 1418d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 14190705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 14200705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 14210705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar assert(OS.tell() - Start == F.getFileSize()); 14220705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 14230705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 14240705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar/// WriteFileData - Write the \arg SD data to the output file. 14250705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbarstatic void WriteFileData(raw_ostream &OS, const MCSectionData &SD, 14260705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MachObjectWriter &MOW) { 1427d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Ignore virtual sections. 1428d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) { 1429d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(SD.getFileSize() == 0); 1430d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar return; 1431d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 1432d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 14330705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar uint64_t Start = OS.tell(); 14340705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar (void) Start; 14357eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 14360705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar for (MCSectionData::const_iterator it = SD.begin(), 14370705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar ie = SD.end(); it != ie; ++it) 14380705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar WriteFileData(OS, *it, MOW); 14390705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 14406742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar // Add section padding. 14416742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!"); 14426742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar MOW.WriteZeros(SD.getFileSize() - SD.getSize()); 14436742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar 14440705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar assert(OS.tell() - Start == SD.getFileSize()); 14450705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 14460705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1447fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCAssembler::Finish() { 1448b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar DEBUG_WITH_TYPE("mc-dump", { 1449b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar llvm::errs() << "assembler backend - pre-layout\n--\n"; 1450b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar dump(); }); 1451b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1452f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Layout until everything fits. 1453f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar while (LayoutOnce()) 1454f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 1455f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1456f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar DEBUG_WITH_TYPE("mc-dump", { 1457f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar llvm::errs() << "assembler backend - post-layout\n--\n"; 1458f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar dump(); }); 1459f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1460f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Write the object file. 1461ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // 1462ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // FIXME: Factor out MCObjectWriter. 1463ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar bool Is64Bit = StringRef(getBackend().getTarget().getName()) == "x86-64"; 1464ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar MachObjectWriter MOW(OS, Is64Bit); 1465f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MOW.WriteObject(*this); 1466f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1467f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar OS.flush(); 1468f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar} 1469f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1470f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbarbool MCAssembler::FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF) { 1471f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: Share layout object. 1472f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCAsmLayout Layout(*this); 1473f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1474f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Currently we only need to relax X86::reloc_pcrel_1byte. 1475f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (unsigned(Fixup.Kind) != X86::reloc_pcrel_1byte) 1476f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return false; 1477f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1478f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // If we cannot resolve the fixup value, it requires relaxation. 1479f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCValue Target; 1480f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar uint64_t Value; 1481f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (!EvaluateFixup(Layout, Fixup, DF, Target, Value)) 1482f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return true; 1483f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1484f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Otherwise, relax if the value is too big for a (signed) i8. 1485f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return int64_t(Value) != int64_t(int8_t(Value)); 1486f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar} 1487f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1488f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbarbool MCAssembler::LayoutOnce() { 1489d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Layout the concrete sections and fragments. 14905e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar uint64_t Address = 0; 1491edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar MCSectionData *Prev = 0; 1492edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 14936742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar MCSectionData &SD = *it; 14946742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar 1495d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Skip virtual sections. 1496d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) 1497d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar continue; 1498d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1499edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // Align this section if necessary by adding padding bytes to the previous 1500edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // section. 1501edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) { 1502edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar assert(Prev && "Missing prev section!"); 1503edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar Prev->setFileSize(Prev->getFileSize() + Pad); 1504edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar Address += Pad; 1505edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar } 15066742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar 15076742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar // Layout the section fragments and its size. 15086742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar SD.setAddress(Address); 1509edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar LayoutSection(SD); 15106742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar Address += SD.getFileSize(); 1511edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 1512edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar Prev = &SD; 15135e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar } 15140705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1515d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Layout the virtual sections. 1516d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1517d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCSectionData &SD = *it; 1518d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1519d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (!isVirtualSection(SD.getSection())) 1520d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar continue; 1521d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1522b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar // Align this section if necessary by adding padding bytes to the previous 1523b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar // section. 1524f8b8ad77a8b5632886a4cfe41d798bae7277efcbDaniel Dunbar if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) 1525b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar Address += Pad; 1526b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar 1527d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setAddress(Address); 1528d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar LayoutSection(SD); 1529d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar Address += SD.getSize(); 1530d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 1531d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1532f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Scan the fixups in order and relax any that don't fit. 1533f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1534f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCSectionData &SD = *it; 1535b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1536f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (MCSectionData::iterator it2 = SD.begin(), 1537f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ie2 = SD.end(); it2 != ie2; ++it2) { 1538f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCDataFragment *DF = dyn_cast<MCDataFragment>(it2); 1539f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (!DF) 1540f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 15410705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1542f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(), 1543f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ie3 = DF->fixup_end(); it3 != ie3; ++it3) { 1544f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCAsmFixup &Fixup = *it3; 1545f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1546f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Check whether we need to relax this fixup. 1547f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (!FixupNeedsRelaxation(Fixup, DF)) 1548f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 1549f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1550f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Relax the instruction. 1551f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1552f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is a huge temporary hack which just looks for x86 1553f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // branches; the only thing we need to relax on x86 is 1554f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 'X86::reloc_pcrel_1byte'. Once we have MCInst fragments, this will be 1555f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // replaced by a TargetAsmBackend hook (most likely tblgen'd) to relax 1556f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // an individual MCInst. 1557f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar SmallVectorImpl<char> &C = DF->getContents(); 1558f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar uint64_t PrevOffset = Fixup.Offset; 1559f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar unsigned Amt = 0; 1560f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1561f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // jcc instructions 1562f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (unsigned(C[Fixup.Offset-1]) >= 0x70 && 1563f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar unsigned(C[Fixup.Offset-1]) <= 0x7f) { 1564f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C[Fixup.Offset] = C[Fixup.Offset-1] + 0x10; 1565f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C[Fixup.Offset-1] = char(0x0f); 1566f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ++Fixup.Offset; 1567f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Amt = 4; 1568f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1569f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // jmp rel8 1570f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } else if (C[Fixup.Offset-1] == char(0xeb)) { 1571f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C[Fixup.Offset-1] = char(0xe9); 1572f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Amt = 3; 1573f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1574f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } else 1575f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar llvm_unreachable("unknown 1 byte pcrel instruction!"); 1576f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1577f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Fixup.Value = MCBinaryExpr::Create( 1578f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCBinaryExpr::Sub, Fixup.Value, 1579f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCConstantExpr::Create(3, getContext()), 1580f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar getContext()); 1581f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C.insert(C.begin() + Fixup.Offset, Amt, char(0)); 1582f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Fixup.Kind = MCFixupKind(X86::reloc_pcrel_4byte); 1583f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1584f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Update the remaining fixups, which have slid. 1585f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1586f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is bad for performance, but will be eliminated by the 1587f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // move to MCInst specific fragments. 1588f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ++it3; 1589f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (; it3 != ie3; ++it3) 1590f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar it3->Offset += Amt; 1591b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1592f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Update all the symbols for this fragment, which may have slid. 1593f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1594f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is really really bad for performance, but will be 1595f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // eliminated by the move to MCInst specific fragments. 1596f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (MCAssembler::symbol_iterator it = symbol_begin(), 1597f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ie = symbol_end(); it != ie; ++it) { 1598f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCSymbolData &SD = *it; 1599f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1600f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (it->getFragment() != DF) 1601f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 1602f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1603f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (SD.getOffset() > PrevOffset) 1604f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar SD.setOffset(SD.getOffset() + Amt); 1605f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1606f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1607f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Restart layout. 1608f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1609f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is O(N^2), but will be eliminated once we have a smart 1610f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // MCAsmLayout object. 1611f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return true; 1612f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1613f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1614f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1615f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1616f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return false; 1617f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar} 1618b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1619b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar// Debugging methods 1620b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1621b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarnamespace llvm { 1622b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1623b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarraw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) { 16242be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value 16252be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar << " Kind:" << AF.Kind << ">"; 1626b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar return OS; 1627b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1628b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1629b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1630b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1631b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCFragment::dump() { 1632b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1633b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1634b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCFragment " << (void*) this << " Offset:" << Offset 1635b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " FileSize:" << FileSize; 1636b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1637b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << ">"; 1638b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1639b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1640b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCAlignFragment::dump() { 1641b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1642b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1643b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCAlignFragment "; 1644b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1645b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1646b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Alignment:" << getAlignment() 1647b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Value:" << getValue() << " ValueSize:" << getValueSize() 1648b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">"; 1649b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1650b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1651b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCDataFragment::dump() { 1652b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1653b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1654b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCDataFragment "; 1655b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1656b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1657b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Contents:["; 1658b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (unsigned i = 0, e = getContents().size(); i != e; ++i) { 1659b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (i) OS << ","; 1660b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1661b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 16622be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar OS << "] (" << getContents().size() << " bytes)"; 16630bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar 16640bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar if (!getFixups().empty()) { 16650bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << ",\n "; 16660bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << " Fixups:["; 16670bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) { 166845aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar if (it != fixup_begin()) OS << ",\n "; 16690bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << *it; 16700bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar } 16710bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << "]"; 16720bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar } 16730bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar 16740bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << ">"; 1675b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1676b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1677b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCFillFragment::dump() { 1678b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1679b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1680b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCFillFragment "; 1681b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1682b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1683b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Value:" << getValue() << " ValueSize:" << getValueSize() 1684b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Count:" << getCount() << ">"; 1685b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1686b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1687b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCOrgFragment::dump() { 1688b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1689b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1690b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCOrgFragment "; 1691b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1692b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1693b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Offset:" << getOffset() << " Value:" << getValue() << ">"; 1694b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1695b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1696b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCZeroFillFragment::dump() { 1697b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1698b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1699b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCZeroFillFragment "; 1700b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1701b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1702b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Size:" << getSize() << " Alignment:" << getAlignment() << ">"; 1703b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1704b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1705b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCSectionData::dump() { 1706b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1707b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1708b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCSectionData"; 1709b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Alignment:" << getAlignment() << " Address:" << Address 1710b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Size:" << Size << " FileSize:" << FileSize 171145aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar << " Fragments:[\n "; 1712b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1713b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (it != begin()) OS << ",\n "; 1714b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar it->dump(); 1715b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 1716b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "]>"; 1717b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1718b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1719b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCSymbolData::dump() { 1720b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1721b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1722b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCSymbolData Symbol:" << getSymbol() 1723b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Fragment:" << getFragment() << " Offset:" << getOffset() 1724b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Flags:" << getFlags() << " Index:" << getIndex(); 1725b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (isCommon()) 1726b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " (common, size:" << getCommonSize() 1727b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " align: " << getCommonAlignment() << ")"; 1728b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (isExternal()) 1729b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " (external)"; 1730b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (isPrivateExtern()) 1731b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " (private extern)"; 1732b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << ">"; 1733b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1734b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1735b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCAssembler::dump() { 1736b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1737b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1738b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCAssembler\n"; 173945aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar OS << " Sections:[\n "; 1740b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1741b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (it != begin()) OS << ",\n "; 1742b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar it->dump(); 1743b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 1744b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "],\n"; 1745b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Symbols:["; 1746b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1747b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { 174845aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar if (it != symbol_begin()) OS << ",\n "; 1749b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar it->dump(); 1750b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 1751b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "]>\n"; 1752b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1753