1de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===- yaml2macho - Convert YAML to a Mach object file --------------------===// 2de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 3de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// The LLVM Compiler Infrastructure 4de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 5de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 6de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// License. See LICENSE.TXT for details. 7de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// 8de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===// 9de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// 10de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// \file 11de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// \brief The Mach component of yaml2obj. 12de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// 13de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar//===----------------------------------------------------------------------===// 14de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 15de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "yaml2obj.h" 16de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/ObjectYAML/ObjectYAML.h" 17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/Error.h" 18de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/LEB128.h" 19de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/MachO.h" 20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/YAMLTraits.h" 21de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 23de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/Format.h" 24de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 25de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace llvm; 26de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 27de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarnamespace { 28de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 29de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass MachOWriter { 30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic: 31de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachOWriter(MachOYAML::Object &Obj) : Obj(Obj), is64Bit(true), fileStart(0) { 32de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar is64Bit = Obj.Header.magic == MachO::MH_MAGIC_64 || 33de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Obj.Header.magic == MachO::MH_CIGAM_64; 34de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar memset(reinterpret_cast<void *>(&Header), 0, sizeof(MachO::mach_header_64)); 35de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 37de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeMachO(raw_ostream &OS); 38de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 39de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate: 40de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeHeader(raw_ostream &OS); 41de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeLoadCommands(raw_ostream &OS); 42de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeSectionData(raw_ostream &OS); 43de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeLinkEditData(raw_ostream &OS); 44de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void writeBindOpcodes(raw_ostream &OS, 45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::vector<MachOYAML::BindOpcode> &BindOpcodes); 46de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // LinkEdit writers 47de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeRebaseOpcodes(raw_ostream &OS); 48de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeBasicBindOpcodes(raw_ostream &OS); 49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeWeakBindOpcodes(raw_ostream &OS); 50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeLazyBindOpcodes(raw_ostream &OS); 51de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeNameList(raw_ostream &OS); 52de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeStringTable(raw_ostream &OS); 53de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeExportTrie(raw_ostream &OS); 54de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry); 56de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void ZeroToOffset(raw_ostream &OS, size_t offset); 57de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachOYAML::Object &Obj; 59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool is64Bit; 60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t fileStart; 61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachO::mach_header_64 Header; 63de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}; 64de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 65de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeMachO(raw_ostream &OS) { 66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar fileStart = OS.tell(); 67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = writeHeader(OS)) 68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = writeLoadCommands(OS)) 70de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 71de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = writeSectionData(OS)) 72de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 73de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 74de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 75de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 76de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeHeader(raw_ostream &OS) { 77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.magic = Obj.Header.magic; 78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.cputype = Obj.Header.cputype; 79de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.cpusubtype = Obj.Header.cpusubtype; 80de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.filetype = Obj.Header.filetype; 81de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.ncmds = Obj.Header.ncmds; 82de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.sizeofcmds = Obj.Header.sizeofcmds; 83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.flags = Obj.Header.flags; 84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Header.reserved = Obj.Header.reserved; 85de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 86de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto header_size = 87de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header); 88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write((const char *)&Header, header_size); 89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 90de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 91de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 92de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 93de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <typename SectionType> 94de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarSectionType constructSection(MachOYAML::Section Sec) { 95de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SectionType TempSec; 96de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar memcpy(reinterpret_cast<void *>(&TempSec.sectname[0]), &Sec.sectname[0], 16); 97de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar memcpy(reinterpret_cast<void *>(&TempSec.segname[0]), &Sec.segname[0], 16); 98de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.addr = Sec.addr; 99de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.size = Sec.size; 100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.offset = Sec.offset; 101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.align = Sec.align; 102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.reloff = Sec.reloff; 103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.nreloc = Sec.nreloc; 104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.flags = Sec.flags; 105de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.reserved1 = Sec.reserved1; 106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.reserved2 = Sec.reserved2; 107de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return TempSec; 108de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <typename StructType> 111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t writeLoadCommandData(MachOYAML::LoadCommand &LC, raw_ostream &OS) { 112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return 0; 113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 116de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t writeLoadCommandData<MachO::segment_command>(MachOYAML::LoadCommand &LC, 117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS) { 118de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar size_t BytesWritten = 0; 119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (const auto &Sec : LC.Sections) { 120de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto TempSec = constructSection<MachO::section>(Sec); 121de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&(TempSec)), 122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar sizeof(MachO::section)); 123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten += sizeof(MachO::section); 124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return BytesWritten; 126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t 130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarwriteLoadCommandData<MachO::segment_command_64>(MachOYAML::LoadCommand &LC, 131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS) { 132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar size_t BytesWritten = 0; 133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (const auto &Sec : LC.Sections) { 134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto TempSec = constructSection<MachO::section_64>(Sec); 135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar TempSec.reserved3 = Sec.reserved3; 136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&(TempSec)), 137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar sizeof(MachO::section_64)); 138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten += sizeof(MachO::section_64); 139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return BytesWritten; 141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t writePayloadString(MachOYAML::LoadCommand &LC, raw_ostream &OS) { 144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar size_t BytesWritten = 0; 145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!LC.PayloadString.empty()) { 146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(LC.PayloadString.c_str(), LC.PayloadString.length()); 147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten = LC.PayloadString.length(); 148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return BytesWritten; 150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t writeLoadCommandData<MachO::dylib_command>(MachOYAML::LoadCommand &LC, 154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS) { 155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return writePayloadString(LC, OS); 156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t writeLoadCommandData<MachO::dylinker_command>(MachOYAML::LoadCommand &LC, 160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS) { 161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return writePayloadString(LC, OS); 162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarsize_t writeLoadCommandData<MachO::rpath_command>(MachOYAML::LoadCommand &LC, 166de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS) { 167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return writePayloadString(LC, OS); 168de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 169de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ZeroFillBytes(raw_ostream &OS, size_t Size) { 171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::vector<uint8_t> FillData; 172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FillData.insert(FillData.begin(), Size, 0); 173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<char *>(FillData.data()), Size); 174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid Fill(raw_ostream &OS, size_t Size, uint32_t Data) { 177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::vector<uint32_t> FillData; 178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FillData.insert(FillData.begin(), (Size / 4) + 1, Data); 179de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<char *>(FillData.data()), Size); 180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid MachOWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { 183de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto currOffset = OS.tell() - fileStart; 184de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (currOffset < Offset) 185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroFillBytes(OS, Offset - currOffset); 186de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 187de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 188de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeLoadCommands(raw_ostream &OS) { 189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &LC : Obj.LoadCommands) { 190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar size_t BytesWritten = 0; 191de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ 192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case MachO::LCName: \ 193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&(LC.Data.LCStruct##_data)), \ 194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar sizeof(MachO::LCStruct)); \ 195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten = sizeof(MachO::LCStruct); \ 196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten += writeLoadCommandData<MachO::LCStruct>(LC, OS); \ 197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (LC.Data.load_command_data.cmd) { 200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar default: 201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&(LC.Data.load_command_data)), 202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar sizeof(MachO::load_command)); 203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten = sizeof(MachO::load_command); 204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten += writeLoadCommandData<MachO::load_command>(LC, OS); 205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/MachO.def" 207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LC.PayloadBytes.size() > 0) { 210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(LC.PayloadBytes.data()), 211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LC.PayloadBytes.size()); 212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten += LC.PayloadBytes.size(); 213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (LC.ZeroPadBytes > 0) { 216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroFillBytes(OS, LC.ZeroPadBytes); 217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar BytesWritten += LC.ZeroPadBytes; 218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Fill remaining bytes with 0. This will only get hit in partially 221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // specified test cases. 222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto BytesRemaining = LC.Data.load_command_data.cmdsize - BytesWritten; 223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (BytesRemaining > 0) { 224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroFillBytes(OS, BytesRemaining); 225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 228de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeSectionData(raw_ostream &OS) { 231de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &LC : Obj.LoadCommands) { 232de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (LC.Data.load_command_data.cmd) { 233de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case MachO::LC_SEGMENT: 234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case MachO::LC_SEGMENT_64: 235de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto currOffset = OS.tell() - fileStart; 236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto segname = LC.Data.segment_command_data.segname; 237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t segOff = is64Bit ? LC.Data.segment_command_64_data.fileoff 238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : LC.Data.segment_command_data.fileoff; 239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 240de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (0 == strncmp(&segname[0], "__LINKEDIT", 16)) { 241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = writeLinkEditData(OS)) 242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Zero Fill any data between the end of the last thing we wrote and the 245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // start of this section. 246de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (currOffset < segOff) { 247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroFillBytes(OS, segOff - currOffset); 248de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 249de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &Sec : LC.Sections) { 251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Zero Fill any data between the end of the last thing we wrote and 252de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // the 253de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // start of this section. 254de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert( 255de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.tell() - fileStart <= Sec.offset && 256de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar "Wrote too much data somewhere, section offsets don't line up."); 257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar currOffset = OS.tell() - fileStart; 258de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (currOffset < Sec.offset) { 259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroFillBytes(OS, Sec.offset - currOffset); 260de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 261de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 262de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Fills section data with 0xDEADBEEF 263de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Fill(OS, Sec.size, 0xDEADBEEFu); 264de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 265de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 266de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t segSize = is64Bit ? LC.Data.segment_command_64_data.filesize 267de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : LC.Data.segment_command_data.filesize; 268de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroToOffset(OS, segOff + segSize); 269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 270de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 271de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 272de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 273de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 274de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 275de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid MachOWriter::writeBindOpcodes( 276de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS, std::vector<MachOYAML::BindOpcode> &BindOpcodes) { 277de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 278de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Opcode : BindOpcodes) { 279de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint8_t OpByte = Opcode.Opcode | Opcode.Imm; 280de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<char *>(&OpByte), 1); 281de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Data : Opcode.ULEBExtraData) { 282de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeULEB128(Data, OS); 283de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 284de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Data : Opcode.SLEBExtraData) { 285de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(Data, OS); 286de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 287de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!Opcode.Symbol.empty()) { 288de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(Opcode.Symbol.data(), Opcode.Symbol.size()); 289de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write('\0'); 290de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 291de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 294de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid MachOWriter::dumpExportEntry(raw_ostream &OS, 295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachOYAML::ExportEntry &Entry) { 296de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(Entry.TerminalSize, OS); 297de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Entry.TerminalSize > 0) { 298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(Entry.Flags, OS); 299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(Entry.Other, OS); 301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS << Entry.ImportName; 302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write('\0'); 303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } else { 304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(Entry.Address, OS); 305de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) 306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(Entry.Other, OS); 307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 308de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 309de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(static_cast<uint8_t>(Entry.Children.size())); 310de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto EE : Entry.Children) { 311de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS << EE.Name; 312de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write('\0'); 313de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeSLEB128(EE.NodeOffset, OS); 314de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 315de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto EE : Entry.Children) 316de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dumpExportEntry(OS, EE); 317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 318de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 319de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeExportTrie(raw_ostream &OS) { 320de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar dumpExportEntry(OS, Obj.LinkEdit.ExportTrie); 321de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 322de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 323de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 324de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <typename NListType> 325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS) { 326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar NListType ListEntry; 327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ListEntry.n_strx = NLE.n_strx; 328de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ListEntry.n_type = NLE.n_type; 329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ListEntry.n_sect = NLE.n_sect; 330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ListEntry.n_desc = NLE.n_desc; 331de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ListEntry.n_value = NLE.n_value; 332de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&ListEntry), sizeof(NListType)); 333de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 334de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 335de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeLinkEditData(raw_ostream &OS) { 336de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar typedef Error (MachOWriter::*writeHandler)(raw_ostream &); 337de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar typedef std::pair<uint64_t, writeHandler> writeOperation; 338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::vector<writeOperation> WriteQueue; 339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachO::dyld_info_command *DyldInfoOnlyCmd = 0; 341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachO::symtab_command *SymtabCmd = 0; 342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto &LC : Obj.LoadCommands) { 343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar switch (LC.Data.load_command_data.cmd) { 344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case MachO::LC_SYMTAB: 345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar SymtabCmd = &LC.Data.symtab_command_data; 346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back( 347de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::make_pair(SymtabCmd->symoff, &MachOWriter::writeNameList)); 348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back( 349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::make_pair(SymtabCmd->stroff, &MachOWriter::writeStringTable)); 350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar case MachO::LC_DYLD_INFO_ONLY: 352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar DyldInfoOnlyCmd = &LC.Data.dyld_info_command_data; 353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->rebase_off, 354de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar &MachOWriter::writeRebaseOpcodes)); 355de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->bind_off, 356de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar &MachOWriter::writeBasicBindOpcodes)); 357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->weak_bind_off, 358de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar &MachOWriter::writeWeakBindOpcodes)); 359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->lazy_bind_off, 360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar &MachOWriter::writeLazyBindOpcodes)); 361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->export_off, 362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar &MachOWriter::writeExportTrie)); 363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar break; 364de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 367de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar std::sort(WriteQueue.begin(), WriteQueue.end(), 368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar [](const writeOperation &a, const writeOperation &b) { 369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return a.first < b.first; 370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar }); 371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 372de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto writeOp : WriteQueue) { 373de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroToOffset(OS, writeOp.first); 374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = (this->*writeOp.second)(OS)) 375de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 376de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 377de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 379de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 380de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 381de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeRebaseOpcodes(raw_ostream &OS) { 382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; 383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Opcode : LinkEdit.RebaseOpcodes) { 385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint8_t OpByte = Opcode.Opcode | Opcode.Imm; 386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<char *>(&OpByte), 1); 387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Data : Opcode.ExtraData) { 388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar encodeULEB128(Data, OS); 389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 394de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeBasicBindOpcodes(raw_ostream &OS) { 395de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeBindOpcodes(OS, Obj.LinkEdit.BindOpcodes); 396de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 397de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 398de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 399de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeWeakBindOpcodes(raw_ostream &OS) { 400de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeBindOpcodes(OS, Obj.LinkEdit.WeakBindOpcodes); 401de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 402de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 403de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 404de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeLazyBindOpcodes(raw_ostream &OS) { 405de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeBindOpcodes(OS, Obj.LinkEdit.LazyBindOpcodes); 406de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 407de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 408de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeNameList(raw_ostream &OS) { 410de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto NLE : Obj.LinkEdit.NameList) { 411de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (is64Bit) 412de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeNListEntry<MachO::nlist_64>(NLE, OS); 413de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 414de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeNListEntry<MachO::nlist>(NLE, OS); 415de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 416de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 417de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 418de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 419de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError MachOWriter::writeStringTable(raw_ostream &OS) { 420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Str : Obj.LinkEdit.StringTable) { 421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(Str.data(), Str.size()); 422de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write('\0'); 423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 425de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 426de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass UniversalWriter { 428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarpublic: 429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar UniversalWriter(yaml::YamlObjectFile &ObjectFile) 430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : ObjectFile(ObjectFile), fileStart(0) {} 431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeMachO(raw_ostream &OS); 433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 434de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarprivate: 435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeFatHeader(raw_ostream &OS); 436de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error writeFatArchs(raw_ostream &OS); 437de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 438de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void ZeroToOffset(raw_ostream &OS, size_t offset); 439de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar yaml::YamlObjectFile &ObjectFile; 441de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar uint64_t fileStart; 442de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}; 443de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 444de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError UniversalWriter::writeMachO(raw_ostream &OS) { 445de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar fileStart = OS.tell(); 446de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ObjectFile.MachO) { 447de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachOWriter Writer(*ObjectFile.MachO); 448de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Writer.writeMachO(OS); 449de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 450de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = writeFatHeader(OS)) 451de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 452de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = writeFatArchs(OS)) 453de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 454de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &FatFile = *ObjectFile.FatMachO; 455de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert(FatFile.FatArchs.size() == FatFile.Slices.size()); 456de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (size_t i = 0; i < FatFile.Slices.size(); i++) { 457de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroToOffset(OS, FatFile.FatArchs[i].offset); 458de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachOWriter Writer(FatFile.Slices[i]); 459de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = Writer.writeMachO(OS)) 460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Err; 461de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto SliceEnd = FatFile.FatArchs[i].offset + FatFile.FatArchs[i].size; 462de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroToOffset(OS, SliceEnd); 463de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 464de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 466de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 467de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError UniversalWriter::writeFatHeader(raw_ostream &OS) { 468de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &FatFile = *ObjectFile.FatMachO; 469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar MachO::fat_header header; 470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar header.magic = FatFile.Header.magic; 471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar header.nfat_arch = FatFile.Header.nfat_arch; 472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (sys::IsLittleEndianHost) 473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar swapStruct(header); 474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&header), sizeof(MachO::fat_header)); 475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <typename FatArchType> 479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarFatArchType constructFatArch(MachOYAML::FatArch &Arch) { 480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArchType FatArch; 481de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArch.cputype = Arch.cputype; 482de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArch.cpusubtype = Arch.cpusubtype; 483de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArch.offset = Arch.offset; 484de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArch.size = Arch.size; 485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArch.align = Arch.align; 486de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return FatArch; 487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 488de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 489de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <typename StructType> 490de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid writeFatArch(MachOYAML::FatArch &LC, raw_ostream &OS) {} 491de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 492de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 493de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid writeFatArch<MachO::fat_arch>(MachOYAML::FatArch &Arch, raw_ostream &OS) { 494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto FatArch = constructFatArch<MachO::fat_arch>(Arch); 495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (sys::IsLittleEndianHost) 496de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar swapStruct(FatArch); 497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&FatArch), sizeof(MachO::fat_arch)); 498de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 499de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 500de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainartemplate <> 501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid writeFatArch<MachO::fat_arch_64>(MachOYAML::FatArch &Arch, 502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar raw_ostream &OS) { 503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto FatArch = constructFatArch<MachO::fat_arch_64>(Arch); 504de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar FatArch.reserved = Arch.reserved; 505de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (sys::IsLittleEndianHost) 506de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar swapStruct(FatArch); 507de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar OS.write(reinterpret_cast<const char *>(&FatArch), 508de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar sizeof(MachO::fat_arch_64)); 509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 510de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarError UniversalWriter::writeFatArchs(raw_ostream &OS) { 512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto &FatFile = *ObjectFile.FatMachO; 513de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool is64Bit = FatFile.Header.magic == MachO::FAT_MAGIC_64; 514de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (auto Arch : FatFile.FatArchs) { 515de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (is64Bit) 516de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeFatArch<MachO::fat_arch_64>(Arch, OS); 517de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar else 518de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar writeFatArch<MachO::fat_arch>(Arch, OS); 519de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 520de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 521de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 522de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 523de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 524de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid UniversalWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) { 525de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto currOffset = OS.tell() - fileStart; 526de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (currOffset < Offset) 527de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ZeroFillBytes(OS, Offset - currOffset); 528de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 529de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 530de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} // end anonymous namespace 531de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 532de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarint yaml2macho(yaml::YamlObjectFile &Doc, raw_ostream &Out) { 533de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar UniversalWriter Writer(Doc); 534de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (auto Err = Writer.writeMachO(Out)) { 535de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar errs() << toString(std::move(Err)); 536de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return 1; 537de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return 0; 539de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar} 540