[llvm] r270901 - [obj2yaml][yaml2obj] Support for MachO bind opcodes
Chris Bieneman via llvm-commits
llvm-commits at lists.llvm.org
Thu May 26 13:06:18 PDT 2016
Author: cbieneman
Date: Thu May 26 15:06:14 2016
New Revision: 270901
URL: http://llvm.org/viewvc/llvm-project?rev=270901&view=rev
Log:
[obj2yaml][yaml2obj] Support for MachO bind opcodes
This adds support for YAML round tripping dyld info bind opcodes. Bind opcodes can have signed or unsigned LEB128 data, and they can have symbols associated with them.
Added:
llvm/trunk/test/ObjectYAML/MachO/bind_opcode.yaml
Modified:
llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
llvm/trunk/tools/obj2yaml/macho2yaml.cpp
llvm/trunk/tools/yaml2obj/yaml2macho.cpp
Modified: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h?rev=270901&r1=270900&r2=270901&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h Thu May 26 15:06:14 2016
@@ -63,8 +63,17 @@ struct RebaseOpcode {
std::vector<yaml::Hex64> ExtraData;
};
+struct BindOpcode {
+ MachO::BindOpcode Opcode;
+ uint8_t Imm;
+ std::vector<yaml::Hex64> ULEBExtraData;
+ std::vector<int64_t> SLEBExtraData;
+ StringRef Symbol;
+};
+
struct LinkEditData {
std::vector<MachOYAML::RebaseOpcode> RebaseOpcodes;
+ std::vector<MachOYAML::BindOpcode> BindOpcodes;
};
struct Object {
@@ -81,7 +90,9 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
+LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
namespace llvm {
namespace yaml {
@@ -106,6 +117,10 @@ template <> struct MappingTraits<MachOYA
static void mapping(IO &IO, MachOYAML::RebaseOpcode &RebaseOpcode);
};
+template <> struct MappingTraits<MachOYAML::BindOpcode> {
+ static void mapping(IO &IO, MachOYAML::BindOpcode &BindOpcode);
+};
+
template <> struct MappingTraits<MachOYAML::Section> {
static void mapping(IO &IO, MachOYAML::Section &Section);
};
@@ -116,25 +131,43 @@ template <> struct MappingTraits<MachOYA
template <> struct ScalarEnumerationTraits<MachO::LoadCommandType> {
static void enumeration(IO &io, MachO::LoadCommandType &value) {
#include "llvm/Support/MachO.def"
- io.enumFallback<Hex32>(value);
+ io.enumFallback<Hex32>(value);
}
};
-#define ENUM_CASE(Enum) \
- io.enumCase(value, #Enum, MachO::Enum);
+#define ENUM_CASE(Enum) io.enumCase(value, #Enum, MachO::Enum);
template <> struct ScalarEnumerationTraits<MachO::RebaseOpcode> {
static void enumeration(IO &io, MachO::RebaseOpcode &value) {
- ENUM_CASE(REBASE_OPCODE_DONE)
- ENUM_CASE(REBASE_OPCODE_SET_TYPE_IMM)
- ENUM_CASE(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
- ENUM_CASE(REBASE_OPCODE_ADD_ADDR_ULEB)
- ENUM_CASE(REBASE_OPCODE_ADD_ADDR_IMM_SCALED)
- ENUM_CASE(REBASE_OPCODE_DO_REBASE_IMM_TIMES)
- ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES)
- ENUM_CASE(REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB)
- ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB)
- io.enumFallback<Hex8>(value);
+ ENUM_CASE(REBASE_OPCODE_DONE)
+ ENUM_CASE(REBASE_OPCODE_SET_TYPE_IMM)
+ ENUM_CASE(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
+ ENUM_CASE(REBASE_OPCODE_ADD_ADDR_ULEB)
+ ENUM_CASE(REBASE_OPCODE_ADD_ADDR_IMM_SCALED)
+ ENUM_CASE(REBASE_OPCODE_DO_REBASE_IMM_TIMES)
+ ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES)
+ ENUM_CASE(REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB)
+ ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB)
+ io.enumFallback<Hex8>(value);
+ }
+};
+
+template <> struct ScalarEnumerationTraits<MachO::BindOpcode> {
+ static void enumeration(IO &io, MachO::BindOpcode &value) {
+ ENUM_CASE(BIND_OPCODE_DONE)
+ ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM)
+ ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB)
+ ENUM_CASE(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM)
+ ENUM_CASE(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
+ ENUM_CASE(BIND_OPCODE_SET_TYPE_IMM)
+ ENUM_CASE(BIND_OPCODE_SET_ADDEND_SLEB)
+ ENUM_CASE(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
+ ENUM_CASE(BIND_OPCODE_ADD_ADDR_ULEB)
+ ENUM_CASE(BIND_OPCODE_DO_BIND)
+ ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB)
+ ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED)
+ ENUM_CASE(BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB)
+ io.enumFallback<Hex8>(value);
}
};
Modified: llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MachOYAML.cpp?rev=270901&r1=270900&r2=270901&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MachOYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MachOYAML.cpp Thu May 26 15:06:14 2016
@@ -97,18 +97,28 @@ void MappingTraits<MachOYAML::Object>::m
IO.setContext(nullptr);
}
-void MappingTraits<MachOYAML::LinkEditData>::mapping(IO &IO,
- MachOYAML::LinkEditData &LinkEditData) {
+void MappingTraits<MachOYAML::LinkEditData>::mapping(
+ IO &IO, MachOYAML::LinkEditData &LinkEditData) {
IO.mapOptional("RebaseOpcodes", LinkEditData.RebaseOpcodes);
+ IO.mapOptional("BindOpcodes", LinkEditData.BindOpcodes);
}
-void MappingTraits<MachOYAML::RebaseOpcode>::mapping(IO &IO,
- MachOYAML::RebaseOpcode &RebaseOpcode) {
+void MappingTraits<MachOYAML::RebaseOpcode>::mapping(
+ IO &IO, MachOYAML::RebaseOpcode &RebaseOpcode) {
IO.mapRequired("Opcode", RebaseOpcode.Opcode);
IO.mapRequired("Imm", RebaseOpcode.Imm);
IO.mapOptional("ExtraData", RebaseOpcode.ExtraData);
}
+void MappingTraits<MachOYAML::BindOpcode>::mapping(
+ IO &IO, MachOYAML::BindOpcode &BindOpcode) {
+ IO.mapRequired("Opcode", BindOpcode.Opcode);
+ IO.mapRequired("Imm", BindOpcode.Imm);
+ IO.mapOptional("ULEBExtraData", BindOpcode.ULEBExtraData);
+ IO.mapOptional("SLEBExtraData", BindOpcode.SLEBExtraData);
+ IO.mapOptional("Symbol", BindOpcode.Symbol);
+}
+
template <typename StructType>
void mapLoadCommandData(IO &IO, MachOYAML::LoadCommand &LoadCommand) {}
Added: llvm/trunk/test/ObjectYAML/MachO/bind_opcode.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/bind_opcode.yaml?rev=270901&view=auto
==============================================================================
--- llvm/trunk/test/ObjectYAML/MachO/bind_opcode.yaml (added)
+++ llvm/trunk/test/ObjectYAML/MachO/bind_opcode.yaml Thu May 26 15:06:14 2016
@@ -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: 1032
+ bind_size: 96
+ weak_bind_off: 0
+ weak_bind_size: 0
+ 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:
+ BindOpcodes:
+ - 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: BindOpcodes:
+#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
+
Modified: llvm/trunk/tools/obj2yaml/macho2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/macho2yaml.cpp?rev=270901&r1=270900&r2=270901&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/macho2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/macho2yaml.cpp Thu May 26 15:06:14 2016
@@ -29,6 +29,9 @@ class MachODumper {
void dumpHeader(std::unique_ptr<MachOYAML::Object> &Y);
void dumpLoadCommands(std::unique_ptr<MachOYAML::Object> &Y);
void dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y);
+ void dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y);
+ void dumpBindOpcodes(std::vector<MachOYAML::BindOpcode> &BindOpcodes,
+ ArrayRef<uint8_t> OpcodeBuffer, bool Lazy = false);
public:
MachODumper(const object::MachOObjectFile &O) : Obj(O) {}
@@ -192,6 +195,11 @@ void MachODumper::dumpLoadCommands(std::
}
void MachODumper::dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y) {
+ dumpRebaseOpcodes(Y);
+ dumpBindOpcodes(Y->LinkEdit.BindOpcodes, Obj.getDyldInfoBindOpcodes());
+}
+
+void MachODumper::dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y) {
MachOYAML::LinkEditData &LEData = Y->LinkEdit;
auto RebaseOpcodes = Obj.getDyldInfoRebaseOpcodes();
@@ -231,6 +239,64 @@ void MachODumper::dumpLinkEdit(std::uniq
break;
}
}
+
+void MachODumper::dumpBindOpcodes(
+ std::vector<MachOYAML::BindOpcode> &BindOpcodes,
+ ArrayRef<uint8_t> OpcodeBuffer, bool Lazy) {
+ for (auto OpCode = OpcodeBuffer.begin(); OpCode != OpcodeBuffer.end();
+ ++OpCode) {
+ MachOYAML::BindOpcode BindOp;
+ BindOp.Opcode =
+ static_cast<MachO::BindOpcode>(*OpCode & MachO::BIND_OPCODE_MASK);
+ BindOp.Imm = *OpCode & MachO::BIND_IMMEDIATE_MASK;
+
+ unsigned Count;
+ uint64_t ULEB = 0;
+ int64_t SLEB = 0;
+ const uint8_t *SymStart;
+
+ switch (BindOp.Opcode) {
+ case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
+ ULEB = decodeULEB128(OpCode + 1, &Count);
+ BindOp.ULEBExtraData.push_back(ULEB);
+ OpCode += Count;
+ // Intentionally no break here -- this opcode has two ULEB values
+
+ case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
+ case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
+ case MachO::BIND_OPCODE_ADD_ADDR_ULEB:
+ case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
+ ULEB = decodeULEB128(OpCode + 1, &Count);
+ BindOp.ULEBExtraData.push_back(ULEB);
+ OpCode += Count;
+ break;
+
+ case MachO::BIND_OPCODE_SET_ADDEND_SLEB:
+ SLEB = decodeSLEB128(OpCode + 1, &Count);
+ BindOp.SLEBExtraData.push_back(SLEB);
+ OpCode += Count;
+ break;
+
+ case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
+ SymStart = ++OpCode;
+ while (*OpCode) {
+ ++OpCode;
+ }
+ BindOp.Symbol = StringRef(reinterpret_cast<const char *>(SymStart),
+ OpCode - SymStart);
+ break;
+ default:
+ break;
+ }
+
+ BindOpcodes.push_back(BindOp);
+
+ // Lazy bindings have DONE opcodes between operations, so we need to keep
+ // processing after a DONE.
+ if (!Lazy && BindOp.Opcode == MachO::BIND_OPCODE_DONE)
+ break;
+ }
+}
Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) {
MachODumper Dumper(Obj);
Modified: llvm/trunk/tools/yaml2obj/yaml2macho.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2macho.cpp?rev=270901&r1=270900&r2=270901&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2macho.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2macho.cpp Thu May 26 15:06:14 2016
@@ -289,6 +289,23 @@ Error MachOWriter::writeLinkEditData(raw
}
}
+ ZeroToOffset(OS, DyldInfoOnlyCmd->bind_off);
+
+ for (auto Opcode : LinkEdit.BindOpcodes) {
+ uint8_t OpByte = Opcode.Opcode | Opcode.Imm;
+ OS.write(reinterpret_cast<char *>(&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);
+ }
+ }
+
// Fill to the end of the string table
ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize);
More information about the llvm-commits
mailing list