Moved Over To OOP to Abstract ELF Binary Generation #1

Merged
Karutoh merged 5 commits from oop into main 2024-02-15 15:48:45 -08:00
15 changed files with 346 additions and 128 deletions
Showing only changes of commit 53a7e6b37d - Show all commits

View File

@ -27,6 +27,7 @@ endif ()
set(CMAKE_CXX_STANDARD 20)
add_executable(Compiler
src/ELF64_Sym.cpp include/ELF64_Sym.h
src/ELF64_Section.cpp include/ELF64_Section.h
src/ELF64_Program.cpp include/ELF64_Program.h
src/ELF64.cpp include/ELF64.h

Binary file not shown.

View File

@ -1,18 +1,22 @@
# ninja log v5
0 222 1707982539439184710 CMakeFiles/Compiler.dir/src/ELF64.cpp.o 7203a7b7f92d3a
0 161 1707978871138561402 CMakeFiles/Compiler.dir/src/ELF64_Program.cpp.o 6531657353b15e1e
1 171 1707981742781983377 CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o 886965ebb1584f45
222 286 1707982539502518597 Compiler ed968931e95b249c
0 57 1707982626129941948 build.ninja 8efbe7f6ed9511af
0 223 1707996608606923476 CMakeFiles/Compiler.dir/src/ELF64.cpp.o 7203a7b7f92d3a
1 162 1707992216831404362 CMakeFiles/Compiler.dir/src/ELF64_Program.cpp.o 6531657353b15e1e
1 166 1707996223750353941 CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o 886965ebb1584f45
223 282 1707996608663590955 Compiler 6d7a3ac418bcbfae
0 15 1707998140776325315 build.ninja 8efbe7f6ed9511af
1 166 1707955167336856399 CMakeFiles/Compiler.dir/main.cpp.o 7e18d66cc0ec0bf7
0 167 1707980675233295598 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
0 184 1707996608566922903 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
0 151 1707965004973740575 CMakeFiles/Compiler.dir/src/ELF.cpp.o bd59b885017e2e72
0 4 0 clean aa1517684869203c
0 163 1707982629519971506 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
163 223 1707982629579972029 Compiler 6d7a3ac418bcbfae
0 4 0 clean aa1517684869203c
1 155 1707982632830000361 CMakeFiles/Compiler.dir/src/ELF64_Program.cpp.o 6531657353b15e1e
1 168 1707982632843333811 CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o 886965ebb1584f45
1 176 1707982632850000536 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
1 230 1707982632903334334 CMakeFiles/Compiler.dir/src/ELF64.cpp.o 7203a7b7f92d3a
230 290 1707982632963334857 Compiler 6d7a3ac418bcbfae
0 3 0 clean aa1517684869203c
0 153 1708001529297448257 CMakeFiles/Compiler.dir/src/ELF64_Sym.cpp.o 9891c59f9d4d387b
0 170 1708001529314115065 CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o 886965ebb1584f45
1 171 1708001529317448427 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
0 227 1708001529374115574 CMakeFiles/Compiler.dir/src/ELF64.cpp.o 7203a7b7f92d3a
227 287 1708001529430782721 Compiler b603a0c69744a064
1 165 1708001692258830975 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
165 222 1708001692315498123 Compiler b603a0c69744a064
1 162 1708001814103198322 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
162 220 1708001814159865469 Compiler b603a0c69744a064
0 151 1708001978274591713 CMakeFiles/Compiler.dir/src/ELF64_Sym.cpp.o 9891c59f9d4d387b
0 173 1708001978297925244 CMakeFiles/Compiler.dir/src/main.cpp.o d6e32444f822aba9
173 236 1708001978357925753 Compiler b603a0c69744a064

Binary file not shown.

View File

@ -1,3 +1,3 @@
Start testing: Feb 14 23:37 PST
Start testing: Feb 15 05:04 PST
----------------------------------------------------------
End testing: Feb 14 23:37 PST
End testing: Feb 15 05:04 PST

View File

@ -49,6 +49,14 @@ cmake_ninja_workdir = /home/karutoh/CLionProjects/Compiler/cmake-build-debug/
build cmake_object_order_depends_target_Compiler: phony || CMakeFiles/Compiler.dir
build CMakeFiles/Compiler.dir/src/ELF64_Sym.cpp.o: CXX_COMPILER__Compiler_unscanned_Debug /home/karutoh/CLionProjects/Compiler/src/ELF64_Sym.cpp || cmake_object_order_depends_target_Compiler
DEFINES = -DLWE_WS_XCB
DEP_FILE = CMakeFiles/Compiler.dir/src/ELF64_Sym.cpp.o.d
FLAGS = -g -std=gnu++20 -fdiagnostics-color=always -Wno-stringop-overflow
INCLUDES = -I/home/karutoh/CLionProjects/Compiler/include
OBJECT_DIR = CMakeFiles/Compiler.dir
OBJECT_FILE_DIR = CMakeFiles/Compiler.dir/src
build CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o: CXX_COMPILER__Compiler_unscanned_Debug /home/karutoh/CLionProjects/Compiler/src/ELF64_Section.cpp || cmake_object_order_depends_target_Compiler
DEFINES = -DLWE_WS_XCB
DEP_FILE = CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o.d
@ -89,7 +97,7 @@ build CMakeFiles/Compiler.dir/src/main.cpp.o: CXX_COMPILER__Compiler_unscanned_D
#############################################
# Link the executable Compiler
build Compiler: CXX_EXECUTABLE_LINKER__Compiler_Debug CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o CMakeFiles/Compiler.dir/src/ELF64_Program.cpp.o CMakeFiles/Compiler.dir/src/ELF64.cpp.o CMakeFiles/Compiler.dir/src/main.cpp.o
build Compiler: CXX_EXECUTABLE_LINKER__Compiler_Debug CMakeFiles/Compiler.dir/src/ELF64_Sym.cpp.o CMakeFiles/Compiler.dir/src/ELF64_Section.cpp.o CMakeFiles/Compiler.dir/src/ELF64_Program.cpp.o CMakeFiles/Compiler.dir/src/ELF64.cpp.o CMakeFiles/Compiler.dir/src/main.cpp.o
FLAGS = -g
LINK_LIBRARIES = -Wl,-rpath,/home/karutoh/.local/lib -lxcb -lxcb-cursor -lxcb-xfixes -lxcb-xinput -lz -lasound -lEHS
LINK_PATH = -L/home/karutoh/.local/lib

View File

@ -29,7 +29,6 @@
class ELF64
{
private:
ehs::UInt_8 subArch;
ehs::UInt_8 endianness;
ehs::UInt_8 abi;
ehs::UInt_16 type;
@ -41,7 +40,7 @@ private:
public:
ELF64();
ELF64(ehs::UInt_8 subArch, ehs::UInt_8 end, ehs::UInt_8 abi, ehs::UInt_16 type, ehs::UInt_16 arch);
ELF64(ehs::UInt_8 end, ehs::UInt_8 abi, ehs::UInt_16 type, ehs::UInt_16 arch);
ELF64(ehs::Serializer<ehs::UInt_64>& data);
@ -53,8 +52,6 @@ public:
ELF64& operator=(const ELF64& header);
ehs::UInt_8 GetSubArchitecture() const;
ehs::UInt_8 GetEndianness() const;
ehs::UInt_8 GetABI() const;
@ -75,6 +72,16 @@ public:
void AddSection(ELF64_Section newSection);
ELF64_Section* GetSection(ehs::UInt_64 sectionHashId) const;
ELF64_Section* GetSection(const ehs::Str_8& sectionId) const;
ehs::UInt_64 GetLastSegmentOffset() const;
ehs::Vec2_u64 SegmentRange(ehs::UInt_64 sectionHashId);
ehs::Vec2_u64 SegmentRange(const ehs::Str_8& sectionId);
ehs::Serializer<ehs::UInt_64> Serialize() const;
private:

View File

@ -19,8 +19,6 @@ class ELF64_Program
private:
friend class ELF64;
ELF64* owner;
ehs::UInt_16 sectionIndex;
ehs::UInt_32 type;
ehs::UInt_32 flags;
ehs::UInt_64 offset;
@ -33,7 +31,7 @@ private:
public:
ELF64_Program();
ELF64_Program(ehs::UInt_16 sectionIndex, ehs::UInt_32 type, ehs::UInt_32 flags, ehs::UInt_64 address, ehs::UInt_64 align);
ELF64_Program(ehs::UInt_32 type, ehs::UInt_32 flags, ehs::UInt_64 offset, ehs::UInt_64 address, ehs::UInt_64 size, ehs::UInt_64 adjustedMemSize, ehs::UInt_64 align);
ELF64_Program(ehs::Serializer<ehs::UInt_64>& data);

View File

@ -7,6 +7,7 @@
/// Section types.
#define SECH_TYPE_NULL 0x0000
#define SECH_TYPE_PROGBITS 0x0001
#define SECH_TYPE_SYMTAB 0x0002
#define SECH_TYPE_STRTAB 0x0003
/// Section flags.
@ -23,22 +24,22 @@ private:
ehs::UInt_64 hashId;
ehs::Str_8 id;
ehs::UInt_32 programIndex;
ehs::UInt_32 nameOffset;
ehs::UInt_64 fileOffset;
ehs::UInt_32 type;
ehs::UInt_64 flags;
ehs::UInt_64 vAddr;
ehs::UInt_64 segmentOffset;
ehs::UInt_32 associatedIndex;
ehs::UInt_32 link;
ehs::UInt_32 info;
ehs::UInt_64 align;
ehs::UInt_64 entrySize;
ehs::UInt_64 entries;
ehs::Serializer<ehs::UInt_64> data;
public:
ELF64_Section();
ELF64_Section(ehs::Str_8 id, ehs::UInt_32 type, ehs::UInt_64 flags, ehs::UInt_64 align);
ELF64_Section(ehs::Str_8 id, ehs::UInt_64 fileOffset, ehs::UInt_32 type, ehs::UInt_64 flags, ehs::UInt_64 vAddr, ehs::UInt_64 align);
ELF64_Section(ELF64_Section&& sect) noexcept;
@ -58,8 +59,14 @@ public:
ehs::UInt_64 GetVirtualAddress() const;
void SetLink(ehs::UInt_32 newLink);
void SetInfo(ehs::UInt_32 newInfo);
ehs::UInt_64 GetAlignment() const;
void SetEntries(ehs::UInt_64 newEntries);
void SetData(ehs::Serializer<ehs::UInt_64> newData);
ehs::Serializer<ehs::UInt_64>& GetData();

93
include/ELF64_Sym.h Normal file
View File

@ -0,0 +1,93 @@
#pragma once
#include <ehs/Serializer.h>
/// The symbol's type is not specified.
#define SYM_TYPE_NOTYPE 0x00
/// The symbol is associated with a data object, such as a variable, an array, and so on.
#define SYM_TYPE_OBJECT 0x01
/// The symbol is associated with a function or other executable code.
#define SYM_TYPE_FUNC 0x02
/// The symbol is associated with a section. Symbol table entries of this type exist primarily for relocation and normally have STB_LOCAL binding.
#define SYM_TYPE_SECTION 0x03
/// Conventionally, the symbol's name gives the name of the source file associated with the object file. A file symbol has STB_LOCAL binding, its section index is SHN_ABS, and it precedes the other STB_LOCAL symbols for the file, if it is present.
#define SYM_TYPE_FILE 0x04
/// The symbol labels an uninitialized common block.
#define SYM_TYPE_COMMON 0x05
/// The symbol specifies a Thread-Local Storage entity. When defined, it gives the assigned offset for the symbol, not the actual address. Symbols of type STT_TLS can be referenced by only special thread-local storage relocations and thread-local storage relocations can only reference symbols with type STT_TLS. Implementation need not support thread-local storage.
#define SYM_TYPE_TLS 0x06
/// Values in this inclusive range are reserved for operating system-specific semantics.
#define SYM_TYPE_LOOS 0x0A
/// Values in this inclusive range are reserved for operating system-specific semantics.
#define SYM_TYPE_HIOS 0x0C
/// Values in this inclusive range are reserved for processor-specific semantics. If meanings are specified, the processor supplement explains them.
#define SYM_TYPE_LOPROC 0x0D
/// Values in this inclusive range are reserved for processor-specific semantics. If meanings are specified, the processor supplement explains them.
#define SYM_TYPE_HIPROC 0x0F
/// Local symbols are not visible outside the object file containing their definition. Local symbols of the same name may exist in multiple files without interfering with each other.
#define SYM_BIND_LOCAL 0x00
/// Global symbols are visible to all object files being combined. One file's definition of a global symbol will satisfy another file's undefined reference to the same global symbol.
#define SYM_BIND_GLOBAL 0x01
/// Weak symbols resemble global symbols, but their definitions have lower precedence.
#define SYM_BIND_WEAK 0x02
/// Values in this inclusive range are reserved for operating system-specific semantics.
#define SYM_BIND_LOOS 0x0A
/// Values in this inclusive range are reserved for operating system-specific semantics.
#define SYM_BIND_HIOS 0x0C
/// Values in this inclusive range are reserved for processor-specific semantics. If meanings are specified, the processor supplement explains them.
#define SYM_BIND_LOPROC 0x0D
/// Values in this inclusive range are reserved for processor-specific semantics. If meanings are specified, the processor supplement explains them.
#define SYM_BIND_HIPROC 0x0F
#define SYM_BIND(i) ((i)>>4)
#define SYM_TYPE(i) ((i)&0xf)
#define SYM_INFO(b,t) (((b)<<4)+((t)&0xf))
/// The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type. That is, global and weak symbols are visible outside of their defining component (executable file or shared object). Local symbols are hidden, as described below. Global and weak symbols are also preemptable, that is, they may by preempted by definitions of the same name in another component.
#define SYM_VIS_DEFAULT 0x00
/// The meaning of this visibility attribute may be defined by processor supplements to further constrain hidden symbols. A processor supplement's definition should be such that generic tools can safely treat internal symbols as hidden.
#define SYM_VIS_INTERNAL 0x01
/// A symbol defined in the current component is hidden if its name is not visible to other components. Such a symbol is necessarily protected. This attribute may be used to control the external interface of a component. Note that an object named by such a symbol may still be referenced from another component if its address is passed outside.
#define SYM_VIS_HIDDEN 0x02
/// A symbol defined in the current component is protected if it is visible in other components but not preemptable, meaning that any reference to such a symbol from within the defining component must be resolved to the definition in that component, even if there is a definition in another component that would preempt by the default rules. A symbol with STB_LOCAL binding may not have STV_PROTECTED visibility. If a symbol definition with STV_PROTECTED visibility from a shared object is taken as resolving a reference from an executable or another shared object, the SHN_UNDEF symbol table entry created has STV_DEFAULT visibility.
#define SYM_VIS_PROTECTED 0x03
#define SYM_SIZE 24
class ELF64_Sym
{
private:
ehs::UInt_32 nameOffset;
ehs::UInt_8 type;
ehs::UInt_8 visibility;
ehs::UInt_16 section;
ehs::UInt_64 value;
ehs::UInt_64 size;
public:
ELF64_Sym();
ELF64_Sym(ehs::UInt_32 nameOffset, ehs::UInt_8 type, ehs::UInt_8 visibility, ehs::UInt_16 section, ehs::UInt_64 value, ehs::UInt_64 size);
void Serialize(ehs::Serializer<ehs::UInt_64>& inData) const;
};

View File

@ -4,14 +4,14 @@ constexpr ehs::Char_8 Elf_Magic[] = "\x7F" "ELF";
constexpr ehs::UInt_8 Elf_Magic_Size = sizeof(Elf_Magic) - 1;
ELF64::ELF64()
: subArch(ELFH_ARCH_64), endianness(ELFH_END_LE), abi(ELFH_ABI_SYSTEMV), type(ELFH_TYPE_EXEC),
: endianness(ELFH_END_LE), abi(ELFH_ABI_SYSTEMV), type(ELFH_TYPE_EXEC),
arch(ELFH_MARCH_AMD_X86_64), entryPoint(0)
{
InitializeSections();
}
ELF64::ELF64(ehs::UInt_8 subArch, ehs::UInt_8 end, ehs::UInt_8 abi, ehs::UInt_16 type, ehs::UInt_16 arch)
: subArch(subArch), endianness(end), abi(abi), type(type), arch(arch), entryPoint(0)
ELF64::ELF64(ehs::UInt_8 end, ehs::UInt_8 abi, ehs::UInt_16 type, ehs::UInt_16 arch)
: endianness(end), abi(abi), type(type), arch(arch), entryPoint(0)
{
InitializeSections();
}
@ -21,11 +21,10 @@ ELF64::ELF64(ehs::Serializer<ehs::UInt_64>& data)
}
ELF64::ELF64(ELF64&& header) noexcept
: subArch(header.subArch), endianness(header.endianness), abi(header.abi), type(header.type), arch(header.arch),
: endianness(header.endianness), abi(header.abi), type(header.type), arch(header.arch),
entryPoint(header.entryPoint), programs((ehs::Vector<ELF64_Program, ehs::UInt_16>&&)header.programs),
sections((ehs::Vector<ELF64_Section, ehs::UInt_16>&&)header.sections)
{
header.subArch = ELFH_ARCH_64;
header.endianness = ELFH_END_LE;
header.abi = ELFH_ABI_SYSTEMV;
header.type = ELFH_TYPE_EXEC;
@ -36,7 +35,7 @@ ELF64::ELF64(ELF64&& header) noexcept
}
ELF64::ELF64(const ELF64& header)
: subArch(header.subArch), endianness(header.endianness), abi(header.abi), type(header.type), arch(header.arch),
: endianness(header.endianness), abi(header.abi), type(header.type), arch(header.arch),
entryPoint(header.entryPoint), programs(header.programs), sections(header.sections)
{
}
@ -46,7 +45,6 @@ ELF64& ELF64::operator=(ELF64&& header) noexcept
if (this == &header)
return *this;
subArch = header.subArch;
endianness = header.endianness;
abi = header.abi;
type = header.type;
@ -55,7 +53,6 @@ ELF64& ELF64::operator=(ELF64&& header) noexcept
programs = (ehs::Vector<ELF64_Program, ehs::UInt_16>&&)header.programs;
sections = (ehs::Vector<ELF64_Section, ehs::UInt_16>&&)header.sections;
header.subArch = ELFH_ARCH_64;
header.endianness = ELFH_END_LE;
header.abi = ELFH_ABI_SYSTEMV;
header.type = ELFH_TYPE_EXEC;
@ -72,7 +69,6 @@ ELF64& ELF64::operator=(const ELF64& header)
if (this == &header)
return *this;
subArch = header.subArch;
endianness = header.endianness;
abi = header.abi;
type = header.type;
@ -84,11 +80,6 @@ ELF64& ELF64::operator=(const ELF64& header)
return *this;
}
ehs::UInt_8 ELF64::GetSubArchitecture() const
{
return subArch;
}
ehs::UInt_8 ELF64::GetEndianness() const
{
return endianness;
@ -142,13 +133,6 @@ void ELF64::AddProgram(ELF64_Program newProgram)
}
*/
newProgram.owner = this;
if (programs.Size())
sections[newProgram.sectionIndex].programIndex = programs.End() + 1;
else
sections[newProgram.sectionIndex].programIndex = programs.End();
programs.Push((ELF64_Program&&)newProgram);
}
@ -189,6 +173,71 @@ void ELF64::AddSection(ELF64_Section newSection)
sections.Push((ELF64_Section&&)newSection);
}
ELF64_Section* ELF64::GetSection(ehs::UInt_64 sectionHashId) const
{
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
if (sections[i].GetHashId() == sectionHashId)
return &sections[i];
return nullptr;
}
ELF64_Section* ELF64::GetSection(const ehs::Str_8& sectionId) const
{
return GetSection(sectionId.Hash_64());
}
ehs::UInt_64 ELF64::GetLastSegmentOffset() const
{
ehs::UInt_64 offset = ELFH_SIZE + PRGH_SIZE * programs.Size();
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
{
if (sections[i].fileOffset)
offset = sections[i].fileOffset;
offset += sections[i].GetData().Size();
}
return offset;
}
ehs::Vec2_u64 ELF64::SegmentRange(ehs::UInt_64 sectionHashId)
{
ehs::UInt_64 offset = ELFH_SIZE + PRGH_SIZE * programs.Size();
if (sectionHashId)
{
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
{
if (sections[i].GetHashId() == sectionHashId)
return {offset, sections[i].GetData().Size()};
else
{
if (sections[i].fileOffset)
offset = sections[i].fileOffset;
offset += sections[i].GetData().Size();
}
}
}
else
{
ehs::UInt_64 scale = 0;
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
scale += sections[i].GetData().Size();
return {offset, scale};
}
return {};
}
ehs::Vec2_u64 ELF64::SegmentRange(const ehs::Str_8& sectionId)
{
return SegmentRange(sectionId.Hash_64());
}
ehs::Serializer<ehs::UInt_64> ELF64::Serialize() const
{
ehs::Serializer<ehs::UInt_64> result(ehs::Endianness::LE);
@ -196,7 +245,7 @@ ehs::Serializer<ehs::UInt_64> ELF64::Serialize() const
ehs::Util::Copy(&result[0], Elf_Magic, Elf_Magic_Size);
result.SetOffset(Elf_Magic_Size);
result.Write(subArch);
result.Write<ehs::UInt_8>(ELFH_ARCH_64);
result.Write(endianness);
result.Write<ehs::UInt_8>(1);
result.Write(abi);
@ -209,10 +258,7 @@ ehs::Serializer<ehs::UInt_64> ELF64::Serialize() const
result.Write(type);
result.Write(arch);
result.Write<ehs::UInt_32>(1);
ehs::UInt_64 entryAddress = result.GetOffset();
result.Write<ehs::UInt_64>(0);
result.Write(programs[entryPoint].pAddr);
result.Write<ehs::UInt_64>(ELFH_SIZE);
result.Write(RetrieveSectionsOffset());
result.Write<ehs::UInt_32>(0);
@ -223,34 +269,25 @@ ehs::Serializer<ehs::UInt_64> ELF64::Serialize() const
result.Write(sections.Size());
result.Write(FindShStrTabIndex());
ehs::Array<ehs::Serializer<ehs::UInt_64>, ehs::UInt_16> segmentData(sections.Size());
ehs::UInt_64 segmentOffset = 0;
const ehs::UInt_64 programsSize = PRGH_SIZE * programs.Size();
for (ehs::UInt_16 i = 1; i < sections.Size(); i++)
{
sections[i].segmentOffset = result.GetOffset() + programsSize + segmentOffset;
segmentData[i] = sections[i].GetData();
if (sections[i].programIndex < EHS_UINT_16_MAX + 1)
{
sections[i].vAddr = programs[entryPoint].pAddr + result.GetOffset() + programsSize + segmentOffset;
programs[sections[i].programIndex].fileSize = segmentData[i].Size();
}
segmentOffset += segmentData[i].Size();
}
for (ehs::UInt_16 i = 0; i < programs.Size(); i++)
programs[i].Serialize(result);
for (ehs::UInt_16 i = 0; i < segmentData.Size(); i++)
result.WriteSer(segmentData[i]);
for (ehs::UInt_16 i = 1; i < sections.Size(); i++)
{
if (sections[i].fileOffset)
{
ehs::UInt_64 padding = sections[i].fileOffset - result.Size();
result.Resize(result.Size() + padding);
ehs::Util::Zero(&result[result.GetOffset()], padding);
result.SetOffset(result.GetOffset() + padding);
}
sections[i].segmentOffset = result.GetOffset();
result.WriteSer(sections[i].GetData());
}
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
sections[i].Serialize(result);
*(ehs::UInt_64*)(&result[entryAddress]) = programs[entryPoint].pAddr + sections[programs[entryPoint].sectionIndex].segmentOffset;
return result;
}
@ -259,11 +296,11 @@ void ELF64::InitializeSections()
{
ehs::Str_8 nullName = ".NULL";
ELF64_Section null(nullName, SECH_TYPE_NULL, 0, 0);
ELF64_Section null(nullName, 0, SECH_TYPE_NULL, 0, 0, 0);
ehs::Str_8 shStrTabName = ".shstrtab";
ELF64_Section shStrTab(shStrTabName, SECH_TYPE_STRTAB, SECH_FLAG_STRINGS, 1);
ELF64_Section shStrTab(shStrTabName, 0, SECH_TYPE_STRTAB, SECH_FLAG_STRINGS, 0, 1);
ehs::Serializer<ehs::UInt_64>& data = shStrTab.GetData();
@ -288,7 +325,12 @@ ehs::UInt_64 ELF64::RetrieveSectionsOffset() const
ehs::UInt_64 result = ELFH_SIZE + PRGH_SIZE * programs.Size();
for (ehs::UInt_16 i = 0; i < sections.Size(); i++)
{
if (sections[i].fileOffset)
result = sections[i].fileOffset;
result += sections[i].GetData().Size();
}
return result;
}

