Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Store the relocation offset delta in the code stream (#2271)
Browse files Browse the repository at this point in the history
RyuJIT depends on the relocation offset delta to be stored in the code stream because of it applies additional fixups to it.

Tweak the list of Top200 tests to include coverage for this issue.

Fixes #2254
  • Loading branch information
jkotas authored Nov 27, 2016
1 parent 0d054ad commit da458b2
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,25 +219,19 @@ public void EmitInt(Reservation reservation, int emit)
_data[offset + 3] = (byte)((emit >> 24) & 0xFF);
}

public void AddRelocAtOffset(ISymbolNode symbol, RelocType relocType, int offset, int delta = 0)
{
Relocation symbolReloc = new Relocation(relocType, offset, symbol, delta);
_relocs.Add(symbolReloc);
}

public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
{
AddRelocAtOffset(symbol, relocType, _data.Count, delta);
_relocs.Add(new Relocation(relocType, _data.Count, symbol));

// And add space for the reloc
switch (relocType)
{
case RelocType.IMAGE_REL_BASED_REL32:
case RelocType.IMAGE_REL_BASED_ABSOLUTE:
EmitInt(0);
EmitInt(delta);
break;
case RelocType.IMAGE_REL_BASED_DIR64:
EmitLong(0);
EmitLong(delta);
break;
default:
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,15 @@ public void EmitBlobWithRelocs(byte[] blob, Relocation[] relocs)
{
Relocation reloc = relocs[nextRelocIndex];

int size = EmitSymbolReference(reloc.Target, reloc.Delta, reloc.RelocType);
long delta;
unsafe
{
fixed (void* location = &blob[i])
{
delta = Relocation.ReadValue(reloc.RelocType, location);
}
}
int size = EmitSymbolReference(reloc.Target, (int)delta, reloc.RelocType);

// Update nextRelocIndex/Offset
if (++nextRelocIndex < relocs.Length)
Expand Down Expand Up @@ -791,7 +799,15 @@ public static void EmitObject(string objectFilePath, IEnumerable<DependencyNode>
{
Relocation reloc = relocs[nextRelocIndex];

int size = objectWriter.EmitSymbolReference(reloc.Target, reloc.Delta, reloc.RelocType);
long delta;
unsafe
{
fixed (void* location = &nodeContents.Data[i])
{
delta = Relocation.ReadValue(reloc.RelocType, location);
}
}
int size = objectWriter.EmitSymbolReference(reloc.Target, (int)delta, reloc.RelocType);

// Update nextRelocIndex/Offset
if (++nextRelocIndex < relocs.Length)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ILCompiler.DependencyAnalysis
{
Expand All @@ -22,14 +18,46 @@ public struct Relocation
public readonly RelocType RelocType;
public readonly int Offset;
public readonly ISymbolNode Target;
public readonly int Delta;

public Relocation(RelocType relocType, int offset, ISymbolNode target, int delta)
public Relocation(RelocType relocType, int offset, ISymbolNode target)
{
RelocType = relocType;
Offset = offset;
Target = target;
Delta = delta;
}

public unsafe static void WriteValue(RelocType relocType, void* location, long value)
{
switch (relocType)
{
case RelocType.IMAGE_REL_BASED_ABSOLUTE:
case RelocType.IMAGE_REL_BASED_HIGHLOW:
case RelocType.IMAGE_REL_BASED_REL32:
*(int*)location = (int)value;
break;
case RelocType.IMAGE_REL_BASED_DIR64:
*(long*)location = value;
break;
default:
Debug.Fail("Invalid RelocType: " + relocType);
break;
}
}

public unsafe static long ReadValue(RelocType relocType, void* location)
{
switch (relocType)
{
case RelocType.IMAGE_REL_BASED_ABSOLUTE:
case RelocType.IMAGE_REL_BASED_HIGHLOW:
case RelocType.IMAGE_REL_BASED_REL32:
return *(int*)location;
case RelocType.IMAGE_REL_BASED_DIR64:
return *(long*)location;
default:
Debug.Fail("Invalid RelocType: " + relocType);
return 0;
}
}
}
}
8 changes: 7 additions & 1 deletion src/JitInterface/src/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2954,6 +2954,9 @@ private BlockType findKnownBlock(void* location, out int offset)

private void recordRelocation(void* location, void* target, ushort fRelocType, ushort slotNum, int addlDelta)
{
// slotNum is not unused
Debug.Assert(slotNum == 0);

int relocOffset;
BlockType locationBlock = findKnownBlock(location, out relocOffset);
Debug.Assert(locationBlock != BlockType.Unknown, "BlockType.Unknown not expected");
Expand Down Expand Up @@ -2996,9 +2999,12 @@ private void recordRelocation(void* location, void* target, ushort fRelocType, u

relocDelta += addlDelta;

// relocDelta is stored as the value
Relocation.WriteValue((RelocType)fRelocType, location, relocDelta);

if (_relocs.Count == 0)
_relocs.EnsureCapacity(_code.Length / 32 + 1);
_relocs.Add(new Relocation((RelocType)fRelocType, relocOffset, relocTarget, relocDelta));
_relocs.Add(new Relocation((RelocType)fRelocType, relocOffset, relocTarget));
}

private ushort getRelocTypeHint(void* target)
Expand Down
2 changes: 1 addition & 1 deletion tests/Top200.CoreCLR.issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\ExcepFilters\excepobj\excepobj\excepobj.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\ExcepFilters\fault\fault\fault.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\ExcepFilters\mixed\mixed\mixed.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\ExcepFilters\mixed3\mixed3\mixed3.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\FaultHandlers\Nesting\Nesting\Nesting.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\nullabletypes\isinst_d\isinst_d.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Directed\nullabletypes\isinst_do\isinst_do.cmd" />
<IncludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\DevDiv_142976\DevDiv_142976\DevDiv_142976.cmd" />
Expand Down

0 comments on commit da458b2

Please sign in to comment.