Skip to content

Commit

Permalink
Merge commit '1e3bbed3ef66b79be7818f6c6ecf2ac639ffeb19' into develop/…
Browse files Browse the repository at this point in the history
…697bis
  • Loading branch information
SteveGilham committed Oct 14, 2020
2 parents 4eaf997 + 1e3bbed commit 39ae43e
Show file tree
Hide file tree
Showing 30 changed files with 1,745 additions and 135 deletions.
2 changes: 1 addition & 1 deletion Mono.Cecil.Cil/CodeReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void ReadFatMethod ()
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
{
var position = reader.position;
var variables = reader.ReadVariables (local_var_token);
var variables = reader.ReadVariables (local_var_token, method);
reader.position = position;

return variables;
Expand Down
5 changes: 5 additions & 0 deletions Mono.Cecil.Cil/ILProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,5 +283,10 @@ public void RemoveAt (int index)

instructions.RemoveAt (index);
}

public void Clear ()
{
instructions.Clear ();
}
}
}
136 changes: 113 additions & 23 deletions Mono.Cecil.Cil/MethodBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public bool HasVariables {
public Collection<VariableDefinition> Variables {
get {
if (variables == null)
Interlocked.CompareExchange (ref variables, new VariableDefinitionCollection (), null);
Interlocked.CompareExchange (ref variables, new VariableDefinitionCollection (this.method), null);

return variables;
}
Expand Down Expand Up @@ -134,13 +134,17 @@ public ILProcessor GetILProcessor ()

sealed class VariableDefinitionCollection : Collection<VariableDefinition> {

internal VariableDefinitionCollection ()
readonly MethodDefinition method;

internal VariableDefinitionCollection (MethodDefinition method)
{
this.method = method;
}

internal VariableDefinitionCollection (int capacity)
internal VariableDefinitionCollection (MethodDefinition method, int capacity)
: base (capacity)
{
this.method = method;
}

protected override void OnAdd (VariableDefinition item, int index)
Expand All @@ -151,9 +155,7 @@ protected override void OnAdd (VariableDefinition item, int index)
protected override void OnInsert (VariableDefinition item, int index)
{
item.index = index;

for (int i = index; i < size; i++)
items [i].index = i + 1;
UpdateVariableIndices (index, 1);
}

protected override void OnSet (VariableDefinition item, int index)
Expand All @@ -163,10 +165,47 @@ protected override void OnSet (VariableDefinition item, int index)

protected override void OnRemove (VariableDefinition item, int index)
{
UpdateVariableIndices (index + 1, -1, item);
item.index = -1;
}

void UpdateVariableIndices (int startIndex, int offset, VariableDefinition variableToRemove = null)
{
for (int i = startIndex; i < size; i++)
items [i].index = i + offset;

for (int i = index + 1; i < size; i++)
items [i].index = i - 1;
var debug_info = method == null ? null : method.debug_info;
if (debug_info == null || debug_info.Scope == null)
return;

foreach (var scope in debug_info.GetScopes ()) {
if (!scope.HasVariables)
continue;

var variables = scope.Variables;
int variableDebugInfoIndexToRemove = -1;
for (int i = 0; i < variables.Count; i++) {
var variable = variables [i];

// If a variable is being removed detect if it has debug info counterpart, if so remove that as well.
// Note that the debug info can be either resolved (has direct reference to the VariableDefinition)
// or unresolved (has only the number index of the variable) - this needs to handle both cases.
if (variableToRemove != null &&
((variable.index.IsResolved && variable.index.ResolvedVariable == variableToRemove) ||
(!variable.index.IsResolved && variable.Index == variableToRemove.Index))) {
variableDebugInfoIndexToRemove = i;
continue;
}

// For unresolved debug info updates indeces to keep them pointing to the same variable.
if (!variable.index.IsResolved && variable.Index >= startIndex) {
variable.index = new VariableIndex (variable.Index + offset);
}
}

if (variableDebugInfoIndexToRemove >= 0)
variables.RemoveAt (variableDebugInfoIndexToRemove);
}
}
}

Expand Down Expand Up @@ -197,25 +236,31 @@ protected override void OnAdd (Instruction item, int index)

protected override void OnInsert (Instruction item, int index)
{
if (size == 0)
return;
int startOffset = 0;
if (size != 0) {
var current = items [index];
if (current == null) {
var last = items [index - 1];
last.next = item;
item.previous = last;
return;
}

var current = items [index];
if (current == null) {
var last = items [index - 1];
last.next = item;
item.previous = last;
return;
}
startOffset = current.Offset;

var previous = current.previous;
if (previous != null) {
previous.next = item;
item.previous = previous;
var previous = current.previous;
if (previous != null) {
previous.next = item;
item.previous = previous;
}

current.previous = item;
item.next = current;
}

current.previous = item;
item.next = current;
var scope = GetLocalScope ();
if (scope != null)
UpdateLocalScope (scope, startOffset, item.GetSize (), instructionRemoved: null);
}

protected override void OnSet (Instruction item, int index)
Expand All @@ -227,6 +272,12 @@ protected override void OnSet (Instruction item, int index)

current.previous = null;
current.next = null;

var scope = GetLocalScope ();
if (scope != null) {
var sizeOfCurrent = current.GetSize ();
UpdateLocalScope (scope, current.Offset + sizeOfCurrent, item.GetSize () - sizeOfCurrent, current);
}
}

protected override void OnRemove (Instruction item, int index)
Expand All @@ -241,6 +292,12 @@ protected override void OnRemove (Instruction item, int index)

RemoveSequencePoint (item);

var scope = GetLocalScope ();
if (scope != null) {
var size = item.GetSize ();
UpdateLocalScope (scope, item.Offset + size, -size, item);
}

item.previous = null;
item.next = null;
}
Expand All @@ -259,5 +316,38 @@ void RemoveSequencePoint (Instruction instruction)
}
}
}

