Index: llvm/trunk/test/tools/dsymutil/ARM/swift-ast.test =================================================================== --- llvm/trunk/test/tools/dsymutil/ARM/swift-ast.test +++ llvm/trunk/test/tools/dsymutil/ARM/swift-ast.test @@ -0,0 +1,26 @@ +RUN: llvm-dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.fat -o %T/swift-ast.dSYM -verbose -no-swiftmodule-timestamp | FileCheck %s --check-prefix=DSYMUTIL +RUN: llvm-readobj -sections -section-data %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.fat | FileCheck %s --check-prefix=READOBJ + +The tested object file has been created by the dummy Swift code: +let x = 1 + +Compiled with: + swiftc /tmp/test.swift -Onone -target armv7-apple-ios8.1 -c -o swift-ast-armv7.o + ld swift-ast-armv7.o -add_ast_path swift-ast.swiftmodule -arch armv7 -ios_version_min 8.1 -syslibroot /path/to/iPhoneOS.sdk -L/path/to/usr/lib/swift/iphoneos -lobjc -lSystem -o swift-ast.macho.armv7 + + swiftc /tmp/test.swift -Onone -target arm64-apple-ios8.1 -c -o swift-ast-arm64.o + ld swift-ast-arm64.o -add_ast_path swift-ast.swiftmodule -arch arm64 -ios_version_min 8.1 -syslibroot /path/to/iPhoneOS.sdk -L/path/to/usr/lib/swift/iphoneos -lobjc -lSystem -o swift-ast.macho.arm64 + + lipo -create swift-ast.macho.armv7 swift-ast.macho.arm64 -o swift-ast.macho.fat + +DSYMUTIL: filename:{{.*}}swift-ast.swiftmodule +DSYMUTIL: DEBUG MAP OBJECT:{{.*}}swift-ast.swiftmodule + +READOBJ: Name:{{.*}}__swift_ast +READOBJ: |SWIFTMODULE DATA| +READOBJ-NEXT: |.| +READOBJ: |SWIFTMODULE DATA| +READOBJ-NEXT: |.| + +RUN: llvm-dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.fat -no-output -verbose 2>&1 | FileCheck %s --check-prefix=TIMESTAMP +TIMESTAMP: Warning: Timestamp mismatch Index: llvm/trunk/test/tools/dsymutil/X86/swift-ast-x86_64.test =================================================================== --- llvm/trunk/test/tools/dsymutil/X86/swift-ast-x86_64.test +++ llvm/trunk/test/tools/dsymutil/X86/swift-ast-x86_64.test @@ -1,14 +1,19 @@ -RUN: llvm-dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -o %T/swift-ast.dSYM -verbose | FileCheck %s --check-prefix=DSYMUTIL +RUN: llvm-dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -o %T/swift-ast.dSYM -verbose -no-swiftmodule-timestamp | FileCheck %s --check-prefix=DSYMUTIL RUN: llvm-readobj -sections -section-data %T/swift-ast.dSYM/Contents/Resources/DWARF/swift-ast.macho.x86_64 | FileCheck %s --check-prefix=READOBJ The tested object file has been created by the dummy Swift code: let x = 1 -Compiled with: swiftc /tmp/test.swift -Onone -target x86_64-apple-macosx10.9 -c -Linked with: ld swift-ast.o -add_ast_path Inputs/swift-ast.swiftmodule -arch x86_64 -lSystem -macosx_version_min 10.9.0 +Compiled with: + swiftc /tmp/test.swift -Onone -target x86_64-apple-macosx10.9 -c + ld swift-ast.o -add_ast_path Inputs/swift-ast.swiftmodule -arch x86_64 -lSystem -macosx_version_min 10.9.0 DSYMUTIL: filename:{{.*}}swift-ast.swiftmodule DSYMUTIL: DEBUG MAP OBJECT:{{.*}}swift-ast.swiftmodule READOBJ: Name:{{.*}}__swift_ast READOBJ: |SWIFTMODULE DATA| +READOBJ-NEXT: |.| + +RUN: llvm-dsymutil -oso-prepend-path %p/.. %p/../Inputs/swift-ast.macho.x86_64 -no-output -verbose 2>&1 | FileCheck %s --check-prefix=TIMESTAMP +TIMESTAMP: Warning: Timestamp mismatch Index: llvm/trunk/tools/dsymutil/BinaryHolder.h =================================================================== --- llvm/trunk/tools/dsymutil/BinaryHolder.h +++ llvm/trunk/tools/dsymutil/BinaryHolder.h @@ -66,12 +66,6 @@ MapArchiveAndGetMemberBuffers(StringRef Filename, sys::TimePoint Timestamp); - void changeBackingMemoryBuffer(std::unique_ptr &&MemBuf); - ErrorOr getObjfileForArch(const Triple &T); - -public: - BinaryHolder(bool Verbose) : Verbose(Verbose) {} - /// Return the MemoryBufferRef that holds the memory mapping for the /// given \p Filename. This function will try to parse archive /// member specifications of the form /path/to/archive.a(member.o). @@ -85,6 +79,12 @@ GetMemoryBuffersForFile(StringRef Filename, sys::TimePoint Timestamp); + void changeBackingMemoryBuffer(std::unique_ptr &&MemBuf); + ErrorOr getObjfileForArch(const Triple &T); + +public: + BinaryHolder(bool Verbose) : Verbose(Verbose) {} + /// Get the ObjectFiles designated by the \p Filename. This /// might be an archive member specification of the form /// /path/to/archive.a(member.o). Index: llvm/trunk/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/trunk/tools/dsymutil/DwarfLinker.cpp +++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp @@ -525,8 +525,8 @@ /// Emit the string table described by \p Pool. void emitStrings(const NonRelocatableStringpool &Pool); - /// Emit the swift_ast section stored in \p Buffers. - void emitSwiftAST(const std::vector &Buffers); + /// Emit the swift_ast section stored in \p Buffer. + void emitSwiftAST(StringRef Buffer); /// Emit debug_ranges for \p FuncRange by translating the /// original \p Entries. @@ -712,12 +712,11 @@ } /// Emit the swift_ast section stored in \p Buffers. -void DwarfStreamer::emitSwiftAST(const std::vector &Buffers) { +void DwarfStreamer::emitSwiftAST(StringRef Buffer) { MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection(); SwiftASTSection->setAlignment(1 << 5); MS->SwitchSection(SwiftASTSection); - for (auto Buf : Buffers) - MS->EmitBytes(Buf.getBuffer()); + MS->EmitBytes(Buffer); } /// Emit the debug_range section contents for \p FuncRange by @@ -3491,12 +3490,28 @@ // N_AST objects (swiftmodule files) should get dumped directly into the // appropriate DWARF section. if (Obj->getType() == MachO::N_AST) { - auto ErrOrMemBufferRefs = BinHolder.GetMemoryBuffersForFile( - Obj->getObjectFilename(), Obj->getTimestamp()); - if (ErrOrMemBufferRefs.getError()) + StringRef File = Obj->getObjectFilename(); + auto ErrorOrMem = MemoryBuffer::getFile(File); + if (!ErrorOrMem) { + errs() << "Warning: Could not open " << File << "\n"; continue; + } + sys::fs::file_status Stat; + if (auto errc = sys::fs::status(File, Stat)) { + errs() << "Warning: " << errc.message() << "\n"; + continue; + } + if (!Options.NoTimestamp && Stat.getLastModificationTime() != + sys::TimePoint<>(Obj->getTimestamp())) { + errs() << "Warning: Timestamp mismatch for " << File << ": " + << Stat.getLastModificationTime() << " and " + << sys::TimePoint<>(Obj->getTimestamp()) << "\n"; + continue; + } + + // Copy the module into the .swift_ast section. if (!Options.NoOutput) - Streamer->emitSwiftAST(ErrOrMemBufferRefs.get()); + Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer()); continue; } Index: llvm/trunk/tools/dsymutil/dsymutil.h =================================================================== --- llvm/trunk/tools/dsymutil/dsymutil.h +++ llvm/trunk/tools/dsymutil/dsymutil.h @@ -25,12 +25,13 @@ namespace dsymutil { struct LinkOptions { - bool Verbose; ///< Verbosity - bool NoOutput; ///< Skip emitting output - bool NoODR; ///< Do not unique types according to ODR + bool Verbose; ///< Verbosity + bool NoOutput; ///< Skip emitting output + bool NoODR; ///< Do not unique types according to ODR + bool NoTimestamp; ///< Do not check swiftmodule timestamp std::string PrependPath; ///< -oso-prepend-path - LinkOptions() : Verbose(false), NoOutput(false) {} + LinkOptions() : Verbose(false), NoOutput(false), NoTimestamp(false) {} }; /// \brief Extract the DebugMaps from the given file. Index: llvm/trunk/tools/dsymutil/dsymutil.cpp =================================================================== --- llvm/trunk/tools/dsymutil/dsymutil.cpp +++ llvm/trunk/tools/dsymutil/dsymutil.cpp @@ -68,7 +68,10 @@ NoOutput("no-output", desc("Do the link in memory, but do not emit the result file."), init(false), cat(DsymCategory)); - +static opt + NoTimestamp("no-swiftmodule-timestamp", + desc("Don't check timestamp for swiftmodule files."), + init(false), cat(DsymCategory)); static list ArchFlags( "arch", desc("Link DWARF debug information only for specified CPU architecture\n" @@ -266,6 +269,7 @@ Options.Verbose = Verbose; Options.NoOutput = NoOutput; Options.NoODR = NoODR; + Options.NoTimestamp = NoTimestamp; Options.PrependPath = OsoPrependPath; llvm::InitializeAllTargetInfos();