View File

@ -1,30 +1,27 @@
#include "ELF64_Program.h"
ELF64_Program::ELF64_Program()
: owner(nullptr), sectionIndex(0), type(PRGH_TYPE_LOAD), flags(PRGH_FLAG_EXEC | PRGH_FLAG_READ), offset(0), vAddr(0),
pAddr(0), fileSize(0), adjustedMemSize(0), align(0x200000)
: type(PRGH_TYPE_LOAD), flags(PRGH_FLAG_EXEC | PRGH_FLAG_READ), offset(0), vAddr(0), pAddr(0), fileSize(0),
adjustedMemSize(0), align(0x200000)
{
}
ELF64_Program::ELF64_Program(ehs::UInt_16 sectionIndex, ehs::UInt_32 type, ehs::UInt_32 flags, ehs::UInt_64 address, ehs::UInt_64 align)
: owner(nullptr), sectionIndex(sectionIndex), type(type), flags(flags), offset(0), vAddr(address), pAddr(address),
fileSize(0), adjustedMemSize(0), align(align)
ELF64_Program::ELF64_Program(ehs::UInt_32 type, ehs::UInt_32 flags, ehs::UInt_64 offset, ehs::UInt_64 address, ehs::UInt_64 size, ehs::UInt_64 adjustedMemSize, ehs::UInt_64 align)
: type(type), flags(flags), offset(offset), vAddr(address), pAddr(address), fileSize(size),
adjustedMemSize(adjustedMemSize), align(align)
{
}
ELF64_Program::ELF64_Program(ehs::Serializer<ehs::UInt_64>& data)
: owner(nullptr), sectionIndex(0), type(PRGH_TYPE_LOAD), flags(PRGH_FLAG_EXEC | PRGH_FLAG_READ), offset(0), vAddr(0),
pAddr(0), fileSize(0), adjustedMemSize(0), align(0x200000)
: type(PRGH_TYPE_LOAD), flags(PRGH_FLAG_EXEC | PRGH_FLAG_READ), offset(0), vAddr(0), pAddr(0), fileSize(0),
adjustedMemSize(0), align(0x200000)
{
}
ELF64_Program::ELF64_Program(ELF64_Program&& program) noexcept
: owner(program.owner), sectionIndex(program.sectionIndex), type(program.type), flags(program.flags),
offset(program.offset), vAddr(program.vAddr), pAddr(program.pAddr), fileSize(program.fileSize),
adjustedMemSize(program.adjustedMemSize), align(program.align)
: type(program.type), flags(program.flags), offset(program.offset), vAddr(program.vAddr), pAddr(program.pAddr),
fileSize(program.fileSize), adjustedMemSize(program.adjustedMemSize), align(program.align)
{
program.owner = nullptr;
program.sectionIndex = 0;
program.type = PRGH_TYPE_LOAD;
program.flags = PRGH_FLAG_EXEC | PRGH_FLAG_READ;
program.offset = 0;
@ -36,9 +33,8 @@ ELF64_Program::ELF64_Program(ELF64_Program&& program) noexcept
}
ELF64_Program::ELF64_Program(const ELF64_Program& program)
: owner(nullptr), sectionIndex(0), type(program.type), flags(program.flags),
offset(program.offset), vAddr(program.vAddr), pAddr(program.pAddr), fileSize(program.fileSize),
adjustedMemSize(program.adjustedMemSize), align(program.align)
: type(program.type), flags(program.flags), offset(program.offset), vAddr(program.vAddr), pAddr(program.pAddr),
fileSize(program.fileSize), adjustedMemSize(program.adjustedMemSize), align(program.align)
{
}
@ -47,8 +43,6 @@ ELF64_Program& ELF64_Program::operator=(ELF64_Program&& program) noexcept
if (this == &program)
return *this;
owner = program.owner;
sectionIndex = program.sectionIndex;
type = program.type;
flags = program.flags;
offset = program.offset;
@ -58,8 +52,6 @@ ELF64_Program& ELF64_Program::operator=(ELF64_Program&& program) noexcept
adjustedMemSize = program.adjustedMemSize;
align = program.align;
program.owner = nullptr;
program.sectionIndex = 0;
program.type = PRGH_TYPE_LOAD;
program.flags = PRGH_FLAG_EXEC | PRGH_FLAG_READ;
program.offset = 0;
@ -77,8 +69,6 @@ ELF64_Program& ELF64_Program::operator=(const ELF64_Program& program)
if (this == &program)
return *this;
owner = nullptr;
sectionIndex = program.sectionIndex;
type = program.type;
flags = program.flags;
offset = program.offset;

View File

@ -1,41 +1,41 @@
#include "ELF64_Section.h"
ELF64_Section::ELF64_Section()
: hashId(0), programIndex(EHS_UINT_16_MAX + 1), nameOffset(0), type(0), flags(0), vAddr(0), segmentOffset(0), associatedIndex(0),
info(0), align(0), entrySize(0), data(ehs::Endianness::LE)
: hashId(0), nameOffset(0), fileOffset(0), type(0), flags(0), vAddr(0), segmentOffset(0), link(0),
info(0), align(0), entries(0), data(ehs::Endianness::LE)
{
}
ELF64_Section::ELF64_Section(ehs::Str_8 id, ehs::UInt_32 type, ehs::UInt_64 flags, ehs::UInt_64 align)
: hashId(id.Hash_64()), id((ehs::Str_8&&)id), programIndex(EHS_UINT_16_MAX + 1), nameOffset(0), type(type), flags(flags), vAddr(0),
segmentOffset(0), associatedIndex(0), info(0), align(align), entrySize(0), data(ehs::Endianness::LE)
ELF64_Section::ELF64_Section(ehs::Str_8 id, ehs::UInt_64 fileOffset, ehs::UInt_32 type, ehs::UInt_64 flags, ehs::UInt_64 vAddr, ehs::UInt_64 align)
: hashId(id.Hash_64()), id((ehs::Str_8&&)id), nameOffset(0), fileOffset(fileOffset), type(type), flags(flags), vAddr(vAddr),
segmentOffset(0), link(0), info(0), align(align), entries(0), data(ehs::Endianness::LE)
{
}
ELF64_Section::ELF64_Section(ELF64_Section&& sect) noexcept
: hashId(sect.hashId), id((ehs::Str_8&&)sect.id), programIndex(sect.programIndex), nameOffset(sect.nameOffset),
: hashId(sect.hashId), id((ehs::Str_8&&)sect.id), nameOffset(sect.nameOffset), fileOffset(sect.fileOffset),
type(sect.type), flags(sect.flags), vAddr(sect.vAddr), segmentOffset(sect.segmentOffset),
associatedIndex(sect.associatedIndex), info(sect.info), align(sect.align), entrySize(sect.entrySize),
link(sect.link), info(sect.info), align(sect.align), entries(sect.entries),
data((ehs::Serializer<ehs::UInt_64>&&)sect.data)
{
sect.hashId = 0;
sect.programIndex = EHS_UINT_16_MAX + 1;
sect.nameOffset = 0;
sect.fileOffset = 0;
sect.type = 0;
sect.flags = 0;
sect.vAddr = 0;
sect.segmentOffset = 0;
sect.associatedIndex = 0;
sect.link = 0;
sect.info = 0;
sect.align = 0;
sect.entrySize = 0;
sect.entries = 0;
}
ELF64_Section::ELF64_Section(const ELF64_Section& sect)
: hashId(sect.hashId), id(sect.id), programIndex(EHS_UINT_16_MAX + 1), nameOffset(0), type(sect.type),
flags(sect.flags), vAddr(sect.vAddr), segmentOffset(sect.segmentOffset), associatedIndex(sect.associatedIndex),
info(sect.info), align(sect.align), entrySize(sect.entrySize), data(sect.data)
: hashId(sect.hashId), id(sect.id), nameOffset(0), fileOffset(sect.fileOffset), type(sect.type),
flags(sect.flags), vAddr(sect.vAddr), segmentOffset(sect.segmentOffset), link(sect.link),
info(sect.info), align(sect.align), entries(sect.entries), data(sect.data)
{
}
@ -46,29 +46,29 @@ ELF64_Section& ELF64_Section::operator=(ELF64_Section&& sect) noexcept
hashId = sect.hashId;
id = (ehs::Str_8&&)sect.id;
programIndex = sect.programIndex;
nameOffset = sect.nameOffset;
fileOffset = sect.fileOffset;
type = sect.type;
flags = sect.flags;
vAddr = sect.vAddr;
segmentOffset = sect.segmentOffset;
associatedIndex = sect.associatedIndex;
link = sect.link;
info = sect.info;
align = sect.align;
entrySize = sect.entrySize;
entries = sect.entries;
data = (ehs::Serializer<ehs::UInt_64>&&)sect.data;
sect.hashId = 0;
sect.programIndex = EHS_UINT_16_MAX + 1;
sect.nameOffset = 0;
sect.fileOffset = 0;
sect.type = 0;
sect.flags = 0;
sect.vAddr = 0;
sect.segmentOffset = 0;
sect.associatedIndex = 0;
sect.link = 0;
sect.info = 0;
sect.align = 0;
sect.entrySize = 0;
sect.entries = 0;
sect.data = {ehs::Endianness::LE};
return *this;
@ -81,16 +81,16 @@ ELF64_Section& ELF64_Section::operator=(const ELF64_Section& sect)
hashId = sect.hashId;
id = sect.id;
programIndex = EHS_UINT_16_MAX + 1;
nameOffset = 0;
fileOffset = sect.fileOffset;
type = sect.type;
flags = sect.flags;
vAddr = sect.vAddr;
segmentOffset = sect.segmentOffset;
associatedIndex = sect.associatedIndex;
link = sect.link;
info = sect.info;
align = sect.align;
entrySize = sect.entrySize;
entries = sect.entries;
data = sect.data;
return *this;
@ -121,11 +121,26 @@ ehs::UInt_64 ELF64_Section::GetVirtualAddress() const
return vAddr;
}
void ELF64_Section::SetLink(ehs::UInt_32 newLink)
{
link = newLink;
}
void ELF64_Section::SetInfo(ehs::UInt_32 newInfo)
{
info = newInfo;
}
ehs::UInt_64 ELF64_Section::GetAlignment() const
{
return align;
}
void ELF64_Section::SetEntries(ehs::UInt_64 newEntries)
{
entries = newEntries;
}
void ELF64_Section::SetData(ehs::Serializer<ehs::UInt_64> newData)
{
data = (ehs::Serializer<ehs::UInt_64>&&)newData;
@ -144,8 +159,8 @@ void ELF64_Section::Serialize(ehs::Serializer<ehs::UInt_64>& inData) const
inData.Write(vAddr);
inData.Write(segmentOffset);
inData.Write(data.Size());
inData.Write(associatedIndex);
inData.Write(link);
inData.Write(info);
inData.Write(align);
inData.Write(entrySize);
inData.Write(entries);
}

