Ejemplo n.º 1
0
 public Relocation(RelocType relocType, int offset, ISymbolNode target, int delta)
 {
     RelocType = relocType;
     Offset = offset;
     Target = target;
     Delta = delta;
 }
Ejemplo n.º 2
0
 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;
     }
 }
Ejemplo n.º 3
0
 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;
     }
 }
Ejemplo n.º 4
0
 public void AddRelocAtOffset(ISymbolNode symbol, RelocType relocType, int offset, int delta = 0)
 {
     Relocation symbolReloc = new Relocation();
     symbolReloc.Target = symbol;
     symbolReloc.RelocType = relocType;
     symbolReloc.Offset = offset;
     symbolReloc.Delta = delta;
     _relocs.Add(symbolReloc);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Process a single relocation by copying the required number of bytes into a
        /// buffer, applying the relocation and writing it to the output file.
        /// </summary>
        /// <param name="relocationType">Relocation type to process</param>
        /// <param name="sourceRVA">RVA representing the address to relocate</param>
        /// <param name="targetRVA">RVA representing the relocation target</param>
        public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targetRVA)
        {
            int  relocationLength = 0;
            long delta            = 0;

            switch (relocationType)
            {
            case RelocType.IMAGE_REL_BASED_ABSOLUTE:
                // No relocation
                return;

            case RelocType.IMAGE_REL_BASED_HIGHLOW:
            {
                relocationLength = 4;
                delta            = unchecked (targetRVA + (int)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_ADDR32NB:
            case RelocType.IMAGE_REL_SYMBOL_SIZE:
            {
                relocationLength = 4;
                delta            = targetRVA;
                break;
            }

            case RelocType.IMAGE_REL_BASED_REL32:
            {
                relocationLength = 4;
                delta            = targetRVA - sourceRVA - 4;
                break;
            }

            case RelocType.IMAGE_REL_BASED_DIR64:
            {
                relocationLength = 8;
                delta            = unchecked (targetRVA + (long)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_MOV32:
            {
                relocationLength = 8;
                delta            = unchecked (targetRVA + (int)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_BRANCH24:
            {
                relocationLength = 4;
                delta            = targetRVA - sourceRVA - 4;
                break;
            }

            case RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21:
            {
                relocationLength = 4;
                delta            = (targetRVA - sourceRVA) >> 12;
                break;
            }

            case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A:
            {
                relocationLength = 4;
                delta            = targetRVA & 0xfff;
                break;
            }

            default:
                throw new NotSupportedException();
            }

            if (relocationLength > 0)
            {
                CopyBytesToBuffer(_relocationBuffer, relocationLength);
                unsafe
                {
                    fixed(byte *bufferContent = _relocationBuffer)
                    {
                        long value = Relocation.ReadValue(relocationType, bufferContent);

                        // Supporting non-zero values for ARM64 would require refactoring this function
                        if (((relocationType == RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21) || (relocationType == RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A)) && (value != 0))
                        {
                            throw new NotSupportedException();
                        }

                        Relocation.WriteValue(relocationType, bufferContent, unchecked (value + delta));
                    }
                }

                // Write the relocated bytes to the output file
                _outputStream.Write(_relocationBuffer, 0, relocationLength);
                _outputFilePos += relocationLength;
            }
        }
Ejemplo n.º 6
0
        public void EmitReloc(ISymbolNode symbol, RelocType relocType)
        {
            AddRelocAtOffset(symbol, relocType, _data.Count);

            // And add space for the reloc
            switch (relocType)
            {
                case RelocType.IMAGE_REL_BASED_REL32:
                    EmitInt(0);
                    break;
                case RelocType.IMAGE_REL_BASED_DIR64:
                    EmitLong(0);
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
        public int EmitSymbolRef(string realSymbolName, int offsetFromSymbolName, bool isFunction, RelocType relocType, int delta = 0)
        {
            int symbolStartOffset = _currentObjectData.Count;

            // Workaround for ObjectWriter's lack of support for IMAGE_REL_BASED_RELPTR32
            // https://github.com/dotnet/corert/issues/3278
            if (relocType == RelocType.IMAGE_REL_BASED_RELPTR32)
            {
                relocType = RelocType.IMAGE_REL_BASED_REL32;
                delta     = checked (delta + sizeof(int));
            }

            EmitBlob(new byte[this._nodeFactory.Target.PointerSize]);
            if (relocType == RelocType.IMAGE_REL_BASED_REL32)
            {
                return(this._nodeFactory.Target.PointerSize);
            }

            _currentObjectSymbolRefs.Add(symbolStartOffset, new SymbolRefData(isFunction, realSymbolName, delta));
            return(_nodeFactory.Target.PointerSize);
        }
Ejemplo n.º 8
0
 public void AddRelocAtOffset(ISymbolNode symbol, RelocType relocType, int offset, int delta = 0)
 {
     Relocation symbolReloc = new Relocation(relocType, offset, symbol, delta);
     _relocs.Add(symbolReloc);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Emit the .reloc section based on file relocation information in the individual blocks.
        /// We rely on the fact that the .reloc section is emitted last so that, by the time
        /// it's getting serialized, all other sections that may contain relocations have already
        /// been laid out.
        /// </summary>
        private BlobBuilder SerializeRelocationSection(SectionLocation sectionLocation)
        {
            // There are 12 bits for the relative offset
            const int RelocationTypeShift      = 12;
            const int MaxRelativeOffsetInBlock = (1 << RelocationTypeShift) - 1;

            // Even though the format doesn't dictate it, it seems customary
            // to align the base RVA's on 4K boundaries.
            const int BaseRVAAlignment = 1 << RelocationTypeShift;

            BlobBuilder   builder         = new BlobBuilder();
            int           baseRVA         = 0;
            List <ushort> offsetsAndTypes = null;

            Section relocSection = FindSection(R2RPEBuilder.RelocSectionName);

            if (relocSection != null)
            {
                relocSection.FilePosWhenPlaced = sectionLocation.PointerToRawData;
                relocSection.RVAWhenPlaced     = sectionLocation.RelativeVirtualAddress;
                builder = relocSection.Content;
            }

            // Traverse relocations in all sections in their RVA order
            // By now, all "normal" sections with relocations should already have been laid out
            foreach (Section section in _sections.OrderBy((sec) => sec.RVAWhenPlaced))
            {
                foreach (PlacedObjectData placedObjectData in section.PlacedObjectDataToRelocate)
                {
                    for (int relocIndex = 0; relocIndex < placedObjectData.Relocs.Length; relocIndex++)
                    {
                        RelocType relocType     = placedObjectData.Relocs[relocIndex].RelocType;
                        RelocType fileRelocType = Relocation.GetFileRelocationType(relocType);
                        if (fileRelocType != RelocType.IMAGE_REL_BASED_ABSOLUTE)
                        {
                            int relocationRVA = section.RVAWhenPlaced + placedObjectData.Offset + placedObjectData.Relocs[relocIndex].Offset;
                            if (offsetsAndTypes != null && relocationRVA - baseRVA > MaxRelativeOffsetInBlock)
                            {
                                // Need to flush relocation block as the current RVA is too far from base RVA
                                FlushRelocationBlock(builder, baseRVA, offsetsAndTypes);
                                offsetsAndTypes = null;
                            }
                            if (offsetsAndTypes == null)
                            {
                                // Create new relocation block
                                baseRVA         = relocationRVA & -BaseRVAAlignment;
                                offsetsAndTypes = new List <ushort>();
                            }
                            ushort offsetAndType = (ushort)(((ushort)fileRelocType << RelocationTypeShift) | (relocationRVA - baseRVA));
                            offsetsAndTypes.Add(offsetAndType);
                        }
                    }
                }
            }

            if (offsetsAndTypes != null)
            {
                FlushRelocationBlock(builder, baseRVA, offsetsAndTypes);
            }

            if (builder.Count != 0)
            {
                _relocationDirectoryEntry = new DirectoryEntry(sectionLocation.RelativeVirtualAddress, builder.Count);
            }

            return(builder);
        }
Ejemplo n.º 10
0
 private static extern int EmitSymbolRef(IntPtr objWriter, byte[] symbolName, RelocType relocType, int delta);
Ejemplo n.º 11
0
        public void AddRelocAtOffset(ISymbolNode symbol, RelocType relocType, int offset, int delta = 0)
        {
            Relocation symbolReloc = new Relocation(relocType, offset, symbol, delta);

            _relocs.Add(symbolReloc);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Process a single relocation by copying the required number of bytes into a
        /// buffer, applying the relocation and writing it to the output file.
        /// </summary>
        /// <param name="relocationType">Relocation type to process</param>
        /// <param name="sourceRVA">RVA representing the address to relocate</param>
        /// <param name="targetRVA">RVA representing the relocation target</param>
        public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targetRVA, int filePosWhenPlaced)
        {
            int  relocationLength = 0;
            long delta            = 0;

            switch (relocationType)
            {
            case RelocType.IMAGE_REL_BASED_ABSOLUTE:
                // No relocation
                return;

            case RelocType.IMAGE_REL_BASED_HIGHLOW:
            {
                relocationLength = 4;
                delta            = unchecked (targetRVA + (int)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_ADDR32NB:
            case RelocType.IMAGE_REL_SYMBOL_SIZE:
            {
                relocationLength = 4;
                delta            = targetRVA;
                break;
            }

            case RelocType.IMAGE_REL_BASED_REL32:
            {
                relocationLength = 4;
                delta            = targetRVA - sourceRVA - 4;
                break;
            }

            case RelocType.IMAGE_REL_BASED_DIR64:
            {
                relocationLength = 8;
                delta            = unchecked (targetRVA + (long)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_MOV32:
            {
                relocationLength = 8;
                delta            = unchecked (targetRVA + (int)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_MOV32_PCREL:
            {
                relocationLength = 8;
                const uint offsetCorrection = 12;
                delta = unchecked (targetRVA - (sourceRVA + offsetCorrection));
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_BRANCH24:
            {
                relocationLength = 4;
                delta            = targetRVA - sourceRVA - 4;
                break;
            }

            case RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21:
            {
                relocationLength = 4;
                int sourcePageRVA = sourceRVA & ~0xfff;
                // Page delta always fits in 21 bits as long as we use 4-byte RVAs
                delta = ((targetRVA - sourcePageRVA) >> 12) & 0x1f_ffff;
                break;
            }

            case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A:
            {
                relocationLength = 4;
                delta            = targetRVA & 0xfff;
                break;
            }

            case RelocType.IMAGE_REL_FILE_ABSOLUTE:
            {
                relocationLength = 4;
                delta            = filePosWhenPlaced;
                break;
            }

            case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC:
            case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR:
            {
                relocationLength = 8;
                delta            = targetRVA - sourceRVA;
                break;
            }

            default:
                throw new NotSupportedException();
            }

            if (relocationLength > 0)
            {
                CopyBytesToBuffer(_relocationBuffer, relocationLength);
                unsafe
                {
                    fixed(byte *bufferContent = _relocationBuffer)
                    {
                        long value = Relocation.ReadValue(relocationType, bufferContent);

                        // Supporting non-zero values for ARM64 would require refactoring this function
                        if (((relocationType == RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21) ||
                             (relocationType == RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A) ||
                             (relocationType == RelocType.IMAGE_REL_BASED_LOONGARCH64_PC) ||
                             (relocationType == RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR)
                             ) && (value != 0))
                        {
                            throw new NotSupportedException();
                        }

                        Relocation.WriteValue(relocationType, bufferContent, unchecked (value + delta));
                    }
                }

                // Write the relocated bytes to the output file
                _outputStream.Write(_relocationBuffer, 0, relocationLength);
                _outputFilePos += relocationLength;
            }
        }
Ejemplo n.º 13
0
        // Returns size of the emitted symbol reference
        public int EmitSymbolReference(ISymbolNode target, int delta, RelocType relocType)
        {
            string targetName = GetSymbolToEmitForTargetPlatform(target.MangledName);

            return(EmitSymbolRef(targetName, relocType, delta));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Process a single relocation by copying the required number of bytes into a
        /// buffer, applying the relocation and writing it to the output file.
        /// </summary>
        /// <param name="relocationType">Relocation type to process</param>
        /// <param name="sourceRVA">RVA representing the address to relocate</param>
        /// <param name="targetRVA">RVA representing the relocation target</param>
        public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targetRVA)
        {
            int  relocationLength = 0;
            long delta            = 0;

            switch (relocationType)
            {
            case RelocType.IMAGE_REL_BASED_ABSOLUTE:
                // No relocation
                return;

            case RelocType.IMAGE_REL_BASED_HIGHLOW:
            {
                relocationLength = 4;
                delta            = unchecked (targetRVA + (int)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_ADDR32NB:
            {
                relocationLength = 4;
                delta            = targetRVA;
                break;
            }

            case RelocType.IMAGE_REL_BASED_REL32:
            {
                relocationLength = 4;
                delta            = targetRVA - sourceRVA - 4;
                break;
            }

            case RelocType.IMAGE_REL_BASED_DIR64:
            {
                relocationLength = 8;
                delta            = unchecked (targetRVA + (long)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_MOV32:
            {
                relocationLength = 8;
                delta            = unchecked (targetRVA + (int)_defaultImageBase);
                break;
            }

            case RelocType.IMAGE_REL_BASED_THUMB_BRANCH24:
            {
                relocationLength = 4;
                delta            = targetRVA - sourceRVA - 4;
                break;
            }

            default:
                throw new NotSupportedException();
            }

            if (relocationLength > 0)
            {
                CopyBytesToBuffer(_relocationBuffer, relocationLength);
                unsafe
                {
                    fixed(byte *bufferContent = _relocationBuffer)
                    {
                        long value = Relocation.ReadValue(relocationType, bufferContent);

                        Relocation.WriteValue(relocationType, bufferContent, unchecked (value + delta));
                    }
                }

                // Write the relocated bytes to the output file
                _outputStream.Write(_relocationBuffer, 0, relocationLength);
                _outputFilePos += relocationLength;
            }
        }
Ejemplo n.º 15
0
 public int EmitSymbolRef(string symbolName, RelocType relocType, int delta = 0)
 {
     return(EmitSymbolRef(_nativeObjectWriter, symbolName, relocType, delta));
 }
Ejemplo n.º 16
0
        // Returns size of the emitted symbol reference
        public int EmitSymbolReference(ISymbolNode target, int delta, RelocType relocType)
        {
            _sb.Clear();
            AppendExternCPrefix(_sb);
            target.AppendMangledName(NodeFactory.NameMangler, _sb);

            return EmitSymbolRef(_sb, relocType, delta);
        }
Ejemplo n.º 17
0
 public int EmitSymbolRef(Utf8StringBuilder symbolName, RelocType relocType, int delta = 0)
 {
     return EmitSymbolRef(_nativeObjectWriter, symbolName.Append('\0').UnderlyingArray, relocType, delta);
 }
Ejemplo n.º 18
0
 public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
 {
     _builder.EmitReloc(symbol, relocType, delta);
 }
Ejemplo n.º 19
0
 public Relocation(RelocType relocType, int offset, ISymbolNode target)
 {
     RelocType = relocType;
     Offset = offset;
     Target = target;
 }
Ejemplo n.º 20
0
        /// <summary>
        /// Add an ObjectData block to a given section.
        /// </summary>
        /// <param name="data">Block to add</param>
        /// <param name="sectionIndex">Section index</param>
        /// <param name="name">Node name to emit in the map file</param>
        /// <param name="mapFileBuilder">Optional map file to emit</param>
        public void AddObjectData(ObjectNode.ObjectData objectData, int sectionIndex, string name, MapFileBuilder mapFileBuilder)
        {
            Section section = _sections[sectionIndex];

            // Calculate alignment padding - apparently ObjectDataBuilder can produce an alignment of 0
            int alignedOffset = section.Content.Count;

            if (objectData.Alignment > 1)
            {
                alignedOffset = (section.Content.Count + objectData.Alignment - 1) & -objectData.Alignment;
                int padding = alignedOffset - section.Content.Count;
                if (padding > 0)
                {
                    if ((section.Characteristics & SectionCharacteristics.ContainsCode) != 0)
                    {
                        uint cp = _codePadding;
                        while (padding >= sizeof(uint))
                        {
                            section.Content.WriteUInt32(cp);
                            padding -= sizeof(uint);
                        }
                        if (padding >= 2)
                        {
                            section.Content.WriteUInt16(unchecked ((ushort)cp));
                            cp >>= 16;
                        }
                        if ((padding & 1) != 0)
                        {
                            section.Content.WriteByte(unchecked ((byte)cp));
                        }
                    }
                    else
                    {
                        section.Content.WriteBytes(0, padding);
                    }
                }
            }

            if (mapFileBuilder != null)
            {
                MapFileNode node = new MapFileNode(sectionIndex, alignedOffset, objectData.Data.Length, name);
                mapFileBuilder.AddNode(node);
                if (objectData.Relocs != null)
                {
                    foreach (Relocation reloc in objectData.Relocs)
                    {
                        RelocType fileReloc = Relocation.GetFileRelocationType(reloc.RelocType);
                        if (fileReloc != RelocType.IMAGE_REL_BASED_ABSOLUTE)
                        {
                            mapFileBuilder.AddRelocation(node, fileReloc);
                        }
                    }
                }
            }

            section.Content.WriteBytes(objectData.Data);

            if (objectData.DefinedSymbols != null)
            {
                foreach (ISymbolDefinitionNode symbol in objectData.DefinedSymbols)
                {
                    if (mapFileBuilder != null)
                    {
                        Utf8StringBuilder sb = new Utf8StringBuilder();
                        symbol.AppendMangledName(GetNameMangler(), sb);
                        int sectionRelativeOffset = alignedOffset + symbol.Offset;
                        mapFileBuilder.AddSymbol(new MapFileSymbol(sectionIndex, sectionRelativeOffset, sb.ToString()));
                    }
                    _symbolMap.Add(symbol, new SymbolTarget(
                                       sectionIndex: sectionIndex,
                                       offset: alignedOffset + symbol.Offset,
                                       size: objectData.Data.Length));
                }
            }

            if (objectData.Relocs != null && objectData.Relocs.Length != 0)
            {
                section.PlacedObjectDataToRelocate.Add(new PlacedObjectData(alignedOffset, objectData));
            }
        }
Ejemplo n.º 21
0
 public int EmitSymbolRef(string symbolName, RelocType relocType, int delta = 0)
 {
     return EmitSymbolRef(_nativeObjectWriter, symbolName, relocType, delta);
 }
Ejemplo n.º 22
0
        public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
        {
            _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(delta);
                    break;
                case RelocType.IMAGE_REL_BASED_DIR64:
                    EmitLong(delta);
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
Ejemplo n.º 23
0
        private void ComputeDependencyNodeDependencies(List <DependencyNodeCore <NodeFactory> > obj)
        {
            foreach (MethodCodeNode methodCodeNodeNeedingCode in obj)
            {
                MethodDesc method     = methodCodeNodeNeedingCode.Method;
                string     methodName = method.ToString();
                Log.WriteLine("Compiling " + methodName);

                var methodIL = _ilProvider.GetMethodIL(method);
                if (methodIL == null)
                {
                    return;
                }

                MethodCode methodCode;
                try
                {
                    if (_skipJitList.Contains(new TypeAndMethod(method.OwningType.Name, method.Name)))
                    {
                        throw new NotImplementedException("SkipJIT");
                    }

                    methodCode = _corInfo.CompileMethod(method);

                    if (methodCode.Relocs != null)
                    {
                        if (methodCode.Relocs.Any(r => r.Target is FieldDesc))
                        {
                            // We only support FieldDesc for InitializeArray intrinsic right now.
                            throw new NotImplementedException("RuntimeFieldHandle is not implemented");
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.WriteLine("*** " + e.Message + " (" + method + ")");

                    // Call the __not_yet_implemented method
                    DependencyAnalysis.X64.X64Emitter emit = new DependencyAnalysis.X64.X64Emitter(_nodeFactory);
                    emit.Builder.RequireAlignment(_nodeFactory.Target.MinimumFunctionAlignment);
                    emit.Builder.DefinedSymbols.Add(methodCodeNodeNeedingCode);

                    emit.EmitLEAQ(emit.TargetRegister.Arg0, _nodeFactory.StringIndirection(method.ToString()));
                    DependencyAnalysis.X64.AddrMode loadFromArg0 =
                        new DependencyAnalysis.X64.AddrMode(emit.TargetRegister.Arg0, null, 0, 0, DependencyAnalysis.X64.AddrModeSize.Int64);
                    emit.EmitMOV(emit.TargetRegister.Arg0, ref loadFromArg0);
                    emit.EmitMOV(emit.TargetRegister.Arg0, ref loadFromArg0);

                    emit.EmitLEAQ(emit.TargetRegister.Arg1, _nodeFactory.StringIndirection(e.Message));
                    DependencyAnalysis.X64.AddrMode loadFromArg1 =
                        new DependencyAnalysis.X64.AddrMode(emit.TargetRegister.Arg1, null, 0, 0, DependencyAnalysis.X64.AddrModeSize.Int64);
                    emit.EmitMOV(emit.TargetRegister.Arg1, ref loadFromArg1);
                    emit.EmitMOV(emit.TargetRegister.Arg1, ref loadFromArg1);

                    emit.EmitJMP(_nodeFactory.ExternSymbol("__not_yet_implemented"));
                    methodCodeNodeNeedingCode.SetCode(emit.Builder.ToObjectData());
                    continue;
                }

                ObjectDataBuilder objData = new ObjectDataBuilder();
                objData.Alignment = _nodeFactory.Target.MinimumFunctionAlignment;
                objData.EmitBytes(methodCode.Code);
                objData.DefinedSymbols.Add(methodCodeNodeNeedingCode);

                BlobNode readOnlyDataBlob = null;
                if (methodCode.ROData != null)
                {
                    readOnlyDataBlob = _nodeFactory.ReadOnlyDataBlob(
                        "__readonlydata_" + _nameMangler.GetMangledMethodName(method),
                        methodCode.ROData, methodCode.RODataAlignment);
                }

                if (methodCode.Relocs != null)
                {
                    for (int i = 0; i < methodCode.Relocs.Length; i++)
                    {
                        // TODO: Arbitrary relocs
                        if (methodCode.Relocs[i].Block != BlockType.Code)
                        {
                            throw new NotImplementedException();
                        }

                        int         offset    = methodCode.Relocs[i].Offset;
                        int         delta     = methodCode.Relocs[i].Delta;
                        RelocType   relocType = (RelocType)methodCode.Relocs[i].RelocType;
                        ISymbolNode targetNode;

                        object target = methodCode.Relocs[i].Target;
                        if (target is MethodDesc)
                        {
                            targetNode = _nodeFactory.MethodEntrypoint((MethodDesc)target);
                        }
                        else if (target is ReadyToRunHelper)
                        {
                            targetNode = _nodeFactory.ReadyToRunHelper((ReadyToRunHelper)target);
                        }
                        else if (target is JitHelper)
                        {
                            targetNode = _nodeFactory.ExternSymbol(((JitHelper)target).MangledName);
                        }
                        else if (target is string)
                        {
                            targetNode = _nodeFactory.StringIndirection((string)target);
                        }
                        else if (target is TypeDesc)
                        {
                            targetNode = _nodeFactory.NecessaryTypeSymbol((TypeDesc)target);
                        }
                        else if (target is RvaFieldData)
                        {
                            var rvaFieldData = (RvaFieldData)target;
                            targetNode = _nodeFactory.ReadOnlyDataBlob(rvaFieldData.MangledName,
                                                                       rvaFieldData.Data, _typeSystemContext.Target.PointerSize);
                        }
                        else if (target is BlockRelativeTarget)
                        {
                            var blockRelativeTarget = (BlockRelativeTarget)target;
                            // TODO: Arbitrary block relative relocs
                            if (blockRelativeTarget.Block != BlockType.ROData)
                            {
                                throw new NotImplementedException();
                            }
                            targetNode = readOnlyDataBlob;
                        }
                        else
                        {
                            // TODO:
                            throw new NotImplementedException();
                        }

                        objData.AddRelocAtOffset(targetNode, relocType, offset, delta);
                    }
                }
                // TODO: ColdCode
                if (methodCode.ColdCode != null)
                {
                    throw new NotImplementedException();
                }

                methodCodeNodeNeedingCode.SetCode(objData.ToObjectData());

                methodCodeNodeNeedingCode.InitializeFrameInfos(methodCode.FrameInfos);
                methodCodeNodeNeedingCode.InitializeDebugLocInfos(methodCode.DebugLocInfos);
            }
        }
Ejemplo n.º 24
0
 public int EmitSymbolRef(Utf8StringBuilder symbolName, RelocType relocType, int delta = 0)
 {
     return(EmitSymbolRef(_nativeObjectWriter, symbolName.Append('\0').UnderlyingArray, relocType, delta));
 }
Ejemplo n.º 25
0
 public Relocation(RelocType relocType, int offset, ISymbolNode target)
 {
     RelocType = relocType;
     Offset    = offset;
     Target    = target;
 }
Ejemplo n.º 26
0
 private static extern int EmitSymbolRef(IntPtr objWriter, string symbolName, RelocType relocType, int delta);
Ejemplo n.º 27
0
 public void AddRelocation(MapFileNode node, RelocType relocType)
 {
     node.AddRelocation();
     _relocCounts.TryGetValue(relocType, out int relocTypeCount);
     _relocCounts[relocType] = relocTypeCount + 1;
 }
Ejemplo n.º 28
0
        // Returns size of the emitted symbol reference
        public int EmitSymbolReference(ISymbolNode target, int delta, RelocType relocType)
        {
            string targetName = GetSymbolToEmitForTargetPlatform(target.MangledName);

            return EmitSymbolRef(targetName, relocType, delta);
        }
Ejemplo n.º 29
0
 // IsDirectCallOrJump reports whether r is a relocation for a direct
 // call or a direct jump.
 public static bool IsDirectCallOrJump(this RelocType r)
 {
     return(r.IsDirectCall() || r.IsDirectJump());
 }