From 45ad72aa8e57f0b49856f231f8c3f561692aa1dd Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 2 Jun 2016 22:54:06 +0000 Subject: [PATCH] [obj2yaml] [yaml2obj] Support for MachO nlist and string table This commit adds round tripping for MachO symbol data. Symbols are entries in the name list, that contain offsets into the string table which is at the end of the __LINKEDIT segment. llvm-svn: 271604 --- include/llvm/ObjectYAML/MachOYAML.h | 15 + lib/ObjectYAML/MachOYAML.cpp | 11 + test/ObjectYAML/MachO/symtab.yaml | 511 ++++++++++++++++++++++++++++ tools/obj2yaml/macho2yaml.cpp | 37 ++ tools/yaml2obj/yaml2macho.cpp | 43 ++- 5 files changed, 610 insertions(+), 7 deletions(-) create mode 100644 test/ObjectYAML/MachO/symtab.yaml diff --git a/include/llvm/ObjectYAML/MachOYAML.h b/include/llvm/ObjectYAML/MachOYAML.h index ee11055b972..dee1bec3af3 100644 --- a/include/llvm/ObjectYAML/MachOYAML.h +++ b/include/llvm/ObjectYAML/MachOYAML.h @@ -57,6 +57,13 @@ struct LoadCommand { uint64_t ZeroPadBytes; }; +struct NListEntry { + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + uint16_t n_desc; + uint64_t n_value; +}; struct RebaseOpcode { MachO::RebaseOpcode Opcode; uint8_t Imm; @@ -91,6 +98,8 @@ struct LinkEditData { std::vector WeakBindOpcodes; std::vector LazyBindOpcodes; MachOYAML::ExportEntry ExportTrie; + std::vector NameList; + std::vector StringTable; }; struct Object { @@ -111,6 +120,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef) namespace llvm { namespace yaml { @@ -147,6 +158,10 @@ template <> struct MappingTraits { static void mapping(IO &IO, MachOYAML::Section &Section); }; +template <> struct MappingTraits { + static void mapping(IO &IO, MachOYAML::NListEntry &NListEntry); +}; + #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ io.enumCase(value, #LCName, MachO::LCName); diff --git a/lib/ObjectYAML/MachOYAML.cpp b/lib/ObjectYAML/MachOYAML.cpp index 6fe137215cf..b4e808552df 100644 --- a/lib/ObjectYAML/MachOYAML.cpp +++ b/lib/ObjectYAML/MachOYAML.cpp @@ -104,6 +104,8 @@ void MappingTraits::mapping( IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes); IO.mapOptional("LazyBindOpcodes", LinkEditData.LazyBindOpcodes); IO.mapOptional("ExportTrie", LinkEditData.ExportTrie); + IO.mapOptional("NameList", LinkEditData.NameList); + IO.mapOptional("StringTable", LinkEditData.StringTable); } void MappingTraits::mapping( @@ -134,6 +136,15 @@ void MappingTraits::mapping( IO.mapOptional("Children", ExportEntry.Children); } +void MappingTraits::mapping( + IO &IO, MachOYAML::NListEntry &NListEntry) { + IO.mapRequired("n_strx", NListEntry.n_strx); + IO.mapRequired("n_type", NListEntry.n_type); + IO.mapRequired("n_sect", NListEntry.n_sect); + IO.mapRequired("n_desc", NListEntry.n_desc); + IO.mapRequired("n_value", NListEntry.n_value); +} + template void mapLoadCommandData(IO &IO, MachOYAML::LoadCommand &LoadCommand) {} diff --git a/test/ObjectYAML/MachO/symtab.yaml b/test/ObjectYAML/MachO/symtab.yaml new file mode 100644 index 00000000000..7472d4462d3 --- /dev/null +++ b/test/ObjectYAML/MachO/symtab.yaml @@ -0,0 +1,511 @@ +# RUN: yaml2obj -format=macho %s | obj2yaml | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 16 + sizeofcmds: 1408 + flags: 0x00218085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 552 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 8192 + fileoff: 0 + filesize: 8192 + maxprot: 7 + initprot: 5 + nsects: 6 + flags: 0 + Sections: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __DATA + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 4096 + maxprot: 7 + initprot: 3 + nsects: 3 + flags: 0 + Sections: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294979584 + vmsize: 4096 + fileoff: 12288 + filesize: 2508 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 12288 + rebase_size: 8 + bind_off: 12296 + bind_size: 96 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 12392 + lazy_bind_size: 624 + export_off: 13016 + export_size: 48 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 13080 + nsyms: 30 + stroff: 13700 + strsize: 1096 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 9 + iextdefsym: 9 + nextdefsym: 2 + iundefsym: 11 + nundefsym: 19 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 13560 + nindirectsyms: 35 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_LOAD_DYLINKER + cmdsize: 32 + name: 12 + PayloadString: /usr/lib/dyld + ZeroPadBytes: 7 + - cmd: LC_UUID + cmdsize: 24 + uuid: 461A1B28-822F-3F38-B670-645419E636F5 + - cmd: LC_VERSION_MIN_MACOSX + cmdsize: 16 + version: 658176 + sdk: 658176 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 4448 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 7864576 + compatibility_version: 65536 + PayloadString: '/usr/lib/libc++.1.dylib' + ZeroPadBytes: 1 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 80349697 + compatibility_version: 65536 + PayloadString: /usr/lib/libSystem.B.dylib + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 13064 + datasize: 16 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 13080 + datasize: 0 +LinkEditData: + NameList: + - n_strx: 2 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294971808 + - n_strx: 69 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294971888 + - n_strx: 166 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294973024 + - n_strx: 204 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294973056 + - n_strx: 320 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294974784 + - n_strx: 344 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294974800 + - n_strx: 387 + n_type: 30 + n_sect: 1 + n_desc: 128 + n_value: 4294974832 + - n_strx: 420 + n_type: 14 + n_sect: 4 + n_desc: 0 + n_value: 4294975104 + - n_strx: 438 + n_type: 14 + n_sect: 4 + n_desc: 0 + n_value: 4294975280 + - n_strx: 456 + n_type: 15 + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 476 + n_type: 15 + n_sect: 1 + n_desc: 0 + n_value: 4294971744 + - n_strx: 482 + n_type: 1 + n_sect: 0 + n_desc: 512 + n_value: 0 + - n_strx: 498 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 537 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 567 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 642 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 711 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 774 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 834 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 851 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 875 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 897 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 954 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 982 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 999 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 1018 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 1035 + n_type: 1 + n_sect: 0 + n_desc: 256 + n_value: 0 + - n_strx: 1057 + n_type: 1 + n_sect: 0 + n_desc: 512 + n_value: 0 + - n_strx: 1065 + n_type: 1 + n_sect: 0 + n_desc: 512 + n_value: 0 + - n_strx: 1073 + n_type: 1 + n_sect: 0 + n_desc: 512 + n_value: 0 + StringTable: + - ' ' + - __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc + - __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m + - __ZNSt3__111char_traitsIcE6lengthEPKc + - __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_ + - ___clang_call_terminate + - __ZNSt3__111char_traitsIcE11eq_int_typeEii + - __ZNSt3__111char_traitsIcE3eofEv + - GCC_except_table2 + - GCC_except_table4 + - __mh_execute_header + - _main + - __Unwind_Resume + - __ZNKSt3__16locale9use_facetERNS0_2idE + - __ZNKSt3__18ios_base6getlocEv + - __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc + - __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev + - __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_ + - __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev + - __ZNSt3__14coutE + - __ZNSt3__15ctypeIcE2idE + - __ZNSt3__16localeD1Ev + - __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv + - __ZNSt3__18ios_base5clearEj + - __ZSt9terminatev + - ___cxa_begin_catch + - ___cxa_end_catch + - ___gxx_personality_v0 + - _memset + - _strlen + - dyld_stub_binder +... + +#CHECK: NameList: +#CHECK: - n_strx: 2 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294971808 +#CHECK: - n_strx: 69 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294971888 +#CHECK: - n_strx: 166 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294973024 +#CHECK: - n_strx: 204 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294973056 +#CHECK: - n_strx: 320 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294974784 +#CHECK: - n_strx: 344 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294974800 +#CHECK: - n_strx: 387 +#CHECK: n_type: 30 +#CHECK: n_sect: 1 +#CHECK: n_desc: 128 +#CHECK: n_value: 4294974832 +#CHECK: - n_strx: 420 +#CHECK: n_type: 14 +#CHECK: n_sect: 4 +#CHECK: n_desc: 0 +#CHECK: n_value: 4294975104 +#CHECK: - n_strx: 438 +#CHECK: n_type: 14 +#CHECK: n_sect: 4 +#CHECK: n_desc: 0 +#CHECK: n_value: 4294975280 +#CHECK: - n_strx: 456 +#CHECK: n_type: 15 +#CHECK: n_sect: 1 +#CHECK: n_desc: 16 +#CHECK: n_value: 4294967296 +#CHECK: - n_strx: 476 +#CHECK: n_type: 15 +#CHECK: n_sect: 1 +#CHECK: n_desc: 0 +#CHECK: n_value: 4294971744 +#CHECK: - n_strx: 482 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 512 +#CHECK: n_value: 0 +#CHECK: - n_strx: 498 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 537 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 567 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 642 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 711 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 774 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 834 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 851 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 875 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 897 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 954 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 982 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 999 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 1018 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 1035 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 256 +#CHECK: n_value: 0 +#CHECK: - n_strx: 1057 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 512 +#CHECK: n_value: 0 +#CHECK: - n_strx: 1065 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 512 +#CHECK: n_value: 0 +#CHECK: - n_strx: 1073 +#CHECK: n_type: 1 +#CHECK: n_sect: 0 +#CHECK: n_desc: 512 +#CHECK: n_value: 0 +#CHECK: StringTable: +#CHECK: - ' ' +#CHECK: - __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc +#CHECK: - __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m +#CHECK: - __ZNSt3__111char_traitsIcE6lengthEPKc +#CHECK: - __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_ +#CHECK: - ___clang_call_terminate +#CHECK: - __ZNSt3__111char_traitsIcE11eq_int_typeEii +#CHECK: - __ZNSt3__111char_traitsIcE3eofEv +#CHECK: - GCC_except_table2 +#CHECK: - GCC_except_table4 +#CHECK: - __mh_execute_header +#CHECK: - _main +#CHECK: - __Unwind_Resume +#CHECK: - __ZNKSt3__16locale9use_facetERNS0_2idE +#CHECK: - __ZNKSt3__18ios_base6getlocEv +#CHECK: - __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc +#CHECK: - __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev +#CHECK: - __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_ +#CHECK: - __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev +#CHECK: - __ZNSt3__14coutE +#CHECK: - __ZNSt3__15ctypeIcE2idE +#CHECK: - __ZNSt3__16localeD1Ev +#CHECK: - __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv +#CHECK: - __ZNSt3__18ios_base5clearEj +#CHECK: - __ZSt9terminatev +#CHECK: - ___cxa_begin_catch +#CHECK: - ___cxa_end_catch +#CHECK: - ___gxx_personality_v0 +#CHECK: - _memset +#CHECK: - _strlen +#CHECK: - dyld_stub_binder diff --git a/tools/obj2yaml/macho2yaml.cpp b/tools/obj2yaml/macho2yaml.cpp index be584f2ffe7..24bd6a60da4 100644 --- a/tools/obj2yaml/macho2yaml.cpp +++ b/tools/obj2yaml/macho2yaml.cpp @@ -33,6 +33,7 @@ class MachODumper { void dumpBindOpcodes(std::vector &BindOpcodes, ArrayRef OpcodeBuffer, bool Lazy = false); void dumpExportTrie(std::unique_ptr &Y); + void dumpSymbols(std::unique_ptr &Y); public: MachODumper(const object::MachOObjectFile &O) : Obj(O) {} @@ -210,6 +211,7 @@ void MachODumper::dumpLinkEdit(std::unique_ptr &Y) { dumpBindOpcodes(Y->LinkEdit.LazyBindOpcodes, Obj.getDyldInfoLazyBindOpcodes(), true); dumpExportTrie(Y); + dumpSymbols(Y); } void MachODumper::dumpRebaseOpcodes(std::unique_ptr &Y) { @@ -424,6 +426,41 @@ void MachODumper::dumpExportTrie(std::unique_ptr &Y) { processExportNode(ExportsTrie.begin(), ExportsTrie.end(), LEData.ExportTrie); } +template +MachOYAML::NListEntry constructNameList(const nlist_t &nlist) { + MachOYAML::NListEntry NL; + NL.n_strx = nlist.n_strx; + NL.n_type = nlist.n_type; + NL.n_sect = nlist.n_sect; + NL.n_desc = nlist.n_desc; + NL.n_value = nlist.n_value; + return NL; +} + +void MachODumper::dumpSymbols(std::unique_ptr &Y) { + MachOYAML::LinkEditData &LEData = Y->LinkEdit; + + for (auto Symbol : Obj.symbols()) { + MachOYAML::NListEntry NLE = + Obj.is64Bit() ? constructNameList( + *reinterpret_cast( + Symbol.getRawDataRefImpl().p)) + : constructNameList( + *reinterpret_cast( + Symbol.getRawDataRefImpl().p)); + LEData.NameList.push_back(NLE); + } + + StringRef RemainingTable = Obj.getStringTableData(); + while (RemainingTable.size() > 0) { + auto SymbolPair = RemainingTable.split('\0'); + RemainingTable = SymbolPair.second; + if (SymbolPair.first.empty()) + break; + LEData.StringTable.push_back(SymbolPair.first); + } +} + Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) { MachODumper Dumper(Obj); Expected> YAML = Dumper.dump(); diff --git a/tools/yaml2obj/yaml2macho.cpp b/tools/yaml2obj/yaml2macho.cpp index b825c9a3494..d65aabc5c86 100644 --- a/tools/yaml2obj/yaml2macho.cpp +++ b/tools/yaml2obj/yaml2macho.cpp @@ -165,7 +165,7 @@ size_t writeLoadCommandData(MachOYAML::LoadCommand &LC, template <> size_t writeLoadCommandData(MachOYAML::LoadCommand &LC, - raw_ostream &OS) { + raw_ostream &OS) { return writePayloadString(LC, OS); } @@ -295,23 +295,23 @@ void MachOWriter::writeBindOpcodes( } } -void MachOWriter::dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry) { +void MachOWriter::dumpExportEntry(raw_ostream &OS, + MachOYAML::ExportEntry &Entry) { encodeSLEB128(Entry.TerminalSize, OS); if (Entry.TerminalSize > 0) { encodeSLEB128(Entry.Flags, OS); - if ( Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT ) { + if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { encodeSLEB128(Entry.Other, OS); OS << Entry.ImportName; OS.write('\0'); - } - else { + } else { encodeSLEB128(Entry.Address, OS); if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) encodeSLEB128(Entry.Other, OS); } } OS.write(static_cast(Entry.Children.size())); - for (auto EE : Entry.Children){ + for (auto EE : Entry.Children) { OS << EE.Name; OS.write('\0'); encodeSLEB128(EE.NodeOffset, OS); @@ -325,6 +325,17 @@ Error MachOWriter::writeExportTrie(raw_ostream &OS) { return Error::success(); } +template +void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS) { + NListType ListEntry; + ListEntry.n_strx = NLE.n_strx; + ListEntry.n_type = NLE.n_type; + ListEntry.n_sect = NLE.n_sect; + ListEntry.n_desc = NLE.n_desc; + ListEntry.n_value = NLE.n_value; + OS.write(reinterpret_cast(&ListEntry), sizeof(NListType)); +} + Error MachOWriter::writeLinkEditData(raw_ostream &OS) { MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; MachO::dyld_info_command *DyldInfoOnlyCmd = 0; @@ -357,9 +368,27 @@ Error MachOWriter::writeLinkEditData(raw_ostream &OS) { LinkEdit.LazyBindOpcodes); ZeroToOffset(OS, DyldInfoOnlyCmd->export_off); - if(auto Err = writeExportTrie(OS)) + if (auto Err = writeExportTrie(OS)) return Err; + ZeroToOffset(OS, SymtabCmd->symoff); + + for (auto NLE : LinkEdit.NameList) { + if (is64Bit) + writeNListEntry(NLE, OS); + else + writeNListEntry(NLE, OS); + } + + auto currOffset = OS.tell() - fileStart; + if (currOffset < SymtabCmd->stroff) + Fill(OS, SymtabCmd->stroff - currOffset, 0xDEADBEEFu); + + for (auto Str : LinkEdit.StringTable) { + OS.write(Str.data(), Str.size()); + OS.write('\0'); + } + // Fill to the end of the string table ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize);