FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
elf.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <cstdint>
12#include <cstdio>
13#include <fstream>
14#include <elf.h>
15#include <cstdlib>
16#include <cstring>
17#include <unistd.h>
18#include <sys/stat.h>
19#include <sys/types.h>
20#include <expected>
21
22#include "../macro.hpp"
23#include "../std/expected.hpp"
24
33namespace ns_elf
34{
35
36namespace fs = std::filesystem;
37
38#if defined(__LP64__)
39#define ElfW(type) Elf64_ ## type
40#else
41#define ElfW(type) Elf32_ ## type
42#endif
43
52[[nodiscard]] inline Value<void> copy_binary(fs::path const& path_file_input
53 , fs::path const& path_file_output
54 , std::pair<uint64_t,uint64_t> section)
55{
56 // Open source and output files
57 std::ifstream f_in{path_file_input, std::ios::binary};
58 return_if(not f_in.is_open(), Error("E::Failed to open in file {}", path_file_input));
59 std::ofstream f_out{path_file_output, std::ios::binary};
60 return_if(not f_out.is_open(), Error("E::Failed to open out file {}", path_file_output));
61 // Calculate the size of the data to read
62 uint64_t size = section.second - section.first;
63 // Seek to the start offset in the input file
64 f_in.seekg(section.first, std::ios::beg);
65 // Read in chunks
66 const size_t size_buf = 4096;
67 char buffer[size_buf];
68 while( size > 0 )
69 {
70 std::streamsize read_size = static_cast<std::streamsize>(std::min(static_cast<uint64_t>(size_buf), size));
71 f_in.read(buffer, read_size);
72 f_out.write(buffer, read_size);
73 size -= read_size;
74 } // while
75 return {};
76}
77
85[[nodiscard]] inline Value<uint64_t> skip_elf_header(fs::path const& path_file_elf
86 , uint64_t offset = 0)
87{
88 struct File
89 {
90 FILE* ptr;
91 File(FILE* ptr) : ptr(ptr) {};
92 ~File() { if(ptr) { ::fclose(ptr); } }
93 };
94 // Either Elf64_Ehdr or Elf32_Ehdr depending on architecture.
95 ElfW(Ehdr) header;
96 // Try to open header file
97 File file(fopen(path_file_elf.c_str(), "rb"));
98 return_if(file.ptr == nullptr, Error("E::Could not open file '{}': {}", path_file_elf, strerror(errno)));
99 // Seek the position to read the header
100 return_if(fseek(file.ptr, offset, SEEK_SET) < 0
101 , Error("E::Could not seek in file '{}': {}", path_file_elf, strerror(errno))
102 )
103 // read the header
104 return_if(fread(&header, sizeof(header), 1, file.ptr) != 1
105 , Error("E::Could not read elf header")
106 );
107 // check so its really an elf file
108 return_if(std::memcmp(header.e_ident, ELFMAG, SELFMAG) != 0, Error("E::'{}' not an elf file", path_file_elf));
109 offset = header.e_shoff + (header.e_ehsize * header.e_shnum);
110 return offset;
111}
112
113} // namespace ns_elf
114
115/* vim: set expandtab fdm=marker ts=2 sw=2 tw=100 et :*/
Enhanced error handling framework built on std::expected.
Simplified macros for common control flow patterns with optional logging.
ELF binary manipulation and reserved space management.
Value< uint64_t > skip_elf_header(fs::path const &path_file_elf, uint64_t offset=0)
Skips the elf header starting from 'offset' and returns the offset to the first byte afterwards.
Definition elf.hpp:85
Value< void > copy_binary(fs::path const &path_file_input, fs::path const &path_file_output, std::pair< uint64_t, uint64_t > section)
Copies the binary data between [offset.first, offset.second] from path_file_input to path_file_output...
Definition elf.hpp:52
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44