Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit f225f12

Browse files
matthidnosami
authored andcommitted
Fix dotnet#3113 by porting the relevant roslyn codeand integrate it into the codebase (dotnet#7024)
1 parent ec99412 commit f225f12

File tree

12 files changed

+1065
-42
lines changed

12 files changed

+1065
-42
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ source_link.json
119119
.vs/
120120
System.ValueTuple.dll
121121
tests/fsharpqa/testenv/bin/System.ValueTuple.dll
122-
*/.fake
122+
**/.fake
123+
.ionide
123124
/fcs/packages/
124125
*/paket-files/
125126
/fcs/TestResult.xml

fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,18 @@
230230
</Compile>
231231
</ItemGroup>
232232
<ItemGroup>
233+
<Compile Include="$(FSharpSourcesRoot)/absil/writenativeres.fsi">
234+
<Link>AbsIL/writenativeres.fsi</Link>
235+
</Compile>
236+
<Compile Include="$(FSharpSourcesRoot)/absil/writenativeres.fs">
237+
<Link>AbsIL/writenativeres.fs</Link>
238+
</Compile>
239+
<Compile Include="$(FSharpSourcesRoot)/absil/cvtres.fsi">
240+
<Link>AbsIL/cvtres.fsi</Link>
241+
</Compile>
242+
<Compile Include="$(FSharpSourcesRoot)/absil/cvtres.fs">
243+
<Link>AbsIL/cvtres.fs</Link>
244+
</Compile>
233245
<Compile Include="$(FSharpSourcesRoot)/absil/ilsupp.fsi">
234246
<Link>AbsIL/ilsupp.fsi</Link>
235247
</Compile>

src/absil/cvtres.fs

Lines changed: 723 additions & 0 deletions
Large diffs are not rendered by default.

src/absil/cvtres.fsi

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module internal FSharp.Compiler.AbstractIL.Internal.CVTres
2+
3+
open System
4+
open System.IO
5+
6+
type BYTE = System.Byte
7+
type DWORD = System.UInt32
8+
type WCHAR = System.Char
9+
type WORD = System.UInt16
10+
11+
[<Class>]
12+
type RESOURCE_STRING =
13+
member Ordinal: WORD with get, set
14+
member theString : string with get, set
15+
16+
[<Class>]
17+
type RESOURCE =
18+
member pstringType : RESOURCE_STRING with get, set
19+
member pstringName : RESOURCE_STRING with get, set
20+
member DataSize : DWORD with get, set
21+
member HeaderSize : DWORD with get, set
22+
member DataVersion : DWORD with get, set
23+
member MemoryFlags : WORD with get, set
24+
member LanguageId : WORD with get, set
25+
member Version : DWORD with get, set
26+
member Characteristics : DWORD with get, set
27+
member data : byte[] with get, set
28+
29+
[<Class>]
30+
type CvtResFile =
31+
static member ReadResFile : stream:Stream -> System.Collections.Generic.List<RESOURCE>
32+
33+
[<Class>]
34+
type Win32ResourceConversions =
35+
static member AppendIconToResourceStream : resStream:Stream * iconStream:Stream -> unit
36+
static member AppendVersionToResourceStream : resStream:Stream * isDll:System.Boolean * fileVersion:string * originalFileName:string * internalName:string * productVersion:string * assemblyVersion:Version * ?fileDescription:string * ?legalCopyright:string * ?legalTrademarks:string * ?productName:string * ?comments:string * ?companyName:string -> unit
37+
static member AppendManifestToResourceStream : resStream:Stream * manifestStream:Stream * isDll:System.Boolean -> unit

src/absil/ilread.fs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ open Internal.Utilities
2020
open Internal.Utilities.Collections
2121
open FSharp.Compiler.AbstractIL
2222
open FSharp.Compiler.AbstractIL.Internal
23-
#if !FX_NO_PDB_READER
24-
open FSharp.Compiler.AbstractIL.Internal.Support
25-
#endif
23+
open FSharp.Compiler.AbstractIL.Internal.Support
2624
open FSharp.Compiler.AbstractIL.Diagnostics
2725
open FSharp.Compiler.AbstractIL.Internal.BinaryConstants
2826
open FSharp.Compiler.AbstractIL.IL
@@ -1551,14 +1549,10 @@ let readNativeResources (pectxt: PEReader) =
15511549
[ if pectxt.nativeResourcesSize <> 0x0 && pectxt.nativeResourcesAddr <> 0x0 then
15521550
let start = pectxt.anyV2P (pectxt.fileName + ": native resources", pectxt.nativeResourcesAddr)
15531551
if pectxt.noFileOnDisk then
1554-
#if !FX_NO_LINKEDRESOURCES
15551552
let unlinkedResource =
15561553
let linkedResource = seekReadBytes (pectxt.pefile.GetView()) start pectxt.nativeResourcesSize
15571554
unlinkResource pectxt.nativeResourcesAddr linkedResource
15581555
yield ILNativeResource.Out unlinkedResource
1559-
#else
1560-
()
1561-
#endif
15621556
else
15631557
yield ILNativeResource.In (pectxt.fileName, pectxt.nativeResourcesAddr, start, pectxt.nativeResourcesSize ) ]
15641558