ScopeDebugInformation GetLocalScope ()
{
var debug_info = method.debug_info;
if (debug_info == null)
return null;

return debug_info.Scope;
}

static void UpdateLocalScope (ScopeDebugInformation scope, int startFromOffset, int offset, Instruction instructionRemoved)
{
// For both start and enf offsets on the scope:
// * If the offset is resolved (points to instruction by reference) only update it if the instruction it points to is being removed.
// For non-removed instructions it remains correct regardless of any updates to the instructions.
// * If the offset is not resolved (stores the instruction offset number itself)
// update the number accordingly to keep it pointing to the correct instruction (by offset).

if ((!scope.Start.IsResolved && scope.Start.Offset >= startFromOffset) ||
(instructionRemoved != null && scope.Start.ResolvedInstruction == instructionRemoved))
scope.Start = new InstructionOffset (scope.Start.Offset + offset);

// For end offset only update it if it's not the special sentinel value "EndOfMethod"; that should remain as-is.
if (!scope.End.IsEndOfMethod &&
((!scope.End.IsResolved && scope.End.Offset >= startFromOffset) ||
(instructionRemoved != null && scope.End.ResolvedInstruction == instructionRemoved)))
scope.End = new InstructionOffset (scope.End.Offset + offset);

if (scope.HasScopes) {
foreach (var subScope in scope.Scopes)
UpdateLocalScope (subScope, startFromOffset, offset, instructionRemoved);
}
}
}
}
8 changes: 8 additions & 0 deletions Mono.Cecil.Cil/Symbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ public bool IsEndOfMethod {
get { return instruction == null && !offset.HasValue; }
}

internal bool IsResolved => instruction != null;

internal Instruction ResolvedInstruction => instruction;

public InstructionOffset (Instruction instruction)
{
if (instruction == null)
Expand Down Expand Up @@ -244,6 +248,10 @@ public int Index {
}
}

internal bool IsResolved => variable != null;

internal VariableDefinition ResolvedVariable => variable;

