Skip to content

Commit

Permalink
[NativeAOT/x86] Add SAFESEH support to assembly files and ObjectWriter (
Browse files Browse the repository at this point in the history
#100433)

* Add SAFESEH support to assembly files and ObjectWriter

* Specify SafeSEH only on x86, emit feat.00 symbol only if non-zero

* Use /SAFESEH flag for NativeAOT/x86

* Minor cleanup
  • Loading branch information
filipnavara authored Mar 29, 2024
1 parent 7486be8 commit 34d13b2
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ The .NET Foundation licenses this file to you under the MIT license.
<LinkerArg Condition="'$(OutputType)' == 'WinExe' or '$(OutputType)' == 'Exe'" Include="/ENTRY:$(EntryPointSymbol) /NOEXP /NOIMPLIB" />
<LinkerArg Include="/NATVIS:&quot;$(MSBuildThisFileDirectory)NativeAOT.natvis&quot;" />
<LinkerArg Condition="'$(ControlFlowGuard)' == 'Guard'" Include="/guard:cf" />
<LinkerArg Condition="'$(_targetArchitecture)' == 'x86'" Include="/safeseh" />
<LinkerArg Condition="'$(OutputType)' == 'WinExe' or '$(OutputType)' == 'Exe'" Include="/STACK:$(IlcDefaultStackSize)" />
<!-- Do not warn if someone declares UnmanagedCallersOnly with an entrypoint of 'DllGetClassObject' and similar -->
<LinkerArg Include="/IGNORE:4104" />
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ if(CLR_CMAKE_TARGET_WIN32)
if (CLR_CMAKE_TARGET_ARCH_AMD64)
add_definitions(-DFEATURE_SPECIAL_USER_MODE_APC)
endif()
if (CLR_CMAKE_TARGET_ARCH_I386)
add_compile_options($<$<COMPILE_LANGUAGE:ASM_MASM>:/safeseh>)
endif()
else()
if(NOT CLR_CMAKE_TARGET_APPLE)
add_definitions(-DFEATURE_READONLY_GS_COOKIE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ private protected override void EmitSymbolTable(
IDictionary<string, SymbolDefinition> definedSymbols,
SortedSet<string> undefinedSymbols)
{
Feat00Flags feat00Flags = _machine is Machine.I386 ? Feat00Flags.SafeSEH : 0;

foreach (var (symbolName, symbolDefinition) in definedSymbols)
{
if (_symbolNameToIndex.TryGetValue(symbolName, out uint symbolIndex))
Expand Down Expand Up @@ -253,13 +255,18 @@ private protected override void EmitSymbolTable(
gfidsSectionWriter.WriteLittleEndian<uint>(_symbolNameToIndex[symbolName]);
}

feat00Flags |= Feat00Flags.ControlFlowGuard;
}

if (feat00Flags != 0)
{
// Emit the feat.00 symbol that controls various linker behaviors
_symbols.Add(new CoffSymbol
{
Name = "@feat.00",
StorageClass = CoffSymbolClass.IMAGE_SYM_CLASS_STATIC,
SectionIndex = uint.MaxValue, // IMAGE_SYM_ABSOLUTE
Value = 0x800, // cfGuardCF flags this object as control flow guard aware
Value = (uint)feat00Flags,
});
}
}
Expand Down Expand Up @@ -1118,5 +1125,14 @@ public static uint CalculateChecksum(Stream stream)
return crc;
}
}

private enum Feat00Flags : uint
{
SafeSEH = 1,
StackGuard = 0x100,
SoftwareDevelopmentLifecycle = 0x200,
ControlFlowGuard = 0x800,
ExceptionContinuationMetadata = 0x4000,
}
}
}

0 comments on commit 34d13b2

Please sign in to comment.