From 132d3236bb884433bf94e961f6d32264e0334aec Mon Sep 17 00:00:00 2001 From: ornitorrincos Date: Tue, 18 Aug 2026 12:15:05 +0200 Subject: --- misc-host/ELF/ELF-loader-test/.gitignore | 1 + misc-host/ELF/ELF-loader-test/ELF-loader-test.pro | 19 + .../ELF/ELF-loader-test/ELF-loader-test.pro.user | 472 +++++++++++++++++++++ .../ELF/ELF-loader-test/bootloader_compat.cpp | 18 + misc-host/ELF/ELF-loader-test/bootloader_compat.h | 35 ++ misc-host/ELF/ELF-loader-test/datatypes.h | 16 + misc-host/ELF/ELF-loader-test/deployment.pri | 191 +++++++++ misc-host/ELF/ELF-loader-test/elf64header.h | 97 +++++ misc-host/ELF/ELF-loader-test/elfinfoprint.cpp | 74 ++++ misc-host/ELF/ELF-loader-test/elfinfoprint.h | 12 + misc-host/ELF/ELF-loader-test/main.cpp | 12 + 11 files changed, 947 insertions(+) create mode 100644 misc-host/ELF/ELF-loader-test/.gitignore create mode 100644 misc-host/ELF/ELF-loader-test/ELF-loader-test.pro create mode 100644 misc-host/ELF/ELF-loader-test/ELF-loader-test.pro.user create mode 100644 misc-host/ELF/ELF-loader-test/bootloader_compat.cpp create mode 100644 misc-host/ELF/ELF-loader-test/bootloader_compat.h create mode 100644 misc-host/ELF/ELF-loader-test/datatypes.h create mode 100644 misc-host/ELF/ELF-loader-test/deployment.pri create mode 100644 misc-host/ELF/ELF-loader-test/elf64header.h create mode 100644 misc-host/ELF/ELF-loader-test/elfinfoprint.cpp create mode 100644 misc-host/ELF/ELF-loader-test/elfinfoprint.h create mode 100644 misc-host/ELF/ELF-loader-test/main.cpp (limited to 'misc-host/ELF/ELF-loader-test') diff --git a/misc-host/ELF/ELF-loader-test/.gitignore b/misc-host/ELF/ELF-loader-test/.gitignore new file mode 100644 index 0000000..ee4c926 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/.gitignore @@ -0,0 +1 @@ +/test diff --git a/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro b/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro new file mode 100644 index 0000000..b945d81 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + elfinfoprint.cpp \ + main.cpp \ + bootloader_compat.cpp + +include(deployment.pri) +qtcAddDeployment() + +HEADERS += \ + datatypes.h \ + elf64header.h \ + elfinfoprint.h \ + bootloader_compat.h + diff --git a/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro.user b/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro.user new file mode 100644 index 0000000..243fdee --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro.user @@ -0,0 +1,472 @@ + + + + + + EnvironmentId + {2c3e9189-5d42-4938-9849-c0bb2ac935ae} + + + ProjectExplorer.Project.ActiveTarget + 1 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + GCC + GCC + {d432c706-8e6f-4f4f-92f1-4099cda2d690} + 0 + 0 + 0 + + /home/ornitorrincos/OS-github/misc-host/ELF/build-ELF-loader-test-GCC-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/ornitorrincos/OS-github/misc-host/ELF/build-ELF-loader-test-GCC-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + ELF-loader-test + + Qt4ProjectManager.Qt4RunConfiguration:/home/ornitorrincos/OS-github/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro + + ELF-loader-test.pro + false + true + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.Target.1 + + Clang + Clang + {e689128d-986e-453c-9cd3-1600795ccd25} + 0 + 0 + 0 + + /home/ornitorrincos/OS-github/misc-host/ELF/build-ELF-loader-test-Clang-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/ornitorrincos/OS-github/misc-host/ELF/build-ELF-loader-test-Clang-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + ELF-loader-test + + Qt4ProjectManager.Qt4RunConfiguration:/home/ornitorrincos/OS-github/misc-host/ELF/ELF-loader-test/ELF-loader-test.pro + + ELF-loader-test.pro + false + true + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/misc-host/ELF/ELF-loader-test/bootloader_compat.cpp b/misc-host/ELF/ELF-loader-test/bootloader_compat.cpp new file mode 100644 index 0000000..038e597 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/bootloader_compat.cpp @@ -0,0 +1,18 @@ +#include "bootloader_compat.h" +#include +#include + +UEFIPrint Print = wprintf; + +void * EFIAPI LoadFile(char * name, UINTN memtype) +{ + FILE * f = fopen(name, "rb"); + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + char * mem = (char*)malloc(fsize); + fread(mem, fsize, 1, f); + fclose(f); + + return mem; +} diff --git a/misc-host/ELF/ELF-loader-test/bootloader_compat.h b/misc-host/ELF/ELF-loader-test/bootloader_compat.h new file mode 100644 index 0000000..d6f56a5 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/bootloader_compat.h @@ -0,0 +1,35 @@ +#ifndef BOOTLOADER_COMPAT_H +#define BOOTLOADER_COMPAT_H + +// partial API of UEFI/bootloader + +#include +#include + +#define EFIAPI +#define IN +#define OUT + +// basic UEFI datatypes +typedef uint8_t BOOLEAN; +typedef int8_t INT8; +typedef uint8_t UINT8; +typedef int16_t INT16; +typedef uint16_t UINT16; +typedef int32_t INT32; +typedef uint32_t UINT32; +typedef int64_t INT64; +typedef uint64_t UINT64; +typedef char CHAR8; +typedef wchar_t CHAR16; +typedef uint64_t UINTN; + +// UEFI native functions +typedef int (*UEFIPrint)(const wchar_t *, ...); +extern UEFIPrint Print; + +// Bootloader defined +void * EFIAPI LoadFile(char * name, UINTN memtype); + +#endif // BOOTLOADER_COMPAT_H + diff --git a/misc-host/ELF/ELF-loader-test/datatypes.h b/misc-host/ELF/ELF-loader-test/datatypes.h new file mode 100644 index 0000000..b50c3c8 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/datatypes.h @@ -0,0 +1,16 @@ +#ifndef DATATYPES_H +#define DATATYPES_H + +#include + +// sizes as defined in the System V ABI +typedef uint16_t Elf64_Half; +typedef uint64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef int32_t Elf64_Word; +typedef uint64_t Elf64_Xword; + + + +#endif // DATATYPES_H + diff --git a/misc-host/ELF/ELF-loader-test/deployment.pri b/misc-host/ELF/ELF-loader-test/deployment.pri new file mode 100644 index 0000000..5f1749f --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/deployment.pri @@ -0,0 +1,191 @@ +# This file was generated by an application wizard of Qt Creator. +# The code below handles deployment to Android and Maemo, aswell as copying +# of the application data to shadow build directories on desktop. +# It is recommended not to modify this file, since newer versions of Qt Creator +# may offer an updated version of it. + +defineTest(qtcAddDeployment) { +for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + greaterThan(QT_MAJOR_VERSION, 4) { + itemsources = $${item}.files + } else { + itemsources = $${item}.sources + } + $$itemsources = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath= $$eval($${deploymentfolder}.target) + export($$itemsources) + export($$itempath) + DEPLOYMENT += $$item +} + +MAINPROFILEPWD = $$PWD + +android-no-sdk { + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + target.path = /data/user/qt + + export(target.path) + INSTALLS += target +} else:android { + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = /assets/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + + export(target.path) + INSTALLS += target +} else:win32 { + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, /, \\) + sourcePathSegments = $$split(source, \\) + target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments) + target = $$replace(target, /, \\) + target ~= s,\\\\\\.?\\\\,\\, + !isEqual(source,$$target) { + !isEmpty(copyCommand):copyCommand += && + isEqual(QMAKE_DIR_SEP, \\) { + copyCommand += $(COPY_DIR) \"$$source\" \"$$target\" + } else { + source = $$replace(source, \\\\, /) + target = $$OUT_PWD/$$eval($${deploymentfolder}.target) + target = $$replace(target, \\\\, /) + copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\" + } + } + } + !isEmpty(copyCommand) { + copyCommand = @echo Copying application data... && $$copyCommand + copydeploymentfolders.commands = $$copyCommand + first.depends = $(first) copydeploymentfolders + export(first.depends) + export(copydeploymentfolders.commands) + QMAKE_EXTRA_TARGETS += first copydeploymentfolders + } +} else:ios { + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, \\\\, /) + target = $CODESIGNING_FOLDER_PATH/$$eval($${deploymentfolder}.target) + target = $$replace(target, \\\\, /) + sourcePathSegments = $$split(source, /) + targetFullPath = $$target/$$last(sourcePathSegments) + targetFullPath ~= s,/\\.?/,/, + !isEqual(source,$$targetFullPath) { + !isEmpty(copyCommand):copyCommand += && + copyCommand += mkdir -p \"$$target\" + copyCommand += && cp -r \"$$source\" \"$$target\" + } + } + !isEmpty(copyCommand) { + copyCommand = echo Copying application data... && $$copyCommand + !isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";" + QMAKE_POST_LINK += "$$copyCommand" + export(QMAKE_POST_LINK) + } +} else:unix { + maemo5 { + desktopfile.files = $${TARGET}.desktop + desktopfile.path = /usr/share/applications/hildon + icon.files = $${TARGET}64.png + icon.path = /usr/share/icons/hicolor/64x64/apps + } else:!isEmpty(MEEGO_VERSION_MAJOR) { + desktopfile.files = $${TARGET}_harmattan.desktop + desktopfile.path = /usr/share/applications + icon.files = $${TARGET}80.png + icon.path = /usr/share/icons/hicolor/80x80/apps + } else { # Assumed to be a Desktop Unix + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, \\\\, /) + macx { + target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target) + } else { + target = $$OUT_PWD/$$eval($${deploymentfolder}.target) + } + target = $$replace(target, \\\\, /) + sourcePathSegments = $$split(source, /) + targetFullPath = $$target/$$last(sourcePathSegments) + targetFullPath ~= s,/\\.?/,/, + !isEqual(source,$$targetFullPath) { + !isEmpty(copyCommand):copyCommand += && + copyCommand += $(MKDIR) \"$$target\" + copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\" + } + } + !isEmpty(copyCommand) { + copyCommand = @echo Copying application data... && $$copyCommand + copydeploymentfolders.commands = $$copyCommand + first.depends = $(first) copydeploymentfolders + export(first.depends) + export(copydeploymentfolders.commands) + QMAKE_EXTRA_TARGETS += first copydeploymentfolders + } + } + !isEmpty(target.path) { + installPrefix = $${target.path} + } else { + installPrefix = /opt/$${TARGET} + } + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + !isEmpty(desktopfile.path) { + export(icon.files) + export(icon.path) + export(desktopfile.files) + export(desktopfile.path) + INSTALLS += icon desktopfile + } + + isEmpty(target.path) { + target.path = $${installPrefix}/bin + export(target.path) + } + INSTALLS += target +} + +export (ICON) +export (INSTALLS) +export (DEPLOYMENT) +export (LIBS) +export (QMAKE_EXTRA_TARGETS) +} + diff --git a/misc-host/ELF/ELF-loader-test/elf64header.h b/misc-host/ELF/ELF-loader-test/elf64header.h new file mode 100644 index 0000000..ed83168 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/elf64header.h @@ -0,0 +1,97 @@ +#ifndef ELF64HEADER_H +#define ELF64HEADER_H + +#include "datatypes.h" + +#define EI_NIDENT 16 + +// ELF header +typedef struct { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; + +// Section header +typedef struct { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; + +// indentification struct +enum Elf_Ident { + EI_MAG0 = 0, // 0x7F + EI_MAG1 = 1, // 'E' + EI_MAG2 = 2, // 'L' + EI_MAG3 = 3, // 'F' + EI_CLASS = 4, // Architecture (32/64) + EI_DATA = 5, // Byte Order + EI_VERSION = 6, // ELF Version + EI_OSABI = 7, // OS Specific + EI_ABIVERSION = 8, // OS Specific + EI_PAD = 9 // Padding +}; + +// MAgic Numbers +#define ELFMAG0 0x7F +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +#define ELFCLASS64 2 + + +enum Elf_Type { + ET_NONE = 0, // Unkown Type + ET_REL = 1, // Relocatable File + ET_EXEC = 2 // Executable File +}; + + +// Machine +#define EM_X86_64 62 + +// version +#define EV_CURRENT 1 + +// Section header specific values +# define SHN_UNDEF (0x00) // Undefined/Not present + +enum ShT_Types { + SHT_NULL = 0, + SHT_PROGBITS = 1, + SHT_SYMTAB = 2, + SHT_STRTAB = 3, + SHT_RELA = 4, + SHT_NOBITS = 8, + SHT_REL = 9, +}; + +enum ShT_Attributes { + SHF_WRITE = 0x01, + SHF_ALLOC = 0x02 +}; + + + +#endif // ELF64HEADER_H + diff --git a/misc-host/ELF/ELF-loader-test/elfinfoprint.cpp b/misc-host/ELF/ELF-loader-test/elfinfoprint.cpp new file mode 100644 index 0000000..d5dcbfd --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/elfinfoprint.cpp @@ -0,0 +1,74 @@ +#include "elfinfoprint.h" + +#include "bootloader_compat.h" + + +bool IsElf(Elf64_Ehdr * header) +{ + if(!header) + { + return false; + } + + if(header->e_ident[EI_MAG0] != ELFMAG0) { + return false; + } + if(header->e_ident[EI_MAG1] != ELFMAG1) { + return false; + } + if(header->e_ident[EI_MAG2] != ELFMAG2) { + return false; + } + if(header->e_ident[EI_MAG3] != ELFMAG3) { + return false; + } + + return true; +} + +void ElfInfoPrint(Elf64_Ehdr * header) +{ + // check if actual elf file + if(!IsElf(header)) + { + Print(L"Not an ELF File\n"); + return; + } + + if(header->e_type == ET_EXEC) + { + Print(L"Executable file\n"); + } + + if(header->e_machine == EM_X86_64) + { + Print(L"AMD64 Machine\n"); + } else + { + Print(L"Unrecorginzed Machine\n"); + } + + Print(L"Entry point: hx%x\n", header->e_entry); + + + char * strtable = elf_str_table(header); + Print(L"%s\n", strtable); +} + +// functions to access section headers +Elf64_Shdr *elf_sheader(Elf64_Ehdr *hdr) +{ + return (Elf64_Shdr *)((uintptr_t)hdr + hdr->e_shoff); +} + +Elf64_Shdr *elf_section(Elf64_Ehdr *hdr, int idx) +{ + return &elf_sheader(hdr)[idx]; +} + +char *elf_str_table(Elf64_Ehdr *hdr) +{ + if(hdr->e_shstrndx == SHN_UNDEF) return NULL; + return (char *)hdr + elf_section(hdr, hdr->e_shstrndx)->sh_offset; +} + diff --git a/misc-host/ELF/ELF-loader-test/elfinfoprint.h b/misc-host/ELF/ELF-loader-test/elfinfoprint.h new file mode 100644 index 0000000..2f61860 --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/elfinfoprint.h @@ -0,0 +1,12 @@ +#ifndef ELFINFOPRINT_H +#define ELFINFOPRINT_H + + +#include "elf64header.h" + +void ElfInfoPrint(Elf64_Ehdr * header); + +Elf64_Shdr *elf_sheader(Elf64_Ehdr *hdr); +Elf64_Shdr *elf_section(Elf64_Ehdr *hdr, int idx); +char *elf_str_table(Elf64_Ehdr *hdr); +#endif // ELFINFOPRINT_H diff --git a/misc-host/ELF/ELF-loader-test/main.cpp b/misc-host/ELF/ELF-loader-test/main.cpp new file mode 100644 index 0000000..30b44bf --- /dev/null +++ b/misc-host/ELF/ELF-loader-test/main.cpp @@ -0,0 +1,12 @@ +#include +#include "bootloader_compat.h" +#include "elfinfoprint.h" + +int main(void) +{ + void * kernel = LoadFile("kernel.bin", 0); + + ElfInfoPrint((Elf64_Ehdr *)kernel); + return 0; +} + -- cgit v1.2.3-70-g09d2