Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.0.0)
project(FatELF)

include(CheckSymbolExists)
include(GNUInstallDirs)

execute_process(
COMMAND git rev-list HEAD~..
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
Expand Down Expand Up @@ -37,5 +40,19 @@ add_fatelf_executable(fatelf-verify)
add_fatelf_executable(fatelf-split)
add_fatelf_executable(fatelf-validate)

set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_symbol_exists(memfd_create sys/mman.h MEMFD)
check_symbol_exists(fexecve unistd.h FEXECVE)
if(MEMFD AND FEXECVE AND EXISTS /proc/self/exe)
add_fatelf_executable(fatelf-exec)

find_program(BINFMT systemd-binfmt PATHS /usr/lib/systemd)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on the fence as to whether /usr/lib ought to be replaced with ${CMAKE_INSTALL_FULL_LIBDIR}.

if(BINFMT)
configure_file(fatelf.conf.in fatelf.conf)
install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d)
install(FILES ${CMAKE_BINARY_DIR}/fatelf.conf DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d/)
endif()
endif()

# end of CMakeLists.txt ...

1 change: 1 addition & 0 deletions fatelf.conf.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:fatelf-v1:M::\xFA\x70\x0E\x1F\x01\x00::${CMAKE_INSTALL_FULL_BINDIR}/fatelf-exec:
49 changes: 49 additions & 0 deletions utils/fatelf-exec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* FatELF; support multiple ELF binaries in one file.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Henry W. Wilson.
*/

#define _GNU_SOURCE
#define FATELF_UTILS 1
#include "fatelf-utils.h"
#include <sys/mman.h>
#include <unistd.h>

static FATELF_record * xfind_matching_record(FATELF_record const *tgt, FATELF_header *header)
{
for (uint8_t i = 0; i < header->num_records; i++)
if (fatelf_record_matches(header->records + i, tgt))
return header->records + i;

xfail("Unable to find %s in FatElf records", fatelf_get_target_name(tgt, FATELF_WANT_EVERYTHING));
} // xfind_matching_record

int main(int argc, char *argv[], char *envp[])
{
xfatelf_init(argc, (char const**)argv);
if (argc < 2)
xfail("USAGE: %s [--version] fatelf-file [args...]", argv[0]);

int fd = xopen(argv[1], O_RDONLY | O_CLOEXEC, 0);
FATELF_header *header = xread_fatelf_header(argv[1], fd);

int self = xopen("/proc/self/exe", O_RDONLY | O_CLOEXEC, 0);
FATELF_record self_elf;
xread_elf_header(argv[0], self, 0, &self_elf);

FATELF_record const *rec = xfind_matching_record(&self_elf, header);

int outfd = memfd_create("ELF", MFD_CLOEXEC);
if (outfd < 0)
xfail("memfd_create");

xcopyfile_range(argv[1], fd, "memfd:ELF", outfd, rec->offset, rec->size);

fexecve(outfd, (argv + 1), envp);
xfail("fexecve");
} // main

// end of fatelf-exec.c ...
2 changes: 1 addition & 1 deletion utils/fatelf-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const char *fatelf_build_version = MAKEBUILDVERSTRINGLITERAL(APPID, APPREV);


// Report an error to stderr and terminate immediately with exit(1).
void xfail(const char *fmt, ...)
[[noreturn]] void xfail(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
Expand Down
2 changes: 1 addition & 1 deletion utils/fatelf-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ typedef struct fatelf_osabi_info
// all functions that start with 'x' may call exit() on error!

// Report an error to stderr and terminate immediately with exit(1).
void xfail(const char *fmt, ...) FATELF_ISPRINTF(1,2);
[[noreturn]] void xfail(const char *fmt, ...) FATELF_ISPRINTF(1,2);

// Wrap malloc() with an xfail(), so this returns memory or calls exit().
// Memory is guaranteed to be initialized to zero.
Expand Down