From f5d67a920c6464ecca63c9a16e25ba756360fbc5 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Fri, 9 Sep 2016 12:27:30 -0700 Subject: [PATCH 1/8] Minor refactor of writePortablePdbInfo --- src/absil/ilwrite.fs | 40 +++++++++++++++++++++++++++------------- src/absil/ilwritepdb.fs | 15 +++++++++------ src/absil/ilwritepdb.fsi | 5 ++++- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index f2bb3402b36..c03f3b96df8 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -3590,7 +3590,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: with e -> failwith ("Could not open file for writing (binary mode): " + outfile) - let pdbData,debugDirectoryChunk,debugDataChunk,textV2P,mappings = + let pdbData,pdbOpt,debugDirectoryChunk,debugDataChunk,textV2P,mappings = try let imageBaseReal = modul.ImageBase // FIXED CHOICE @@ -3683,7 +3683,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: let importLookupTableChunk,next = chunk 0x14 next let importNameHintTableChunk,next = chunk 0x0e next let mscoreeStringChunk,next = chunk 0x0c next - + let next = align 0x10 (next + 0x05) - 0x05 let importTableChunk = { addr=importTableChunk.addr; size = next - importTableChunk.addr} let importTableChunkPadding = importTableChunk.size - (0x28 + 0x14 + 0x0e + 0x0c) @@ -3691,8 +3691,20 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: let next = next + 0x03 let entrypointCodeChunk,next = chunk 0x06 next let globalpointerCodeChunk,next = chunk (if isItanium then 0x8 else 0x0) next - - let debugDirectoryChunk,next = chunk (if pdbfile = None then 0x0 else sizeof_IMAGE_DEBUG_DIRECTORY) next + + let pdbOpt = + match portablePDB with + | true -> Some (generatePortablePdb fixupOverlappingSequencePoints showTimes pdbData) + | _ -> None + + let debugDirectoryChunk,next = + chunk (if pdbfile = None then + 0x0 + else if embeddedPDB && portablePDB then + sizeof_IMAGE_DEBUG_DIRECTORY * 2 + else + sizeof_IMAGE_DEBUG_DIRECTORY + ) next // The debug data is given to us by the PDB writer and appears to // typically be the type of the data plus the PDB file name. We fill // this in after we've written the binary. We approximate the size according @@ -3705,6 +3717,12 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: + System.Text.Encoding.Unicode.GetByteCount(f) // See bug 748444 + debugDataJustInCase))) next +// let debugEmbeddedPdbChunk,next = +// chunk (align 0x4 (match embeddedPDB with +// | None -> 0x0 +// | Some f -> (24 +// + System.Text.Encoding.Unicode.GetByteCount(f) // See bug 748444 +// + debugDataJustInCase))) next let textSectionSize = next - textSectionAddr let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize) @@ -4145,7 +4163,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: FileSystemUtilites.setExecutablePermission outfile with _ -> () - pdbData,debugDirectoryChunk,debugDataChunk,textV2P,mappings + pdbData,pdbOpt,debugDirectoryChunk,debugDataChunk,textV2P,mappings // Looks like a finally with e -> @@ -4169,15 +4187,11 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: | Some fpdb -> try let idd = -#if FX_NO_PDB_WRITER - ignore portablePDB - writePortablePdbInfo fixupOverlappingSequencePoints showTimes fpdb pdbData -#else - if portablePDB then - writePortablePdbInfo fixupOverlappingSequencePoints showTimes fpdb pdbData - else + match pdbOpt with + | Some struct(contentId, stream) -> + writePortablePdbInfo contentId stream showTimes fpdb + | None -> writePdbInfo fixupOverlappingSequencePoints showTimes outfile fpdb pdbData -#endif reportTime showTimes "Generate PDB Info" // Now we have the debug data we can go back and fill in the debug directory in the image diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 2f019e51d61..43be0c34121 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -200,9 +200,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = Array.sortInPlaceBy fst allSps spCounts, allSps -let writePortablePdbInfo (fixupSPs:bool) showTimes fpdb (info:PdbData) = - - try FileSystem.FileDelete fpdb with _ -> () +let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = sortMethods showTimes info let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods @@ -362,10 +360,15 @@ let writePortablePdbInfo (fixupSPs:bool) showTimes fpdb (info:PdbData) = let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, null) let blobBuilder = new BlobBuilder() let contentId= serializer.Serialize(blobBuilder) - - reportTime showTimes "PDB: Created" - use portablePdbStream = new FileStream(fpdb, FileMode.Create, FileAccess.ReadWrite) + use portablePdbStream = new MemoryStream() blobBuilder.WriteContentTo(portablePdbStream) + reportTime showTimes "PDB: Created" + struct (contentId, portablePdbStream) + +let writePortablePdbInfo (contentId:BlobContentId) (stream:MemoryStream) showTimes fpdb = + try FileSystem.FileDelete fpdb with _ -> () + use pdbFile = new FileStream(fpdb, FileMode.Create, FileAccess.ReadWrite) + stream.WriteTo(pdbFile) reportTime showTimes "PDB: Closed" pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32(contentId.Stamp)) fpdb diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi index de03c2bbf37..a5468483267 100644 --- a/src/absil/ilwritepdb.fsi +++ b/src/absil/ilwritepdb.fsi @@ -7,6 +7,8 @@ open Microsoft.FSharp.Compiler.AbstractIL.IL open Microsoft.FSharp.Compiler.ErrorLogger open Microsoft.FSharp.Compiler.Range open System.Collections.Generic +open System.IO +open System.Reflection.Metadata type PdbDocumentData = ILSourceDocument @@ -75,7 +77,8 @@ type idd = iddTimestamp: int32; iddData: byte[]; } -val writePortablePdbInfo : fixupOverlappingSequencePoints:bool -> showTimes:bool -> fpdb:string -> info:PdbData -> idd +val generatePortablePdb : fixupSPs:bool -> showTimes:bool -> info:PdbData -> struct (BlobContentId * MemoryStream) +val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> idd #if !FX_NO_PDB_WRITER val writePdbInfo : fixupOverlappingSequencePoints:bool -> showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> idd From 9c49282040ce368bfa3716a64743f2895a458226 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Tue, 6 Sep 2016 17:11:22 -0700 Subject: [PATCH 2/8] Add command line switches for embedded pdbs --- src/absil/ilwrite.fs | 5 +- src/absil/ilwrite.fsi | 1 + src/absil/ilwritepdb.fs | 59 +++--- src/fsharp/CompileOps.fs | 3 + src/fsharp/CompileOps.fsi | 2 + src/fsharp/CompileOptions.fs | 16 +- src/fsharp/FSComp.txt | 2 +- src/fsharp/fsc.fs | 1 + .../CompilerOptions/fsc/help/comparer.fsx | 6 +- .../fsc/help/help40.437.1033.bsl | 172 +++++++++--------- .../fsi/exename/help40.437.1033.bsl | 92 +++++----- .../fsi/help/help.437.1033.bsl | 62 ------- .../fsi/help/help40-nologo.437.1033.bsl | 94 +++++----- .../fsi/help/help40.437.1033.bsl | 96 +++++----- 14 files changed, 285 insertions(+), 326 deletions(-) delete mode 100644 tests/fsharpqa/Source/CompilerOptions/fsi/help/help.437.1033.bsl diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index c03f3b96df8..acbef818ae7 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -3541,7 +3541,7 @@ let writeDirectory os dict = let writeBytes (os: BinaryWriter) (chunk:byte[]) = os.Write(chunk,0,chunk.Length) -let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, +let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: ILStrongNameSigner option, portablePDB, embeddedPDB, fixupOverlappingSequencePoints, emitTailcalls, showTimes, dumpDebugInfo) modul noDebugData = // Store the public key from the signer into the manifest. This means it will be written // to the binary and also acts as an indicator to leave space for delay sign @@ -4247,6 +4247,7 @@ type options = { ilg: ILGlobals; pdbfile: string option portablePDB: bool + embeddedPDB: bool signer: ILStrongNameSigner option fixupOverlappingSequencePoints: bool emitTailcalls : bool @@ -4255,6 +4256,6 @@ type options = let WriteILBinary (outfile, (args: options), modul, noDebugData) = - ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, + ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes, args.dumpDebugInfo) modul noDebugData) diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi index aab8b46221b..51d1842b208 100644 --- a/src/absil/ilwrite.fsi +++ b/src/absil/ilwrite.fsi @@ -19,6 +19,7 @@ type options = { ilg: ILGlobals pdbfile: string option portablePDB: bool + embeddedPDB: bool signer : ILStrongNameSigner option fixupOverlappingSequencePoints : bool emitTailcalls: bool diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 43be0c34121..5822b737324 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -247,6 +247,7 @@ let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = index.Add(doc.File, handle) index + let mutable lastLocalVariableHandle = Unchecked.defaultof metadata.SetCapacity(TableIndex.MethodDebugInformation, info.Methods.Length) info.Methods |> Array.iteri (fun _i minfo -> let docHandle, sequencePointBlob = @@ -270,26 +271,28 @@ let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = // If part of the method body is in another document returns nil handle. let tryGetSingleDocumentIndex = let mutable singleDocumentIndex = 0 - for i in 1 .. sps.Length - 1 do + for i in 0 .. sps.Length - 1 do let index = sps.[i].Document if index <> singleDocumentIndex then singleDocumentIndex <- index singleDocumentIndex - if sps.Length = 0 then + // Filter out feefee (Hidden) sequence points + let sps = sps |> Array.filter(fun sp -> sp.Line <> 0xfeefee && sp.EndLine <> 0xfeefee) + + if sps.Length = 0 then Unchecked.defaultof, Unchecked.defaultof else - let builder = new BlobBuilder() - builder.WriteCompressedInteger(minfo.LocalSignatureToken) - let mutable previousNonHiddenStartLine = -1 let mutable previousNonHiddenStartColumn = -1 let mutable previousDocumentIndex = -1 let mutable singleDocumentIndex = tryGetSingleDocumentIndex let mutable currentDocumentIndex = previousDocumentIndex - for i in 0 .. (sps.Length - 1) do + let builder = new BlobBuilder() + builder.WriteCompressedInteger(minfo.LocalSignatureToken) + for i in 0 .. (sps.Length - 1) do if previousDocumentIndex <> currentDocumentIndex then // optional document in header or document record: if previousDocumentIndex <> -1 then @@ -304,16 +307,9 @@ let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = else builder.WriteCompressedInteger(sps.[i].Offset) - // F# does not support hidden sequence points yet !!! - // if (sequencePoints[i].IsHidden) - // { - // builder.WriteInt16(0); - // continue; - // } - - let deltaLines = sps.[i].EndLine - sps.[i].Line; - let deltaColumns = sps.[i].EndColumn - sps.[i].Column; - builder.WriteCompressedInteger(deltaLines); + let deltaLines = sps.[i].EndLine - sps.[i].Line + let deltaColumns = sps.[i].EndColumn - sps.[i].Column + builder.WriteCompressedInteger(deltaLines) if deltaLines = 0 then builder.WriteCompressedInteger(deltaColumns) @@ -333,23 +329,30 @@ let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = getDocumentHandle singleDocumentIndex, metadata.GetOrAddBlob(builder) - // Write the scopes - let mutable lastLocalVariableHandle = Unchecked.defaultof + // Write the scopes let nextHandle handle = MetadataTokens.LocalVariableHandle(MetadataTokens.GetRowNumber(LocalVariableHandle.op_Implicit(handle)) + 1) - let rec writePdbScope top scope = - if top || scope.Locals.Length <> 0 || scope.Children.Length <> 0 then - lastLocalVariableHandle <- nextHandle lastLocalVariableHandle + let rec writePdbScope scope = + if scope.Children.Length = 0 then + metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), + Unchecked.defaultof, + nextHandle lastLocalVariableHandle, + Unchecked.defaultof, + 0, + scope.EndOffset - scope.StartOffset) |>ignore + else metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), - Unchecked.defaultof, - lastLocalVariableHandle, - Unchecked.defaultof, - scope.StartOffset, - scope.EndOffset - scope.StartOffset) |>ignore + Unchecked.defaultof, + nextHandle lastLocalVariableHandle, + Unchecked.defaultof, + scope.StartOffset, + scope.EndOffset - scope.StartOffset) |>ignore + for localVariable in scope.Locals do lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) - scope.Children |> Array.iter (writePdbScope false) - writePdbScope true minfo.RootScope + scope.Children |> Array.iter (writePdbScope) + + writePdbScope minfo.RootScope metadata.AddMethodDebugInformation(docHandle, sequencePointBlob) |> ignore) let entryPoint = diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 879ccf0f2c4..7ada6090e9e 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -2072,6 +2072,7 @@ type TcConfigBuilder = mutable useSignatureDataFile : bool mutable jitTracking : bool mutable portablePDB : bool + mutable embeddedPDB : bool mutable ignoreSymbolStoreSequencePoints : bool mutable internConstantStrings : bool mutable extraOptimizationIterations : int @@ -2241,6 +2242,7 @@ type TcConfigBuilder = useSignatureDataFile = false jitTracking = true portablePDB = true + embeddedPDB = true ignoreSymbolStoreSequencePoints = false internConstantStrings = true extraOptimizationIterations = 0 @@ -2729,6 +2731,7 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = member x.useSignatureDataFile = data.useSignatureDataFile member x.jitTracking = data.jitTracking member x.portablePDB = data.portablePDB + member x.embeddedPDB = data.embeddedPDB member x.ignoreSymbolStoreSequencePoints = data.ignoreSymbolStoreSequencePoints member x.internConstantStrings = data.internConstantStrings member x.extraOptimizationIterations = data.extraOptimizationIterations diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index 1d00cd89d98..34a4f8bf763 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -306,6 +306,7 @@ type TcConfigBuilder = mutable useSignatureDataFile : bool mutable jitTracking : bool mutable portablePDB : bool + mutable embeddedPDB : bool mutable ignoreSymbolStoreSequencePoints : bool mutable internConstantStrings : bool mutable extraOptimizationIterations : int @@ -459,6 +460,7 @@ type TcConfig = member useSignatureDataFile : bool member jitTracking : bool member portablePDB : bool + member embeddedPDB : bool member ignoreSymbolStoreSequencePoints : bool member internConstantStrings : bool member extraOptimizationIterations : int diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index c1867acbb52..ccf2c6e96e6 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -119,7 +119,7 @@ let PrintCompilerOption (CompilerOption(_s,_tag,_spec,_,help) as compilerOption) // single space - space. // description - words upto but excluding the final character of the line. assert(flagWidth = 30) - printf "%-30s" (compilerOptionUsage compilerOption) + printf "%-40s" (compilerOptionUsage compilerOption) let printWord column (word:string) = // Have printed upto column. // Now print the next word including any preceeding whitespace. @@ -127,7 +127,7 @@ let PrintCompilerOption (CompilerOption(_s,_tag,_spec,_,help) as compilerOption) if column + 1 (*space*) + word.Length >= lineWidth then // NOTE: "equality" ensures final character of the line is never printed printfn "" (* newline *) assert(flagWidth = 30) - printf "%-30s %s" ""(*<--flags*) word + printf "%-40s %s" ""(*<--flags*) word flagWidth + 1 + word.Length else printf " %s" word @@ -474,11 +474,12 @@ let SetDebugSwitch (tcConfigB : TcConfigBuilder) (dtype : string option) (s : Op match dtype with | Some(s) -> match s with - | "portable" -> tcConfigB.portablePDB <- true ; tcConfigB.jitTracking <- true - | "pdbonly" -> tcConfigB.portablePDB <- false; tcConfigB.jitTracking <- false - | "full" -> tcConfigB.portablePDB <- false; tcConfigB.jitTracking <- true + | "portable" -> tcConfigB.portablePDB <- true ; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- true + | "pdbonly" -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- false + | "embedded" -> tcConfigB.portablePDB <- true; tcConfigB.embeddedPDB <- true; tcConfigB.jitTracking <- true + | "full" -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- true | _ -> error(Error(FSComp.SR.optsUnrecognizedDebugType(s), rangeCmdArgs)) - | None -> tcConfigB.portablePDB <- false; tcConfigB.jitTracking <- s = OptionSwitch.On; + | None -> tcConfigB.portablePDB <- false; tcConfigB.embeddedPDB <- false; tcConfigB.jitTracking <- s = OptionSwitch.On; tcConfigB.debuginfo <- s = OptionSwitch.On let setOutFileName tcConfigB s = @@ -499,7 +500,7 @@ let tagFileList = "" let tagDirList = "" let tagPathList = "" let tagResInfo = "" -let tagFullPDBOnlyPortable = "{full|pdbonly|portable}" +let tagFullPDBOnlyPortable = "{full|pdbonly|portable|embedded}" let tagWarnList = "" let tagSymbolList = "" let tagAddress = "
" @@ -522,6 +523,7 @@ let PrintOptionInfo (tcConfigB:TcConfigBuilder) = printfn " doFinalSimplify. . . . : %+A" tcConfigB.doFinalSimplify printfn " jitTracking . . . . . : %+A" tcConfigB.jitTracking printfn " portablePDB. . . . . . : %+A" tcConfigB.portablePDB + printfn " embeddedPDB. . . . . . : %+A" tcConfigB.embeddedPDB printfn " debuginfo . . . . . . : %+A" tcConfigB.debuginfo printfn " resolutionEnvironment : %+A" tcConfigB.resolutionEnvironment printfn " product . . . . . . . : %+A" tcConfigB.productNameForBannerText diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index cefdff8663e..8f14f835865 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -839,7 +839,7 @@ optsNowin32manifest,"Do not include the default Win32 manifest" optsResource,"Embed the specified managed resource" optsLinkresource,"Link the specified resource to this assembly where the resinfo format is [,[,public|private]]" optsDebugPM,"Emit debug information (Short form: -g)" -optsDebug,"Specify debugging type: full, portable, pdbonly. ('%s' is the default if no debuggging type specified and enables attaching a debugger to a running program. 'portable' is a cross-platform format)." +optsDebug,"Specify debugging type: full, portable, embedded, pdbonly. ('%s' is the default if no debuggging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file)." optsOptimize,"Enable optimizations (Short form: -O)" optsTailcalls,"Enable or disable tailcalls" optsCrossoptimize,"Enable or disable cross-module optimizations" diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 43b1659e453..73be4f34e89 100755 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1741,6 +1741,7 @@ module FileWriter = emitTailcalls = tcConfig.emitTailcalls showTimes = tcConfig.showTimes portablePDB = tcConfig.portablePDB + embeddedPDB = tcConfig.embeddedPDB signer = GetSigner signingInfo fixupOverlappingSequencePoints = false dumpDebugInfo = tcConfig.dumpDebugInfo }, diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/help/comparer.fsx b/tests/fsharpqa/Source/CompilerOptions/fsc/help/comparer.fsx index 5ea487fbd26..3b812c21ae1 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/help/comparer.fsx +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/help/comparer.fsx @@ -17,8 +17,8 @@ let f2 = File2List fn2 let mutable i = 0 let compare (f1:string list) (f2:string list) = List.forall2 (fun (a:string) (b:string) -> - let aa = System.Text.RegularExpressions.Regex.Replace(a, @"F# Compiler version .+", "F# 3.0 Compiler version") - let bb = System.Text.RegularExpressions.Regex.Replace(b, @"F# Compiler version .+", "F# 3.0 Compiler version") + let aa = System.Text.RegularExpressions.Regex.Replace(a, @"F# Compiler version .+", "F# Compiler") + let bb = System.Text.RegularExpressions.Regex.Replace(b, @"F# Compiler version .+", "F# Compiler") i <- i+1 if (aa = bb) then @@ -30,4 +30,4 @@ let compare (f1:string list) (f2:string list) = List.forall2 (fun (a:string) (b: false ) f1 f2 -exit (if (f1.Length = f2.Length && compare f1 f2) then 0 else 1) +exit (if (f1.Length = f2.Length && compare f1 f2) then 0 else printfn "File lengths differ"; 1) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl index 227de6e5682..1d028d6669d 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/help/help40.437.1033.bsl @@ -1,110 +1,112 @@ -Microsoft (R) F# Compiler version 12.0.50525.0 +Microsoft (R) F# Compiler version 3.0 Copyright (c) Microsoft Corporation. All Rights Reserved. - OUTPUT FILES - ---out: Name of the output file (Short form: -o) ---target:exe Build a console executable ---target:winexe Build a Windows executable ---target:library Build a library (Short form: -a) ---target:module Build a module that can be added to another - assembly ---delaysign[+|-] Delay-sign the assembly using only the public - portion of the strong name key ---publicsign[+|-] Public-sign the assembly using only the public - portion of the strong name key, and mark the - assembly as signed ---doc: Write the xmldoc of the assembly to the given - file ---keyfile: Specify a strong name key file ---keycontainer: Specify a strong name key container ---platform: Limit which platforms this code can run on: x86, - Itanium, x64, anycpu32bitpreferred, or anycpu. - The default is anycpu. ---nooptimizationdata Only include optimization information essential - for implementing inlined constructs. Inhibits - cross-module inlining but improves binary - compatibility. ---nointerfacedata Don't add a resource to the generated assembly - containing F#-specific metadata ---sig: Print the inferred interface of the assembly to - a file ---nocopyfsharpcore Don't copy FSharp.Core.dll along the produced - binaries +--out: Name of the output file (Short form: -o) +--target:exe Build a console executable +--target:winexe Build a Windows executable +--target:library Build a library (Short form: -a) +--target:module Build a module that can be added to another + assembly +--delaysign[+|-] Delay-sign the assembly using only the public + portion of the strong name key +--publicsign[+|-] Public-sign the assembly using only the public + portion of the strong name key, and mark the + assembly as signed +--doc: Write the xmldoc of the assembly to the given + file +--keyfile: Specify a strong name key file +--keycontainer: Specify a strong name key container +--platform: Limit which platforms this code can run on: x86, + Itanium, x64, anycpu32bitpreferred, or anycpu. + The default is anycpu. +--nooptimizationdata Only include optimization information essential + for implementing inlined constructs. Inhibits + cross-module inlining but improves binary + compatibility. +--nointerfacedata Don't add a resource to the generated assembly + containing F#-specific metadata +--sig: Print the inferred interface of the assembly to + a file +--nocopyfsharpcore Don't copy FSharp.Core.dll along the produced + binaries - INPUT FILES - ---reference: Reference an assembly (Short form: -r) +--reference: Reference an assembly (Short form: -r) - RESOURCES - ---win32res: Specify a Win32 resource file (.res) ---win32manifest: Specify a Win32 manifest file ---nowin32manifest Do not include the default Win32 manifest ---resource: Embed the specified managed resource ---linkresource: Link the specified resource to this assembly - where the resinfo format is [,[,public|private]] +--win32res: Specify a Win32 resource file (.res) +--win32manifest: Specify a Win32 manifest file +--nowin32manifest Do not include the default Win32 manifest +--resource: Embed the specified managed resource +--linkresource: Link the specified resource to this assembly + where the resinfo format is [,[,public|private]] - CODE GENERATION - ---debug[+|-] Emit debug information (Short form: -g) ---debug:{full|pdbonly|portable} Specify debugging type: full, portable, pdbonly. - ('full' is the default if no debuggging type - specified and enables attaching a debugger to a - running program. 'portable' is a cross-platform - format). ---optimize[+|-] Enable optimizations (Short form: -O) ---tailcalls[+|-] Enable or disable tailcalls ---crossoptimize[+|-] Enable or disable cross-module optimizations +--debug[+|-] Emit debug information (Short form: -g) +--debug:{full|pdbonly|portable|embedded} Specify debugging type: full, portable, + embedded, pdbonly. ('full' is the default if no + debuggging type specified and enables attaching + a debugger to a running program, 'portable' is a + cross-platform format, 'embedded' is a + cross-platform format embedded into the output + file). +--optimize[+|-] Enable optimizations (Short form: -O) +--tailcalls[+|-] Enable or disable tailcalls +--crossoptimize[+|-] Enable or disable cross-module optimizations - ERRORS AND WARNINGS - ---warnaserror[+|-] Report all warnings as errors ---warnaserror[+|-]: Report specific warnings as errors ---warn: Set a warning level (0-5) ---nowarn: Disable specific warning messages ---warnon: Enable specific warnings that may be off by - default ---consolecolors[+|-] Output warning and error messages in color +--warnaserror[+|-] Report all warnings as errors +--warnaserror[+|-]: Report specific warnings as errors +--warn: Set a warning level (0-5) +--nowarn: Disable specific warning messages +--warnon: Enable specific warnings that may be off by + default +--consolecolors[+|-] Output warning and error messages in color - LANGUAGE - ---checked[+|-] Generate overflow checks ---define: Define conditional compilation symbols (Short - form: -d) ---mlcompatibility Ignore ML compatibility warnings +--checked[+|-] Generate overflow checks +--define: Define conditional compilation symbols (Short + form: -d) +--mlcompatibility Ignore ML compatibility warnings - MISCELLANEOUS - ---nologo Suppress compiler copyright message ---help Display this usage message (Short form: -?) ---@ Read response file for more options +--nologo Suppress compiler copyright message +--help Display this usage message (Short form: -?) +--@ Read response file for more options - ADVANCED - ---codepage: Specify the codepage used to read source files ---utf8output Output messages in UTF-8 encoding ---fullpaths Output messages with fully qualified paths ---lib: Specify a directory for the include path which - is used to resolve source files and assemblies - (Short form: -I) ---baseaddress:
Base address for the library to be built ---noframework Do not reference the default CLI assemblies by - default ---standalone Statically link the F# library and all - referenced DLLs that depend on it into the - assembly being generated ---staticlink: Statically link the given assembly and all - referenced DLLs that depend on this assembly. - Use an assembly name e.g. mylib, not a DLL name. ---pdb: Name the output debug file ---simpleresolution Resolve assembly references using - directory-based rules rather than MSBuild - resolution ---highentropyva[+|-] Enable high-entropy ASLR ---subsystemversion: Specify subsystem version of this assembly ---targetprofile: Specify target framework profile of this - assembly. Valid values are mscorlib or netcore. - Default - mscorlib ---quotations-debug[+|-] Emit debug information in quotations +--codepage: Specify the codepage used to read source files +--utf8output Output messages in UTF-8 encoding +--fullpaths Output messages with fully qualified paths +--lib: Specify a directory for the include path which + is used to resolve source files and assemblies + (Short form: -I) +--baseaddress:
Base address for the library to be built +--noframework Do not reference the default CLI assemblies by + default +--standalone Statically link the F# library and all + referenced DLLs that depend on it into the + assembly being generated +--staticlink: Statically link the given assembly and all + referenced DLLs that depend on this assembly. + Use an assembly name e.g. mylib, not a DLL name. +--pdb: Name the output debug file +--simpleresolution Resolve assembly references using + directory-based rules rather than MSBuild + resolution +--highentropyva[+|-] Enable high-entropy ASLR +--subsystemversion: Specify subsystem version of this assembly +--targetprofile: Specify target framework profile of this + assembly. Valid values are mscorlib or netcore. + Default - mscorlib +--quotations-debug[+|-] Emit debug information in quotations diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl index 3aaba1fffc8..61dc02ef058 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/exename/help40.437.1033.bsl @@ -3,63 +3,65 @@ Usage: fsharpi [script.fsx []] - INPUT FILES - ---use: Use the given file on startup as initial input ---load: #load the given file on startup ---reference: Reference an assembly (Short form: -r) --- ... Treat remaining arguments as command line - arguments, accessed using fsi.CommandLineArgs +--use: Use the given file on startup as initial input +--load: #load the given file on startup +--reference: Reference an assembly (Short form: -r) +-- ... Treat remaining arguments as command line + arguments, accessed using fsi.CommandLineArgs - CODE GENERATION - ---debug[+|-] Emit debug information (Short form: -g) ---debug:{full|pdbonly|portable} Specify debugging type: full, portable, pdbonly. - ('pdbonly' is the default if no debuggging type - specified and enables attaching a debugger to a - running program. 'portable' is a cross-platform - format). ---optimize[+|-] Enable optimizations (Short form: -O) ---tailcalls[+|-] Enable or disable tailcalls ---crossoptimize[+|-] Enable or disable cross-module optimizations +--debug[+|-] Emit debug information (Short form: -g) +--debug:{full|pdbonly|portable|embedded} Specify debugging type: full, portable, + embedded, pdbonly. ('pdbonly' is the default if + no debuggging type specified and enables + attaching a debugger to a running program, + 'portable' is a cross-platform format, + 'embedded' is a cross-platform format embedded + into the output file). +--optimize[+|-] Enable optimizations (Short form: -O) +--tailcalls[+|-] Enable or disable tailcalls +--crossoptimize[+|-] Enable or disable cross-module optimizations - ERRORS AND WARNINGS - ---warnaserror[+|-] Report all warnings as errors ---warnaserror[+|-]: Report specific warnings as errors ---warn: Set a warning level (0-5) ---nowarn: Disable specific warning messages ---warnon: Enable specific warnings that may be off by - default ---consolecolors[+|-] Output warning and error messages in color +--warnaserror[+|-] Report all warnings as errors +--warnaserror[+|-]: Report specific warnings as errors +--warn: Set a warning level (0-5) +--nowarn: Disable specific warning messages +--warnon: Enable specific warnings that may be off by + default +--consolecolors[+|-] Output warning and error messages in color - LANGUAGE - ---checked[+|-] Generate overflow checks ---define: Define conditional compilation symbols (Short - form: -d) ---mlcompatibility Ignore ML compatibility warnings +--checked[+|-] Generate overflow checks +--define: Define conditional compilation symbols (Short + form: -d) +--mlcompatibility Ignore ML compatibility warnings - MISCELLANEOUS - ---nologo Suppress compiler copyright message ---help Display this usage message (Short form: -?) +--nologo Suppress compiler copyright message +--help Display this usage message (Short form: -?) - ADVANCED - ---codepage: Specify the codepage used to read source files ---utf8output Output messages in UTF-8 encoding ---fullpaths Output messages with fully qualified paths ---lib: Specify a directory for the include path which - is used to resolve source files and assemblies - (Short form: -I) ---noframework Do not reference the default CLI assemblies by - default ---exec Exit fsi after loading the files or running the - .fsx script given on the command line ---gui[+|-] Execute interactions on a Windows Forms event - loop (on by default) ---quiet Suppress fsi writing to stdout ---readline[+|-] Support TAB completion in console (on by - default) ---quotations-debug[+|-] Emit debug information in quotations ---shadowcopyreferences[+|-] Prevents references from being locked by the F# - Interactive process \ No newline at end of file +--codepage: Specify the codepage used to read source files +--utf8output Output messages in UTF-8 encoding +--fullpaths Output messages with fully qualified paths +--lib: Specify a directory for the include path which + is used to resolve source files and assemblies + (Short form: -I) +--noframework Do not reference the default CLI assemblies by + default +--exec Exit fsi after loading the files or running the + .fsx script given on the command line +--gui[+|-] Execute interactions on a Windows Forms event + loop (on by default) +--quiet Suppress fsi writing to stdout +--readline[+|-] Support TAB completion in console (on by + default) +--quotations-debug[+|-] Emit debug information in quotations +--shadowcopyreferences[+|-] Prevents references from being locked by the F# + Interactive process diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help.437.1033.bsl deleted file mode 100644 index 5afc1c8249d..00000000000 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help.437.1033.bsl +++ /dev/null @@ -1,62 +0,0 @@ -Microsoft (R) F# 2.0 Interactive build 2.0.50727.0 -Copyright (c) Microsoft Corporation. All Rights Reserved. - -Usage: fsi.exe [script.fsx []] - - - - INPUT FILES - ---use: Use the given file on startup as initial input ---load: #load the given file on startup ---reference: Reference an assembly (Short form: -r) --- ... Treat remaining arguments as command line - arguments, accessed using fsi.CommandLineArgs - - - - CODE GENERATION - ---debug[+|-] Emit debug information (Short form: -g) ---debug:{full|pdbonly|portable} Specify debugging type: full, portable, pdbonly. - ('pdbonly' is the default if no debuggging type - specified and enables attaching a debugger to a - running program. 'portable' is a cross-platform - format). ---optimize[+|-] Enable optimizations (Short form: -O) ---tailcalls[+|-] Enable or disable tailcalls ---crossoptimize[+|-] Enable or disable cross-module optimizations - - - - ERRORS AND WARNINGS - ---warnaserror[+|-] Report all warnings as errors ---warnaserror[+|-]: Report specific warnings as errors ---warn: Set a warning level (0-4) ---nowarn: Disable specific warning messages ---consolecolors[+|-] Output warning and error messages in color - - - - LANGUAGE - ---checked[+|-] Generate overflow checks ---define: Define conditional compilation symbols (Short - form: -d) ---mlcompatibility Ignore ML compatibility warnings - - - - MISCELLANEOUS - ---nologo Suppress compiler copyright message ---help Display this usage message (Short form: -?) - - - - ADVANCED - ---codepage: Specify the codepage used to read source files ---utf8output Output messages in UTF-8 encoding ---fullpaths Output messages with fully qualified paths ---lib: Specify a directory for the include path which - is used to resolve source files and assemblies - (Short form: -I) ---noframework Do not reference the default CLI assemblies by - default ---exec Exit fsi after loading the files or running the - .fsx script given on the command line ---gui[+|-] Execute interactions on a Windows Forms event - loop (on by default) ---quiet Suppress fsi writing to stdout ---readline[+|-] Support TAB completion in console (on by - default) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl index 3ffd8e94bdf..a044d368a20 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40-nologo.437.1033.bsl @@ -1,65 +1,67 @@ -Usage: Fsi.exe [script.fsx []] +Usage: fsi.exe [script.fsx []] - INPUT FILES - ---use: Use the given file on startup as initial input ---load: #load the given file on startup ---reference: Reference an assembly (Short form: -r) --- ... Treat remaining arguments as command line - arguments, accessed using fsi.CommandLineArgs +--use: Use the given file on startup as initial input +--load: #load the given file on startup +--reference: Reference an assembly (Short form: -r) +-- ... Treat remaining arguments as command line + arguments, accessed using fsi.CommandLineArgs - CODE GENERATION - ---debug[+|-] Emit debug information (Short form: -g) ---debug:{full|pdbonly|portable} Specify debugging type: full, portable, pdbonly. - ('pdbonly' is the default if no debuggging type - specified and enables attaching a debugger to a - running program. 'portable' is a cross-platform - format). ---optimize[+|-] Enable optimizations (Short form: -O) ---tailcalls[+|-] Enable or disable tailcalls ---crossoptimize[+|-] Enable or disable cross-module optimizations +--debug[+|-] Emit debug information (Short form: -g) +--debug:{full|pdbonly|portable|embedded} Specify debugging type: full, portable, + embedded, pdbonly. ('pdbonly' is the default if + no debuggging type specified and enables + attaching a debugger to a running program, + 'portable' is a cross-platform format, + 'embedded' is a cross-platform format embedded + into the output file). +--optimize[+|-] Enable optimizations (Short form: -O) +--tailcalls[+|-] Enable or disable tailcalls +--crossoptimize[+|-] Enable or disable cross-module optimizations - ERRORS AND WARNINGS - ---warnaserror[+|-] Report all warnings as errors ---warnaserror[+|-]: Report specific warnings as errors ---warn: Set a warning level (0-5) ---nowarn: Disable specific warning messages ---warnon: Enable specific warnings that may be off by - default ---consolecolors[+|-] Output warning and error messages in color +--warnaserror[+|-] Report all warnings as errors +--warnaserror[+|-]: Report specific warnings as errors +--warn: Set a warning level (0-5) +--nowarn: Disable specific warning messages +--warnon: Enable specific warnings that may be off by + default +--consolecolors[+|-] Output warning and error messages in color - LANGUAGE - ---checked[+|-] Generate overflow checks ---define: Define conditional compilation symbols (Short - form: -d) ---mlcompatibility Ignore ML compatibility warnings +--checked[+|-] Generate overflow checks +--define: Define conditional compilation symbols (Short + form: -d) +--mlcompatibility Ignore ML compatibility warnings - MISCELLANEOUS - ---nologo Suppress compiler copyright message ---help Display this usage message (Short form: -?) +--nologo Suppress compiler copyright message +--help Display this usage message (Short form: -?) - ADVANCED - ---codepage: Specify the codepage used to read source files ---utf8output Output messages in UTF-8 encoding ---fullpaths Output messages with fully qualified paths ---lib: Specify a directory for the include path which - is used to resolve source files and assemblies - (Short form: -I) ---noframework Do not reference the default CLI assemblies by - default ---exec Exit fsi after loading the files or running the - .fsx script given on the command line ---gui[+|-] Execute interactions on a Windows Forms event - loop (on by default) ---quiet Suppress fsi writing to stdout ---readline[+|-] Support TAB completion in console (on by - default) ---quotations-debug[+|-] Emit debug information in quotations ---shadowcopyreferences[+|-] Prevents references from being locked by the F# - Interactive process \ No newline at end of file +--codepage: Specify the codepage used to read source files +--utf8output Output messages in UTF-8 encoding +--fullpaths Output messages with fully qualified paths +--lib: Specify a directory for the include path which + is used to resolve source files and assemblies + (Short form: -I) +--noframework Do not reference the default CLI assemblies by + default +--exec Exit fsi after loading the files or running the + .fsx script given on the command line +--gui[+|-] Execute interactions on a Windows Forms event + loop (on by default) +--quiet Suppress fsi writing to stdout +--readline[+|-] Support TAB completion in console (on by + default) +--quotations-debug[+|-] Emit debug information in quotations +--shadowcopyreferences[+|-] Prevents references from being locked by the F# + Interactive process diff --git a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl index 722596ffd71..a0d495ad635 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl +++ b/tests/fsharpqa/Source/CompilerOptions/fsi/help/help40.437.1033.bsl @@ -1,67 +1,69 @@ -Microsoft (R) F# Interactive build 4.0.30319.17303 +Microsoft (R) F# Interactive version 4.1 Copyright (c) Microsoft Corporation. All Rights Reserved. -Usage: Fsi.exe [script.fsx []] +Usage: fsi.exe [script.fsx []] - INPUT FILES - ---use: Use the given file on startup as initial input ---load: #load the given file on startup ---reference: Reference an assembly (Short form: -r) --- ... Treat remaining arguments as command line - arguments, accessed using fsi.CommandLineArgs +--use: Use the given file on startup as initial input +--load: #load the given file on startup +--reference: Reference an assembly (Short form: -r) +-- ... Treat remaining arguments as command line + arguments, accessed using fsi.CommandLineArgs - CODE GENERATION - ---debug[+|-] Emit debug information (Short form: -g) ---debug:{full|pdbonly|portable} Specify debugging type: full, portable, pdbonly. - ('pdbonly' is the default if no debuggging type - specified and enables attaching a debugger to a - running program. 'portable' is a cross-platform - format). ---optimize[+|-] Enable optimizations (Short form: -O) ---tailcalls[+|-] Enable or disable tailcalls ---crossoptimize[+|-] Enable or disable cross-module optimizations +--debug[+|-] Emit debug information (Short form: -g) +--debug:{full|pdbonly|portable|embedded} Specify debugging type: full, portable, + embedded, pdbonly. ('pdbonly' is the default if + no debuggging type specified and enables + attaching a debugger to a running program, + 'portable' is a cross-platform format, + 'embedded' is a cross-platform format embedded + into the output file). +--optimize[+|-] Enable optimizations (Short form: -O) +--tailcalls[+|-] Enable or disable tailcalls +--crossoptimize[+|-] Enable or disable cross-module optimizations - ERRORS AND WARNINGS - ---warnaserror[+|-] Report all warnings as errors ---warnaserror[+|-]: Report specific warnings as errors ---warn: Set a warning level (0-5) ---nowarn: Disable specific warning messages ---warnon: Enable specific warnings that may be off by - default ---consolecolors[+|-] Output warning and error messages in color +--warnaserror[+|-] Report all warnings as errors +--warnaserror[+|-]: Report specific warnings as errors +--warn: Set a warning level (0-5) +--nowarn: Disable specific warning messages +--warnon: Enable specific warnings that may be off by + default +--consolecolors[+|-] Output warning and error messages in color - LANGUAGE - ---checked[+|-] Generate overflow checks ---define: Define conditional compilation symbols (Short - form: -d) ---mlcompatibility Ignore ML compatibility warnings +--checked[+|-] Generate overflow checks +--define: Define conditional compilation symbols (Short + form: -d) +--mlcompatibility Ignore ML compatibility warnings - MISCELLANEOUS - ---nologo Suppress compiler copyright message ---help Display this usage message (Short form: -?) +--nologo Suppress compiler copyright message +--help Display this usage message (Short form: -?) - ADVANCED - ---codepage: Specify the codepage used to read source files ---utf8output Output messages in UTF-8 encoding ---fullpaths Output messages with fully qualified paths ---lib: Specify a directory for the include path which - is used to resolve source files and assemblies - (Short form: -I) ---noframework Do not reference the default CLI assemblies by - default ---exec Exit fsi after loading the files or running the - .fsx script given on the command line ---gui[+|-] Execute interactions on a Windows Forms event - loop (on by default) ---quiet Suppress fsi writing to stdout ---readline[+|-] Support TAB completion in console (on by - default) ---quotations-debug[+|-] Emit debug information in quotations ---shadowcopyreferences[+|-] Prevents references from being locked by the F# - Interactive process \ No newline at end of file +--codepage: Specify the codepage used to read source files +--utf8output Output messages in UTF-8 encoding +--fullpaths Output messages with fully qualified paths +--lib: Specify a directory for the include path which + is used to resolve source files and assemblies + (Short form: -I) +--noframework Do not reference the default CLI assemblies by + default +--exec Exit fsi after loading the files or running the + .fsx script given on the command line +--gui[+|-] Execute interactions on a Windows Forms event + loop (on by default) +--quiet Suppress fsi writing to stdout +--readline[+|-] Support TAB completion in console (on by + default) +--quotations-debug[+|-] Emit debug information in quotations +--shadowcopyreferences[+|-] Prevents references from being locked by the F# + Interactive process From 34b177a4a0315d0903b48e86ce05c03517acc360 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Sat, 10 Sep 2016 01:44:12 -0700 Subject: [PATCH 3/8] Embed PDBs in the .exe --- src/absil/ilwrite.fs | 82 +++++++------- src/absil/ilwritepdb.fs | 100 ++++++++++++------ src/absil/ilwritepdb.fsi | 15 ++- .../FSharp.Compiler/FSharp.Compiler.fsproj | 2 +- 4 files changed, 127 insertions(+), 72 deletions(-) diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index acbef818ae7..4248c280e97 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -3054,10 +3054,6 @@ let generateIL requiredDataFixups (desiredMetadataVersion,generatePdb, ilg : ILG //===================================================================== // TABLES+BLOBS --> PHYSICAL METADATA+BLOBS //===================================================================== -type BinaryChunk = - { size: int32 - addr: int32 } - let chunk sz next = ({addr=next; size=sz},next + sz) let nochunk next = ({addr= 0x0;size= 0x0; } ,next) @@ -3590,7 +3586,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: with e -> failwith ("Could not open file for writing (binary mode): " + outfile) - let pdbData,pdbOpt,debugDirectoryChunk,debugDataChunk,textV2P,mappings = + let pdbData,pdbOpt,debugDirectoryChunk,debugDataChunk,debugEmbeddedPdbChunk,textV2P,mappings = try let imageBaseReal = modul.ImageBase // FIXED CHOICE @@ -3694,9 +3690,11 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: let pdbOpt = match portablePDB with - | true -> Some (generatePortablePdb fixupOverlappingSequencePoints showTimes pdbData) + | true -> + let struct (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints showTimes pdbData + if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream) + else Some (pdbStream) | _ -> None - let debugDirectoryChunk,next = chunk (if pdbfile = None then 0x0 @@ -3712,17 +3710,19 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: let debugDataJustInCase = 40 let debugDataChunk,next = chunk (align 0x4 (match pdbfile with - | None -> 0x0 + | None -> 0 | Some f -> (24 + System.Text.Encoding.Unicode.GetByteCount(f) // See bug 748444 + debugDataJustInCase))) next -// let debugEmbeddedPdbChunk,next = -// chunk (align 0x4 (match embeddedPDB with -// | None -> 0x0 -// | Some f -> (24 -// + System.Text.Encoding.Unicode.GetByteCount(f) // See bug 748444 -// + debugDataJustInCase))) next + let debugEmbeddedPdbChunk,next = + let streamLength = + match pdbOpt with + | Some struct (_,_,stream) -> int(stream.Length) + | None -> 0 + chunk (align 0x4 (match embeddedPDB with + | true -> 8 + streamLength + | _ -> 0 )) next let textSectionSize = next - textSectionAddr let nextPhys = align alignPhys (textSectionPhysLoc + textSectionSize) @@ -4112,11 +4112,14 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: if isItanium then write (Some (textV2P globalpointerCodeChunk.addr)) os " itanium global pointer" [| 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy; 0x0uy |] - + if pdbfile.IsSome then - write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create sizeof_IMAGE_DEBUG_DIRECTORY 0x0uy) + write (Some (textV2P debugDirectoryChunk.addr)) os "debug directory" (Array.create debugDirectoryChunk.size 0x0uy) write (Some (textV2P debugDataChunk.addr)) os "debug data" (Array.create debugDataChunk.size 0x0uy) - + + if embeddedPDB then + write (Some (textV2P debugEmbeddedPdbChunk.addr)) os "debug data" (Array.create debugEmbeddedPdbChunk.size 0x0uy) + writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize) // DATA SECTION @@ -4163,7 +4166,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: FileSystemUtilites.setExecutablePermission outfile with _ -> () - pdbData,pdbOpt,debugDirectoryChunk,debugDataChunk,textV2P,mappings + pdbData,pdbOpt,debugDirectoryChunk,debugDataChunk,debugEmbeddedPdbChunk,textV2P,mappings // Looks like a finally with e -> @@ -4188,10 +4191,15 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: try let idd = match pdbOpt with - | Some struct(contentId, stream) -> - writePortablePdbInfo contentId stream showTimes fpdb + | Some struct(originalLength, contentId, stream) -> + if embeddedPDB then + printfn "Embedded" + embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk + else + printfn "Portable" + writePortablePdbInfo contentId stream showTimes fpdb debugDataChunk | None -> - writePdbInfo fixupOverlappingSequencePoints showTimes outfile fpdb pdbData + writePdbInfo fixupOverlappingSequencePoints showTimes outfile fpdb pdbData debugDataChunk reportTime showTimes "Generate PDB Info" // Now we have the debug data we can go back and fill in the debug directory in the image @@ -4200,19 +4208,22 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: try // write the IMAGE_DEBUG_DIRECTORY os2.BaseStream.Seek (int64 (textV2P debugDirectoryChunk.addr), SeekOrigin.Begin) |> ignore - writeInt32 os2 idd.iddCharacteristics // IMAGE_DEBUG_DIRECTORY.Characteristics - writeInt32 os2 idd.iddTimestamp - writeInt32AsUInt16 os2 idd.iddMajorVersion - writeInt32AsUInt16 os2 idd.iddMinorVersion - writeInt32 os2 idd.iddType - writeInt32 os2 idd.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData - writeInt32 os2 debugDataChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData - writeInt32 os2 (textV2P debugDataChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData - - // write the debug raw data as given us by the PDB writer - os2.BaseStream.Seek (int64 (textV2P debugDataChunk.addr), SeekOrigin.Begin) |> ignore - if debugDataChunk.size < idd.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable" - writeBytes os2 idd.iddData + for i in idd do + writeInt32 os2 i.iddCharacteristics // IMAGE_DEBUG_DIRECTORY.Characteristics + writeInt32 os2 i.iddTimestamp + writeInt32AsUInt16 os2 i.iddMajorVersion + writeInt32AsUInt16 os2 i.iddMinorVersion + writeInt32 os2 i.iddType + writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData + writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData + writeInt32 os2 (textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData + + // Write the Debug Data + for i in idd do + // write the debug raw data as given us by the PDB writer + os2.BaseStream.Seek (int64 (textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore + if i.iddChunk.size < i.iddData.Length then failwith "Debug data area is not big enough. Debug info may not be usable" + writeBytes os2 i.iddData os2.Dispose() with e -> failwith ("Error while writing debug directory entry: "+e.Message) @@ -4223,6 +4234,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: end ignore debugDataChunk + ignore debugEmbeddedPdbChunk reportTime showTimes "Finalize PDB" /// Sign the binary. No further changes to binary allowed past this point! @@ -4242,7 +4254,6 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: //Finished writing and signing the binary and debug info... mappings - type options = { ilg: ILGlobals; pdbfile: string option @@ -4254,7 +4265,6 @@ type options = showTimes: bool dumpDebugInfo:bool } - let WriteILBinary (outfile, (args: options), modul, noDebugData) = ignore (writeBinaryAndReportMappings (outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB, args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes, diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index 5822b737324..e759ca3c1ab 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -6,6 +6,7 @@ open System open System.Collections.Generic open System.Collections.Immutable open System.IO +open System.IO.Compression open System.Reflection open System.Reflection.Metadata open System.Reflection.Metadata.Ecma335 @@ -86,9 +87,9 @@ type PdbData = Methods: PdbMethodData[] TableRowCounts: int[] } -//--------------------------------------------------------------------- -// Portable PDB Writer -//--------------------------------------------------------------------- +type BinaryChunk = + { size: int32 + addr: int32 } type idd = { iddCharacteristics: int32; @@ -96,34 +97,60 @@ type idd = iddMinorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) iddType: int32; iddTimestamp: int32; - iddData: byte[];} + iddData: byte[]; + iddChunk: BinaryChunk } -let magicNumber = 0x53445352L -let pdbGetDebugInfo (mvid:byte[]) (timestamp:int32) (filepath:string) = - let iddDataBuffer = +//--------------------------------------------------------------------- +// Portable PDB Writer +//--------------------------------------------------------------------- +let cvMagicNumber = 0x53445352L +let pdbGetCvDebugInfo (mvid:byte[]) (timestamp:int32) (filepath:string) (cvChunk:BinaryChunk) = + let iddCvBuffer = + // Debug directory entry let path = (System.Text.Encoding.UTF8.GetBytes filepath) let buffer = Array.zeroCreate (sizeof + mvid.Length + sizeof + path.Length + 1) - let struct (offset, size) = struct(0, sizeof) // Magic Number RSDS dword: 0x53445352L - Buffer.BlockCopy(BitConverter.GetBytes(magicNumber), 0, buffer, offset, size) - + Buffer.BlockCopy(BitConverter.GetBytes(cvMagicNumber), 0, buffer, offset, size) let struct (offset, size) = struct (offset + size, mvid.Length) // mvid Guid Buffer.BlockCopy(mvid, 0, buffer, offset, size) - let struct (offset, size) = struct (offset + size, sizeof) // # of pdb files generated (1) Buffer.BlockCopy(BitConverter.GetBytes(1), 0, buffer, offset, size) - let struct (offset, size) = struct (offset + size, path.Length) // Path to pdb string Buffer.BlockCopy(path, 0, buffer, offset, size) - buffer - - { iddCharacteristics = 0x0; // Reserved - iddMajorVersion = 0x0; // VersionMajor should be 0 - iddMinorVersion = 0x0; // VersionMinor should be 0 - iddType = 0x2; // IMAGE_DEBUG_TYPE_CODEVIEW + { iddCharacteristics = 0; // Reserved + iddMajorVersion = 0; // VersionMajor should be 0 + iddMinorVersion = 0; // VersionMinor should be 0 + iddType = 2; // IMAGE_DEBUG_TYPE_CODEVIEW iddTimestamp = timestamp; - iddData = iddDataBuffer } // Path name to the pdb file when built + iddData = iddCvBuffer; // Path name to the pdb file when built + iddChunk = cvChunk; + } + +let pdbMagicNumber= 0x4244504dL +let pdbGetPdbDebugInfo (embeddedPDBChunk:BinaryChunk) (uncompressedLength:int64) (stream:MemoryStream) = + let iddPdbBuffer = + let buffer = Array.zeroCreate (sizeof + sizeof + int(stream.Length)) + let struct (offset, size) = struct(0, sizeof) // Magic Number dword: 0x4244504dL + Buffer.BlockCopy(BitConverter.GetBytes(pdbMagicNumber), 0, buffer, offset, size) + let struct (offset, size) = struct(offset + size, sizeof) // Uncompressed size + Buffer.BlockCopy(BitConverter.GetBytes((int uncompressedLength)), 0, buffer, offset, size) + let struct (offset, size) = struct(offset + size, int(stream.Length)) // Uncompressed size + Buffer.BlockCopy(stream.ToArray(), 0, buffer, offset, size) + buffer + { iddCharacteristics = 0; // Reserved + iddMajorVersion = 0; // VersionMajor should be 0 + iddMinorVersion = 0x0100; // VersionMinor should be 0 + iddType = 17; // IMAGE_DEBUG_TYPE_EMBEDDEDPDB + iddTimestamp = 0; + iddData = iddPdbBuffer; // Path name to the pdb file when built + iddChunk = embeddedPDBChunk; + } + +let pdbGetDebugInfo (mvid:byte[]) (timestamp:int32) (filepath:string) (cvChunk:BinaryChunk) (embeddedPDBChunk:BinaryChunk option) (uncompressedLength:int64) (stream:MemoryStream option)= + match stream, embeddedPDBChunk with + | None, _ | _,None -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk |] + | Some s, Some chunk -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk; pdbGetPdbDebugInfo chunk uncompressedLength s; |] // Document checksum algorithms let guidSourceHashMD5 = System.Guid(0x406ea660u, 0x64cfus, 0x4c82us, 0xb6uy, 0xf0uy, 0x42uy, 0xd4uy, 0x81uy, 0x72uy, 0xa7uy, 0x99uy) //406ea660-64cf-4c82-b6f0-42d48172a799 @@ -201,7 +228,6 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = spCounts, allSps let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = - sortMethods showTimes info let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods let externalRowCounts = getRowCounts info.TableRowCounts @@ -363,17 +389,28 @@ let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = let serializer = PortablePdbBuilder(metadata, externalRowCounts, entryPoint, null) let blobBuilder = new BlobBuilder() let contentId= serializer.Serialize(blobBuilder) - use portablePdbStream = new MemoryStream() + let portablePdbStream = new MemoryStream() blobBuilder.WriteContentTo(portablePdbStream) reportTime showTimes "PDB: Created" - struct (contentId, portablePdbStream) + struct (portablePdbStream.Length, contentId, portablePdbStream) + +let compressPortablePdbStream (uncompressedLength:int64) (contentId:BlobContentId) (stream:MemoryStream) = + let compressedStream = new MemoryStream() + use compressionStream = new DeflateStream(compressedStream, CompressionMode.Compress,true) + stream.WriteTo(compressionStream) + struct (uncompressedLength, contentId, compressedStream) -let writePortablePdbInfo (contentId:BlobContentId) (stream:MemoryStream) showTimes fpdb = +let writePortablePdbInfo (contentId:BlobContentId) (stream:MemoryStream) showTimes fpdb cvChunk = try FileSystem.FileDelete fpdb with _ -> () use pdbFile = new FileStream(fpdb, FileMode.Create, FileAccess.ReadWrite) stream.WriteTo(pdbFile) reportTime showTimes "PDB: Closed" - pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32(contentId.Stamp)) fpdb + pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fpdb cvChunk None 0L None + +let embedPortablePdbInfo (uncompressedLength:int64) (contentId:BlobContentId) (stream:MemoryStream) showTimes fpdb cvChunk pdbChunk = + reportTime showTimes "PDB: Closed" + let fn = Path.GetFileName(fpdb) + pdbGetDebugInfo (contentId.Guid.ToByteArray()) (int32 (contentId.Stamp)) fn cvChunk (Some pdbChunk) uncompressedLength (Some stream) #if FX_NO_PDB_WRITER #else @@ -381,7 +418,7 @@ let writePortablePdbInfo (contentId:BlobContentId) (stream:MemoryStream) showTim // PDB Writer. The function [WritePdbInfo] abstracts the // imperative calls to the Symbol Writer API. //--------------------------------------------------------------------- -let writePdbInfo fixupOverlappingSequencePoints showTimes f fpdb info = +let writePdbInfo fixupOverlappingSequencePoints showTimes f fpdb info cvChunk = try FileSystem.FileDelete fpdb with _ -> () @@ -490,12 +527,13 @@ let writePdbInfo fixupOverlappingSequencePoints showTimes f fpdb info = pdbClose !pdbw f fpdb; reportTime showTimes "PDB: Closed" - { iddCharacteristics = res.iddCharacteristics; - iddMajorVersion = res.iddMajorVersion; - iddMinorVersion = res.iddMinorVersion; - iddType = res.iddType; - iddTimestamp = info.Timestamp; - iddData = res.iddData} + [| { iddCharacteristics = res.iddCharacteristics; + iddMajorVersion = res.iddMajorVersion; + iddMinorVersion = res.iddMinorVersion; + iddType = res.iddType; + iddTimestamp = info.Timestamp; + iddData = res.iddData + iddChunk = cvChunk } |] #endif #if ENABLE_MONO_SUPPORT diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi index a5468483267..1baf1d4b98c 100644 --- a/src/absil/ilwritepdb.fsi +++ b/src/absil/ilwritepdb.fsi @@ -69,17 +69,24 @@ val logDebugInfo : string -> PdbData -> unit val writeMdbInfo<'a> : string -> string -> PdbData -> 'a #endif +type BinaryChunk = + { size: int32 + addr: int32 } + type idd = { iddCharacteristics: int32; iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) iddMinorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) iddType: int32; iddTimestamp: int32; - iddData: byte[]; } + iddData: byte[]; + iddChunk: BinaryChunk } -val generatePortablePdb : fixupSPs:bool -> showTimes:bool -> info:PdbData -> struct (BlobContentId * MemoryStream) -val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> idd +val generatePortablePdb : fixupSPs:bool -> showTimes:bool -> info:PdbData -> struct (int64 * BlobContentId * MemoryStream) +val compressPortablePdbStream : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> struct (int64 * BlobContentId * MemoryStream) +val embedPortablePdbInfo : uncompressedLength:int64 -> contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> pdbChunk:BinaryChunk -> idd[] +val writePortablePdbInfo : contentId:BlobContentId -> stream:MemoryStream -> showTimes:bool -> fpdb:string -> cvChunk:BinaryChunk -> idd[] #if !FX_NO_PDB_WRITER -val writePdbInfo : fixupOverlappingSequencePoints:bool -> showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> idd +val writePdbInfo : fixupOverlappingSequencePoints:bool -> showTimes:bool -> f:string -> fpdb:string -> info:PdbData -> cvChunk:BinaryChunk -> idd[] #endif diff --git a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj index 24d87a98c01..da37aa76f7d 100644 --- a/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj +++ b/src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj @@ -528,7 +528,7 @@ ..\..\..\packages\Microsoft.DiaSymReader.1.0.8\lib\portable-net45+win8\Microsoft.DiaSymReader.dll ..\..\..\packages\System.Reflection.Metadata.1.4.1-beta-24227-04\lib\portable-net45+win8\System.Reflection.Metadata.dll ..\..\..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - ..\..\..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dllfalse + ..\..\..\packages\System.ValueTuple.4.0.0-rc3-24212-01\lib\netstandard1.1\System.ValueTuple.dlltrue From 3931ad022ad1a7b67673b3573607f50c00417073 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Sun, 11 Sep 2016 13:01:23 -0700 Subject: [PATCH 4/8] Enable embedded portable pdbs --- src/absil/ilwrite.fs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index 4248c280e97..a26cbe33aca 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -4199,7 +4199,11 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: printfn "Portable" writePortablePdbInfo contentId stream showTimes fpdb debugDataChunk | None -> +#if FX_NO_PDB_WRITER + Array.empty +#else writePdbInfo fixupOverlappingSequencePoints showTimes outfile fpdb pdbData debugDataChunk +#endif reportTime showTimes "Generate PDB Info" // Now we have the debug data we can go back and fill in the debug directory in the image From 921346840a6011c385ea6c1de1ed97875a06ebb7 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Sun, 11 Sep 2016 18:26:49 -0700 Subject: [PATCH 5/8] Update fsharp.build.dll to understand embedded --- lkg/FSharp-14.0.23413.0/bin/FSharp.Build.dll | Bin 55808 -> 56320 bytes src/fsharp/FSharp.Build/Fsc.fs | 1 + 2 files changed, 1 insertion(+) diff --git a/lkg/FSharp-14.0.23413.0/bin/FSharp.Build.dll b/lkg/FSharp-14.0.23413.0/bin/FSharp.Build.dll index b0f401edb503dc1dc814aa9b3671ff6861384532..e8d1b6f4612ca380fa91348c8fa815bfe9847f2b 100644 GIT binary patch delta 13689 zcmbt*d0B5@s-F*iOYzt zTtLJGi@Np_eKCb-^P@zX(Znjcrb|ySw%_=dyo_}jODqO^%J{ow1Uu5zVErRwHyR;( z8@t(Pw|`mq2$8K`NgpCwMYXQPBV9|Chn%e4VBT8RVAOjnuHIUWng;m2mfA9h$D(*F zk2ZoxH4{1a@{q?;GT&?QSR8kE4mss;NwUSddIPeaw{3)7Jsmo)m29aQaMJIip6F0C z+-D1HMZqfl9;?yqy*TT&oLagj0mf_d*lxUtJ9dw~uFYdl&EY8&k8fh?@L|DkGhK^V|H=1Pv`ygC2-Db zc`k3GgLWF*ix*bfeKc}47%Ahz`AIFrVJ>?*!e~`uIQ%+`k80-{g??W)X-`k>p_TMP z_*7eGPp|AlW(8SdPjBx-?i8ftqf`l6ftoz1sZO<}_aTr9aE@vj+0xy>QU-0bcl#aE$INIc4PW^zQ_ZK|j|+E9w6cWEDo8$@!#8+5w+xG3uT^WK1^R zE2&^j#@N!JY)elvN=hqP2hhc_t8ij5Eq&y*+tMi<0C|)?Rp69@k}?%Y zXU;EMdZl0n_ApYWl2?Y)e-9%0DZ=OGKB27Yqcj!G41WUu! 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 delta 13310 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 PeSAd1w-M*x|1 null | "PORTABLE" -> "portable" | "PDBONLY" -> "pdbonly" + | "EMBEDDED" -> "embedded" | "FULL" -> "full" | _ -> null) // NoFramework From ec31f55231e3e025e3768b28786ec5efdf7b2414 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Sun, 11 Sep 2016 22:00:42 -0700 Subject: [PATCH 6/8] Clean up --- src/absil/ilwrite.fs | 2 -- src/absil/ilwritepdb.fs | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/absil/ilwrite.fs b/src/absil/ilwrite.fs index a26cbe33aca..966de947a05 100644 --- a/src/absil/ilwrite.fs +++ b/src/absil/ilwrite.fs @@ -4193,10 +4193,8 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer: match pdbOpt with | Some struct(originalLength, contentId, stream) -> if embeddedPDB then - printfn "Embedded" embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk else - printfn "Portable" writePortablePdbInfo contentId stream showTimes fpdb debugDataChunk | None -> #if FX_NO_PDB_WRITER diff --git a/src/absil/ilwritepdb.fs b/src/absil/ilwritepdb.fs index e759ca3c1ab..1b82f9352dd 100644 --- a/src/absil/ilwritepdb.fs +++ b/src/absil/ilwritepdb.fs @@ -140,7 +140,7 @@ let pdbGetPdbDebugInfo (embeddedPDBChunk:BinaryChunk) (uncompressedLength:int64) buffer { iddCharacteristics = 0; // Reserved iddMajorVersion = 0; // VersionMajor should be 0 - iddMinorVersion = 0x0100; // VersionMinor should be 0 + iddMinorVersion = 0x0100; // VersionMinor should be 0x0100 iddType = 17; // IMAGE_DEBUG_TYPE_EMBEDDEDPDB iddTimestamp = 0; iddData = iddPdbBuffer; // Path name to the pdb file when built @@ -149,7 +149,7 @@ let pdbGetPdbDebugInfo (embeddedPDBChunk:BinaryChunk) (uncompressedLength:int64) let pdbGetDebugInfo (mvid:byte[]) (timestamp:int32) (filepath:string) (cvChunk:BinaryChunk) (embeddedPDBChunk:BinaryChunk option) (uncompressedLength:int64) (stream:MemoryStream option)= match stream, embeddedPDBChunk with - | None, _ | _,None -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk |] + | None, _ | _, None -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk |] | Some s, Some chunk -> [| pdbGetCvDebugInfo mvid timestamp filepath cvChunk; pdbGetPdbDebugInfo chunk uncompressedLength s; |] // Document checksum algorithms @@ -227,7 +227,7 @@ let fixupOverlappingSequencePoints fixupSPs showTimes methods = Array.sortInPlaceBy fst allSps spCounts, allSps -let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = +let generatePortablePdb fixupSPs showTimes (info:PdbData) = sortMethods showTimes info let _spCounts, _allSps = fixupOverlappingSequencePoints fixupSPs showTimes info.Methods let externalRowCounts = getRowCounts info.TableRowCounts @@ -360,18 +360,18 @@ let generatePortablePdb (fixupSPs:bool) showTimes (info:PdbData) = let rec writePdbScope scope = if scope.Children.Length = 0 then metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), - Unchecked.defaultof, - nextHandle lastLocalVariableHandle, - Unchecked.defaultof, - 0, - scope.EndOffset - scope.StartOffset) |>ignore + Unchecked.defaultof, + nextHandle lastLocalVariableHandle, + Unchecked.defaultof, + 0, + scope.EndOffset - scope.StartOffset) |>ignore else metadata.AddLocalScope(MetadataTokens.MethodDefinitionHandle(minfo.MethToken), - Unchecked.defaultof, - nextHandle lastLocalVariableHandle, - Unchecked.defaultof, - scope.StartOffset, - scope.EndOffset - scope.StartOffset) |>ignore + Unchecked.defaultof, + nextHandle lastLocalVariableHandle, + Unchecked.defaultof, + scope.StartOffset, + scope.EndOffset - scope.StartOffset) |>ignore for localVariable in scope.Locals do lastLocalVariableHandle <- metadata.AddLocalVariable(LocalVariableAttributes.None, localVariable.Index, metadata.GetOrAddString(localVariable.Name)) From 992aa7a944ed62b7aae93311f030278d16a99d29 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 12 Sep 2016 14:36:25 -0700 Subject: [PATCH 7/8] Move BinaryChunk to ilwrite.fsi --- src/absil/ilwrite.fsi | 4 ++++ src/absil/ilwritepdb.fsi | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi index 51d1842b208..54be8089db7 100644 --- a/src/absil/ilwrite.fsi +++ b/src/absil/ilwrite.fsi @@ -26,5 +26,9 @@ type options = showTimes : bool dumpDebugInfo : bool } +type BinaryChunk = + { size: int32 + addr: int32 } + /// Write a binary to the file system. Extra configuration parameters can also be specified. val WriteILBinary: filename: string * options: options * input: ILModuleDef * noDebugData: bool -> unit diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi index 1baf1d4b98c..9c2735dead4 100644 --- a/src/absil/ilwritepdb.fsi +++ b/src/absil/ilwritepdb.fsi @@ -69,10 +69,6 @@ val logDebugInfo : string -> PdbData -> unit val writeMdbInfo<'a> : string -> string -> PdbData -> 'a #endif -type BinaryChunk = - { size: int32 - addr: int32 } - type idd = { iddCharacteristics: int32; iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *) From d98750d143e7cce1669c5b7dca84505be49babf1 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 12 Sep 2016 14:43:21 -0700 Subject: [PATCH 8/8] Revert "Move BinaryChunk to ilwrite.fsi" This reverts commit 992aa7a944ed62b7aae93311f030278d16a99d29. --- src/absil/ilwrite.fsi | 4 ---- src/absil/ilwritepdb.fsi | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/absil/ilwrite.fsi b/src/absil/ilwrite.fsi index 54be8089db7..51d1842b208 100644 --- a/src/absil/ilwrite.fsi +++ b/src/absil/ilwrite.fsi @@ -26,9 +26,5 @@ type options = showTimes : bool dumpDebugInfo : bool } -type BinaryChunk = - { size: int32 - addr: int32 } - /// Write a binary to the file system. Extra configuration parameters can also be specified. val WriteILBinary: filename: string * options: options * input: ILModuleDef * noDebugData: bool -> unit diff --git a/src/absil/ilwritepdb.fsi b/src/absil/ilwritepdb.fsi index 9c2735dead4..1baf1d4b98c 100644 --- a/src/absil/ilwritepdb.fsi +++ b/src/absil/ilwritepdb.fsi @@ -69,6 +69,10 @@ val logDebugInfo : string -> PdbData -> unit val writeMdbInfo<'a> : string -> string -> PdbData -> 'a #endif +type BinaryChunk = + { size: int32 + addr: int32 } + type idd = { iddCharacteristics: int32; iddMajorVersion: int32; (* actually u16 in IMAGE_DEBUG_DIRECTORY *)