MCAssembler.cpp revision ee0d89245eabf93d89b5fef7ac8707680796826d
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); 55d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar unsigned Type = SMO.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 56d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar return (Type == MCSectionMachO::S_ZEROFILL); 57d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar} 58d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 599a7795cbed47159566fd8f57b846fcf14ffb0272Duncan Sandsstatic unsigned getFixupKindLog2Size(unsigned Kind) { 602be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar switch (Kind) { 612be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar default: llvm_unreachable("invalid fixup kind!"); 62f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar case X86::reloc_pcrel_1byte: 632be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_1: return 0; 642be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_2: return 1; 65f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar case X86::reloc_pcrel_4byte: 66f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar case X86::reloc_riprel_4byte: 672be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_4: return 2; 682be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar case FK_Data_8: return 3; 692be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar } 702be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar} 712be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar 729a7795cbed47159566fd8f57b846fcf14ffb0272Duncan Sandsstatic bool isFixupKindPCRel(unsigned Kind) { 73591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar switch (Kind) { 74591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar default: 75591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar return false; 76591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar case X86::reloc_pcrel_1byte: 77591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar case X86::reloc_pcrel_4byte: 78591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar case X86::reloc_riprel_4byte: 79591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar return true; 80591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar } 81591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar} 82591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar 83fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass MachObjectWriter { 84fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // See <mach-o/loader.h>. 85fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar enum { 86fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Header_Magic32 = 0xFEEDFACE, 87fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Header_Magic64 = 0xFEEDFACF 88fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar }; 897eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 90ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar enum { 91ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Header32Size = 28, 92ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Header64Size = 32, 93ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand32Size = 56, 94ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand64Size = 72, 95ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Section32Size = 68, 96ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Section64Size = 80, 97ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SymtabLoadCommandSize = 24, 98ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar DysymtabLoadCommandSize = 80, 99ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Nlist32Size = 12, 100ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Nlist64Size = 16, 101ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar RelocationInfoSize = 8 102ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar }; 103fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 104fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar enum HeaderFileType { 105fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar HFT_Object = 0x1 106fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar }; 107fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1086009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar enum HeaderFlags { 1096009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar HF_SubsectionsViaSymbols = 0x2000 1106009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar }; 1116009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 112fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar enum LoadCommandType { 113f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar LCT_Segment = 0x1, 114f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar LCT_Symtab = 0x2, 115ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar LCT_Dysymtab = 0xb, 116ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar LCT_Segment64 = 0x19 117fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar }; 118fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1193edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // See <mach-o/nlist.h>. 1203edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar enum SymbolTypeType { 1213edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STT_Undefined = 0x00, 1223edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STT_Absolute = 0x02, 1233edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STT_Section = 0x0e 1243edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar }; 1253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 1263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar enum SymbolTypeFlags { 1273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // If any of these bits are set, then the entry is a stab entry number (see 1283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // <mach-o/stab.h>. Otherwise the other masks apply. 1293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_StabsEntryMask = 0xe0, 1303edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 1313edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_TypeMask = 0x0e, 1323edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_External = 0x01, 1333edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar STF_PrivateExtern = 0x10 1343edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar }; 1353edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 136ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar /// IndirectSymbolFlags - Flags for encoding special values in the indirect 137ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar /// symbol entry. 138ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar enum IndirectSymbolFlags { 139ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar ISF_Local = 0x80000000, 140ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar ISF_Absolute = 0x40000000 141ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar }; 142ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar 1433f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar /// RelocationFlags - Special flags for addresses. 1443f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar enum RelocationFlags { 1453f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RF_Scattered = 0x80000000 1463f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar }; 1473f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 1483f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar enum RelocationInfoType { 1493f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_Vanilla = 0, 1503f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_Pair = 1, 1513f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_Difference = 2, 1523f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_PreboundLazyPointer = 3, 1533f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RIT_LocalDifference = 4 1543f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar }; 1553f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 1563edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar /// MachSymbolData - Helper struct for containing some precomputed information 1573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar /// on symbols. 1583edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar struct MachSymbolData { 1593edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MCSymbolData *SymbolData; 1603edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint64_t StringIndex; 1613edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint8_t SectionIndex; 1623edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 1633edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Support lexicographic sorting. 1643edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar bool operator<(const MachSymbolData &RHS) const { 1653edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar const std::string &Name = SymbolData->getSymbol().getName(); 1663edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar return Name < RHS.SymbolData->getSymbol().getName(); 1673edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 1683edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar }; 1693edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 170fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar raw_ostream &OS; 171ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar unsigned Is64Bit : 1; 172ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar unsigned IsLSB : 1; 173fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 174fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic: 175ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar MachObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool _IsLSB = true) 176ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar : OS(_OS), Is64Bit(_Is64Bit), IsLSB(_IsLSB) { 177fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 178fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 179fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @name Helper Methods 180fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @{ 181fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1820705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar void Write8(uint8_t Value) { 1830705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar OS << char(Value); 1840705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 1850705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1860705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar void Write16(uint16_t Value) { 1870705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar if (IsLSB) { 1880705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 0)); 1890705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 8)); 1900705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } else { 1910705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 8)); 1920705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write8(uint8_t(Value >> 0)); 1930705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 1940705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 1950705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 196fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar void Write32(uint32_t Value) { 197fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if (IsLSB) { 1980705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 0)); 1990705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 16)); 2000705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } else { 2010705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 16)); 2020705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write16(uint16_t(Value >> 0)); 2030705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 2040705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 2050705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 2060705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar void Write64(uint64_t Value) { 2070705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar if (IsLSB) { 2080705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 0)); 2090705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 32)); 210fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } else { 2110705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 32)); 2120705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar Write32(uint32_t(Value >> 0)); 213fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 214fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 215fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 216fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar void WriteZeros(unsigned N) { 217fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar const char Zeros[16] = { 0 }; 2187eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 219fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar for (unsigned i = 0, e = N / 16; i != e; ++i) 220fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar OS << StringRef(Zeros, 16); 2217eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 222fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar OS << StringRef(Zeros, N % 16); 223fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 224fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 2252928c83b010f7cfdb0f819199d806f6942a7d995Daniel Dunbar void WriteString(StringRef Str, unsigned ZeroFillSize = 0) { 226fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar OS << Str; 227fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if (ZeroFillSize) 228fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteZeros(ZeroFillSize - Str.size()); 229fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 230fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 231fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @} 2327eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 233ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, 234ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar bool SubsectionsViaSymbols) { 2356009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar uint32_t Flags = 0; 2366009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 2376009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar if (SubsectionsViaSymbols) 2386009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Flags |= HF_SubsectionsViaSymbols; 2396009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 240ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct mach_header (28 bytes) or 241ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct mach_header_64 (32 bytes) 242fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 243fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar uint64_t Start = OS.tell(); 244fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (void) Start; 245fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 246ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(Is64Bit ? Header_Magic64 : Header_Magic32); 247fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 248fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // FIXME: Support cputype. 249ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(Is64Bit ? MachO::CPUTypeX86_64 : MachO::CPUTypeI386); 250fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // FIXME: Support cpusubtype. 25145f8c095ad94888716ceff54daf2fdf2f2f668a4Chris Lattner Write32(MachO::CPUSubType_I386_ALL); 252fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(HFT_Object); 2536009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Write32(NumLoadCommands); // Object files have a single load command, the 2546009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar // segment. 255f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(LoadCommandsSize); 2566009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Write32(Flags); 257ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) 258ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(0); // reserved 259fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 260ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar assert(OS.tell() - Start == Is64Bit ? Header64Size : Header32Size); 261fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 262fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 263ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar /// WriteSegmentLoadCommand - Write a segment load command. 2640705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar /// 2650705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar /// \arg NumSections - The number of sections in this segment. 2660705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar /// \arg SectionDataSize - The total size of the sections. 267ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar void WriteSegmentLoadCommand(unsigned NumSections, 268ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t VMSize, 269ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t SectionDataStartOffset, 270ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t SectionDataSize) { 271ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct segment_command (56 bytes) or 272ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct segment_command_64 (72 bytes) 273fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 274fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar uint64_t Start = OS.tell(); 275fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (void) Start; 276fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 277ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar unsigned SegmentLoadCommandSize = Is64Bit ? SegmentLoadCommand64Size : 278ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand32Size; 279ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(Is64Bit ? LCT_Segment64 : LCT_Segment); 280ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SegmentLoadCommandSize + 281ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar NumSections * (Is64Bit ? Section64Size : Section32Size)); 282fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 283fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteString("", 16); 284ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) { 285ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(0); // vmaddr 286ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(VMSize); // vmsize 287ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SectionDataStartOffset); // file offset 288ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SectionDataSize); // file size 289ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } else { 290ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(0); // vmaddr 291ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(VMSize); // vmsize 292ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SectionDataStartOffset); // file offset 293ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SectionDataSize); // file size 294ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } 295fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0x7); // maxprot 296fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0x7); // initprot 297fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(NumSections); 298fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0); // flags 299fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 300ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar assert(OS.tell() - Start == SegmentLoadCommandSize); 301fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 302fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 303ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar void WriteSection(const MCSectionData &SD, uint64_t FileOffset, 304ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t RelocationsStart, unsigned NumRelocations) { 305d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // The offset is unused for virtual sections. 306d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) { 307d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(SD.getFileSize() == 0 && "Invalid file size!"); 308d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar FileOffset = 0; 309d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 310d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 311ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct section (68 bytes) or 312ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // struct section_64 (80 bytes) 313fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 314fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar uint64_t Start = OS.tell(); 315fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (void) Start; 316fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 317fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar // FIXME: cast<> support! 318fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar const MCSectionMachO &Section = 319fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar static_cast<const MCSectionMachO&>(SD.getSection()); 320fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteString(Section.getSectionName(), 16); 321fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar WriteString(Section.getSegmentName(), 16); 322ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) { 323ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SD.getAddress()); // address 324ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write64(SD.getSize()); // size 325ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } else { 326ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SD.getAddress()); // address 327ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(SD.getSize()); // size 328ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar } 3292ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar Write32(FileOffset); 330fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 331e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar unsigned Flags = Section.getTypeAndAttributes(); 332e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar if (SD.hasInstructions()) 333e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; 334e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar 335fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); 336fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(Log2_32(SD.getAlignment())); 3373f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(NumRelocations ? RelocationsStart : 0); 3383f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(NumRelocations); 339e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar Write32(Flags); 340fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(0); // reserved1 341fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Write32(Section.getStubSize()); // reserved2 342ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar if (Is64Bit) 343ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Write32(0); // reserved3 344fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 345ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar assert(OS.tell() - Start == Is64Bit ? Section64Size : Section32Size); 346fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar } 3472ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar 348f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, 349f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t StringTableOffset, 350f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t StringTableSize) { 351f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // struct symtab_command (24 bytes) 352f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 353f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint64_t Start = OS.tell(); 354f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar (void) Start; 355f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 356f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(LCT_Symtab); 357f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(SymtabLoadCommandSize); 358f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(SymbolOffset); 359f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumSymbols); 360f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(StringTableOffset); 361f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(StringTableSize); 362f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 363f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(OS.tell() - Start == SymtabLoadCommandSize); 364f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 365f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 366f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, 367f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumLocalSymbols, 368f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t FirstExternalSymbol, 369f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumExternalSymbols, 370f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t FirstUndefinedSymbol, 371f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumUndefinedSymbols, 372f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t IndirectSymbolOffset, 373f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint32_t NumIndirectSymbols) { 374f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // struct dysymtab_command (80 bytes) 375f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 376f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint64_t Start = OS.tell(); 377f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar (void) Start; 378f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 379f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(LCT_Dysymtab); 380f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(DysymtabLoadCommandSize); 381f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(FirstLocalSymbol); 382f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumLocalSymbols); 383f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(FirstExternalSymbol); 384f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumExternalSymbols); 385f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(FirstUndefinedSymbol); 386f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumUndefinedSymbols); 387f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // tocoff 388f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // ntoc 389f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // modtaboff 390f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nmodtab 391f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // extrefsymoff 392f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nextrefsyms 393f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(IndirectSymbolOffset); 394f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(NumIndirectSymbols); 395f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // extreloff 396f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nextrel 397f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // locreloff 398f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write32(0); // nlocrel 399f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 400f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(OS.tell() - Start == DysymtabLoadCommandSize); 401f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 402f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 4033edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar void WriteNlist32(MachSymbolData &MSD) { 4045e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar MCSymbolData &Data = *MSD.SymbolData; 405cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar const MCSymbol &Symbol = Data.getSymbol(); 4063edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint8_t Type = 0; 4078f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar uint16_t Flags = Data.getFlags(); 4088f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar uint32_t Address = 0; 4093edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4103edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Set the N_TYPE bits. See <mach-o/nlist.h>. 4113edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // 4123edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // FIXME: Are the prebound or indirect fields possible here? 4133edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (Symbol.isUndefined()) 4143edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type = STT_Undefined; 4153edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar else if (Symbol.isAbsolute()) 4163edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type = STT_Absolute; 4173edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar else 4183edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type = STT_Section; 4193edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4203edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // FIXME: Set STAB bits. 4213edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4225e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar if (Data.isPrivateExtern()) 4236aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar Type |= STF_PrivateExtern; 4243edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Set external bit. 4265e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar if (Data.isExternal() || Symbol.isUndefined()) 4273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Type |= STF_External; 4283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 4298f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // Compute the symbol address. 4308f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (Symbol.isDefined()) { 4318f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (Symbol.isAbsolute()) { 4328f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar llvm_unreachable("FIXME: Not yet implemented!"); 4338f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } else { 4348f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar Address = Data.getAddress(); 4358f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } 4368f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } else if (Data.isCommon()) { 4378f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // Common symbols are encoded with the size in the address 4388f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // field, and their alignment in the flags. 4398f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Address = Data.getCommonSize(); 4408f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 4418f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // Common alignment is packed into the 'desc' bits. 4428f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (unsigned Align = Data.getCommonAlignment()) { 4438f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar unsigned Log2Size = Log2_32(Align); 4448f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); 4458f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar if (Log2Size > 15) 4468f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar llvm_report_error("invalid 'common' alignment '" + 4478f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Twine(Align) + "'"); 4488f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // FIXME: Keep this mask with the SymbolFlags enumeration. 4498f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Flags = (Flags & 0xF0FF) | (Log2Size << 8); 4508f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } 4518f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar } 4528f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 453f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // struct nlist (12 bytes) 454f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 4553edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Write32(MSD.StringIndex); 456f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Write8(Type); 4573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Write8(MSD.SectionIndex); 4587eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 4596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' 4606aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // value. 4618f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar Write16(Flags); 4625e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Write32(Address); 463f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 464f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 4653f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar struct MachRelocationEntry { 4663f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Word0; 4673f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Word1; 4683f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar }; 469cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment, 47027ade18431a3504b412e6359e80c9b88e3b0f932Daniel Dunbar MCAsmFixup &Fixup, 4711253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar const MCValue &Target, 4723f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar std::vector<MachRelocationEntry> &Relocs) { 473cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar uint32_t Address = Fragment.getOffset() + Fixup.Offset; 474e180fa962cc629255bbb0c5f185299c981b042efDaniel Dunbar unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); 475eb3804e39a76a267f13e72a00695f5b18c75b932Daniel Dunbar unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); 4763f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned Type = RIT_Vanilla; 4773f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 4783f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // See <reloc.h>. 4791253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar const MCSymbol *A = Target.getSymA(); 4802101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData *A_SD = &Asm.getSymbolData(*A); 4810ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 482a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar if (!A_SD->getFragment()) 4830ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar llvm_report_error("symbol '" + A->getName() + 4840ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar "' can not be undefined in a subtraction expression"); 4850ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 4868f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar uint32_t Value = A_SD->getAddress(); 4873f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Value2 = 0; 4883f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 4891253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar if (const MCSymbol *B = Target.getSymB()) { 4902101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData *B_SD = &Asm.getSymbolData(*B); 4910ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 492a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar if (!B_SD->getFragment()) 4930ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar llvm_report_error("symbol '" + B->getName() + 4940ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar "' can not be undefined in a subtraction expression"); 4950ce6bd55c38b2e146b5ce887bae576ee538bb575Daniel Dunbar 49607a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // Select the appropriate difference relocation type. 49707a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // 49807a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // Note that there is no longer any semantic difference between these two 49907a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // relocation types from the linkers point of view, this is done solely 50007a9641ebf420ae90aa3667ab4df83cd1ade2117Daniel Dunbar // for pedantic compatibility with 'as'. 501a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar Type = A_SD->isExternal() ? RIT_Difference : RIT_LocalDifference; 5028f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar Value2 = B_SD->getAddress(); 5033f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5043f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5053f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MachRelocationEntry MRE; 5063f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word0 = ((Address << 0) | 5073f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Type << 24) | 5083f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Log2Size << 28) | 5093f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (IsPCRel << 30) | 5103f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RF_Scattered); 5113f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word1 = Value; 5123f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Relocs.push_back(MRE); 5133f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 514a015c1c876bb74a83cbbae06449056e0c6f0e9c9Daniel Dunbar if (Type == RIT_Difference || Type == RIT_LocalDifference) { 5153f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MachRelocationEntry MRE; 5163f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word0 = ((0 << 0) | 517aef9d7af69913740f313c5cc1dfe2a8e1d352227Daniel Dunbar (RIT_Pair << 24) | 5183f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Log2Size << 28) | 519aef9d7af69913740f313c5cc1dfe2a8e1d352227Daniel Dunbar (IsPCRel << 30) | 5203f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RF_Scattered); 5213f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word1 = Value2; 5223f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Relocs.push_back(MRE); 5233f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5243f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5253f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5260bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar void ComputeRelocationInfo(MCAssembler &Asm, MCDataFragment &Fragment, 52727ade18431a3504b412e6359e80c9b88e3b0f932Daniel Dunbar MCAsmFixup &Fixup, 5283f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar std::vector<MachRelocationEntry> &Relocs) { 529f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); 530f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); 531f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar 53218ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar // FIXME: Share layout object. 53318ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar MCAsmLayout Layout(Asm); 53418ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar 535df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // Evaluate the fixup; if the value was resolved, no relocation is needed. 5361253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar MCValue Target; 537df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (Asm.EvaluateFixup(Layout, Fixup, &Fragment, Target, Fixup.FixedValue)) 538df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar return; 5391253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar 540f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar // If this is a difference or a defined symbol plus an offset, then we need 541f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar // a scattered relocation entry. 542f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar uint32_t Offset = Target.getConstant(); 543f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar if (IsPCRel) 544f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar Offset += 1 << Log2Size; 5451253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar if (Target.getSymB() || 5461253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar (Target.getSymA() && !Target.getSymA()->isUndefined() && 547f3a066f7c3ef4e729c92929acab352a93f8d7563Daniel Dunbar Offset)) 548cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target, 5492101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Relocs); 5507eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 5513f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // See <reloc.h>. 552cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar uint32_t Address = Fragment.getOffset() + Fixup.Offset; 5533f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint32_t Value = 0; 5543f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned Index = 0; 5553f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned IsExtern = 0; 5563f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned Type = 0; 5573f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5581253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar if (Target.isAbsolute()) { // constant 5593f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // SymbolNum of 0 indicates the absolute section. 5603a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // 561979ba5b3c7c818b826d06298ee7f79c4234faedbDaniel Dunbar // FIXME: Currently, these are never generated (see code below). I cannot 562979ba5b3c7c818b826d06298ee7f79c4234faedbDaniel Dunbar // find a case where they are actually emitted. 5633f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Type = RIT_Vanilla; 5643f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Value = 0; 5653f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } else { 5661253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar const MCSymbol *Symbol = Target.getSymA(); 5672101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData *SD = &Asm.getSymbolData(*Symbol); 5687eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 5693f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar if (Symbol->isUndefined()) { 5703f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar IsExtern = 1; 5713f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Index = SD->getIndex(); 5723f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Value = 0; 5733f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } else { 5743f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // The index is the section ordinal. 5753f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // 5763f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // FIXME: O(N) 5773f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Index = 1; 578591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); 579591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar for (; it != ie; ++it, ++Index) 5803f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar if (&*it == SD->getFragment()->getParent()) 5813f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar break; 582591047f7149c2e57113c60ed194bc9534a7c1cceDaniel Dunbar assert(it != ie && "Unable to find section index!"); 5838f0448cabcc37f3ecd7099c658346c0ece521e22Daniel Dunbar Value = SD->getAddress(); 5843f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5853f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5863f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Type = RIT_Vanilla; 5873f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5883f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 5893f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // struct relocation_info (8 bytes) 5903f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MachRelocationEntry MRE; 5913f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word0 = Address; 5923f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MRE.Word1 = ((Index << 0) | 5933f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (IsPCRel << 24) | 5943f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Log2Size << 25) | 5953f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (IsExtern << 27) | 5963f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar (Type << 28)); 5973f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Relocs.push_back(MRE); 5983f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 5997eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 6002101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar void BindIndirectSymbols(MCAssembler &Asm) { 6010c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // This is the point where 'as' creates actual symbols for indirect symbols 6020c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // (in the following two passes). It would be easier for us to do this 6030c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // sooner when we see the attribute, but that makes getting the order in the 6040c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // symbol table much more complicated than it is worth. 6050c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // 6060c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: Revisit this when the dust settles. 6070c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6080c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Bind non lazy symbol pointers first. 6090c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 6100c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 6110c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: cast<> support! 6120c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar const MCSectionMachO &Section = 6130c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 6140c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6150c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar unsigned Type = 6160c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 6170c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar if (Type != 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 6300c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar unsigned Type = 6310c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 6320c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar if (Type != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && 6330c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar Type != MCSectionMachO::S_SYMBOL_STUBS) 6340c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar continue; 6350c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6362101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar // Set the symbol type to undefined lazy, but only on construction. 6372101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar // 6382101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar // FIXME: Do not hardcode. 6392101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar bool Created; 6402101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); 6412101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar if (Created) 6422101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Entry.setFlags(Entry.getFlags() | 0x0001); 6430c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 6440c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 6450c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 6463edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar /// ComputeSymbolTable - Compute the symbol table data 647f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// 648f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// \param StringTable [out] - The string table data. 649f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// \param StringIndexMap [out] - Map from symbol names to offsets in the 650f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar /// string table. 6513edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, 6523edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> &LocalSymbolData, 6533edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> &ExternalSymbolData, 6543edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> &UndefinedSymbolData) { 6553edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Build section lookup table. 6563edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar DenseMap<const MCSection*, uint8_t> SectionIndexMap; 6573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned Index = 1; 6583edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 6593edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ie = Asm.end(); it != ie; ++it, ++Index) 6603edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar SectionIndexMap[&it->getSection()] = Index; 6613edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar assert(Index <= 256 && "Too many sections!"); 662f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 663f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Index 0 is always the empty string. 6643edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringMap<uint64_t> StringIndexMap; 665f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar StringTable += '\x00'; 6663edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 6673edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Build the symbol arrays and the string table, but only for non-local 6683edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // symbols. 6693edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // 6703edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // The particular order that we collect the symbols and create the string 6713edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // table, then sort the symbols is chosen to match 'as'. Even though it 6723edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // doesn't matter for correctness, this is important for letting us diff .o 6733edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // files. 674f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 675f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar ie = Asm.symbol_end(); it != ie; ++it) { 676cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar const MCSymbol &Symbol = it->getSymbol(); 6773edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 678959fd883346384e742fff049327a6815e36017e0Daniel Dunbar // Ignore assembler temporaries. 679959fd883346384e742fff049327a6815e36017e0Daniel Dunbar if (it->getSymbol().isTemporary()) 680959fd883346384e742fff049327a6815e36017e0Daniel Dunbar continue; 681959fd883346384e742fff049327a6815e36017e0Daniel Dunbar 68250e48b359eb4e3d3e22d6e447583619d1feaeeaeDaniel Dunbar if (!it->isExternal() && !Symbol.isUndefined()) 6833edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar continue; 684f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 6853edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint64_t &Entry = StringIndexMap[Symbol.getName()]; 686f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!Entry) { 687f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Entry = StringTable.size(); 6883edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringTable += Symbol.getName(); 689f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar StringTable += '\x00'; 690f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 6913edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 6923edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MachSymbolData MSD; 6933edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SymbolData = it; 6943edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.StringIndex = Entry; 6953edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 6963edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (Symbol.isUndefined()) { 6973edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = 0; 6983edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar UndefinedSymbolData.push_back(MSD); 6993edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } else if (Symbol.isAbsolute()) { 7003edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = 0; 7013edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ExternalSymbolData.push_back(MSD); 7023edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } else { 7033edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 7043edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar assert(MSD.SectionIndex && "Invalid section index!"); 7053edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ExternalSymbolData.push_back(MSD); 7063edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 707f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 708f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 7093edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // Now add the data for local symbols. 7103edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 7113edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ie = Asm.symbol_end(); it != ie; ++it) { 712cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel Dunbar const MCSymbol &Symbol = it->getSymbol(); 7133edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 714959fd883346384e742fff049327a6815e36017e0Daniel Dunbar // Ignore assembler temporaries. 715959fd883346384e742fff049327a6815e36017e0Daniel Dunbar if (it->getSymbol().isTemporary()) 716959fd883346384e742fff049327a6815e36017e0Daniel Dunbar continue; 717959fd883346384e742fff049327a6815e36017e0Daniel Dunbar 71850e48b359eb4e3d3e22d6e447583619d1feaeeaeDaniel Dunbar if (it->isExternal() || Symbol.isUndefined()) 7193edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar continue; 7203edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7213edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar uint64_t &Entry = StringIndexMap[Symbol.getName()]; 7223edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (!Entry) { 7233edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar Entry = StringTable.size(); 7243edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringTable += Symbol.getName(); 7253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar StringTable += '\x00'; 7263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 7273edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MachSymbolData MSD; 7293edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SymbolData = it; 7303edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.StringIndex = Entry; 7313edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7323edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar if (Symbol.isAbsolute()) { 7333edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = 0; 7343edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar LocalSymbolData.push_back(MSD); 7353edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } else { 7363edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 7373edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar assert(MSD.SectionIndex && "Invalid section index!"); 7383edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar LocalSymbolData.push_back(MSD); 7393edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 7403edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 7413edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 7423edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar // External and undefined symbols are required to be in lexicographic order. 7433edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 7443edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 7453edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 746be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar // Set the symbol indices. 747be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar Index = 0; 748be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 749be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar LocalSymbolData[i].SymbolData->setIndex(Index++); 750be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 751be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar ExternalSymbolData[i].SymbolData->setIndex(Index++); 752be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 753be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar UndefinedSymbolData[i].SymbolData->setIndex(Index++); 754be9635569401b9a40984c02c6e171aa9da9ad0a2Daniel Dunbar 755f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // The string table is padded to a multiple of 4. 756f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar while (StringTable.size() % 4) 757f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar StringTable += '\x00'; 758f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 759f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 760f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar void WriteObject(MCAssembler &Asm) { 7612ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar unsigned NumSections = Asm.size(); 7622ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar 763ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // Create symbol data for any indirect symbols. 7642101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar BindIndirectSymbols(Asm); 7650c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 766f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Compute symbol table information. 767f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SmallString<256> StringTable; 7683edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> LocalSymbolData; 7693edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> ExternalSymbolData; 7703edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar std::vector<MachSymbolData> UndefinedSymbolData; 771f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar unsigned NumSymbols = Asm.symbol_size(); 772f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 773f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // No symbol table command is written if there are no symbols. 774f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) 7753edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, 7763edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar UndefinedSymbolData); 7777eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 778f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // The section data starts after the header, the segment load command (and 779f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // section headers) and the symbol table. 780f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar unsigned NumLoadCommands = 1; 781ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t LoadCommandsSize = Is64Bit ? 782ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SegmentLoadCommand64Size + NumSections * Section64Size : 783f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SegmentLoadCommand32Size + NumSections * Section32Size; 784f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 785f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Add the symbol table load command sizes, if used. 786f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) { 787f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar NumLoadCommands += 2; 788f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize; 789f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 790f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 791edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // Compute the total size of the section data, as well as its file size and 792edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // vm size. 793ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar uint64_t SectionDataStart = (Is64Bit ? Header64Size : Header32Size) 794ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar + LoadCommandsSize; 7952ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar uint64_t SectionDataSize = 0; 796edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar uint64_t SectionDataFileSize = 0; 797edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar uint64_t VMSize = 0; 798edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 799edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar ie = Asm.end(); it != ie; ++it) { 800edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar MCSectionData &SD = *it; 801edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 802edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar VMSize = std::max(VMSize, SD.getAddress() + SD.getSize()); 803edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 804d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) 805d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar continue; 806d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 807edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SectionDataSize = std::max(SectionDataSize, 808edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SD.getAddress() + SD.getSize()); 8097eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar SectionDataFileSize = std::max(SectionDataFileSize, 810edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SD.getAddress() + SD.getFileSize()); 8112ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar } 8122ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar 8136b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // The section data is padded to 4 bytes. 814edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // 815edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // FIXME: Is this machine dependent? 816edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); 817edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar SectionDataFileSize += SectionDataPadding; 818edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 8192ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar // Write the prolog, starting with the header and load command... 820ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar WriteHeader(NumLoadCommands, LoadCommandsSize, 821ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar Asm.getSubsectionsViaSymbols()); 822ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar WriteSegmentLoadCommand(NumSections, VMSize, 823ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar SectionDataStart, SectionDataSize); 8247eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 8252ae58f2851188c21517d2d0409db1c37dca84b24Daniel Dunbar // ... and then the section headers. 8267eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar // 8273f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // We also compute the section relocations while we do this. Note that 8286b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // computing relocation info will also update the fixup to have the correct 8296b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // value; this will overwrite the appropriate data in the fragment when it 8306b71653c82f86626f64356c308d7356a17b05834Daniel Dunbar // is written. 8313f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar std::vector<MachRelocationEntry> RelocInfos; 832edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; 833cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 834cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar ie = Asm.end(); it != ie; ++it) { 8353f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar MCSectionData &SD = *it; 8363f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 8373f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // The assembler writes relocations in the reverse order they were seen. 8383f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // 8393f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // FIXME: It is probably more complicated than this. 8403f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned NumRelocsStart = RelocInfos.size(); 841cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar for (MCSectionData::reverse_iterator it2 = SD.rbegin(), 842cb7d743b4242345fa1081223b021b1504dce6fb7Daniel Dunbar ie2 = SD.rend(); it2 != ie2; ++it2) 8430bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar if (MCDataFragment *DF = dyn_cast<MCDataFragment>(&*it2)) 8440bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar for (unsigned i = 0, e = DF->fixup_size(); i != e; ++i) 8450bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar ComputeRelocationInfo(Asm, *DF, DF->getFixups()[e - i - 1], 8462101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar RelocInfos); 8473f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 8483f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar unsigned NumRelocs = RelocInfos.size() - NumRelocsStart; 8493f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint64_t SectionStart = SectionDataStart + SD.getAddress(); 850ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar WriteSection(SD, SectionStart, RelocTableEnd, NumRelocs); 8513f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar RelocTableEnd += NumRelocs * RelocationInfoSize; 8523f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 8537eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 854f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the symbol table load command, if used. 855f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) { 856f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar unsigned FirstLocalSymbol = 0; 8573edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned NumLocalSymbols = LocalSymbolData.size(); 8583edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; 8593edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned NumExternalSymbols = ExternalSymbolData.size(); 8603edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; 8613edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); 8620c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); 8630c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar unsigned NumSymTabSymbols = 8640c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; 8650c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; 8660c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar uint64_t IndirectSymbolOffset = 0; 8670c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 8680c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // If used, the indirect symbols are written after the section data. 8690c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar if (NumIndirectSymbols) 8703f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar IndirectSymbolOffset = RelocTableEnd; 8710c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 8720c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // The symbol table is written after the indirect symbol data. 8733f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; 8740c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 8750c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // The string table is written after symbol table. 8760c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar uint64_t StringTableOffset = 8770c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar SymbolTableOffset + NumSymTabSymbols * Nlist32Size; 8780c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, 8790c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar StringTableOffset, StringTable.size()); 8800c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 881f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, 882f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar FirstExternalSymbol, NumExternalSymbols, 883f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar FirstUndefinedSymbol, NumUndefinedSymbols, 884f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar IndirectSymbolOffset, NumIndirectSymbols); 885f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 886fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 887f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the actual section data. 888f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) 889f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar WriteFileData(OS, *it, *this); 890f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 891edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // Write the extra padding. 892edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar WriteZeros(SectionDataPadding); 893edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 8943f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar // Write the relocation entries. 8953f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar for (unsigned i = 0, e = RelocInfos.size(); i != e; ++i) { 8963f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(RelocInfos[i].Word0); 8973f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar Write32(RelocInfos[i].Word1); 8983f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar } 8993f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar 900f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the symbol table data, if used. 901f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (NumSymbols) { 9020c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Write the indirect symbol entries. 903ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar for (MCAssembler::indirect_symbol_iterator 904ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar it = Asm.indirect_symbol_begin(), 905ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 906ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // Indirect symbols in the non lazy symbol pointer section have some 907ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // special handling. 908ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar const MCSectionMachO &Section = 909ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 910ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar unsigned Type = 911ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar Section.getTypeAndAttributes() & MCSectionMachO::SECTION_TYPE; 912ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar if (Type == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { 913ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // If this symbol is defined and internal, mark it as such. 914ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar if (it->Symbol->isDefined() && 9152101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar !Asm.getSymbolData(*it->Symbol).isExternal()) { 916ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar uint32_t Flags = ISF_Local; 917ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar if (it->Symbol->isAbsolute()) 918ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar Flags |= ISF_Absolute; 919ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar Write32(Flags); 920ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar continue; 921ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar } 922ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar } 923ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar 9242101d9c4af4da04939db988c9fe07262b247faa4Daniel Dunbar Write32(Asm.getSymbolData(*it->Symbol).getIndex()); 925ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar } 926f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 9270c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // FIXME: Check that offsets match computed ones. 928f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 929f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the symbol table entries. 9303edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 9313edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar WriteNlist32(LocalSymbolData[i]); 9323edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 9333edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar WriteNlist32(ExternalSymbolData[i]); 9343edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 9353edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar WriteNlist32(UndefinedSymbolData[i]); 936f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 937f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Write the string table. 938f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar OS << StringTable.str(); 939f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 940f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 9413a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar 9423a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) { 9432be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind); 9442be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar 9453a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // FIXME: Endianness assumption. 9462be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar assert(Fixup.Offset + Size <= DF.getContents().size() && 9472be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar "Invalid fixup offset!"); 9482be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar for (unsigned i = 0; i != Size; ++i) 9493a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8)); 9503a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar } 951f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar}; 952fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 953fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar/* *** */ 954fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 9550705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel DunbarMCFragment::MCFragment() : Kind(FragmentType(~0)) { 9560705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 9570705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 9585e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel DunbarMCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) 9590705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar : Kind(_Kind), 9605e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Parent(_Parent), 9610705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar FileSize(~UINT64_C(0)) 962fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar{ 9635e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar if (Parent) 9645e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Parent->getFragmentList().push_back(this); 965fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 966fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 9670705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel DunbarMCFragment::~MCFragment() { 9680705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 9690705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 9705e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbaruint64_t MCFragment::getAddress() const { 9715e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar assert(getParent() && "Missing Section!"); 9725e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar return getParent()->getAddress() + Offset; 9735e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar} 9745e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar 975fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar/* *** */ 976fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 97781e400092f55c2eba157172bfc0dd0df8317638dDaniel DunbarMCSectionData::MCSectionData() : Section(0) {} 978fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 979fb4a6b397665df011348ade24a8e38d2219f095aDaniel DunbarMCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) 98081e400092f55c2eba157172bfc0dd0df8317638dDaniel Dunbar : Section(&_Section), 981fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Alignment(1), 9825e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar Address(~UINT64_C(0)), 9836742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar Size(~UINT64_C(0)), 9843f6a960f9c9ad27f2ac573020df414e8b8cdda04Daniel Dunbar FileSize(~UINT64_C(0)), 985e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar HasInstructions(false) 986fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar{ 987fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if (A) 988fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar A->getSectionList().push_back(this); 989fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 990fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 991fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar/* *** */ 992fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 993efbb5330b8d383a393c83d2da5d631c98b0bb3fdDaniel DunbarMCSymbolData::MCSymbolData() : Symbol(0) {} 994f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 995cb579b3338fe8d9e4424b138f597a4696cb89de3Daniel DunbarMCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, 996f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar uint64_t _Offset, MCAssembler *A) 997efbb5330b8d383a393c83d2da5d631c98b0bb3fdDaniel Dunbar : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), 9988f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar IsExternal(false), IsPrivateExtern(false), 9998f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar CommonSize(0), CommonAlign(0), Flags(0), Index(0) 1000f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar{ 1001f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (A) 1002f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar A->getSymbolList().push_back(this); 1003f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar} 1004f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 1005f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar/* *** */ 1006f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 10071f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel DunbarMCAssembler::MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, 10081f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar raw_ostream &_OS) 10091f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar : Context(_Context), Backend(_Backend), OS(_OS), SubsectionsViaSymbols(false) 10106009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar{ 10116009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar} 1012fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1013fb4a6b397665df011348ade24a8e38d2219f095aDaniel DunbarMCAssembler::~MCAssembler() { 1014fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 1015fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1016df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbarbool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, MCAsmFixup &Fixup, 1017df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar MCDataFragment *DF, 1018df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar MCValue &Target, uint64_t &Value) const { 1019df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (!Fixup.Value->EvaluateAsRelocatable(Target, &Layout)) 1020df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar llvm_report_error("expected relocatable expression"); 1021df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1022df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // FIXME: How do non-scattered symbols work in ELF? I presume the linker 1023df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // doesn't support small relocations, but then under what criteria does the 1024df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // assembler allow symbol differences? 1025df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1026df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar Value = Target.getConstant(); 1027df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1028df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // FIXME: This "resolved" check isn't quite right. The assumption is that if 1029df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // we have a PCrel access to a temporary, then that temporary is in the same 1030df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // atom, and so the value is resolved. We need explicit atom's to implement 1031df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // this more precisely. 1032df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar bool IsResolved = true, IsPCRel = isFixupKindPCRel(Fixup.Kind); 1033df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (const MCSymbol *Symbol = Target.getSymA()) { 1034df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (Symbol->isDefined()) 1035df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar Value += getSymbolData(*Symbol).getAddress(); 1036df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar else 1037df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar IsResolved = false; 1038df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1039df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // With scattered symbols, we assume anything that isn't a PCrel temporary 1040df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // access can have an arbitrary value. 1041df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (getBackend().hasScatteredSymbols() && 1042df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar (!IsPCRel || !Symbol->isTemporary())) 1043df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar IsResolved = false; 1044df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar } 1045df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (const MCSymbol *Symbol = Target.getSymB()) { 1046df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (Symbol->isDefined()) 1047df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar Value -= getSymbolData(*Symbol).getAddress(); 1048df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar else 1049df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar IsResolved = false; 1050df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1051df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // With scattered symbols, we assume anything that isn't a PCrel temporary 1052df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar // access can have an arbitrary value. 1053df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (getBackend().hasScatteredSymbols() && 1054df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar (!IsPCRel || !Symbol->isTemporary())) 1055df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar IsResolved = false; 1056df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar } 1057df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1058df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar if (IsPCRel) 1059da3e9f760ce2328f6dfe69663c2b17da02ece2dbDaniel Dunbar Value -= DF->getAddress() + Fixup.Offset; 1060df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1061df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar return IsResolved; 1062df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar} 1063df3c8f29691a1e3f9ac4afbf05be52dbc898dae9Daniel Dunbar 1064edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbarvoid MCAssembler::LayoutSection(MCSectionData &SD) { 106518ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar MCAsmLayout Layout(*this); 10666742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar uint64_t Address = SD.getAddress(); 10670705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 10680705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) { 10690705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MCFragment &F = *it; 1070d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 10716742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar F.setOffset(Address - SD.getAddress()); 1072d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1073d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // Evaluate fragment size. 1074d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar switch (F.getKind()) { 1075d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Align: { 1076d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCAlignFragment &AF = cast<MCAlignFragment>(F); 10777eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 1078d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar uint64_t Size = OffsetToAlignment(Address, AF.getAlignment()); 10796742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar if (Size > AF.getMaxBytesToEmit()) 1080d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar AF.setFileSize(0); 1081d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar else 10826742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar AF.setFileSize(Size); 1083d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1084d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1085d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1086d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Data: 1087a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case MCFragment::FT_Fill: 1088d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar F.setFileSize(F.getMaxFileSize()); 1089d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1090d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1091d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Org: { 1092d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCOrgFragment &OF = cast<MCOrgFragment>(F); 1093d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 109418ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar int64_t TargetLocation; 109518ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout)) 109618ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar llvm_report_error("expected assembly-time absolute expression"); 1097d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1098d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // FIXME: We need a way to communicate this error. 109918ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar int64_t Offset = TargetLocation - F.getOffset(); 110018ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar if (Offset < 0) 110118ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar llvm_report_error("invalid .org offset '" + Twine(TargetLocation) + 110218ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar "' (at offset '" + Twine(F.getOffset()) + "'"); 11037eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 110418ff2cced7e08ac76d8d5bcff8160a5f9a109cbbDaniel Dunbar F.setFileSize(Offset); 1105d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 11067eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar } 1107d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1108d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar case MCFragment::FT_ZeroFill: { 1109d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCZeroFillFragment &ZFF = cast<MCZeroFillFragment>(F); 1110d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1111d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Align the fragment offset; it is safe to adjust the offset freely since 1112d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // this is only in virtual sections. 111337fad5ce4d81fd459fafe1517d6cd17e7ab49958Daniel Dunbar Address = RoundUpToAlignment(Address, ZFF.getAlignment()); 111437fad5ce4d81fd459fafe1517d6cd17e7ab49958Daniel Dunbar F.setOffset(Address - SD.getAddress()); 1115d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1116d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // FIXME: This is misnamed. 1117d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar F.setFileSize(ZFF.getSize()); 1118d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar break; 1119d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 1120d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1121d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 11226742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar Address += F.getFileSize(); 11230705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 11240705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 11256742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar // Set the section sizes. 11266742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar SD.setSize(Address - SD.getAddress()); 1127d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) 1128d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setFileSize(0); 1129d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar else 1130d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setFileSize(Address - SD.getAddress()); 11310705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 11320705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 11336e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// WriteNopData - Write optimal nops to the output file for the \arg Count 11346e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// bytes. This returns the number of bytes written. It may return 0 if 11356e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// the \arg Count is more than the maximum optimal nops. 11366e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// 11376e72048add2a6464e038121c6c275da37528aa0aKevin Enderby/// FIXME this is X86 32-bit specific and should move to a better place. 11386e72048add2a6464e038121c6c275da37528aa0aKevin Enderbystatic uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) { 113976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby static const uint8_t Nops[16][16] = { 114076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nop 114176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x90}, 114276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // xchg %ax,%ax 114376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x90}, 114476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl (%[re]ax) 114576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x00}, 114676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0(%[re]ax) 114776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x40, 0x00}, 114876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0(%[re]ax,%[re]ax,1) 114976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x44, 0x00, 0x00}, 115076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 115176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 115276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 115376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 115476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax,%[re]ax,1) 115576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 115676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0L(%[re]ax,%[re]ax,1) 115776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 115876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw %cs:0L(%[re]ax,%[re]ax,1) 115976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 116076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0(%[re]ax,%[re]ax,1) 116176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 116276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x44, 0x00, 0x00, 116376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 116476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 116576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 116676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00, 116776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 116876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopw 0(%[re]ax,%[re]ax,1) 116976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) */ 117076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00, 117176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 117276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 117376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 117476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 117576687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 117676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax) 117776687083a5185cedc00fb8bb0d384b814492849aKevin Enderby // nopl 0L(%[re]ax,%[re]ax,1) 117876687083a5185cedc00fb8bb0d384b814492849aKevin Enderby {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 117976687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00} 118076687083a5185cedc00fb8bb0d384b814492849aKevin Enderby }; 118176687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 118276687083a5185cedc00fb8bb0d384b814492849aKevin Enderby if (Count > 15) 118376687083a5185cedc00fb8bb0d384b814492849aKevin Enderby return 0; 118476687083a5185cedc00fb8bb0d384b814492849aKevin Enderby 11856e72048add2a6464e038121c6c275da37528aa0aKevin Enderby for (uint64_t i = 0; i < Count; i++) 118676687083a5185cedc00fb8bb0d384b814492849aKevin Enderby MOW.Write8 (uint8_t(Nops[Count - 1][i])); 11876e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 11886e72048add2a6464e038121c6c275da37528aa0aKevin Enderby return Count; 11896e72048add2a6464e038121c6c275da37528aa0aKevin Enderby} 11906e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 11910705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar/// WriteFileData - Write the \arg F data to the output file. 11920705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbarstatic void WriteFileData(raw_ostream &OS, const MCFragment &F, 11930705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MachObjectWriter &MOW) { 11940705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar uint64_t Start = OS.tell(); 11950705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar (void) Start; 11967eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 11970adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar ++EmittedFragments; 11980adcd35f78b89bf70eb634b7f9ac2103516ca2b2Daniel Dunbar 11990705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar // FIXME: Embed in fragments instead? 12000705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar switch (F.getKind()) { 1201d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Align: { 1202d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCAlignFragment &AF = cast<MCAlignFragment>(F); 1203d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar uint64_t Count = AF.getFileSize() / AF.getValueSize(); 1204d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1205d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // FIXME: This error shouldn't actually occur (the front end should emit 1206d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // multiple .align directives to enforce the semantics it wants), but is 1207d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar // severe enough that we want to report it. How to handle this? 1208d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar if (Count * AF.getValueSize() != AF.getFileSize()) 12097eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar llvm_report_error("undefined .align directive, value size '" + 12107eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar Twine(AF.getValueSize()) + 1211d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar "' is not a divisor of padding size '" + 1212d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar Twine(AF.getFileSize()) + "'"); 1213d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 12146e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // See if we are aligning with nops, and if so do that first to try to fill 12156e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // the Count bytes. Then if that did not fill any bytes or there are any 12166e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // bytes left to fill use the the Value and ValueSize to fill the rest. 12176e72048add2a6464e038121c6c275da37528aa0aKevin Enderby if (AF.getEmitNops()) { 12186e72048add2a6464e038121c6c275da37528aa0aKevin Enderby uint64_t NopByteCount = WriteNopData(Count, MOW); 12196e72048add2a6464e038121c6c275da37528aa0aKevin Enderby Count -= NopByteCount; 12206e72048add2a6464e038121c6c275da37528aa0aKevin Enderby } 12216e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 1222d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar for (uint64_t i = 0; i != Count; ++i) { 1223d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar switch (AF.getValueSize()) { 1224d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar default: 1225d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar assert(0 && "Invalid size!"); 1226d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 1: MOW.Write8 (uint8_t (AF.getValue())); break; 1227d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 2: MOW.Write16(uint16_t(AF.getValue())); break; 1228d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 4: MOW.Write32(uint32_t(AF.getValue())); break; 1229d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case 8: MOW.Write64(uint64_t(AF.getValue())); break; 1230d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1231d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1232d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1233d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 12340705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12353a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar case MCFragment::FT_Data: { 12363a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar MCDataFragment &DF = cast<MCDataFragment>(F); 12373a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar 12383a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // Apply the fixups. 12393a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // 12403a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar // FIXME: Move elsewhere. 12413a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar for (MCDataFragment::const_fixup_iterator it = DF.fixup_begin(), 12423a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar ie = DF.fixup_end(); it != ie; ++it) 12433a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar MOW.ApplyFixup(*it, DF); 12443a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar 12450705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar OS << cast<MCDataFragment>(F).getContents().str(); 12460705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar break; 12473a30b827a5c9bf0ed8f31177b6e447083ce9afecDaniel Dunbar } 12480705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12490705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar case MCFragment::FT_Fill: { 12500705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MCFillFragment &FF = cast<MCFillFragment>(F); 12510705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) { 12520705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar switch (FF.getValueSize()) { 12530705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar default: 12540705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar assert(0 && "Invalid size!"); 1255a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 1: MOW.Write8 (uint8_t (FF.getValue())); break; 1256a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 2: MOW.Write16(uint16_t(FF.getValue())); break; 1257a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 4: MOW.Write32(uint32_t(FF.getValue())); break; 1258a4766d7af91b7e25151b3e97a0831b3615d2abc3Daniel Dunbar case 8: MOW.Write64(uint64_t(FF.getValue())); break; 12590705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 12600705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 12610705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar break; 12620705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 12637eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 1264d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar case MCFragment::FT_Org: { 1265d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MCOrgFragment &OF = cast<MCOrgFragment>(F); 1266d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1267d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar for (uint64_t i = 0, e = OF.getFileSize(); i != e; ++i) 1268d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MOW.Write8(uint8_t(OF.getValue())); 1269d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar 1270d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar break; 1271d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar } 1272d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1273d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar case MCFragment::FT_ZeroFill: { 1274d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(0 && "Invalid zero fill fragment in concrete section!"); 1275d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar break; 1276d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 12770705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar } 12780705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12790705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar assert(OS.tell() - Start == F.getFileSize()); 12800705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 12810705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12820705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar/// WriteFileData - Write the \arg SD data to the output file. 12830705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbarstatic void WriteFileData(raw_ostream &OS, const MCSectionData &SD, 12840705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar MachObjectWriter &MOW) { 1285d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Ignore virtual sections. 1286d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) { 1287d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(SD.getFileSize() == 0); 1288d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar return; 1289d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 1290d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 12910705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar uint64_t Start = OS.tell(); 12920705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar (void) Start; 12937eb85194f2b07bc7ba3f274fc00dc389b77b63bfDaniel Dunbar 12940705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar for (MCSectionData::const_iterator it = SD.begin(), 12950705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar ie = SD.end(); it != ie; ++it) 12960705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar WriteFileData(OS, *it, MOW); 12970705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 12986742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar // Add section padding. 12996742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar assert(SD.getFileSize() >= SD.getSize() && "Invalid section sizes!"); 13006742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar MOW.WriteZeros(SD.getFileSize() - SD.getSize()); 13016742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar 13020705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar assert(OS.tell() - Start == SD.getFileSize()); 13030705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar} 13040705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1305fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCAssembler::Finish() { 1306b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar DEBUG_WITH_TYPE("mc-dump", { 1307b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar llvm::errs() << "assembler backend - pre-layout\n--\n"; 1308b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar dump(); }); 1309b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1310f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Layout until everything fits. 1311f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar while (LayoutOnce()) 1312f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 1313f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1314f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar DEBUG_WITH_TYPE("mc-dump", { 1315f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar llvm::errs() << "assembler backend - post-layout\n--\n"; 1316f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar dump(); }); 1317f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1318f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Write the object file. 1319ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // 1320ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar // FIXME: Factor out MCObjectWriter. 1321ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar bool Is64Bit = StringRef(getBackend().getTarget().getName()) == "x86-64"; 1322ee0d89245eabf93d89b5fef7ac8707680796826dDaniel Dunbar MachObjectWriter MOW(OS, Is64Bit); 1323f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MOW.WriteObject(*this); 1324f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1325f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar OS.flush(); 1326f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar} 1327f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1328f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbarbool MCAssembler::FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF) { 1329f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: Share layout object. 1330f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCAsmLayout Layout(*this); 1331f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1332f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Currently we only need to relax X86::reloc_pcrel_1byte. 1333f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (unsigned(Fixup.Kind) != X86::reloc_pcrel_1byte) 1334f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return false; 1335f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1336f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // If we cannot resolve the fixup value, it requires relaxation. 1337f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCValue Target; 1338f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar uint64_t Value; 1339f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (!EvaluateFixup(Layout, Fixup, DF, Target, Value)) 1340f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return true; 1341f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1342f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Otherwise, relax if the value is too big for a (signed) i8. 1343f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return int64_t(Value) != int64_t(int8_t(Value)); 1344f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar} 1345f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1346f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbarbool MCAssembler::LayoutOnce() { 1347d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Layout the concrete sections and fragments. 13485e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar uint64_t Address = 0; 1349edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar MCSectionData *Prev = 0; 1350edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 13516742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar MCSectionData &SD = *it; 13526742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar 1353d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Skip virtual sections. 1354d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (isVirtualSection(SD.getSection())) 1355d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar continue; 1356d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1357edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // Align this section if necessary by adding padding bytes to the previous 1358edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar // section. 1359edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) { 1360edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar assert(Prev && "Missing prev section!"); 1361edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar Prev->setFileSize(Prev->getFileSize() + Pad); 1362edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar Address += Pad; 1363edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar } 13646742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar 13656742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar // Layout the section fragments and its size. 13666742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar SD.setAddress(Address); 1367edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar LayoutSection(SD); 13686742e34385bff89b897ef0fc930c4bca9e75ac4aDaniel Dunbar Address += SD.getFileSize(); 1369edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar 1370edc670f3f2ba629b6803a1a7ed4aa47061afd276Daniel Dunbar Prev = &SD; 13715e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar } 13720705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1373d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Layout the virtual sections. 1374d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1375d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCSectionData &SD = *it; 1376d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1377d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (!isVirtualSection(SD.getSection())) 1378d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar continue; 1379d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1380b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar // Align this section if necessary by adding padding bytes to the previous 1381b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar // section. 1382f8b8ad77a8b5632886a4cfe41d798bae7277efcbDaniel Dunbar if (uint64_t Pad = OffsetToAlignment(Address, it->getAlignment())) 1383b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar Address += Pad; 1384b2b4acd757194b4b75e571ec7225811f94e753f3Daniel Dunbar 1385d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setAddress(Address); 1386d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar LayoutSection(SD); 1387d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar Address += SD.getSize(); 1388d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar } 1389d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 1390f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Scan the fixups in order and relax any that don't fit. 1391f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1392f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCSectionData &SD = *it; 1393b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1394f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (MCSectionData::iterator it2 = SD.begin(), 1395f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ie2 = SD.end(); it2 != ie2; ++it2) { 1396f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCDataFragment *DF = dyn_cast<MCDataFragment>(it2); 1397f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (!DF) 1398f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 13990705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 1400f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(), 1401f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ie3 = DF->fixup_end(); it3 != ie3; ++it3) { 1402f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCAsmFixup &Fixup = *it3; 1403f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1404f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Check whether we need to relax this fixup. 1405f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (!FixupNeedsRelaxation(Fixup, DF)) 1406f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 1407f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1408f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Relax the instruction. 1409f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1410f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is a huge temporary hack which just looks for x86 1411f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // branches; the only thing we need to relax on x86 is 1412f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 'X86::reloc_pcrel_1byte'. Once we have MCInst fragments, this will be 1413f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // replaced by a TargetAsmBackend hook (most likely tblgen'd) to relax 1414f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // an individual MCInst. 1415f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar SmallVectorImpl<char> &C = DF->getContents(); 1416f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar uint64_t PrevOffset = Fixup.Offset; 1417f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar unsigned Amt = 0; 1418f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1419f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // jcc instructions 1420f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (unsigned(C[Fixup.Offset-1]) >= 0x70 && 1421f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar unsigned(C[Fixup.Offset-1]) <= 0x7f) { 1422f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C[Fixup.Offset] = C[Fixup.Offset-1] + 0x10; 1423f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C[Fixup.Offset-1] = char(0x0f); 1424f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ++Fixup.Offset; 1425f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Amt = 4; 1426f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1427f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // jmp rel8 1428f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } else if (C[Fixup.Offset-1] == char(0xeb)) { 1429f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C[Fixup.Offset-1] = char(0xe9); 1430f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Amt = 3; 1431f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1432f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } else 1433f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar llvm_unreachable("unknown 1 byte pcrel instruction!"); 1434f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1435f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Fixup.Value = MCBinaryExpr::Create( 1436f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCBinaryExpr::Sub, Fixup.Value, 1437f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCConstantExpr::Create(3, getContext()), 1438f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar getContext()); 1439f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar C.insert(C.begin() + Fixup.Offset, Amt, char(0)); 1440f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar Fixup.Kind = MCFixupKind(X86::reloc_pcrel_4byte); 1441f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1442f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Update the remaining fixups, which have slid. 1443f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1444f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is bad for performance, but will be eliminated by the 1445f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // move to MCInst specific fragments. 1446f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ++it3; 1447f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (; it3 != ie3; ++it3) 1448f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar it3->Offset += Amt; 1449b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1450f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Update all the symbols for this fragment, which may have slid. 1451f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1452f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is really really bad for performance, but will be 1453f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // eliminated by the move to MCInst specific fragments. 1454f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar for (MCAssembler::symbol_iterator it = symbol_begin(), 1455f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar ie = symbol_end(); it != ie; ++it) { 1456f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar MCSymbolData &SD = *it; 1457f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1458f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (it->getFragment() != DF) 1459f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar continue; 1460f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1461f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar if (SD.getOffset() > PrevOffset) 1462f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar SD.setOffset(SD.getOffset() + Amt); 1463f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1464f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1465f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // Restart layout. 1466f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // 1467f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // FIXME: This is O(N^2), but will be eliminated once we have a smart 1468f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar // MCAsmLayout object. 1469f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return true; 1470f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1471f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1472f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar } 1473f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar 1474f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar return false; 1475f08fde41f34d739c157b1d75dadbb864e7957cabDaniel Dunbar} 1476b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1477b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar// Debugging methods 1478b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1479b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarnamespace llvm { 1480b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1481b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarraw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) { 14822be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value 14832be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar << " Kind:" << AF.Kind << ">"; 1484b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar return OS; 1485b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1486b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1487b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1488b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1489b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCFragment::dump() { 1490b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1491b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1492b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCFragment " << (void*) this << " Offset:" << Offset 1493b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " FileSize:" << FileSize; 1494b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1495b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << ">"; 1496b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1497b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1498b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCAlignFragment::dump() { 1499b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1500b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1501b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCAlignFragment "; 1502b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1503b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1504b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Alignment:" << getAlignment() 1505b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Value:" << getValue() << " ValueSize:" << getValueSize() 1506b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">"; 1507b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1508b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1509b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCDataFragment::dump() { 1510b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1511b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1512b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCDataFragment "; 1513b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1514b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1515b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Contents:["; 1516b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (unsigned i = 0, e = getContents().size(); i != e; ++i) { 1517b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (i) OS << ","; 1518b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1519b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 15202be2fd073003c0988723d2894dfb117ad90be11bDaniel Dunbar OS << "] (" << getContents().size() << " bytes)"; 15210bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar 15220bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar if (!getFixups().empty()) { 15230bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << ",\n "; 15240bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << " Fixups:["; 15250bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) { 152645aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar if (it != fixup_begin()) OS << ",\n "; 15270bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << *it; 15280bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar } 15290bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << "]"; 15300bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar } 15310bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar 15320bcf074867d4d366f7988a219c7a53265fcb4f23Daniel Dunbar OS << ">"; 1533b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1534b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1535b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCFillFragment::dump() { 1536b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1537b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1538b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCFillFragment "; 1539b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1540b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1541b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Value:" << getValue() << " ValueSize:" << getValueSize() 1542b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Count:" << getCount() << ">"; 1543b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1544b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1545b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCOrgFragment::dump() { 1546b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1547b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1548b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCOrgFragment "; 1549b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1550b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1551b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Offset:" << getOffset() << " Value:" << getValue() << ">"; 1552b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1553b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1554b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCZeroFillFragment::dump() { 1555b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1556b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1557b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCZeroFillFragment "; 1558b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar this->MCFragment::dump(); 1559b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "\n "; 1560b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Size:" << getSize() << " Alignment:" << getAlignment() << ">"; 1561b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1562b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1563b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCSectionData::dump() { 1564b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1565b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1566b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCSectionData"; 1567b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Alignment:" << getAlignment() << " Address:" << Address 1568b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Size:" << Size << " FileSize:" << FileSize 156945aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar << " Fragments:[\n "; 1570b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1571b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (it != begin()) OS << ",\n "; 1572b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar it->dump(); 1573b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 1574b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "]>"; 1575b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1576b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1577b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCSymbolData::dump() { 1578b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1579b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1580b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCSymbolData Symbol:" << getSymbol() 1581b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Fragment:" << getFragment() << " Offset:" << getOffset() 1582b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " Flags:" << getFlags() << " Index:" << getIndex(); 1583b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (isCommon()) 1584b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " (common, size:" << getCommonSize() 1585b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar << " align: " << getCommonAlignment() << ")"; 1586b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (isExternal()) 1587b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " (external)"; 1588b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (isPrivateExtern()) 1589b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " (private extern)"; 1590b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << ">"; 1591b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1592b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1593b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbarvoid MCAssembler::dump() { 1594b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar raw_ostream &OS = llvm::errs(); 1595b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1596b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "<MCAssembler\n"; 159745aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar OS << " Sections:[\n "; 1598b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (iterator it = begin(), ie = end(); it != ie; ++it) { 1599b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar if (it != begin()) OS << ",\n "; 1600b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar it->dump(); 1601b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 1602b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "],\n"; 1603b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << " Symbols:["; 1604b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar 1605b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { 160645aefff64c64d5bd7804f39d994883b98ce4415aDaniel Dunbar if (it != symbol_begin()) OS << ",\n "; 1607b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar it->dump(); 1608b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar } 1609b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar OS << "]>\n"; 1610b7c3a4b195597848e7c2559937914ae1087f3131Daniel Dunbar} 1611