23
src/ELF64_Sym.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "ELF64_Sym.h"
ELF64_Sym::ELF64_Sym()
: nameOffset(0), type(0), visibility(0), section(0), value(0), size(0)
{
}
ELF64_Sym::ELF64_Sym(ehs::UInt_32 nameOffset, ehs::UInt_8 type, ehs::UInt_8 visibility, ehs::UInt_16 section, ehs::UInt_64 value, ehs::UInt_64 size)
: nameOffset(nameOffset), type(type), visibility(visibility), section(section), value(value), size(size)
{
}
void ELF64_Sym::Serialize(ehs::Serializer<ehs::UInt_64>& inData) const
{
inData.Write(nameOffset);
inData.Write(type);
inData.Write(visibility);
inData.Write(section);
inData.Write(value);
inData.Write(size);
}

View File

@ -1,4 +1,5 @@
#include "ELF64.h"
#include "ELF64_Sym.h"
#include <ehs/EHS.h>
#include <ehs/io/Console.h>
@ -23,13 +24,42 @@ ehs::SInt_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVe
ehs::Serializer<ehs::UInt_64> code = codeFile.ReadSerializer_64(ehs::Endianness::LE, codeFile.Size());
codeFile.Release();
ELF64 executable(ELFH_ARCH_64, ELFH_END_LE, ELFH_ABI_SYSTEMV, ELFH_TYPE_EXEC, ELFH_MARCH_AMD_X86_64);
ELF64 executable(ELFH_END_LE, ELFH_ABI_SYSTEMV, ELFH_TYPE_EXEC, ELFH_MARCH_AMD_X86_64);
ELF64_Section text(".text", SECH_TYPE_PROGBITS, SECH_FLAG_ALLOC | SECH_FLAG_EXEC, 16);
ehs::UInt_64 lSgmtOffset = executable.GetLastSegmentOffset();
ELF64_Section text(".text", 0x1000, SECH_TYPE_PROGBITS, SECH_FLAG_ALLOC | SECH_FLAG_EXEC, 0x401000, 16);
text.SetData(code);
executable.AddSection(text);
executable.AddSection((ELF64_Section&&)text);
executable.AddProgram({2, PRGH_TYPE_LOAD, PRGH_FLAG_EXEC | PRGH_FLAG_READ, 0x400000, 0x200000});
ELF64_Section strTab(".strtab", 0, SECH_TYPE_STRTAB, 0, 0, 1);
ehs::Serializer<ehs::UInt_64>& strTabData = strTab.GetData();
constexpr ehs::Char_8 symName[] = "\0_start\0";
strTabData.Resize(sizeof(symName));
ehs::Util::Copy(&strTabData[0], symName, sizeof(symName));
strTabData.SetOffset(sizeof(symName));
executable.AddSection((ELF64_Section&&)strTab);
ELF64_Section symTab(".symtab", 0, SECH_TYPE_SYMTAB, 0, 0, 8);
symTab.SetLink(3);
symTab.SetInfo(2);
symTab.SetEntries(24);
ehs::Serializer<ehs::UInt_64>& symTabData = symTab.GetData();
ELF64_Sym nullSym;
nullSym.Serialize(symTabData);
ELF64_Sym _start(1, SYM_INFO(SYM_BIND_GLOBAL, SYM_TYPE_NOTYPE), SYM_VIS_DEFAULT, 2, 0x401000, 0);
_start.Serialize(symTabData);
executable.AddSection((ELF64_Section&&)symTab);
executable.AddProgram({PRGH_TYPE_LOAD, PRGH_FLAG_READ, 0, 0x400000, lSgmtOffset, 0, 0x1000});
executable.AddProgram({PRGH_TYPE_LOAD, PRGH_FLAG_EXEC | PRGH_FLAG_READ, 0x1000, 0x401000, code.Size(), 0, 0x1000});
executable.SetEntryPoint(1);
ehs::File file(args[2].RemoveAll("\""), ehs::Mode::WRITE, ehs::Disposition::CREATE_PERSISTENT);
file.WriteSerializer_64(executable.Serialize());