From 21d1ed5ab6070d026eb78e6608caaadb27742f9c Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sun, 8 Dec 2019 19:28:31 -0500 Subject: [PATCH] support 64-bit architectures --- .../Executable/ELF/ELFDataFormat.cs | 92 ++++--------------- .../Executable/ELF/ELFSectionEntry.cs | 89 ++++++++++++++++++ .../MicrosoftExecutableDataFormat.cs | 2 +- .../Executable/ExecutableSection.cs | 4 +- .../UniversalEditor.Plugins.Executable.csproj | 1 + 5 files changed, 109 insertions(+), 79 deletions(-) create mode 100644 CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFSectionEntry.cs diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFDataFormat.cs index 820a716e..421f6026 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFDataFormat.cs +++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFDataFormat.cs @@ -54,72 +54,6 @@ namespace UniversalEditor.DataFormats.Executable.ELF unsigned char = Unsigned 1 byte integer */ - private struct ELFSectionEntry - { - public string name; - /// - /// This member specifies the name of the section. Its value is an index into - /// the section header string table section, giving the location of a - /// null-terminated string. - /// - public uint nameindex; - /// - /// This member categorizes the section’s contents and semantics. Section types - /// and their descriptions appear below. - /// - public ELFSectionType type; - /// - /// Sections support 1-bit flags that describe miscellaneous attributes. - /// - public ELFSectionFlags flags; - /// - /// If the section will appear in the memory image of a process, this member - /// gives the address at which the section’s first byte should reside. - /// Otherwise, the member contains 0. - /// - public uint addr; - /// - /// This member’s value gives the byte offset from the beginning of the file - /// to the first byte in the section. One section type, SHT_NOBITS described - /// below, occupies no space in the file, and its sh_offset member locates - /// the conceptual placement in the file. - /// - public uint offset; - /// - /// This member gives the section’s size in bytes. Unless the section type is - /// SHT_NOBITS, the section occupies sh_size bytes in the file. A section of - /// type SHT_NOBITS may have a non-zero size, but it occupies no space in the - /// file. - /// - public uint size; - /// - /// This member holds a section header table index link, whose interpretation - /// depends on the section type. A table below describes the values. - /// - public uint link; - /// - /// This member holds extra information, whose interpretation depends on the - /// section type. A table below describes the values. - /// - public uint info; - /// - /// Some sections have address alignment constraints. For example, if a - /// section holds a doubleword, the system must ensure doubleword alignment - /// for the entire section. That is, the value of sh_addr must be congruent - /// to 0, modulo the value of sh_addralign. Currently, only 0 and positive - /// integral powers of two are allowed. Values 0 and 1 mean the section has - /// no alignment constraints. - /// - public uint addralign; - /// - /// Some sections hold a table of fixed-size entries, such as a symbol table. - /// For such a section, this member gives the size in bytes of each entry. - /// The member contains 0 if the section does not hold a table of fixed-size - /// entries. - /// - public uint entsize; - } - protected override void LoadInternal(ref ObjectModel objectModel) { ExecutableObjectModel exe = (objectModel as ExecutableObjectModel); @@ -146,19 +80,19 @@ namespace UniversalEditor.DataFormats.Executable.ELF mvarObjectFileType = (ELFObjectFileType)br.ReadUInt16(); mvarMachine = (ELFMachine)br.ReadUInt16(); uint e_version = br.ReadUInt32(); - + // This member gives the virtual address to which the system first transfers // control, thus starting the process. If the file has no associated entry // point, this member holds zero. - uint e_entry = br.ReadUInt32(); + ulong e_entry = ReadAddress(br); // This member holds the program header table’s file offset in bytes. If the // file has no program header table, this member holds zero. - uint e_phoff = br.ReadUInt32(); + ulong e_phoff = ReadAddress(br); // This member holds the section header table’s file offset in bytes. If the // file has no section header table, this member holds zero. - uint e_shoff = br.ReadUInt32(); + ulong e_shoff = ReadAddress(br); // This member holds processor-specific flags associated with the file. Flag // names take the form EF_machine_flag. See "Machine Information" for flag @@ -193,21 +127,21 @@ namespace UniversalEditor.DataFormats.Executable.ELF ushort e_shstrndx = br.ReadUInt16(); #endregion #region Section Table - br.Accessor.Position = baseoffset + e_shoff; + br.Accessor.Position = baseoffset + (long)e_shoff; List sections = new List(); for (ushort i = 0; i < e_shnum; i++) { ELFSectionEntry sh = new ELFSectionEntry(); sh.nameindex = br.ReadUInt32(); sh.type = (ELFSectionType)br.ReadUInt32(); - sh.flags = (ELFSectionFlags)br.ReadUInt32(); - sh.addr = br.ReadUInt32(); + sh.flags = (ELFSectionFlags)(Capacity == ELFCapacity.elf64Bit ? br.ReadUInt64() : br.ReadUInt32()); + sh.addr = ReadAddress(br); sh.offset = br.ReadUInt32(); - sh.size = br.ReadUInt32(); + sh.size = (Capacity == ELFCapacity.elf64Bit ? br.ReadUInt64() : br.ReadUInt32()); sh.link = br.ReadUInt32(); sh.info = br.ReadUInt32(); - sh.addralign = br.ReadUInt32(); - sh.entsize = br.ReadUInt32(); + sh.addralign = (Capacity == ELFCapacity.elf64Bit ? br.ReadUInt64() : br.ReadUInt32()); + sh.entsize = (Capacity == ELFCapacity.elf64Bit ? br.ReadUInt64() : br.ReadUInt32()); sections.Add(sh); } #endregion @@ -239,6 +173,12 @@ namespace UniversalEditor.DataFormats.Executable.ELF } } + private ulong ReadAddress(Reader br) + { + bool is64bit = Capacity == ELFCapacity.elf64Bit; + return (is64bit ? br.ReadUInt64() : br.ReadUInt32()); + } + private void sect_DataRequest(object sender, DataRequestEventArgs e) { ExecutableSection sect = (sender as ExecutableSection); diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFSectionEntry.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFSectionEntry.cs new file mode 100644 index 00000000..dcbda12b --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/ELF/ELFSectionEntry.cs @@ -0,0 +1,89 @@ +// +// ELFSectionEntry.cs +// +// Author: +// Mike Becker +// +// Copyright (c) 2019 Mike Becker +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace UniversalEditor.DataFormats.Executable.ELF +{ + public struct ELFSectionEntry + { + public string name; + /// + /// This member specifies the name of the section. Its value is an index into + /// the section header string table section, giving the location of a + /// null-terminated string. + /// + public uint nameindex; + /// + /// This member categorizes the section’s contents and semantics. Section types + /// and their descriptions appear below. + /// + public ELFSectionType type; + /// + /// Sections support 1-bit flags that describe miscellaneous attributes. + /// + public ELFSectionFlags flags; + /// + /// If the section will appear in the memory image of a process, this member + /// gives the address at which the section’s first byte should reside. + /// Otherwise, the member contains 0. + /// + public ulong addr; + /// + /// This member’s value gives the byte offset from the beginning of the file + /// to the first byte in the section. One section type, SHT_NOBITS described + /// below, occupies no space in the file, and its sh_offset member locates + /// the conceptual placement in the file. + /// + public uint offset; + /// + /// This member gives the section’s size in bytes. Unless the section type is + /// SHT_NOBITS, the section occupies sh_size bytes in the file. A section of + /// type SHT_NOBITS may have a non-zero size, but it occupies no space in the + /// file. + /// + public ulong size; + /// + /// This member holds a section header table index link, whose interpretation + /// depends on the section type. A table below describes the values. + /// + public uint link; + /// + /// This member holds extra information, whose interpretation depends on the + /// section type. A table below describes the values. + /// + public uint info; + /// + /// Some sections have address alignment constraints. For example, if a + /// section holds a doubleword, the system must ensure doubleword alignment + /// for the entire section. That is, the value of sh_addr must be congruent + /// to 0, modulo the value of sh_addralign. Currently, only 0 and positive + /// integral powers of two are allowed. Values 0 and 1 mean the section has + /// no alignment constraints. + /// + public ulong addralign; + /// + /// Some sections hold a table of fixed-size entries, such as a symbol table. + /// For such a section, this member gives the size in bytes of each entry. + /// The member contains 0 if the section does not hold a table of fixed-size + /// entries. + /// + public ulong entsize; + } +} diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs index 151082a6..b668d4fc 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs +++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/DataFormats/Executable/Microsoft/MicrosoftExecutableDataFormat.cs @@ -740,7 +740,7 @@ Watcom C++ 10.6 W?h$n(i)v W?h$n(ia)v W?h$n()v { PESectionHeader pesh = new PESectionHeader(); pesh.name = section.Name; - pesh.virtualSize = section.VirtualSize; + pesh.virtualSize = (uint) section.VirtualSize; pesh.virtualAddress = (uint)offset; pesh.rawDataPtr = (uint)offset; pesh.rawDataSize = (uint)section.Data.Length; diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/ObjectModels/Executable/ExecutableSection.cs b/CSharp/Plugins/UniversalEditor.Plugins.Executable/ObjectModels/Executable/ExecutableSection.cs index 8bac287d..a7d3c7e9 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.Executable/ObjectModels/Executable/ExecutableSection.cs +++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/ObjectModels/Executable/ExecutableSection.cs @@ -160,8 +160,8 @@ namespace UniversalEditor.ObjectModels.Executable System.IO.File.WriteAllBytes(FileName, mvarData); } - private uint mvarVirtualSize = 0; - public uint VirtualSize { get { return mvarVirtualSize; } set { mvarVirtualSize = value; } } + private ulong mvarVirtualSize = 0; + public ulong VirtualSize { get { return mvarVirtualSize; } set { mvarVirtualSize = value; } } private uint mvarRelocationOffset = 0; public uint RelocationOffset { get { return mvarRelocationOffset; } set { mvarRelocationOffset = value; } } diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj b/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj index dfc0e9ff..a03aec9c 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj +++ b/CSharp/Plugins/UniversalEditor.Plugins.Executable/UniversalEditor.Plugins.Executable.csproj @@ -101,6 +101,7 @@ +