Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
63638bf
1st pass PEWriter based on CoffObjectWriter
jkoritzinsky Sep 12, 2025
e683065
Add export header support
jkoritzinsky Sep 12, 2025
485ce2d
Emit PE relocs instead of COFF relocs and streamline the exports dire…
jkoritzinsky Sep 12, 2025
70db624
Move files to Common in prep for inclusion in cg2
jkoritzinsky Sep 12, 2025
2d4d8f3
Seal record type
jkoritzinsky Sep 12, 2025
aadac54
Split out Unwind/Debug info into nativeaot-specific files as we don't…
jkoritzinsky Sep 15, 2025
2e29838
Remove support for merging grouped sections. The only sections where …
jkoritzinsky Sep 15, 2025
9d5aa00
Fixup expected sections for R2R to be coded into the nodes themselves.
jkoritzinsky Sep 17, 2025
1c18952
Add TODOs for determinism/checksums in the new PE writer
jkoritzinsky Sep 17, 2025
7ba3359
Add support for symbol-size reloc
jkoritzinsky Sep 17, 2025
a09bade
Add support for custom section alignment
jkoritzinsky Sep 17, 2025
1620f1d
Fix sections for code to avoid AV issues
jkoritzinsky Sep 17, 2025
5cf1dea
Fix R2RCodegenCompilation -> R2RObjectWriter calls
jkoritzinsky Sep 17, 2025
6ef1d40
Add missing alignment set
jkoritzinsky Sep 18, 2025
0cb628b
Fix reloc handling and start moving over weird fixup paths to work on…
jkoritzinsky Sep 18, 2025
eb2554c
Fix typos
jkoritzinsky Sep 19, 2025
89a797c
Remove object dumper as null is okay
jkoritzinsky Sep 19, 2025
93bb15a
Fix how we include/exclude the runtime functions table for component …
jkoritzinsky Sep 20, 2025
626e8fc
Put debug data in .text in the existing linker for now
jkoritzinsky Sep 20, 2025
23a755b
We don't have info about output format at this time, so always put th…
jkoritzinsky Sep 25, 2025
3e87601
Add suppression
jkoritzinsky Sep 25, 2025
482d035
Root the delay load method thunks range node
jkoritzinsky Sep 25, 2025
fd585d9
Copy all metadata into the .cormeta section
jkoritzinsky Sep 25, 2025
871c1a1
Add support for a symbol that represents a range between two symbols …
jkoritzinsky Sep 25, 2025
f1196a2
Write in the DOS program stub
jkoritzinsky Sep 25, 2025
f64f152
Fix UsesSubsectionsViaSymbols to not assume that anything targeting A…
jkoritzinsky Sep 25, 2025
1f6bbce
Remove R2R-specific types from OutputInfoBuilder so it (or a version …
jkoritzinsky Sep 25, 2025
25cda14
Integrate OutputInfoBuilder as an optional component of ObjectWriter
jkoritzinsky Sep 25, 2025
6698c91
Add try-finally
jkoritzinsky Sep 25, 2025
ed7e475
Add a command line option for format and get enough working to genera…
jkoritzinsky Sep 26, 2025
2551c9b
Fix writing PE optional header
jkoritzinsky Sep 26, 2025
0f7e93b
Fix writing section contents and writing out the CLR header.
jkoritzinsky Sep 26, 2025
674c2aa
Fix emitting symbol size for non-methods on R2R (needed for the "size…
jkoritzinsky Sep 26, 2025
f806ffd
Fix ilc build
jkoritzinsky Sep 26, 2025
5631b07
Fix section layout to include section sizes for sections added after …
jkoritzinsky Sep 30, 2025
c357981
Emit cold method code nodes as part of the late phase.
jkoritzinsky Sep 30, 2025
dde50fb
Don't include padding in recorded section layout
jkoritzinsky Sep 30, 2025
9ecea74
Fix absolute file relocs and recording symbol offsets in OutputInfoBu…
jkoritzinsky Sep 30, 2025
a4cc254
Generate the perfmap debug entry during build. We have the informatio…
jkoritzinsky Sep 30, 2025
f1a3fae
Add a concept of a "checksum" reloc to enable a generalized system fo…
jkoritzinsky Sep 30, 2025
eb8829d
Make outputInfoBuilder optional again as we don't need it for back-pa…
jkoritzinsky Sep 30, 2025
abffd27
Handle COFF timestamp and exporting the RTR header for composite mode
jkoritzinsky Oct 1, 2025
e1e5bdb
Fix 32-bit relative relocs in PEObjectWriter
jkoritzinsky Oct 1, 2025
85c4a9b
Change format default
jkoritzinsky Oct 3, 2025
df0c0fa
Port over the rest of the reloc types supported by the PEWriter infra…
jkoritzinsky Oct 3, 2025
4119e55
Fix rel32 relocs to calculate from the end of the reloc (not the start)
jkoritzinsky Oct 6, 2025
57ab7c9
Fix calculating in-page RVA for the reloc map and use the new format …
jkoritzinsky Oct 6, 2025
0d0ca5a
Output the node type name correctly into the map file
jkoritzinsky Oct 6, 2025
43a6c0d
Provide large-enough spans for all R2R-used relocation types.
jkoritzinsky Oct 6, 2025
60a8f06
Add support for all R2R arch targets to PEObjectWriter/CoffObjectWriter
jkoritzinsky Oct 6, 2025
2a6187e
Change the ARM64 import thunks to only emit aligned relocs.
jkoritzinsky Oct 7, 2025
80b1082
Fix ImportThunk offset handling for non-arm64
jkoritzinsky Oct 7, 2025
8b2825a
Always put CLR metadata into the cormeta section (that's how the PE o…
jkoritzinsky Oct 7, 2025
6aabbaf
Remove OriginalName (it's not used since we got rid of the grouped sy…
jkoritzinsky Oct 7, 2025
aca3844
COFF section indexes are 1-based.
jkoritzinsky Oct 7, 2025
0249851
Correctly account for custom PE alignment and add the non-Windows fil…
jkoritzinsky Oct 7, 2025
564de70
Handle section with no alignment bit set
jkoritzinsky Oct 7, 2025
178c2a6
Fix ILC build
jkoritzinsky Oct 7, 2025
f9d0033
Align RiscV and LoongArch64 import thunk relocs
jkoritzinsky Oct 8, 2025
9646f56
Fix machine kind for ARM to match R2R expectation
jkoritzinsky Oct 9, 2025
d9c623c
Correctly use PE32+ for riscv and loongarch64
jkoritzinsky Oct 9, 2025
5ab5fc3
Add handling for multiple thumb bits in PEObjectWriter and unify thum…
jkoritzinsky Oct 9, 2025
e34d7d0
Only add the thumb bit when it was there initially
jkoritzinsky Oct 9, 2025
a3e7f26
Add imageBase for non-pcrel reloc
jkoritzinsky Oct 9, 2025
98221a4
Set up resource directory so resources show up in the structure
jkoritzinsky Oct 10, 2025
32ce05e
We should determine section by format (not exposed yet) instead of ta…
jkoritzinsky Oct 13, 2025
fc7a2e8
Go back to original R2R handling for the thumb bit for R2R. We should…
jkoritzinsky Oct 13, 2025
c28a7a6
Remove LegacyPE builder now that we're passing on Pri0 everywhere
jkoritzinsky Oct 13, 2025
72cbdd5
Handle empty symbol ranges.
jkoritzinsky Oct 13, 2025
5a7e03b
PR feedback
jkoritzinsky Oct 13, 2025
082b414
Fix PDataSection reference
jkoritzinsky Oct 14, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,40 @@ public interface ISymbolDefinitionNode : ISymbolNode
new int Offset { get; }
}

/// <summary>
/// Represents a symbol that should encompass the full range between the start and end symbols specified.
/// </summary>
public interface ISymbolRangeNode : ISymbolNode
{
/// <summary>
/// Return a node that determines the start of the range.
/// This node will be used for linkage.
/// </summary>
ISymbolNode StartNode(NodeFactory factory);

/// <summary>
/// Return a node that is used to determine the symbol size.
/// </summary>
ISymbolNode EndNode(NodeFactory factory);
}

/// <summary>
/// Represents a node that generates a checksum for the resulting output blob.
/// </summary>
public interface IChecksumNode : ISymbolNode
{
int ChecksumSize { get; }

void EmitChecksum(ReadOnlySpan<byte> outputBlob, Span<byte> checksumLocation);
}

/// <summary>
/// Represents a symbol that should not be shared with another symbol during writing of the object file.
/// </summary>
public interface IUniqueSymbolNode : ISymbolNode
{
}

public static class ISymbolNodeExtensions
{
[ThreadStatic]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
// Do not vacate space for this kind of relocation, because
// the space is embedded in the instruction.
break;

case RelocType.IMAGE_REL_FILE_CHECKSUM_CALLBACK:
EmitZeros(delta);
break;
default:
throw new NotImplementedException();
}
Expand All @@ -315,6 +319,11 @@ public void EmitPointerReloc(ISymbolNode symbol, int delta = 0)
EmitReloc(symbol, (_target.PointerSize == 8) ? RelocType.IMAGE_REL_BASED_DIR64 : RelocType.IMAGE_REL_BASED_HIGHLOW, delta);
}

public void EmitChecksumReloc(IChecksumNode checksum)
{
EmitReloc(checksum, RelocType.IMAGE_REL_FILE_CHECKSUM_CALLBACK, checksum.ChecksumSize);
}

public ObjectNode.ObjectData ToObjectData()
{
#if DEBUG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@ public ObjectNodeSection(string name, SectionType type) : this(name, type, null)

public static readonly ObjectNodeSection ModulesWindowsContentSection = new ObjectNodeSection(".modules$I", SectionType.ReadOnly);
public static readonly ObjectNodeSection ModulesUnixContentSection = new ObjectNodeSection("__modules", SectionType.Writeable);

public static readonly ObjectNodeSection DebugDirectorySection = new ObjectNodeSection("debug", SectionType.Debug);
public static readonly ObjectNodeSection CorMetaSection = new ObjectNodeSection("cormeta", SectionType.ReadOnly);
public static readonly ObjectNodeSection Win32ResourcesSection = new ObjectNodeSection("rsrc", SectionType.ReadOnly);
public static readonly ObjectNodeSection PDataSection = new ObjectNodeSection("pdata", SectionType.ReadOnly);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ namespace ILCompiler.DependencyAnalysis
{
public enum RelocType
{
// PE base relocation types.
IMAGE_REL_BASED_ABSOLUTE = 0x00, // No relocation required
IMAGE_REL_BASED_ADDR32NB = 0x02, // The 32-bit address without an image base (RVA)
IMAGE_REL_BASED_HIGHLOW = 0x03, // 32 bit address base
IMAGE_REL_BASED_THUMB_MOV32 = 0x07, // Thumb2: based MOVW/MOVT
IMAGE_REL_BASED_DIR64 = 0x0A, // 64 bit address base

// COFF relocation types
IMAGE_REL_BASED_ADDR32NB = 0x0B, // The 32-bit address without an image base (RVA)

// General relocation types
IMAGE_REL_BASED_REL32 = 0x10, // 32-bit relative address from byte following reloc
IMAGE_REL_BASED_THUMB_BRANCH24 = 0x13, // Thumb2: based B, BL
IMAGE_REL_BASED_THUMB_MOV32_PCREL = 0x14, // Thumb2: based MOVW/MOVT
Expand All @@ -24,6 +29,7 @@ public enum RelocType
// This is a special NGEN-specific relocation type
// for relative pointer (used to make NGen relocation
// section smaller)

IMAGE_REL_SECTION = 0x79, // 16 bit section index containing target

IMAGE_REL_BASED_ARM64_PAGEBASE_REL21 = 0x81, // ADRP
Expand Down Expand Up @@ -63,9 +69,12 @@ public enum RelocType

//
// Relocations for R2R image production
// None of these are "real" relocations that map to an object file's relocation.
// All must be emulated by the object writer.
//
IMAGE_REL_SYMBOL_SIZE = 0x1000, // The size of data in the image represented by the target symbol node
IMAGE_REL_FILE_ABSOLUTE = 0x1001, // 32 bit offset from beginning of image
IMAGE_REL_FILE_CHECKSUM_CALLBACK = 0x1002, // After the image has been emitted, call the IChecksumNode.EmitChecksum method on the target symbol to emit the checksum data.
}

public struct Relocation
Expand Down Expand Up @@ -560,7 +569,20 @@ public static int GetSize(RelocType relocType)
{
RelocType.IMAGE_REL_BASED_DIR64 => 8,
RelocType.IMAGE_REL_BASED_HIGHLOW => 4,
RelocType.IMAGE_REL_BASED_ADDR32NB => 4,
RelocType.IMAGE_REL_BASED_REL32 => 4,
RelocType.IMAGE_REL_BASED_RELPTR32 => 4,
RelocType.IMAGE_REL_FILE_ABSOLUTE => 4,
// The relocation itself aren't these sizes, but their values
// are immediates in instructions within
// a span of this many bytes.
RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21 => 4,
RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A => 4,
RelocType.IMAGE_REL_BASED_THUMB_MOV32 => 8,
RelocType.IMAGE_REL_BASED_THUMB_MOV32_PCREL => 8,
RelocType.IMAGE_REL_BASED_LOONGARCH64_PC => 16,
RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR => 16,
RelocType.IMAGE_REL_BASED_RISCV64_PC => 16,
_ => throw new NotSupportedException(),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,22 @@ public void EmitJMP(ISymbolNode symbol)
{
if (symbol.RepresentsIndirectionCell)
{
Builder.RequireInitialPointerAlignment();

if (Builder.CountBytes % Builder.TargetPointerSize == 0)
{
// Emit a NOP instruction to align the 64-bit reloc below.
EmitNOP();
}

// ldr x12, [PC+0xc]
EmitLDR(Register.X12, 0xc);

// ldr x12, [x12]
EmitLDR(Register.X12, Register.X12);

// br x12
Builder.EmitUInt(0xd61f0180);
EmitJMP(Register.X12);

Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_DIR64);
}
Expand Down Expand Up @@ -215,6 +223,11 @@ public void EmitJNE(ISymbolNode symbol)
EmitJMP(symbol);
}

public void EmitNOP()
{
Builder.EmitUInt(0xD503201F);
}

private static bool InSignedByteRange(int i)
{
return i == (int)(sbyte)i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ public void EmitJMP(ISymbolNode symbol)
{
if (symbol.RepresentsIndirectionCell)
{
Builder.RequireInitialPointerAlignment();

if (Builder.CountBytes % Builder.TargetPointerSize != 0)
{
// Emit a NOP instruction to align the 64-bit reloc below.
EmitNOP();
}

// pcaddi R21, 0
EmitPCADDI(Register.R21);

Expand Down Expand Up @@ -150,5 +158,11 @@ public void EmitDBAR()
{
Builder.EmitUInt(0x38720000);
}

// nop
public void EmitNOP()
{
Builder.EmitUInt(0x03400000);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ public void EmitJMP(ISymbolNode symbol)
{
if (symbol.RepresentsIndirectionCell)
{
Builder.RequireInitialPointerAlignment();

if (Builder.CountBytes % Builder.TargetPointerSize != 0)
{
// Emit a NOP instruction to align the 64-bit reloc below.
EmitNOP();
}

// auipc x29, 0
EmitPC(Register.X29);
// ld x29,16(x29)
Expand Down Expand Up @@ -137,5 +145,10 @@ public void EmitJMPIfZero(Register regSrc, ISymbolNode symbol)
Builder.EmitUInt((uint)(0x00001063 | ((uint)regSrc << 15) | encodedOffset));
EmitJMP(symbol);
}

public void EmitNOP()
{
Builder.EmitUInt(0x00000013);
}
}
}
Loading
Loading