From 301c4e690a84d262125674f34d4b23a09649fdec Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 1 Jul 2014 08:15:41 +0000 Subject: [PATCH] [mach-o] add representation for LC_ID_DYLIB to MachONormalizedFile It still needs to be tied into BinaryReader, but this allows reasonably sensible creation of SharedLibrary atoms on MachO. llvm-svn: 212093 --- .../MachO/MachONormalizedFileBinaryReader.cpp | 9 +++++ .../MachO/MachONormalizedFileBinaryWriter.cpp | 25 ++++++++++++- .../MachO/MachONormalizedFileFromAtoms.cpp | 1 + .../MachO/MachONormalizedFileToAtoms.cpp | 3 +- .../ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 1 - .../mach-o/Inputs/use-dylib-install-names.yaml | 28 +++++++++++++++ lld/test/mach-o/dylib-install-names.yaml | 41 ++++++++++++++++++++++ lld/test/mach-o/lit.local.cfg | 1 + lld/test/mach-o/use-simple-dylib.yaml | 14 ++++---- 9 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 lld/test/mach-o/Inputs/use-dylib-install-names.yaml create mode 100644 lld/test/mach-o/dylib-install-names.yaml diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index bf93a00..7c59915 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -386,6 +386,15 @@ readBinary(std::unique_ptr &mb, } } } + if (cmd == LC_ID_DYLIB) { + const dylib_command *dl = reinterpret_cast(lc); + dylib_command tempDL; + if (swap) { + tempDL = *dl; swapStruct(tempDL); dl = &tempDL; + } + + f->installName = lc + dl->dylib.name; + } return false; }); if (ec) diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index 2f61607..755e9aa 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -324,6 +324,12 @@ uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) { size += segCommandSize; ++count; + // If creating a dylib, add LC_ID_DYLIB. + if (_file.fileType == llvm::MachO::MH_DYLIB) { + size += sizeof(dylib_command) + pointerAlign(_file.installName.size() + 1); + ++count; + } + // Add LC_DYLD_INFO size += sizeof(dyld_info_command); ++count; @@ -621,6 +627,24 @@ std::error_code MachOFileLayout::writeLoadCommands() { else ec = writeSegmentLoadCommands(lc); + // Add LC_ID_DYLIB command for dynamic libraries. + if (_file.fileType == llvm::MachO::MH_DYLIB) { + dylib_command *dc = reinterpret_cast(lc); + StringRef path = _file.installName; + uint32_t size = sizeof(dylib_command) + pointerAlign(path.size() + 1); + dc->cmd = LC_ID_DYLIB; + dc->cmdsize = size; + dc->dylib.name = sizeof(dylib_command); // offset + dc->dylib.timestamp = 0; // FIXME + dc->dylib.current_version = 0; // FIXME + dc->dylib.compatibility_version = 0; // FIXME + if (_swap) + swapStruct(*dc); + memcpy(lc + sizeof(dylib_command), path.begin(), path.size()); + lc[sizeof(dylib_command) + path.size()] = '\0'; + lc += size; + } + // Add LC_DYLD_INFO_ONLY. dyld_info_command* di = reinterpret_cast(lc); di->cmd = LC_DYLD_INFO_ONLY; @@ -720,7 +744,6 @@ std::error_code MachOFileLayout::writeLoadCommands() { lc[sizeof(dylib_command)+dep.path.size()] = '\0'; lc += size; } - } return ec; } diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 67ed62c..9f348a3 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -934,6 +934,7 @@ normalizedFromAtoms(const lld::File &atomFile, f->arch = context.arch(); f->fileType = context.outputMachOType(); f->flags = util.fileFlags(); + f->installName = context.installName(); util.copySegmentInfo(normFile); util.copySections(normFile); util.addDependentDylibs(atomFile, normFile); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 417cabc..5846c3e 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -605,7 +605,8 @@ normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path, ErrorOr> normalizedDylibToAtoms(const NormalizedFile &normalizedFile, StringRef path, bool copyRefs) { - std::unique_ptr file(new MachODylibFile(path)); + std::unique_ptr file( + new MachODylibFile(normalizedFile.installName)); for (auto &sym : normalizedFile.globalSymbols) { assert((sym.scope & N_EXT) && "only expect external symbols here"); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index 7477aea..ddc1fcc 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -508,7 +508,6 @@ struct MappingTraits { } }; - template <> struct ScalarEnumerationTraits { static void enumeration(IO &io, RebaseType &value) { diff --git a/lld/test/mach-o/Inputs/use-dylib-install-names.yaml b/lld/test/mach-o/Inputs/use-dylib-install-names.yaml new file mode 100644 index 0000000..cec2559 --- /dev/null +++ b/lld/test/mach-o/Inputs/use-dylib-install-names.yaml @@ -0,0 +1,28 @@ +--- !mach-o +arch: x86_64 +file-type: MH_OBJECT +flags: [ ] +has-UUID: false +OS: unknown +sections: + - segment: __TEXT + section: __text + type: S_REGULAR + attributes: [ S_ATTR_PURE_INSTRUCTIONS ] + address: 0x0000000000000000 + content: [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00, + 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00, + 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, + 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00, + 0x00, 0x00, 0x00 ] +global-symbols: + - name: _foo + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x0000000000000000 +undefined-symbols: + - name: _myGlobal + type: N_UNDF + scope: [ N_EXT ] + value: 0x0000000000000000 diff --git a/lld/test/mach-o/dylib-install-names.yaml b/lld/test/mach-o/dylib-install-names.yaml new file mode 100644 index 0000000..6a1c6c2 --- /dev/null +++ b/lld/test/mach-o/dylib-install-names.yaml @@ -0,0 +1,41 @@ +# RUN: lld -flavor darwin -arch x86_64 -install_name libwibble.dylib -dylib %s -o %t.dylib +# RUN: macho-dump %t.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE +# RUN: lld -flavor darwin -arch x86_64 %p/Inputs/use-dylib-install-names.yaml %t.dylib -r -print_atoms | FileCheck %s --check-prefix=CHECK-BINARY-READ + +--- !mach-o +arch: x86_64 +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +has-UUID: false +OS: unknown +sections: + - segment: __TEXT + section: __text + type: S_REGULAR + attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] + alignment: 4 + address: 0x0000000000000000 + content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90, + 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3, + 0x31, 0xC0, 0xC3 ] +local-symbols: + - name: _myStatic + type: N_SECT + sect: 1 + value: 0x000000000000000B +global-symbols: + - name: _myGlobal + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x0000000000000001 +... + + +# CHECK-BINARY-WRITE: (('command', 13) +# CHECK-BINARY-WRITE-NEXT: ('size', 40) +# CHECK-BINARY-WRITE-NEXT: ('install_name', 'libwibble.dylib') + +# CHECK-BINARY-READ: shared-library-atoms: +# CHECK-BINARY-READ: - name: _myGlobal +# CHECK-BINARY-READ: load-name: libwibble.dylib diff --git a/lld/test/mach-o/lit.local.cfg b/lld/test/mach-o/lit.local.cfg index 0bd76a6..739a099 100644 --- a/lld/test/mach-o/lit.local.cfg +++ b/lld/test/mach-o/lit.local.cfg @@ -1,3 +1,4 @@ # mach-o test cases encode input files in yaml and use .yaml extension config.suffixes = ['.yaml'] +config.excludes = ['Inputs'] diff --git a/lld/test/mach-o/use-simple-dylib.yaml b/lld/test/mach-o/use-simple-dylib.yaml index 024e983..bfa393d 100644 --- a/lld/test/mach-o/use-simple-dylib.yaml +++ b/lld/test/mach-o/use-simple-dylib.yaml @@ -1,5 +1,5 @@ # RUN: lld -flavor darwin -arch x86_64 -print_atoms -r %s | FileCheck %s -# lld -flavor darwin -arch x86_64 -print_atoms -r %s %p/Inputs/simple-dylib.yaml -o - | FileCheck %s + --- !mach-o arch: x86_64 @@ -110,6 +110,8 @@ global-symbols: sect: 1 desc: [ N_SYMBOL_RESOLVER ] value: 0x0000000000000010 + +install-name: libspecial.dylib ... @@ -118,12 +120,12 @@ global-symbols: # CHECK: - name: _myVariablePreviouslyKnownAsPrivateExtern # CHECK: shared-library-atoms: # CHECK: - name: _myHidden -# CHECK: load-name: {{.*}}use-simple-dylib.yaml +# CHECK: load-name: libspecial.dylib # CHECK: - name: _myGlobal -# CHECK: load-name: {{.*}}use-simple-dylib.yaml +# CHECK: load-name: libspecial.dylib # CHECK: - name: _myHiddenWeak -# CHECK: load-name: {{.*}}use-simple-dylib.yaml +# CHECK: load-name: libspecial.dylib # CHECK: - name: _myGlobalWeak -# CHECK: load-name: {{.*}}use-simple-dylib.yaml +# CHECK: load-name: libspecial.dylib # CHECK: - name: _myResolver -# CHECK: load-name: {{.*}}use-simple-dylib.yaml +# CHECK: load-name: libspecial.dylib -- 2.7.4