From 659b35a5d8c0d6afc97a09f47db739bd192c5939 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 26 May 2016 20:50:05 +0000 Subject: [PATCH] [obj2yaml][yaml2obj] Support for MachO weak bindings This adds support for YAML round tripping dyld info weak bindings. The storage and format of these is the same as regular bind opcodes, they are just interpreted differently by dyld. llvm-svn: 270911 --- llvm/include/llvm/ObjectYAML/MachOYAML.h | 1 + llvm/lib/ObjectYAML/MachOYAML.cpp | 1 + .../ObjectYAML/MachO/weak_bind_opcode.yaml | 133 ++++++++++++++++++ llvm/tools/obj2yaml/macho2yaml.cpp | 2 + llvm/tools/yaml2obj/yaml2macho.cpp | 42 +++--- 5 files changed, 163 insertions(+), 16 deletions(-) create mode 100644 llvm/test/ObjectYAML/MachO/weak_bind_opcode.yaml diff --git a/llvm/include/llvm/ObjectYAML/MachOYAML.h b/llvm/include/llvm/ObjectYAML/MachOYAML.h index 185afdcdd50d..0fe2c939e2b7 100644 --- a/llvm/include/llvm/ObjectYAML/MachOYAML.h +++ b/llvm/include/llvm/ObjectYAML/MachOYAML.h @@ -74,6 +74,7 @@ struct BindOpcode { struct LinkEditData { std::vector RebaseOpcodes; std::vector BindOpcodes; + std::vector WeakBindOpcodes; }; struct Object { diff --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp index 48217af54b70..b466c9785703 100644 --- a/llvm/lib/ObjectYAML/MachOYAML.cpp +++ b/llvm/lib/ObjectYAML/MachOYAML.cpp @@ -101,6 +101,7 @@ void MappingTraits::mapping( IO &IO, MachOYAML::LinkEditData &LinkEditData) { IO.mapOptional("RebaseOpcodes", LinkEditData.RebaseOpcodes); IO.mapOptional("BindOpcodes", LinkEditData.BindOpcodes); + IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes); } void MappingTraits::mapping( diff --git a/llvm/test/ObjectYAML/MachO/weak_bind_opcode.yaml b/llvm/test/ObjectYAML/MachO/weak_bind_opcode.yaml new file mode 100644 index 000000000000..6e652f46baec --- /dev/null +++ b/llvm/test/ObjectYAML/MachO/weak_bind_opcode.yaml @@ -0,0 +1,133 @@ +# RUN: yaml2obj -format=macho %s | obj2yaml | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 4 + sizeofcmds: 224 + flags: 0x00218085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294979584 + vmsize: 4096 + fileoff: 1024 + filesize: 2508 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 1024 + rebase_size: 8 + bind_off: 0 + bind_size: 0 + weak_bind_off: 1032 + weak_bind_size: 96 + lazy_bind_off: 1128 + lazy_bind_size: 624 + export_off: 1752 + export_size: 48 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 1816 + nsyms: 30 + stroff: 2436 + 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: 2296 + nindirectsyms: 35 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 +LinkEditData: + WeakBindOpcodes: + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 1 + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZNSt3__14coutE + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ULEBExtraData: + - 0x0000000000000000 + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZNSt3__15ctypeIcE2idE + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: ___gxx_personality_v0 + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 2 + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: dyld_stub_binder + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + - Opcode: BIND_OPCODE_DONE + Imm: 0 +... + +#CHECK: LinkEditData: +#CHECK: WeakBindOpcodes: +#CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM +#CHECK: Imm: 1 +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: __ZNSt3__14coutE +#CHECK: - Opcode: BIND_OPCODE_SET_TYPE_IMM +#CHECK: Imm: 1 +#CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB +#CHECK: Imm: 2 +#CHECK: ULEBExtraData: +#CHECK: - 0x0000000000000000 +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: __ZNSt3__15ctypeIcE2idE +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: ___gxx_personality_v0 +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM +#CHECK: Imm: 2 +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: dyld_stub_binder +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: - Opcode: BIND_OPCODE_DONE +#CHECK: Imm: 0 + diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp index 7aca3fd82f03..bc3e2c53b954 100644 --- a/llvm/tools/obj2yaml/macho2yaml.cpp +++ b/llvm/tools/obj2yaml/macho2yaml.cpp @@ -197,6 +197,8 @@ void MachODumper::dumpLoadCommands(std::unique_ptr &Y) { void MachODumper::dumpLinkEdit(std::unique_ptr &Y) { dumpRebaseOpcodes(Y); dumpBindOpcodes(Y->LinkEdit.BindOpcodes, Obj.getDyldInfoBindOpcodes()); + dumpBindOpcodes(Y->LinkEdit.WeakBindOpcodes, + Obj.getDyldInfoWeakBindOpcodes()); } void MachODumper::dumpRebaseOpcodes(std::unique_ptr &Y) { diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index a1f5dda9d9de..199515d5c108 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -46,6 +46,8 @@ private: Error writeLoadCommands(raw_ostream &OS); Error writeSectionData(raw_ostream &OS); Error writeLinkEditData(raw_ostream &OS); + void writeBindOpcodes(raw_ostream &OS, uint64_t offset, + std::vector &BindOpcodes); void ZeroToOffset(raw_ostream &OS, size_t offset); @@ -264,6 +266,27 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { return Error::success(); } +void MachOWriter::writeBindOpcodes( + raw_ostream &OS, uint64_t offset, + std::vector &BindOpcodes) { + ZeroToOffset(OS, offset); + + for (auto Opcode : BindOpcodes) { + uint8_t OpByte = Opcode.Opcode | Opcode.Imm; + OS.write(reinterpret_cast(&OpByte), 1); + for (auto Data : Opcode.ULEBExtraData) { + encodeULEB128(Data, OS); + } + for (auto Data : Opcode.SLEBExtraData) { + encodeSLEB128(Data, OS); + } + if (!Opcode.Symbol.empty()) { + OS.write(Opcode.Symbol.data(), Opcode.Symbol.size()); + OS.write("\0", 1); + } + } +} + Error MachOWriter::writeLinkEditData(raw_ostream &OS) { MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; MachO::dyld_info_command *DyldInfoOnlyCmd = 0; @@ -289,22 +312,9 @@ Error MachOWriter::writeLinkEditData(raw_ostream &OS) { } } - ZeroToOffset(OS, DyldInfoOnlyCmd->bind_off); - - for (auto Opcode : LinkEdit.BindOpcodes) { - uint8_t OpByte = Opcode.Opcode | Opcode.Imm; - OS.write(reinterpret_cast(&OpByte), 1); - for (auto Data : Opcode.ULEBExtraData) { - encodeULEB128(Data, OS); - } - for (auto Data : Opcode.SLEBExtraData) { - encodeSLEB128(Data, OS); - } - if(!Opcode.Symbol.empty()) { - OS.write(Opcode.Symbol.data(), Opcode.Symbol.size()); - OS.write("\0", 1); - } - } + writeBindOpcodes(OS, DyldInfoOnlyCmd->bind_off, LinkEdit.BindOpcodes); + writeBindOpcodes(OS, DyldInfoOnlyCmd->weak_bind_off, + LinkEdit.WeakBindOpcodes); // Fill to the end of the string table ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize);