@@ -3054,10 +3054,6 @@ let generateIL requiredDataFixups (desiredMetadataVersion,generatePdb, ilg : ILG
30543054//=====================================================================
30553055// TABLES+BLOBS --> PHYSICAL METADATA+BLOBS
30563056//=====================================================================
3057- type BinaryChunk =
3058- { size: int32
3059- addr: int32 }
3060-
30613057let chunk sz next = ({ addr= next; size= sz}, next + sz)
30623058let nochunk next = ({ addr= 0x0 ; size= 0x0 ; } , next)
30633059
@@ -3541,7 +3537,7 @@ let writeDirectory os dict =
35413537
35423538let writeBytes ( os : BinaryWriter ) ( chunk : byte []) = os.Write( chunk, 0 , chunk.Length)
35433539
3544- let writeBinaryAndReportMappings ( outfile , ilg , pdbfile : string option , signer : ILStrongNameSigner option , portablePDB ,
3540+ let writeBinaryAndReportMappings ( outfile , ilg , pdbfile : string option , signer : ILStrongNameSigner option , portablePDB , embeddedPDB ,
35453541 fixupOverlappingSequencePoints , emitTailcalls , showTimes , dumpDebugInfo ) modul noDebugData =
35463542 // Store the public key from the signer into the manifest. This means it will be written
35473543 // to the binary and also acts as an indicator to leave space for delay sign
@@ -3590,7 +3586,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
35903586 with e ->
35913587 failwith ( " Could not open file for writing (binary mode): " + outfile)
35923588
3593- let pdbData , debugDirectoryChunk , debugDataChunk , textV2P , mappings =
3589+ let pdbData , pdbOpt , debugDirectoryChunk , debugDataChunk , debugEmbeddedPdbChunk , textV2P , mappings =
35943590 try
35953591
35963592 let imageBaseReal = modul.ImageBase // FIXED CHOICE
@@ -3683,28 +3679,50 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
36833679 let importLookupTableChunk , next = chunk 0x14 next
36843680 let importNameHintTableChunk , next = chunk 0x0e next
36853681 let mscoreeStringChunk , next = chunk 0x0c next
3686-
3682+
36873683 let next = align 0x10 ( next + 0x05 ) - 0x05
36883684 let importTableChunk = { addr= importTableChunk.addr; size = next - importTableChunk.addr}
36893685 let importTableChunkPadding = importTableChunk.size - ( 0x28 + 0x14 + 0x0e + 0x0c )
36903686
36913687 let next = next + 0x03
36923688 let entrypointCodeChunk , next = chunk 0x06 next
36933689 let globalpointerCodeChunk , next = chunk ( if isItanium then 0x8 else 0x0 ) next
3694-
3695- let debugDirectoryChunk , next = chunk ( if pdbfile = None then 0x0 else sizeof_ IMAGE_ DEBUG_ DIRECTORY) next
3690+
3691+ let pdbOpt =
3692+ match portablePDB with
3693+ | true ->
3694+ let struct ( uncompressedLength , contentId , stream ) as pdbStream = generatePortablePdb fixupOverlappingSequencePoints showTimes pdbData
3695+ if embeddedPDB then Some ( compressPortablePdbStream uncompressedLength contentId stream)
3696+ else Some ( pdbStream)
3697+ | _ -> None
3698+ let debugDirectoryChunk , next =
3699+ chunk ( if pdbfile = None then
3700+ 0x0
3701+ else if embeddedPDB && portablePDB then
3702+ sizeof_ IMAGE_ DEBUG_ DIRECTORY * 2
3703+ else
3704+ sizeof_ IMAGE_ DEBUG_ DIRECTORY
3705+ ) next
36963706 // The debug data is given to us by the PDB writer and appears to
36973707 // typically be the type of the data plus the PDB file name. We fill
36983708 // this in after we've written the binary. We approximate the size according
36993709 // to what PDB writers seem to require and leave extra space just in case...
37003710 let debugDataJustInCase = 40
37013711 let debugDataChunk , next =
37023712 chunk ( align 0x4 ( match pdbfile with
3703- | None -> 0x0
3713+ | None -> 0
37043714 | Some f -> ( 24
37053715 + System.Text.Encoding.Unicode.GetByteCount( f) // See bug 748444
37063716 + debugDataJustInCase))) next
37073717
3718+ let debugEmbeddedPdbChunk , next =
3719+ let streamLength =
3720+ match pdbOpt with
3721+ | Some struct (_,_, stream) -> int( stream.Length)
3722+ | None -> 0
3723+ chunk ( align 0x4 ( match embeddedPDB with
3724+ | true -> 8 + streamLength
3725+ | _ -> 0 )) next
37083726
37093727 let textSectionSize = next - textSectionAddr
37103728 let nextPhys = align alignPhys ( textSectionPhysLoc + textSectionSize)
@@ -4094,11 +4112,14 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
40944112 if isItanium then
40954113 write ( Some ( textV2P globalpointerCodeChunk.addr)) os " itanium global pointer"
40964114 [| 0x0 uy; 0x0 uy; 0x0 uy; 0x0 uy; 0x0 uy; 0x0 uy; 0x0 uy; 0x0 uy |]
4097-
4115+
40984116 if pdbfile.IsSome then
4099- write ( Some ( textV2P debugDirectoryChunk.addr)) os " debug directory" ( Array.create sizeof _ IMAGE _ DEBUG _ DIRECTORY 0x0 uy)
4117+ write ( Some ( textV2P debugDirectoryChunk.addr)) os " debug directory" ( Array.create debugDirectoryChunk.size 0x0 uy)
41004118 write ( Some ( textV2P debugDataChunk.addr)) os " debug data" ( Array.create debugDataChunk.size 0x0 uy)
4101-
4119+
4120+ if embeddedPDB then
4121+ write ( Some ( textV2P debugEmbeddedPdbChunk.addr)) os " debug data" ( Array.create debugEmbeddedPdbChunk.size 0x0 uy)
4122+
41024123 writePadding os " end of .text" ( dataSectionPhysLoc - textSectionPhysLoc - textSectionSize)
41034124
41044125 // DATA SECTION
@@ -4145,7 +4166,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
41454166 FileSystemUtilites.setExecutablePermission outfile
41464167 with _ ->
41474168 ()
4148- pdbData, debugDirectoryChunk, debugDataChunk, textV2P, mappings
4169+ pdbData, pdbOpt , debugDirectoryChunk, debugDataChunk, debugEmbeddedPdbChunk , textV2P, mappings
41494170
41504171 // Looks like a finally
41514172 with e ->
@@ -4169,14 +4190,17 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
41694190 | Some fpdb ->
41704191 try
41714192 let idd =
4193+ match pdbOpt with
4194+ | Some struct ( originalLength, contentId, stream) ->
4195+ if embeddedPDB then
4196+ embedPortablePdbInfo originalLength contentId stream showTimes fpdb debugDataChunk debugEmbeddedPdbChunk
4197+ else
4198+ writePortablePdbInfo contentId stream showTimes fpdb debugDataChunk
4199+ | None ->
41724200#if FX_ NO_ PDB_ WRITER
4173- ignore portablePDB
4174- writePortablePdbInfo fixupOverlappingSequencePoints showTimes fpdb pdbData
4201+ Array.empty< idd>
41754202#else
4176- if portablePDB then
4177- writePortablePdbInfo fixupOverlappingSequencePoints showTimes fpdb pdbData
4178- else
4179- writePdbInfo fixupOverlappingSequencePoints showTimes outfile fpdb pdbData
4203+ writePdbInfo fixupOverlappingSequencePoints showTimes outfile fpdb pdbData debugDataChunk
41804204#endif
41814205 reportTime showTimes " Generate PDB Info"
41824206
@@ -4186,19 +4210,22 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
41864210 try
41874211 // write the IMAGE_DEBUG_DIRECTORY
41884212 os2.BaseStream.Seek ( int64 ( textV2P debugDirectoryChunk.addr), SeekOrigin.Begin) |> ignore
4189- writeInt32 os2 idd.iddCharacteristics // IMAGE_DEBUG_DIRECTORY.Characteristics
4190- writeInt32 os2 idd.iddTimestamp
4191- writeInt32AsUInt16 os2 idd.iddMajorVersion
4192- writeInt32AsUInt16 os2 idd.iddMinorVersion
4193- writeInt32 os2 idd.iddType
4194- writeInt32 os2 idd.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData
4195- writeInt32 os2 debugDataChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
4196- writeInt32 os2 ( textV2P debugDataChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData
4197-
4198- // write the debug raw data as given us by the PDB writer
4199- os2.BaseStream.Seek ( int64 ( textV2P debugDataChunk.addr), SeekOrigin.Begin) |> ignore
4200- if debugDataChunk.size < idd.iddData.Length then failwith " Debug data area is not big enough. Debug info may not be usable"
4201- writeBytes os2 idd.iddData
4213+ for i in idd do
4214+ writeInt32 os2 i.iddCharacteristics // IMAGE_DEBUG_DIRECTORY.Characteristics
4215+ writeInt32 os2 i.iddTimestamp
4216+ writeInt32AsUInt16 os2 i.iddMajorVersion
4217+ writeInt32AsUInt16 os2 i.iddMinorVersion
4218+ writeInt32 os2 i.iddType
4219+ writeInt32 os2 i.iddData.Length // IMAGE_DEBUG_DIRECTORY.SizeOfData
4220+ writeInt32 os2 i.iddChunk.addr // IMAGE_DEBUG_DIRECTORY.AddressOfRawData
4221+ writeInt32 os2 ( textV2P i.iddChunk.addr) // IMAGE_DEBUG_DIRECTORY.PointerToRawData
4222+
4223+ // Write the Debug Data
4224+ for i in idd do
4225+ // write the debug raw data as given us by the PDB writer
4226+ os2.BaseStream.Seek ( int64 ( textV2P i.iddChunk.addr), SeekOrigin.Begin) |> ignore
4227+ if i.iddChunk.size < i.iddData.Length then failwith " Debug data area is not big enough. Debug info may not be usable"
4228+ writeBytes os2 i.iddData
42024229 os2.Dispose()
42034230 with e ->
42044231 failwith ( " Error while writing debug directory entry: " + e.Message)
@@ -4209,6 +4236,7 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
42094236
42104237 end
42114238 ignore debugDataChunk
4239+ ignore debugEmbeddedPdbChunk
42124240 reportTime showTimes " Finalize PDB"
42134241
42144242 /// Sign the binary. No further changes to binary allowed past this point!
@@ -4228,19 +4256,18 @@ let writeBinaryAndReportMappings (outfile, ilg, pdbfile: string option, signer:
42284256 //Finished writing and signing the binary and debug info...
42294257 mappings
42304258
4231-
42324259type options =
42334260 { ilg: ILGlobals ;
42344261 pdbfile: string option
42354262 portablePDB: bool
4263+ embeddedPDB: bool
42364264 signer: ILStrongNameSigner option
42374265 fixupOverlappingSequencePoints: bool
42384266 emitTailcalls : bool
42394267 showTimes: bool
42404268 dumpDebugInfo: bool }
42414269
4242-
42434270let WriteILBinary ( outfile , ( args : options ), modul , noDebugData ) =
4244- ignore ( writeBinaryAndReportMappings ( outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB,
4271+ ignore ( writeBinaryAndReportMappings ( outfile, args.ilg, args.pdbfile, args.signer, args.portablePDB, args.embeddedPDB ,
42454272 args.fixupOverlappingSequencePoints, args.emitTailcalls, args.showTimes,
42464273 args.dumpDebugInfo) modul noDebugData)
0 commit comments