blob: 8c2bff82fc4d03f914b0b08a6e46608aac0adfa3 [file] [log] [blame] [edit]
/*
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ELF_FILE_H
#define ELF_FILE_H
#include <cstdio>
#include <cstdarg>
#include <cstdint>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "elf.h"
#include "addresses.h"
class elf_file {
public:
elf_file(bool verbose = false) : verbose(verbose) {};
int read_file(std::shared_ptr<std::iostream> file);
void write(std::shared_ptr<std::iostream> file);
const elf32_ph_entry& append_segment(uint32_t vaddr, uint32_t paddr, uint32_t size, const std::string &section_name);
const elf32_header &header(void) const {return eh;}
const std::vector<elf32_ph_entry> &segments(void) const {return ph_entries;}
const std::vector<elf32_sh_entry> &sections(void) const {return sh_entries;}
std::vector<uint8_t> content(const elf32_ph_entry &ph) const;
std::vector<uint8_t> content(const elf32_sh_entry &sh) const;
void content(const elf32_ph_entry &ph, const std::vector<uint8_t> &content);
void content(const elf32_sh_entry &sh, const std::vector<uint8_t> &content);
uint32_t lowest_section_offset(void) const;
uint32_t highest_section_offset(void) const;
const elf32_sh_entry* get_section(const std::string &sh_name);
uint32_t get_symbol(const std::string &sym_name);
const std::string section_name(uint32_t sh_name) const;
const elf32_ph_entry* segment_from_physical_address(uint32_t paddr);
const elf32_ph_entry* segment_from_virtual_address(uint32_t vaddr);
const elf32_ph_entry* segment_from_section(const elf32_sh_entry &sh);
void dump(void) const;
void move_all(int dist);
void remove_ph_holes(void);
void remove_sh_holes(void);
void remove_empty_ph_entries(void);
static std::vector<uint8_t> read_binfile(std::shared_ptr<std::iostream> file);
bool editable = true;
private:
int read_header(void);
void read_ph(void);
void read_sh(void);
void read_sh_data(void);
void read_bytes(unsigned offset, unsigned length, void *dest);
uint32_t append_section_name(const std::string &sh_name_str);
void flatten(void);
private:
elf32_header eh;
std::vector<uint8_t> elf_bytes;
std::vector<elf32_ph_entry> ph_entries;
std::vector<elf32_sh_entry> sh_entries;
std::vector<std::vector<uint8_t>> sh_data;
bool verbose;
};
int rp_check_elf_header(const elf32_header &eh);
int rp_determine_binary_type(const elf32_header &eh, const std::vector<elf32_ph_entry>& entries, address_ranges flash_range, address_ranges ram_range, bool *ram_style);
#endif