public VariableIndex (VariableDefinition variable)
{
if (variable == null)
Expand Down
2 changes: 1 addition & 1 deletion Mono.Cecil.PE/ImageReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ void ComputeTableInformations ()
{
uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header

int stridx_size = image.StringHeap.IndexSize;
int stridx_size = image.StringHeap != null ? image.StringHeap.IndexSize : 2;
int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2;
int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2;

Expand Down
8 changes: 6 additions & 2 deletions Mono.Cecil/AssemblyHashAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ namespace Mono.Cecil {

public enum AssemblyHashAlgorithm : uint {
None = 0x0000,
Reserved = 0x8003, // MD5
SHA1 = 0x8004
MD5 = 0x8003,
SHA1 = 0x8004,
SHA256 = 0x800C,
SHA384 = 0x800D,
SHA512 = 0x800E,
Reserved = 0x8003, // MD5
}
}
8 changes: 2 additions & 6 deletions Mono.Cecil/AssemblyReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2141,7 +2141,7 @@ public CallSite ReadCallSite (MetadataToken token)
return call_site;
}

public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token, MethodDefinition method = null)
{
if (!MoveTo (Table.StandAloneSig, local_var_token.RID))
return null;
Expand All @@ -2156,7 +2156,7 @@ public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token
if (count == 0)
return null;

var variables = new VariableDefinitionCollection ((int) count);
var variables = new VariableDefinitionCollection (method, (int) count);

for (int i = 0; i < count; i++)
variables.Add (new VariableDefinition (reader.ReadTypeSignature ()));
Expand Down Expand Up @@ -2326,10 +2326,6 @@ MemberReference ReadMemberReference (uint rid)
}

member.token = new MetadataToken (TokenType.MemberRef, rid);

if (module.IsWindowsMetadata ())
WindowsRuntimeProjections.Project (member);

return member;
}

Expand Down
8 changes: 4 additions & 4 deletions Mono.Cecil/AssemblyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,8 @@ void AttachTokens ()

void AttachTypeToken (TypeDefinition type)
{
var treatment = WindowsRuntimeProjections.RemoveProjection (type);

type.token = new MetadataToken (TokenType.TypeDef, type_rid++);
type.fields_range.Start = field_rid;
type.methods_range.Start = method_rid;
Expand All @@ -1289,6 +1291,8 @@ void AttachTypeToken (TypeDefinition type)

if (type.HasNestedTypes)
AttachNestedTypesToken (type);

WindowsRuntimeProjections.ApplyProjection (type, treatment);
}

void AttachNestedTypesToken (TypeDefinition type)
Expand Down Expand Up @@ -1990,16 +1994,12 @@ void AddSecurityDeclarations (ISecurityDeclarationProvider owner)

MetadataToken GetMemberRefToken (MemberReference member)
{
var projection = WindowsRuntimeProjections.RemoveProjection (member);

var row = CreateMemberRefRow (member);

MetadataToken token;
if (!member_ref_map.TryGetValue (row, out token))
token = AddMemberReference (member, row);

WindowsRuntimeProjections.ApplyProjection (member, projection);

return token;
}

Expand Down
2 changes: 1 addition & 1 deletion Mono.Cecil/BaseAssemblyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderP
var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
var prefixes = new [] { string.Empty, "v4.0_" };

for (int i = 0; i < 2; i++) {
for (int i = 0; i < gac_paths.Count; i++) {
for (int j = 0; j < gacs.Length; j++) {
var gac = Path.Combine (gac_paths [i], gacs [j]);
var file = GetAssemblyFile (reference, prefixes [i], gac);
Expand Down
2 changes: 1 addition & 1 deletion Mono.Cecil/FieldDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public int Offset {
set { offset = value; }
}

internal new FieldDefinitionProjection WindowsRuntimeProjection {
internal FieldDefinitionProjection WindowsRuntimeProjection {
get { return (FieldDefinitionProjection) projection; }
set { projection = value; }
}
Expand Down
Loading

0 comments on commit 39ae43e

Please sign in to comment.