diff --git a/test/MC/MachO/linker-option-2.s b/test/MC/MachO/linker-option-2.s index 15ce60e6ed4..415d02e536b 100644 --- a/test/MC/MachO/linker-option-2.s +++ b/test/MC/MachO/linker-option-2.s @@ -1,25 +1,18 @@ -// RUN: llvm-mc -n -triple x86_64-apple-darwin10 %s -filetype=obj | macho-dump | FileCheck %s - -// CHECK: ('load_commands_size', 120) -// CHECK: ('load_commands', [ -// CHECK: # Load Command 2 -// CHECK: (('command', 45) -// CHECK: ('size', 16) -// CHECK: ('count', 1) -// CHECK: ('_strings', [ -// CHECK: "a", -// CHECK: ]) -// CHECK: ), -// CHECK: # Load Command 3 -// CHECK: (('command', 45) -// CHECK: ('size', 16) -// CHECK: ('count', 2) -// CHECK: ('_strings', [ -// CHECK: "a", -// CHECK: "b", -// CHECK: ]) -// CHECK: ), -// CHECK: ]) +// RUN: llvm-mc -n -triple x86_64-apple-darwin10 %s -filetype=obj | llvm-readobj -macho-linker-options | FileCheck %s .linker_option "a" .linker_option "a", "b" + +// CHECK: Linker Options { +// CHECK: Size: 16 +// CHECK: Strings [ +// CHECK: Value: a +// CHECK: ] +// CHECK: } +// CHECK: Linker Options { +// CHECK: Size: 16 +// CHECK: Strings [ +// CHECK: Value: a +// CHECK: Value: b +// CHECK: ] +// CHECK: } diff --git a/test/MC/MachO/linker-options.ll b/test/MC/MachO/linker-options.ll index 2cda835c100..09ebd0f9156 100644 --- a/test/MC/MachO/linker-options.ll +++ b/test/MC/MachO/linker-options.ll @@ -4,35 +4,28 @@ ; CHECK-ASM: .linker_option "-lz" ; CHECK-ASM-NEXT: .linker_option "-framework", "Cocoa" -; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=obj -o - %s | macho-dump > %t +; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=obj -o - %s | llvm-readobj -macho-linker-options > %t ; RUN: FileCheck --check-prefix=CHECK-OBJ < %t %s -; CHECK-OBJ: ('load_commands', [ -; CHECK-OBJ: # Load Command 1 -; CHECK-OBJ: (('command', 45) -; CHECK-OBJ: ('size', 16) -; CHECK-OBJ: ('count', 1) -; CHECK-OBJ: ('_strings', [ -; CHECK-OBJ: "-lz", -; CHECK-OBJ: ]) -; CHECK-OBJ: ), -; CHECK-OBJ: # Load Command 2 -; CHECK-OBJ: (('command', 45) -; CHECK-OBJ: ('size', 32) -; CHECK-OBJ: ('count', 2) -; CHECK-OBJ: ('_strings', [ -; CHECK-OBJ: "-framework", -; CHECK-OBJ: "Cocoa", -; CHECK-OBJ: ]) -; CHECK-OBJ: # Load Command 3 -; CHECK-OBJ: (('command', 45) -; CHECK-OBJ: ('size', 24) -; CHECK-OBJ: ('count', 1) -; CHECK-OBJ: ('_strings', [ -; CHECK-OBJ: "-lmath", -; CHECK-OBJ: ]) -; CHECK-OBJ: ), -; CHECK-OBJ: ]) +; CHECK-OBJ: Linker Options { +; CHECK-OBJ: Size: 16 +; CHECK-OBJ: Strings [ +; CHECK-OBJ: Value: -lz +; CHECK-OBJ: ] +; CHECK-OBJ: } +; CHECK-OBJ: Linker Options { +; CHECK-OBJ: Size: 32 +; CHECK-OBJ: Strings [ +; CHECK-OBJ: Value: -framework +; CHECK-OBJ: Value: Cocoa +; CHECK-OBJ: ] +; CHECK-OBJ: } +; CHECK-OBJ: Linker Options { +; CHECK-OBJ: Size: 24 +; CHECK-OBJ: Strings [ +; CHECK-OBJ: Value: -lmath +; CHECK-OBJ: ] +; CHECK-OBJ: } !0 = !{i32 6, !"Linker Options", !{!{!"-lz"}, !{!"-framework", !"Cocoa"}, !{!"-lmath"}}} diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index fd6e00b9e83..177f79fb9c1 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -46,6 +46,7 @@ public: void printMachODysymtab() override; void printMachOSegment() override; void printMachOIndirectSymbols() override; + void printMachOLinkerOptions () override; private: template @@ -791,3 +792,22 @@ void MachODumper::printMachOIndirectSymbols() { } } } + +void MachODumper::printMachOLinkerOptions() { + for (const auto &Load : Obj->load_commands()) { + if (Load.C.cmd == MachO::LC_LINKER_OPTION) { + MachO::linker_option_command LOLC = Obj->getLinkerOptionLoadCommand(Load); + DictScope Group(W, "Linker Options"); + W.printNumber("Size", LOLC.cmdsize); + ListScope D(W, "Strings"); + uint64_t DataSize = LOLC.cmdsize - sizeof(MachO::linker_option_command); + const char *P = Load.Ptr + sizeof(MachO::linker_option_command); + StringRef Data(P, DataSize); + for (unsigned i = 0; i < LOLC.count; ++i) { + std::pair Split = Data.split('\0'); + W.printString("Value", Split.first); + Data = Split.second; + } + } + } +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 65015213201..1a80b0a5459 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -61,6 +61,7 @@ public: virtual void printMachODysymtab() { } virtual void printMachOSegment() { } virtual void printMachOIndirectSymbols() { } + virtual void printMachOLinkerOptions() { } virtual void printStackMap() const = 0; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 2e17525ab71..a8e4ca4893f 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -192,6 +192,11 @@ namespace opts { MachOIndirectSymbols("macho-indirect-symbols", cl::desc("Display MachO indirect symbols")); + // -macho-linker-options + cl::opt + MachOLinkerOptions("macho-linker-options", + cl::desc("Display MachO linker options")); + // -macho-segment cl::opt MachOSegment("macho-segment", @@ -343,6 +348,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printMachODataInCode(); if (opts::MachOIndirectSymbols) Dumper->printMachOIndirectSymbols(); + if (opts::MachOLinkerOptions) + Dumper->printMachOLinkerOptions(); if (opts::MachOSegment) Dumper->printMachOSegment(); if (opts::MachOVersionMin)