Skip to content

Use .alt_entry/.private_extern on Apple platforms #106224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
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
5 changes: 5 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ C_FUNC(\Name):
.endm

.macro ALTERNATE_ENTRY Name
#if defined(__APPLE__)
.alt_entry C_FUNC(\Name)
.private_extern C_FUNC(\Name)
#else
.global C_FUNC(\Name)
#endif
C_FUNC(\Name):
.endm

Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/nativeaot/Runtime/unix/unixasmmacrosarm64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ C_FUNC(\Name):
.endm

.macro ALTERNATE_ENTRY Name
#if defined(__APPLE__)
.alt_entry C_FUNC(\Name)
.private_extern C_FUNC(\Name)
#else
.global C_FUNC(\Name)
#if !defined(__APPLE__)
.hidden C_FUNC(\Name)
#endif
C_FUNC(\Name):
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/pal/inc/unixasmmacrosarm64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
.endm

.macro PATCH_LABEL Name
#if defined(__APPLE__)
.alt_entry C_FUNC(\Name)
.private_extern C_FUNC(\Name)
#else
.global C_FUNC(\Name)
#endif
C_FUNC(\Name):
.endm

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ public bool IsStandardSection
}
}

/// <summary>
/// Returns true if the section contains regular data (as opposed to code, debug info or unwinding data)
/// </summary>
public bool IsDataSection
{
get
{
return Type is SectionType.ReadOnly or SectionType.Writeable or SectionType.Uninitialized;
}
}

public static readonly ObjectNodeSection XDataSection = new ObjectNodeSection("xdata", SectionType.ReadOnly);
public static readonly ObjectNodeSection DataSection = new ObjectNodeSection("data", SectionType.Writeable);
public static readonly ObjectNodeSection ReadOnlyDataSection = new ObjectNodeSection("rdata", SectionType.ReadOnly);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ internal static class MachNative
public const byte N_INDR = 0xA;
public const byte N_SECT = 0xE;
public const byte N_PBUD = 0xC;
public const byte N_PEXT = 0x10;