src/absil/ilsupp.fs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,15 @@ open System.Diagnostics.SymbolStore
2222
open System.Runtime.InteropServices
2323
open System.Runtime.CompilerServices
2424

25+
2526
let DateTime1970Jan01 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) (* ECMA Spec (Oct2002), Part II, 24.2.2 PE File Header. *)
2627
let absilWriteGetTimeStamp () = (DateTime.UtcNow - DateTime1970Jan01).TotalSeconds |> int
2728

28-
#if !FX_NO_LINKEDRESOURCES
2929
// Force inline, so GetLastWin32Error calls are immediately after interop calls as seen by FxCop under Debug build.
3030
let inline ignore _x = ()
3131

3232
// Native Resource linking/unlinking
3333
type IStream = System.Runtime.InteropServices.ComTypes.IStream
34-
#endif
3534

3635
let check _action (hresult) =
3736
if uint32 hresult >= 0x80000000ul then
@@ -56,7 +55,6 @@ let bytesToQWord ((b0: byte), (b1: byte), (b2: byte), (b3: byte), (b4: byte), (b
5655
let dwToBytes n = [| byte (n &&& 0xff) ; byte ((n >>> 8) &&& 0xff) ; byte ((n >>> 16) &&& 0xff) ; byte ((n >>> 24) &&& 0xff) |], 4
5756
let wToBytes (n: int16) = [| byte (n &&& 0xffs) ; byte ((n >>> 8) &&& 0xffs) |], 2
5857

59-
#if !FX_NO_LINKEDRESOURCES
6058
// REVIEW: factor these classes under one hierarchy, use reflection for creation from buffer and toBytes()
6159
// Though, everything I'd like to unify is static - metaclasses?
6260
type IMAGE_FILE_HEADER (m: int16, secs: int16, tds: int32, ptst: int32, nos: int32, soh: int16, c: int16) =
@@ -583,7 +581,7 @@ type ResFormatNode(tid: int32, nid: int32, lid: int32, dataOffset: int32, pbLink
583581

584582
!size
585583

586-
let linkNativeResources (unlinkedResources: byte[] list) (ulLinkedResourceBaseRVA: int32) (fileType: PEFileType) (outputFilePath: string) =
584+
let linkNativeResourcesViaCVTres (unlinkedResources: byte[] list) (ulLinkedResourceBaseRVA: int32) (fileType: PEFileType) (outputFilePath: string) =
587585
let nPEFileType = match fileType with X86 -> 0 | X64 -> 2
588586
let mutable tempResFiles: string list = []
589587
let mutable objBytes: byte[] = [||]
@@ -751,6 +749,39 @@ let linkNativeResources (unlinkedResources: byte[] list) (ulLinkedResourceBaseR
751749
// return the buffer
752750
pResBuffer
753751

752+
let linkNativeResourcesManaged (unlinkedResources: byte[] list) (ulLinkedResourceBaseRVA: int32) (fileType: PEFileType) (outputFilePath: string) =
753+
ignore fileType
754+
ignore outputFilePath
755+
756+
let resources =
757+
unlinkedResources
758+
|> Seq.map (fun s -> new MemoryStream(s))
759+
|> Seq.map (fun s ->
760+
let res = CVTres.CvtResFile.ReadResFile s
761+
s.Dispose()
762+
res)
763+
|> Seq.collect id
764+
// See MakeWin32ResourceList https://github.com/dotnet/roslyn/blob/f40b89234db51da1e1153c14af184e618504be41/src/Compilers/Core/Portable/Compilation/Compilation.cs
765+
|> Seq.map (fun r ->
766+
WriteNativeRes.Win32Resource(data = r.data, codePage = 0u, languageId = uint32 r.LanguageId,
767+
id = int (int16 r.pstringName.Ordinal), name = r.pstringName.theString,
768+
typeId = int (int16 r.pstringType.Ordinal), typeName = r.pstringType.theString))
769+
let bb = new System.Reflection.Metadata.BlobBuilder()
770+
WriteNativeRes.NativeResourceWriter.SerializeWin32Resources(bb, resources, ulLinkedResourceBaseRVA)
771+
bb.ToArray()
772+
773+
let linkNativeResources (unlinkedResources: byte[] list) (ulLinkedResourceBaseRVA: int32) (fileType: PEFileType) (outputFilePath: string) =
774+
#if ENABLE_MONO_SUPPORT
775+
if IL.runningOnMono then
776+
linkNativeResourcesManaged unlinkedResources ulLinkedResourceBaseRVA fileType outputFilePath
777+
else
778+
#endif
779+
#if !FX_NO_LINKEDRESOURCES
780+
linkNativeResourcesViaCVTres unlinkedResources ulLinkedResourceBaseRVA fileType outputFilePath
781+
#else
782+
linkNativeResourcesManaged unlinkedResources ulLinkedResourceBaseRVA fileType outputFilePath
783+
#endif
784+
754785
let unlinkResource (ulLinkedResourceBaseRVA: int32) (pbLinkedResource: byte[]) =
755786
let mutable nResNodes = 0
756787

@@ -854,7 +885,6 @@ let unlinkResource (ulLinkedResourceBaseRVA: int32) (pbLinkedResource: byte[]) =
854885
resBufferOffset <- resBufferOffset + pResNodes.[i].Save(ulLinkedResourceBaseRVA, pbLinkedResource, pResBuffer, resBufferOffset)
855886

856887
pResBuffer
857-
#endif
858888

859889
#if !FX_NO_PDB_WRITER
860890
// PDB Writing

src/absil/ilsupp.fsi

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,16 @@ open FSharp.Compiler.AbstractIL
2929
open FSharp.Compiler.AbstractIL.Internal
3030
open FSharp.Compiler.AbstractIL.IL
3131

32-
#if !FX_NO_LINKEDRESOURCES
3332
type IStream = System.Runtime.InteropServices.ComTypes.IStream
34-
#endif
3533

3634
/// Unmanaged resource file linker - for native resources (not managed ones).
3735
/// The function may be called twice, once with a zero-RVA and
3836
/// arbitrary buffer, and once with the real buffer. The size of the
3937
/// required buffer is returned.
4038
type PEFileType = X86 | X64
4139

42-
#if !FX_NO_LINKEDRESOURCES
4340
val linkNativeResources: unlinkedResources:byte[] list -> rva:int32 -> PEFileType -> tempFilePath:string -> byte[]
4441
val unlinkResource: int32 -> byte[] -> byte[]
45-
#endif
4642

4743
#if !FX_NO_PDB_WRITER
4844
/// PDB reader and associated types

src/absil/ilwrite.fs

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,28 +3741,18 @@ let writeBinaryAndReportMappings (outfile,
37413741
match modul.NativeResources with
37423742
| [] -> [||]
37433743
| resources ->
3744-
#if ENABLE_MONO_SUPPORT
3745-
if runningOnMono then
3746-
[||]
3747-
else
3748-
#endif
3749-
#if FX_NO_LINKEDRESOURCES
3750-
ignore resources
3751-
ignore resourceFormat
3752-
[||]
3753-
#else
3754-
let unlinkedResources =
3755-
resources |> List.map (function
3756-
| ILNativeResource.Out bytes -> bytes
3757-
| ILNativeResource.In (fileName, linkedResourceBase, start, len) ->
3758-
let linkedResource = File.ReadBinaryChunk (fileName, start, len)
3759-
unlinkResource linkedResourceBase linkedResource)
3760-
3761-
begin
3762-
try linkNativeResources unlinkedResources next resourceFormat (Path.GetDirectoryName outfile)
3763-
with e -> failwith ("Linking a native resource failed: "+e.Message+"")
3764-
end
3765-
#endif
3744+
let unlinkedResources =
3745+
resources |> List.map (function
3746+
| ILNativeResource.Out bytes -> bytes
3747+
| ILNativeResource.In (fileName, linkedResourceBase, start, len) ->
3748+
let linkedResource = File.ReadBinaryChunk (fileName, start, len)
3749+
unlinkResource linkedResourceBase linkedResource)
3750+
3751+
begin
3752+
try linkNativeResources unlinkedResources next resourceFormat (Path.GetDirectoryName outfile)
3753+
with e -> failwith ("Linking a native resource failed: "+e.Message+"")
3754+
end
3755+
37663756
let nativeResourcesSize = nativeResources.Length
37673757

37683758
let nativeResourcesChunk, next = chunk nativeResourcesSize next
@@ -4166,14 +4156,12 @@ let writeBinaryAndReportMappings (outfile,
41664156

41674157
writePadding os "end of .text" (dataSectionPhysLoc - textSectionPhysLoc - textSectionSize)
41684158

4169-
// DATA SECTION
4170-
#if !FX_NO_LINKEDRESOURCES
4159+
// DATA SECTION
41714160
match nativeResources with
41724161
| [||] -> ()
41734162
| resources ->
41744163
write (Some (dataSectionVirtToPhys nativeResourcesChunk.addr)) os "raw native resources" [| |]
41754164
writeBytes os resources
4176-
#endif
41774165

41784166
if dummydatap.size <> 0x0 then
41794167
write (Some (dataSectionVirtToPhys dummydatap.addr)) os "dummy data" [| 0x0uy |]

0 commit comments

Comments
 (0)