private void WriteDisplacement(Operand displacement)
{
if (displacement.IsLabel)
{
Debug.Assert(displacement.IsUnresolvedConstant);
// FIXME! remove assertion
Debug.Assert(displacement.Offset == 0);
linker.Link(LinkType.AbsoluteAddress, PatchType.I4, SectionKind.Text, MethodName, (int)codeStream.Position, SectionKind.ROData, displacement.Name, 0);
codeStream.WriteZeroBytes(4);
}
else if (displacement.IsStaticField)
{
Debug.Assert(displacement.IsUnresolvedConstant);
var section = displacement.Field.Data != null ? SectionKind.ROData : SectionKind.BSS;
linker.Link(LinkType.AbsoluteAddress, PatchType.I4, SectionKind.Text, MethodName, (int)codeStream.Position, section, displacement.Field.FullName, 0);
codeStream.WriteZeroBytes(4);
}
else if (displacement.IsSymbol)
{
Debug.Assert(displacement.IsUnresolvedConstant);
var section = (displacement.Method != null) ? SectionKind.Text : SectionKind.ROData;
// First try finding the symbol in the expected section
var symbol = linker.FindSymbol(displacement.Name, section);
// If no symbol found, look in all sections
if (symbol == null)
{
symbol = linker.FindSymbol(displacement.Name);
}
// Otherwise create the symbol in the expected section
if (symbol == null)
{
symbol = linker.GetSymbol(displacement.Name, section);
}
linker.Link(LinkType.AbsoluteAddress, PatchType.I4, SectionKind.Text, MethodName, (int)codeStream.Position, symbol, 0);
codeStream.WriteZeroBytes(4);
}
else
{
codeStream.Write((int)displacement.Offset, Endianness.Little);
}
}