// Symbol descriptor flags
public const ushort REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0;
Expand All @@ -106,6 +107,7 @@ internal static class MachNative
public const ushort REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5;
public const ushort REFERENCED_DYNAMICALLY = 0x10;
public const ushort N_NO_DEAD_STRIP = 0x20;
public const ushort N_ALT_ENTRY = 0x200;
public const ushort N_WEAK_REF = 0x40;
public const ushort N_WEAK_DEF = 0x80;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private protected override void EmitSectionsAndLayout()
Name = $"lsection{sectionIndex}",
Section = section,
Value = section.VirtualAddress,
Descriptor = 0,
Descriptor = (ushort)(section.KeepDataLayout ? N_NO_DEAD_STRIP : 0),
Type = N_SECT,
};
_symbolTable.Add(machSymbol);
Expand Down Expand Up @@ -355,6 +355,7 @@ private protected override void CreateSection(ObjectNodeSection section, string
{
Log2Alignment = 1,
Flags = flags,
KeepDataLayout = section.IsDataSection
};

int sectionIndex = _sections.Count;
Expand Down Expand Up @@ -472,6 +473,10 @@ private protected override void EmitSymbolTable(

// Sort and insert all defined symbols
var sortedDefinedSymbols = new List<MachSymbol>(definedSymbols.Count);
// We emit a local N_NO_DEAD_STRIP symbol for the beginning of all sections marked with
// KeepDataLayout to ensure the final layout is kept intact by the linker. This works in
// tandem with setting the N_ALT_ENTRY flag for all other symbols in the same section in
// the loop below.
Comment on lines +476 to +479
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the PR version still doing this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is.

foreach ((string name, SymbolDefinition definition) in definedSymbols)
{
MachSection section = _sections[definition.SectionIndex];
Expand All @@ -483,8 +488,8 @@ private protected override void EmitSymbolTable(
Name = name,
Section = section,
Value = section.VirtualAddress + (ulong)definition.Value,
Descriptor = N_NO_DEAD_STRIP,
Type = N_SECT | N_EXT,
Descriptor = (ushort)(section.KeepDataLayout || definition.AltEntry ? N_ALT_ENTRY | N_NO_DEAD_STRIP : N_NO_DEAD_STRIP),
Type = (byte)(N_SECT | N_EXT | (definition.Global ? 0 : N_PEXT)),
});
}
sortedDefinedSymbols.Sort((symA, symB) => string.CompareOrdinal(symA.Name, symB.Name));
Expand All @@ -496,7 +501,7 @@ private protected override void EmitSymbolTable(
}

_dySymbolTable.ExternalSymbolsIndex = _dySymbolTable.LocalSymbolsCount;
_dySymbolTable.ExternalSymbolsCount = (uint)definedSymbols.Count;
_dySymbolTable.ExternalSymbolsCount = (uint)sortedDefinedSymbols.Count;

uint savedSymbolIndex = symbolIndex;
foreach (string externSymbol in undefinedSymbols)
Expand Down Expand Up @@ -883,6 +888,7 @@ private sealed class MachSection
public bool IsInFile => Size > 0 && Type != S_ZEROFILL && Type != S_GB_ZEROFILL && Type != S_THREAD_LOCAL_ZEROFILL;

public bool IsDwarfSection { get; }
public bool KeepDataLayout { get; set; }

public IList<MachRelocation> Relocations => relocationCollection ??= new List<MachRelocation>();
public Stream Stream => dataStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace ILCompiler.ObjectWriter
{
public abstract class ObjectWriter
{
private protected sealed record SymbolDefinition(int SectionIndex, long Value, int Size = 0, bool Global = false);
private protected sealed record SymbolDefinition(int SectionIndex, long Value, int Size = 0, bool Global = false, bool AltEntry = false);
private protected sealed record SymbolicRelocation(long Offset, RelocType Type, string SymbolName, long Addend = 0);
private protected sealed record BlockToRelocate(int SectionIndex, long Offset, byte[] Data, Relocation[] Relocations);

Expand Down Expand Up @@ -246,11 +246,12 @@ protected internal void EmitSymbolDefinition(
string symbolName,
long offset = 0,
int size = 0,
bool global = false)
bool global = false,
bool altEntry = false)
{
_definedSymbols.Add(
symbolName,
new SymbolDefinition(sectionIndex, offset, size, global));
new SymbolDefinition(sectionIndex, offset, size, global, altEntry));
}

/// <summary>
Expand Down Expand Up @@ -414,22 +415,26 @@ private void EmitObject(string objectFilePath, IReadOnlyCollection<DependencyNod

sectionWriter.EmitAlignment(nodeContents.Alignment);

bool hasInitialEntrypoint = false;
bool isMethod = node is IMethodBodyNode or AssemblyStubNode;
long thumbBit = _nodeFactory.Target.Architecture == TargetArchitecture.ARM && isMethod ? 1 : 0;
foreach (ISymbolDefinitionNode n in nodeContents.DefinedSymbols)
{
hasInitialEntrypoint |= n.Offset == 0;
sectionWriter.EmitSymbolDefinition(
n == node ? currentSymbolName : GetMangledName(n),
n.Offset + thumbBit,
n.Offset == 0 && isMethod ? nodeContents.Data.Length : 0);
n.Offset == 0 && isMethod ? nodeContents.Data.Length : 0,
altEntry: n.Offset != 0);
if (_nodeFactory.GetSymbolAlternateName(n) is string alternateName)
{
string alternateCName = ExternCName(alternateName);
sectionWriter.EmitSymbolDefinition(
alternateCName,
n.Offset + thumbBit,
n.Offset == 0 && isMethod ? nodeContents.Data.Length : 0,
global: true);
global: true,
altEntry: n.Offset != 0);

if (n is IMethodNode)
{
Expand All @@ -439,6 +444,11 @@ private void EmitObject(string objectFilePath, IReadOnlyCollection<DependencyNod
}
}

// Match the logic for KeepDataLayout in MachSection.CreateSection. If we are in a data section
// we don't need to have a symbol for beginning of the node data. For other nodes, particularly
// executable code, we enforce it though.
Debug.Assert(hasInitialEntrypoint || section.IsDataSection);

if (nodeContents.Relocs is not null)
{
blocksToRelocate.Add(new BlockToRelocate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ public readonly void EmitSymbolDefinition(
string symbolName,
long relativeOffset = 0,
int size = 0,
bool global = false)
bool global = false,
bool altEntry = false)
{
_objectWriter.EmitSymbolDefinition(
SectionIndex,
symbolName,
Position + relativeOffset,
size,
global);
global,
altEntry);
}

public readonly void EmitSymbolReference(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private protected override void EmitUnwindInfo(
string framSymbolName = $"_fram{i}{currentSymbolName}";
if (useFrameNames && start != 0)
{
sectionWriter.EmitSymbolDefinition(framSymbolName, start);
sectionWriter.EmitSymbolDefinition(framSymbolName, start, altEntry: true);
}

string startSymbolName = useFrameNames && start != 0 ? framSymbolName : currentSymbolName;
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/vm/arm64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ NESTED_END ThePreStub, _TEXT

LEAF_ENTRY ThePreStubPatch, _TEXT
nop
.globl C_FUNC(ThePreStubPatchLabel)
C_FUNC(ThePreStubPatchLabel):
PATCH_LABEL ThePreStubPatchLabel
ret lr
LEAF_END ThePreStubPatch, _TEXT

Expand Down
Loading