/// <summary> /// A request to patch already emitted code by storing the calculated virtualAddress value. /// </summary> /// <param name="linkType">Type of the link.</param> /// <param name="methodAddress">The virtual virtualAddress of the method whose code is being patched.</param> /// <param name="methodOffset">The value to store at the position in code.</param> /// <param name="methodRelativeBase">The method relative base.</param> /// <param name="targetAddress">The position in code, where it should be patched.</param> protected override void ApplyPatch(LinkType linkType, long methodAddress, long methodOffset, long methodRelativeBase, long targetAddress) { if (_symbolsResolved == false) { throw new InvalidOperationException(@"Can't apply patches - symbols not resolved."); } // Retrieve the text section Elf32Section text = (Elf32Section)GetSection(SectionKind.Text); // Calculate the patch offset long offset = (methodAddress - text.VirtualAddress.ToInt64()) + methodOffset; if ((linkType & LinkType.KindMask) == LinkType.AbsoluteAddress) { // FIXME: Need a .reloc section with a relocation entry if the module is moved in virtual memory // the runtime loader must patch this link request, we'll fail it until we can do relocations. //throw new NotSupportedException(@".reloc section not supported."); } else { // Change the absolute into a relative offset targetAddress = targetAddress - (methodAddress + methodRelativeBase); } // Save the stream position text.ApplyPatch(offset, linkType, targetAddress); }
/// <summary> /// Initializes a new instance of the <see cref="Elf32Linker"/> class. /// </summary> public Elf32Linker() { _sections = new List <LinkerSection>(); _fileAlignment = FileSectionAlignment; _sectionAlignment = SectionAlignment; // Create the default section set Elf32Section[] sections = new Elf32Section[(int)SectionKind.Max]; sections[(int)SectionKind.Text] = new Elf32CodeSection(); sections[(int)SectionKind.Data] = new Elf32DataSection(); sections[(int)SectionKind.ROData] = new Elf32RoDataSection(); sections[(int)SectionKind.BSS] = new Elf32BssSection(); _sections.AddRange(sections); _nullSection = new Elf32NullSection(); _stringTableSection = new Elf32StringTableSection(); }
/// <summary> /// Allocates a symbol of the given name in the specified section. /// </summary> /// <param name="section">The executable section to allocate From.</param> /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param> /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param> /// <returns> /// A stream, which can be used to populate the section. /// </returns> protected override Stream Allocate(SectionKind section, int size, int alignment) { Elf32Section linkerSection = (Elf32Section)GetSection(section); return(linkerSection.Allocate(size, alignment)); }