Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 147 additions & 52 deletions src/absil/il.fs

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions src/absil/ilread.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3751,20 +3751,20 @@ let openPEFileReader (fileName, pefile: BinaryFile, pdbDirPath, noFileOnDisk) =
let dataSegmentAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 24) (* e.g. 0x0000c000 *)
(* REVIEW: For now, we'll use the DWORD at offset 24 for x64. This currently ok since fsc doesn't support true 64-bit image bases,
but we'll have to fix this up when such support is added. *)
let imageBaseReal = if only64 then dataSegmentAddr else seekReadInt32 pev (peOptionalHeaderPhysLoc + 28) (* Image Base Always 0x400000 (see Section 23.1). - QUERY : no it's not always 0x400000, e.g. 0x034f0000 *)
let alignVirt = seekReadInt32 pev (peOptionalHeaderPhysLoc + 32) (* Section Alignment Always 0x2000 (see Section 23.1). *)
let alignPhys = seekReadInt32 pev (peOptionalHeaderPhysLoc + 36) (* File Alignment Either 0x200 or 0x1000. *)
let imageBaseReal = if only64 then dataSegmentAddr else seekReadInt32 pev (peOptionalHeaderPhysLoc + 28) // Image Base Always 0x400000 (see Section 23.1).
let alignVirt = seekReadInt32 pev (peOptionalHeaderPhysLoc + 32) // Section Alignment Always 0x2000 (see Section 23.1).
let alignPhys = seekReadInt32 pev (peOptionalHeaderPhysLoc + 36) // File Alignment Either 0x200 or 0x1000.
(* x86: 000000c0 *)
let _osMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 40) (* OS Major Always 4 (see Section 23.1). *)
let _osMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 42) (* OS Minor Always 0 (see Section 23.1). *)
let _userMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 44) (* User Major Always 0 (see Section 23.1). *)
let _userMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 46) (* User Minor Always 0 (see Section 23.1). *)
let subsysMajor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 48) (* SubSys Major Always 4 (see Section 23.1). *)
let subsysMinor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 50) (* SubSys Minor Always 0 (see Section 23.1). *)
let _osMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 40) // OS Major Always 4 (see Section 23.1).
let _osMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 42) // OS Minor Always 0 (see Section 23.1).
let _userMajor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 44) // User Major Always 0 (see Section 23.1).
let _userMinor = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 46) // User Minor Always 0 (see Section 23.1).
let subsysMajor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 48) // SubSys Major Always 4 (see Section 23.1).
let subsysMinor = seekReadUInt16AsInt32 pev (peOptionalHeaderPhysLoc + 50) // SubSys Minor Always 0 (see Section 23.1).
(* x86: 000000d0 *)
let _imageEndAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 56) (* Image Size: Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment. e.g. 0x0000e000 *)
let _headerPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 60) (* Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment. *)
let subsys = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 68) (* SubSystem Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (!0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (!0x2). QUERY: Why is this 3 on the images ILASM produces??? *)
let _imageEndAddr = seekReadInt32 pev (peOptionalHeaderPhysLoc + 56) // Image Size: Size, in bytes, of image, including all headers and padding;
let _headerPhysSize = seekReadInt32 pev (peOptionalHeaderPhysLoc + 60) // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding;
let subsys = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 68) // SubSystem Subsystem required to run this image.
let useHighEnthropyVA =
let n = seekReadUInt16 pev (peOptionalHeaderPhysLoc + 70)
let highEnthropyVA = 0x20us
Expand Down
53 changes: 30 additions & 23 deletions src/absil/ilwrite.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3441,7 +3441,8 @@ let writeILMetadataAndCode (generatePdb, desiredMetadataVersion, ilg, emitTailca
// uses of strings in the code
for (codeStartAddr, l) in requiredStringFixups do
for (codeOffset, userStringIndex) in l do
if codeStartAddr < codep.addr || codeStartAddr >= codep.addr + codep.size then failwith "strings-in-code fixup: a group of fixups is located outside the code array";
if codeStartAddr < codep.addr || codeStartAddr >= codep.addr + codep.size then
failwith "strings-in-code fixup: a group of fixups is located outside the code array";
let locInCode = ((codeStartAddr + codeOffset) - codep.addr)
checkFixup32 code locInCode 0xdeadbeef;
let token = getUncodedToken TableNames.UserStrings (userStringAddress userStringIndex)
Expand Down Expand Up @@ -3665,10 +3666,14 @@ let writeBinaryAndReportMappings (outfile,
let pdbOpt =
match portablePDB with
| true ->
let (uncompressedLength, contentId, stream) as pdbStream = generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData deterministic
let (uncompressedLength, contentId, stream) as pdbStream =
generatePortablePdb embedAllSource embedSourceList sourceLink showTimes pdbData deterministic

if embeddedPDB then Some (compressPortablePdbStream uncompressedLength contentId stream)
else Some (pdbStream)

| _ -> None

let debugDirectoryChunk, next =
chunk (if pdbfile = None then
0x0
Expand Down Expand Up @@ -3773,7 +3778,9 @@ let writeBinaryAndReportMappings (outfile,
else
let res = rawdataChunk.addr + dataOffset
if res < rawdataChunk.addr then dprintn ("data rva before data section");
if res >= rawdataChunk.addr + rawdataChunk.size then dprintn ("data rva after end of data section, dataRva = "+string res+", rawdataChunk.addr = "+string rawdataChunk.addr+", rawdataChunk.size = "+string rawdataChunk.size);
if res >= rawdataChunk.addr + rawdataChunk.size then
dprintn ("data rva after end of data section, dataRva = "+string res+", rawdataChunk.addr = "+string rawdataChunk.addr
+ ", rawdataChunk.size = "+string rawdataChunk.size);
res
applyFixup32 metadata metadataOffset dataRva);
end;
Expand Down Expand Up @@ -3868,9 +3875,9 @@ let writeBinaryAndReportMappings (outfile,
writeInt32AsUInt16 os peOptionalHeaderByte; // ECMA spec says 6, some binaries, e.g. fscmanaged.exe say 7, Whidbey binaries say 8
writeInt32 os textSectionPhysSize; // Size of the code (text) section, or the sum of all code sections if there are multiple sections.
// 000000a0
writeInt32 os dataSectionPhysSize; // Size of the initialized data section, or the sum of all such sections if there are multiple data sections.
writeInt32 os 0x00; // Size of the uninitialized data section, or the sum of all such sections if there are multiple uninitialized data sections.
writeInt32 os entrypointCodeChunk.addr; // RVA of entry point , needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000 in a section marked execute/read for EXEs or 0 for DLLs e.g. 0x0000b57e
writeInt32 os dataSectionPhysSize; // Size of the initialized data section
writeInt32 os 0x00; // Size of the uninitialized data section
writeInt32 os entrypointCodeChunk.addr; // RVA of entry point , needs to point to bytes 0xFF 0x25 followed by the RVA+!0x4000000
writeInt32 os textSectionAddr; // e.g. 0x0002000
// 000000b0
if modul.Is64Bit then
Expand All @@ -3892,10 +3899,10 @@ let writeBinaryAndReportMappings (outfile,
writeInt32AsUInt16 os minor;
writeInt32 os 0x00; // Reserved Always 0 (see Section 23.1).
// 000000d0
writeInt32 os imageEndAddr; // Image Size: Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment. e.g. 0x0000e000
writeInt32 os headerSectionPhysSize; // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment.
writeInt32 os imageEndAddr; // Image Size: Size, in bytes, of image, including all headers and padding;
writeInt32 os headerSectionPhysSize; // Header Size Combined size of MS-DOS Header, PE Header, PE Optional Header and padding;
writeInt32 os 0x00; // File Checksum Always 0 (see Section 23.1). QUERY: NOT ALWAYS ZERO
writeInt32AsUInt16 os modul.SubSystemFlags; // SubSystem Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2). QUERY: Why is this 3 on the images ILASM produces
writeInt32AsUInt16 os modul.SubSystemFlags; // SubSystem Subsystem required to run this image.
// DLL Flags Always 0x400 (no unmanaged windows exception handling - see Section 23.1).
// Itanium: see notes at end of file
// IMAGE_DLLCHARACTERISTICS_NX_COMPAT: See FSharp 1.0 bug 5019 and http://blogs.msdn.com/ed_maurer/archive/2007/12/14/nxcompat-and-the-c-compiler.aspx
Expand Down Expand Up @@ -3930,7 +3937,7 @@ let writeBinaryAndReportMappings (outfile,
writeInt32 os 0x00 // Export Table Always 0 (see Section 23.1).
// 00000100
writeDirectory os importTableChunk // Import Table RVA of Import Table, (see clause 24.3.1). e.g. 0000b530
// Native Resource Table: ECMA says Always 0 (see Section 23.1), but mscorlib and other files with resources bound into executable do not. For the moment assume the resources table is always the first resource in the file.
// Native Resource Table: ECMA says Always 0 (see Section 23.1), but mscorlib and other files with resources bound into executable do not.
writeDirectory os nativeResourcesChunk

// 00000110
Expand Down Expand Up @@ -3968,28 +3975,28 @@ let writeBinaryAndReportMappings (outfile,
// 00000178
writeBytes os [| 0x2euy; 0x74uy; 0x65uy; 0x78uy; 0x74uy; 0x00uy; 0x00uy; 0x00uy; |] // ".text\000\000\000"
// 00000180
writeInt32 os textSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x00009584
writeInt32 os textSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x00020000
writeInt32 os textSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. 0x00009600
writeInt32 os textSectionPhysLoc // PointerToRawData RVA to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0. e.g. 00000200
writeInt32 os textSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment.
writeInt32 os textSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section
writeInt32 os textSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes
writeInt32 os textSectionPhysLoc // PointerToRawData RVA to section's first page within the PE file.
// 00000190
writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section.
writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1).
// 00000198
writeInt32AsUInt16 os 0x00// NumberOfRelocations Number of relocations, set to 0 if unused.
writeInt32AsUInt16 os 0x00 // NumberOfLinenumbers Always 0 (see Section 23.1).
writeBytes os [| 0x20uy; 0x00uy; 0x00uy; 0x60uy |] // Characteristics Flags describing section's characteristics, see below. IMAGE_SCN_CNT_CODE || IMAGE_SCN_MEM_EXECUTE || IMAGE_SCN_MEM_READ
writeBytes os [| 0x20uy; 0x00uy; 0x00uy; 0x60uy |] // Characteristics Flags IMAGE_SCN_CNT_CODE || IMAGE_SCN_MEM_EXECUTE || IMAGE_SCN_MEM_READ

write (Some dataSectionHeaderChunk.addr) os "data section header" [| |]

// 000001a0
writeBytes os [| 0x2euy; 0x72uy; 0x73uy; 0x72uy; 0x63uy; 0x00uy; 0x00uy; 0x00uy; |] // ".rsrc\000\000\000"
// writeBytes os [| 0x2e; 0x73; 0x64; 0x61; 0x74; 0x61; 0x00; 0x00; |] // ".sdata\000\000"
writeInt32 os dataSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x0000000c
writeInt32 os dataSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x0000c000
writeInt32 os dataSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment.
writeInt32 os dataSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section.
// 000001b0
writeInt32 os dataSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. e.g. 0x00000200
writeInt32 os dataSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized data, this field should be 0. e.g. 0x00009800
writeInt32 os dataSectionPhysSize // SizeOfRawData Size of the initialized data on disk in bytes,
writeInt32 os dataSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file.
// 000001b8
writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section.
writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1).
Expand All @@ -4001,11 +4008,11 @@ let writeBinaryAndReportMappings (outfile,
write (Some relocSectionHeaderChunk.addr) os "reloc section header" [| |]
// 000001a0
writeBytes os [| 0x2euy; 0x72uy; 0x65uy; 0x6cuy; 0x6fuy; 0x63uy; 0x00uy; 0x00uy; |] // ".reloc\000\000"
writeInt32 os relocSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than Size of Raw Data, the section is zero-padded. e.g. 0x0000000c
writeInt32 os relocSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. e.g. 0x0000c000
writeInt32 os relocSectionSize // VirtualSize: Total size of the section when loaded into memory in bytes rounded to Section Alignment.
writeInt32 os relocSectionAddr // VirtualAddress For executable images this is the address of the first byte of the section.
// 000001b0
writeInt32 os relocSectionPhysSize // SizeOfRawData Size of the initialized reloc on disk in bytes, shall be a multiple of FileAlignment from the PE header. If this is less than VirtualSize the remainder of the section is zero filled. Because this field is rounded while the VirtualSize field is not it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized reloc, this field should be 0. e.g. 0x00000200
writeInt32 os relocSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file. This shall be a multiple of FileAlignment from the optional header. When a section contains only uninitialized reloc, this field should be 0. e.g. 0x00009800
writeInt32 os relocSectionPhysSize // SizeOfRawData Size of the initialized reloc on disk in bytes
writeInt32 os relocSectionPhysLoc // PointerToRawData QUERY: Why does ECMA say "RVA" here? Offset to section's first page within the PE file.
// 000001b8
writeInt32 os 0x00 // PointerToRelocations RVA of Relocation section.
writeInt32 os 0x00 // PointerToLineNumbers Always 0 (see Section 23.1).
Expand Down
Loading