/*
 * Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <memory>

#include "elf.h"
#include "elf_file.h"
#include "errors.h"

#include "portable_endian.h"

// tsk namespace is polluted on windows
#ifdef _WIN32
#undef min
#undef max

#define _CRT_SECURE_NO_WARNINGS
#endif

void eh_he(elf32_header &eh) {
    // Swap to host endianness
    eh.common.magic    = le32toh(eh.common.magic);
    eh.common.type     = le16toh(eh.common.type);
    eh.common.machine  = le16toh(eh.common.machine);
    eh.common.version2 = le32toh(eh.common.version2);
    eh.entry           = le32toh(eh.entry);
    eh.ph_offset       = le32toh(eh.ph_offset);
    eh.sh_offset       = le32toh(eh.sh_offset);
    eh.flags           = le32toh(eh.flags);
    eh.eh_size         = le16toh(eh.eh_size);
    eh.ph_entry_size   = le16toh(eh.ph_entry_size);
    eh.ph_num          = le16toh(eh.ph_num);
    eh.sh_entry_size   = le16toh(eh.sh_entry_size);
    eh.sh_num          = le16toh(eh.sh_num);
    eh.sh_str_index    = le16toh(eh.sh_str_index);
}
void eh_le(elf32_header &eh) {
    // Swap to little endianness
    eh.common.magic    = htole32(eh.common.magic);
    eh.common.type     = htole16(eh.common.type);
    eh.common.machine  = htole16(eh.common.machine);
    eh.common.version2 = htole32(eh.common.version2);
    eh.entry           = htole32(eh.entry);
    eh.ph_offset       = htole32(eh.ph_offset);
    eh.sh_offset       = htole32(eh.sh_offset);
    eh.flags           = htole32(eh.flags);
    eh.eh_size         = htole16(eh.eh_size);
    eh.ph_entry_size   = htole16(eh.ph_entry_size);
    eh.ph_num          = htole16(eh.ph_num);
    eh.sh_entry_size   = htole16(eh.sh_entry_size);
    eh.sh_num          = htole16(eh.sh_num);
    eh.sh_str_index    = htole16(eh.sh_str_index);
}
void ph_he(elf32_ph_entry &ph) {
    // Swap to host endianness
    ph.type     = le32toh(ph.type);
    ph.offset   = le32toh(ph.offset);
    ph.vaddr    = le32toh(ph.vaddr);
    ph.paddr    = le32toh(ph.paddr);
    ph.filez    = le32toh(ph.filez);
    ph.memsz    = le32toh(ph.memsz);
    ph.flags    = le32toh(ph.flags);
    ph.align    = le32toh(ph.align);
}
void ph_le(elf32_ph_entry &ph) {
    // Swap to little endianness
    ph.type     = htole32(ph.type);
    ph.offset   = htole32(ph.offset);
    ph.vaddr    = htole32(ph.vaddr);
    ph.paddr    = htole32(ph.paddr);
    ph.filez    = htole32(ph.filez);
    ph.memsz    = htole32(ph.memsz);
    ph.flags    = htole32(ph.flags);
    ph.align    = htole32(ph.align);
}
void sh_he(elf32_sh_entry &sh) {
    // Swap to host endianness
    sh.name         = le32toh(sh.name);
    sh.type         = le32toh(sh.type);
    sh.flags        = le32toh(sh.flags);
    sh.addr         = le32toh(sh.addr);
    sh.offset       = le32toh(sh.offset);
    sh.size         = le32toh(sh.size);
    sh.link         = le32toh(sh.link);
    sh.info         = le32toh(sh.info);
    sh.addralign    = le32toh(sh.addralign);
    sh.entsize      = le32toh(sh.entsize);
}
void sh_le(elf32_sh_entry &sh) {
    // Swap to little endianness
    sh.name         = htole32(sh.name);
    sh.type         = htole32(sh.type);
    sh.flags        = htole32(sh.flags);
    sh.addr         = htole32(sh.addr);
    sh.offset       = htole32(sh.offset);
    sh.size         = htole32(sh.size);
    sh.link         = htole32(sh.link);
    sh.info         = htole32(sh.info);
    sh.addralign    = htole32(sh.addralign);
    sh.entsize      = htole32(sh.entsize);
}
void sym_he(elf32_sym_entry &sym) {
    // Swap to host endianness
    sym.name    = le32toh(sym.name);
    sym.value   = le32toh(sym.value);
    sym.size    = le32toh(sym.size);
    sym.info    = le32toh(sym.info);
    sym.other   = le32toh(sym.other);
    sym.shndx   = le32toh(sym.shndx);
}
void sym_le(elf32_sym_entry &sym) {
    // Swap to little endianness
    sym.name    = htole32(sym.name);
    sym.value   = htole32(sym.value);
    sym.size    = htole32(sym.size);
    sym.info    = htole32(sym.info);
    sym.other   = htole32(sym.other);
    sym.shndx   = htole32(sym.shndx);
}

// Checks whether an ELF header is compatible with RP2040 / RP3050
// Returns zero on success
int rp_check_elf_header(const elf32_header &eh) {
    if (eh.common.magic != ELF_MAGIC) {
        fail(ERROR_FORMAT, "Not an ELF file");
    }
    if (eh.common.version != 1 || eh.common.version2 != 1) {
        fail(ERROR_FORMAT, "Unrecognized ELF version");
    }
    if (eh.common.arch_class != 1 || eh.common.endianness != 1) {
        fail(ERROR_INCOMPATIBLE, "Require 32 bit little-endian ELF");
    }
    if (eh.eh_size != sizeof(struct elf32_header)) {
        fail(ERROR_FORMAT, "Invalid ELF32 format");
    }
    if (eh.common.machine != EM_ARM && eh.common.machine != EM_RISCV) {
        fail(ERROR_FORMAT, "Not an Arm or RISC-V executable");
    }
    // Accept either ELFOSABI_NONE or ELFOSABI_GNU for EI_OSABI. Compilers may
    // set the OS/ABI field to ELFOSABI_GNU when they use GNU features, such as
    // the SHF_GNU_RETAIN section flag, but the binary is still compatible.
    if (eh.common.abi != 0 /* NONE */ && eh.common.abi != 3 /* GNU */) {
        fail(ERROR_INCOMPATIBLE, "Unrecognized ABI");
    }
    // todo amy not sure if this should be expected or not - we have HARD float in clang only for now
    if (eh.flags & EF_ARM_ABI_FLOAT_HARD) {
//        fail(ERROR_INCOMPATIBLE, "HARD-FLOAT not supported");
    }
    return 0;
}

// Determine binary type (flash or ram)
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) {
    for(const auto &entry : entries) {
        if (entry.type == PT_LOAD && entry.memsz) {
            unsigned int mapped_size = std::min(entry.filez, entry.memsz);
            if (mapped_size) {
                // we back convert the entrypoint from a VADDR to a PADDR to see if it originates in flash, and if
                // so call THAT a flash binary.
                if (eh.entry >= entry.vaddr && eh.entry < entry.vaddr + mapped_size) {
                    uint32_t effective_entry = eh.entry + entry.paddr - entry.vaddr;
                    if (is_address_initialized(ram_range, effective_entry)) {
                        *ram_style = true;
                        return 0;
                    } else if (is_address_initialized(flash_range, effective_entry)) {
                        *ram_style = false;
                        return 0;
                    }
                }
            }
        }
    }
    fail(ERROR_INCOMPATIBLE, "entry point is not in mapped part of file");
    return ERROR_INCOMPATIBLE;
}

void elf_file::read_bytes(unsigned offset, unsigned length, void *dest) {
    if (offset + length > elf_bytes.size()) {
        fail(ERROR_FORMAT, "ELF File Read from 0x%x with size 0x%x exceeds the file size 0x%zx", offset, length, elf_bytes.size());
    }
    memcpy(dest, &elf_bytes[offset], length);
}

int elf_file::read_header(void) {
    read_bytes(0, sizeof(eh), &eh);
    eh_he(eh);  // swap to Host for processing
    return rp_check_elf_header(eh);
}

// Flattens the data in the section array the elf_bytes blob
void elf_file::flatten(void) {
    elf_bytes.resize(sizeof(eh));
    auto eh_out = eh;
    eh_le(eh_out);    // swap to LE for writing
    memcpy(&elf_bytes[0], &eh_out, sizeof(eh_out));

    elf_bytes.resize(std::max(eh.ph_offset + sizeof(elf32_ph_entry) * eh.ph_num, elf_bytes.size()));
    auto ph_entries_out = ph_entries;
    for (auto ph : ph_entries_out) {
        ph_le(ph);  // swap to LE for writing
    }
    memcpy(&elf_bytes[eh.ph_offset], &ph_entries_out[0], sizeof(elf32_ph_entry) * eh.ph_num);

    elf_bytes.resize(std::max(eh.sh_offset + sizeof(elf32_sh_entry) * eh.sh_num, elf_bytes.size()));
    auto sh_entries_out = sh_entries;
    for (auto sh : sh_entries_out) {
        sh_le(sh);  // swap to LE for writing
    }
    memcpy(&elf_bytes[eh.sh_offset], &sh_entries_out[0], sizeof(elf32_sh_entry) * eh.sh_num);

    int idx = 0;
    for (const auto &sh : sh_entries) {
        if (sh.size && sh.type != SHT_NOBITS) {
            elf_bytes.resize(std::max(sh.offset + sh.size, (uint32_t)elf_bytes.size()));
            memcpy(&elf_bytes[sh.offset], &sh_data[idx][0], sh.size);
        }
        idx++;
    }
    if (verbose) printf("Elf file size %zu\n", elf_bytes.size());
}

void elf_file::write(std::shared_ptr<std::iostream> out) {
    flatten();
    out->exceptions(std::iostream::failbit | std::iostream::badbit);
    if (verbose) printf("Writing %lu bytes to file\n", elf_bytes.size());
    out->write(reinterpret_cast<const char*>(&elf_bytes[0]), elf_bytes.size());
}

void elf_file::read_sh(void) {
    if (verbose) printf("%s sh offset %u #entries %d\n", __func__, eh.sh_offset, eh.sh_num);
    if (eh.sh_num) {
        sh_entries.resize(eh.sh_num);
        read_bytes(eh.sh_offset, sizeof(elf32_sh_entry) * eh.sh_num, &sh_entries[0]);
        for (auto sh : sh_entries) {
            sh_he(sh);  // swap to Host for processing
        }
    }
}

// If there are holes between segments, increase the segment size to plug the hole
// This is necessary to ensure that segments are contiguous, which is required for encrypting,
// but this is not necessary for signing/hashing
void elf_file::remove_ph_holes(void) {
    auto sorted_ph_entries = sorted_segments();
    for (int i=0; i+1 < ph_entries.size(); i++) {
        auto ph0 = &(ph_entries[i]);
        const elf32_ph_entry* ph1 = nullptr;
        // ph1 is the next segment by address
        for (int j=0; j+1 < sorted_ph_entries.size(); j++) {
            auto tst_ph0 = sorted_ph_entries[j];
            if (tst_ph0->offset == ph0->offset) {
                ph1 = sorted_ph_entries[j+1];
            }
        }
        if (ph1 == nullptr) {
            // ph0 was the last segment by address - so no gap to plug after it
            continue;
        }
        // ph1file is the next segment in the file
        elf32_ph_entry ph1file = ph_entries[i+1];
        if (
            (ph0->type == PT_LOAD && ph1->type == PT_LOAD)
            && (ph0->filez && ph1->filez)
            && (ph0->paddr + ph0->filez < ph1->paddr)
        ) {
            uint32_t gap = ph1->paddr - ph0->paddr - ph0->filez;
            if (gap > ph1->align) {
                fail(ERROR_INCOMPATIBLE, "Segment %d: Cannot plug gap greater than alignment - gap %d, alignment %d", i, gap, ph1->align);
            }
            if (ph0->offset + ph0->filez + gap > ph1file.offset) {
                fail(ERROR_INCOMPATIBLE, "Segment %d: Cannot plug gap without space in file - gap %d", i, gap);
            }
            if (verbose) printf("Segment %d: Moving end from 0x%08x to 0x%08x to plug gap\n", i, ph0->paddr + ph0->filez, ph1->paddr);
            ph0->filez = ph1->paddr - ph0->paddr;
            ph0->memsz = ph0->filez;
        }
    }
}

// If there are holes within segments, increase the section size to plug the hole
// This is necessary to ensure the whole segment contains data defined in sections, otherwise you end up
// signing/hashing/encrypting data that may not be written, as many tools write in sections not segments
void elf_file::remove_sh_holes(void) {
    bool found_hole = false;
    for (int i=0; i+1 < sh_entries.size(); i++) {
        auto sh0 = &(sh_entries[i]);
        elf32_sh_entry sh1 = sh_entries[i+1];
        if (
            (sh0->type == SHT_PROGBITS && sh1.type == SHT_PROGBITS)
            && (sh0->size && sh1.size)
            && (sh0->addr + sh0->size < sh1.addr)
            && (segment_from_section(*sh0) == segment_from_section(sh1))
            && segment_from_section(*sh0) != NULL
        ) {
            uint32_t gap = sh1.addr - sh0->addr - sh0->size;
            if (gap > sh1.addralign) {
                fail(ERROR_INCOMPATIBLE, "Section %d: Cannot plug gap greater than alignment - gap %d, alignment %d", i, gap, sh1.addralign);
            }
            if (verbose) printf("Section %d: Moving end from 0x%08x to 0x%08x to plug gap\n", i, sh0->addr + sh0->size, sh1.addr);
            sh0->size = sh1.addr - sh0->addr;
            found_hole = true;
        } else if (
            (sh0->type == SHT_PROGBITS)
            && (segment_from_section(*sh0) != segment_from_section(sh1))
            && segment_from_section(*sh0) != NULL
            && (sh0->offset + sh0->size < segment_from_section(*sh0)->offset + segment_from_section(*sh0)->filez)
        ) {
            const elf32_ph_entry *seg = segment_from_section(*sh0);
            uint32_t gap = seg->offset + seg->filez - sh0->offset - sh0->size;
            if (verbose) printf("Section %d: Moving end from 0x%08x to 0x%08x to plug gap at end of segment\n", i, sh0->addr + sh0->size, seg->offset + seg->filez);
            sh0->size = seg->offset + seg->filez - sh0->offset;
            found_hole = true;
        }
    }
    if (found_hole) read_sh_data();
}

void elf_file::remove_empty_ph_entries(void) {
    for (int i = 0; i < ph_entries.size(); i++) {
        if (ph_entries[i].filez == 0) {
            ph_entries.erase(ph_entries.begin() + i);
            eh.ph_num--; i--;
        }
    }
}

// Read the section data from the internal byte array into discrete sections.
// This is used after modifying segments but before inserting new segments
void elf_file::read_sh_data(void) {
    int sh_idx = 0;
    sh_data.resize(eh.sh_num);
    for (const auto &sh: sh_entries) {
        if (sh.size && sh.type != SHT_NOBITS) {
            sh_data[sh_idx].resize(sh.size);
            read_bytes(sh.offset, sh.size, &sh_data[sh_idx][0]);
        }
        sh_idx++;
    }
}

const std::string elf_file::section_name(uint32_t sh_name) const {
    if (!eh.sh_str_index || eh.sh_str_index > eh.sh_num || eh.sh_str_index >= sh_data.size())
        return "";

    if (sh_name > sh_data[eh.sh_str_index].size())
        return "";

    const char * str =(const char *) &sh_data[eh.sh_str_index][0];
    return &str[sh_name];
}

const elf32_sh_entry* elf_file::get_section(const std::string &sh_name) {
    for (unsigned int i = 0; i < sh_entries.size(); i++) {
        if (section_name(sh_entries[i].name) == sh_name) {
            return &sh_entries[i];
        }
    }
    return NULL;
}

uint32_t elf_file::get_symbol(const std::string &sym_name) {
    auto sym_tab = get_section(".symtab");
    auto str_tab = get_section(".strtab");
    if (!sym_tab || !str_tab) {
        return 0;
    }
    auto data = content(*sym_tab);
    auto strings = content(*str_tab);
    const char * str =(const char *) strings.data();
    for (unsigned int i=0; i < sym_tab->size / sizeof(elf32_sym_entry); i++) {
        elf32_sym_entry sym;
        memcpy(&sym, data.data() + i*sizeof(elf32_sym_entry), sizeof(elf32_sym_entry));
        sym_he(sym);    // swap to Host for processing
        if (&str[sym.name] == sym_name) {
            return sym.value;
        }
    }
    return 0;
}

uint32_t elf_file::append_section_name(const std::string &sh_name_str) {
    // Create byte array with new section name
    std::vector<uint8_t> name_bytes(sh_name_str.begin(), sh_name_str.end());
    name_bytes.push_back(0);

    // Append the byte array to section header table remembering the offset
    // of the start of the string for the new section
    elf32_sh_entry &shstrtab = sh_entries[eh.sh_str_index];
    std::vector<uint8_t> &shstrtab_data = sh_data[eh.sh_str_index];
    sh_entries[eh.sh_str_index].size += name_bytes.size();
    uint32_t sh_name = shstrtab_data.size();
    shstrtab_data.insert(shstrtab_data.end(), name_bytes.begin(), name_bytes.end());

    // Move offsets for anything stored after the resized section header table
    for (auto &sh: sh_entries) {
        if (sh.offset > shstrtab.offset)
            sh.offset += name_bytes.size();
    }
    for (auto &ph: ph_entries) {
        if (ph.offset > shstrtab.offset)
            ph.offset += name_bytes.size();
    }
    return sh_name;
}

void elf_file::dump(void) const {
    for (const auto &ph: ph_entries) {
        printf("PH offset %08x vaddr %08x paddr %08x size %08x type %08x\n",
            ph.offset, ph.vaddr, ph.paddr, ph.memsz, ph.type);
    }

    int sh_idx = 0;
    for (const auto &sh: sh_entries) {
        printf("SH[%d] %20s addr %08x offset %08x size %08x type %08x\n",
            sh_idx, section_name(sh.name).c_str(), sh.addr, sh.offset, sh.size, sh.type);
        sh_idx++;
    }
}

void elf_file::move_all(int dist) {
    if (verbose) printf("Incrementing all paddr by %d\n", dist);
    // Remove empty ph entries, as they will likely be moved to invalid addresses
    remove_empty_ph_entries();
    for (auto &ph: ph_entries) {
        ph.paddr += dist;
    }
}

void elf_file::read_ph(void) {
    if (verbose) printf("%s ph offset %u #entries %d\n", __func__, eh.ph_offset, eh.ph_num);
    if (eh.ph_num) {
        ph_entries.resize(eh.ph_num);
        read_bytes(eh.ph_offset, sizeof(elf32_ph_entry) * eh.ph_num, &ph_entries[0]);
        for (auto ph : ph_entries) {
            ph_he(ph);  // swap to Host for processing
        }
    }
}

int elf_file::read_file(std::shared_ptr<std::iostream> file) {
    int rc = 0;
    try {
        elf_bytes = read_binfile(file);
        int rc = read_header();
        if (!rc) {
            read_ph();
            read_sh();
        }
        read_sh_data();
    }
    catch (const std::ios_base::failure &e) {
        std::cerr << "Failed to read elf file" << std::endl;
        rc = -1;
    }
    return rc;
}

uint32_t elf_file::lowest_section_offset(void) const {
    uint32_t offset = eh.sh_offset; // Section header offset is after the data
    for (const auto &sh: sh_entries) {
        if (sh.type != SHT_NULL && sh.offset > 0 && sh.offset < offset) {
            offset = sh.offset;
        }
    }
    return offset;
}

uint32_t elf_file::highest_section_offset(void) const {
    uint32_t offset = 0; // Section header offset is after the data
    for (const auto &sh: sh_entries) {
        if (sh.type != SHT_NULL && sh.offset > 0 && sh.offset >= offset) {
            offset = sh.offset + sh.size;
        }
    }
    return offset;
}

std::vector<uint8_t> elf_file::content(const elf32_ph_entry &ph) const {
    std::vector<uint8_t> content;
    std::copy(elf_bytes.begin() + ph.offset, elf_bytes.begin() + ph.offset + ph.filez, std::back_inserter(content));
    return content;
}

std::vector<uint8_t> elf_file::content(const elf32_sh_entry &sh) const {
    std::vector<uint8_t> content;
    std::copy(elf_bytes.begin() + sh.offset, elf_bytes.begin() + sh.offset + sh.size, std::back_inserter(content));
    return content;
}

void elf_file::content(const elf32_ph_entry &ph, const std::vector<uint8_t> &content) {
    if (!editable) return;
    assert(content.size() <= ph.filez);
    if (verbose) printf("Update segment content offset %x content size %zx physical size %x\n", ph.offset, content.size(), ph.filez);
    memcpy(&elf_bytes[ph.offset], &content[0], std::min(content.size(), (size_t) ph.filez));
    read_sh_data(); // Extract the sections after modifying the content
}

void elf_file::content(const elf32_sh_entry &sh, const std::vector<uint8_t> &content) {
    if (!editable) return;
    assert(content.size() <= sh.size);
    if (verbose) printf("Update section content offset %x content size %zx section size %x\n", sh.offset, content.size(), sh.size);
    memcpy(&elf_bytes[sh.offset], &content[0], std::min(content.size(), (size_t) sh.size));
    read_sh_data();  // Extract the sections after modifying the content
}

const elf32_ph_entry* elf_file::segment_from_physical_address(uint32_t paddr) {
    for (int i = 0; i < eh.ph_num; i++) {
        if (paddr >= ph_entries[i].paddr && paddr < ph_entries[i].paddr + ph_entries[i].filez) {
            if (verbose) printf("segment %d contains physical address %x\n", i, paddr);
            return &ph_entries[i];
        }
    }
    return nullptr;
}

const elf32_ph_entry* elf_file::segment_from_virtual_address(uint32_t vaddr) {
    for (int i = 0; i < eh.ph_num; i++) {
        if (vaddr >= ph_entries[i].vaddr && vaddr < ph_entries[i].vaddr + ph_entries[i].memsz) {
            if (verbose) printf("segment %d contains virtual address %x\n", i, vaddr);
            return &ph_entries[i];
        }
    }
    return NULL;
}

const elf32_ph_entry* elf_file::segment_from_section(const elf32_sh_entry &sh) {
    for (int i = 0; i < eh.ph_num; i++) {
        if (sh.offset >= ph_entries[i].offset && sh.offset < ph_entries[i].offset + ph_entries[i].filez) {
            if (verbose) printf("segment %d contains section %s\n", i, section_name(sh.name).c_str());
            return &ph_entries[i];
        }
    }
    return nullptr;
}

std::vector<elf32_ph_entry *> elf_file::sorted_segments_modifiable(void) {
    std::vector<elf32_ph_entry *> phys_sorted_segs;
    std::transform(ph_entries.begin(), ph_entries.end(), std::back_inserter(phys_sorted_segs), [](elf32_ph_entry &seg) {
        return &seg;
    });
    std::sort(phys_sorted_segs.begin(), phys_sorted_segs.end(), [](elf32_ph_entry *first, elf32_ph_entry *second) {
        return first->physical_address() < second->physical_address();
    });
    return phys_sorted_segs;
}

std::vector<const elf32_ph_entry *> elf_file::sorted_segments(void) {
    std::vector<const elf32_ph_entry *> const_sorted_segs;
    auto sorted_segs = sorted_segments_modifiable();
    std::transform(sorted_segs.begin(), sorted_segs.end(), std::back_inserter(const_sorted_segs), [](const elf32_ph_entry *seg) {
        return (const elf32_ph_entry *)seg;
    });
    return const_sorted_segs;
}

void elf_file::store_squashed(model_t model) {
    uint32_t highest_ram_address = 0;
    uint32_t highest_flash_address = 0;

    for(const auto &seg : sorted_segments()) {
        const uint32_t paddr = seg->physical_address();
        const uint32_t psize = seg->physical_size();
        if (psize == 0) continue;
        if (paddr >= model->sram_start() && paddr < model->sram_striped_end()) {
            highest_ram_address = std::max(paddr + psize, highest_ram_address);
        } else if (paddr >=  model->flash_start() && paddr < model->flash_end()) {
            highest_flash_address = std::max(paddr + psize, highest_flash_address);
        }
    }

    if (highest_flash_address != 0) {
        // cannot squash flash binaries
        return;
    }

    uint32_t last_seg_end = 0;
    uint32_t last_seg_start = 0;

    std::vector<elf32_ph_entry *> xip_sram_segs = {};

    auto squash_seg = [&](elf32_ph_entry *seg) {
        const uint32_t paddr = seg->physical_address();
        const uint32_t psize = seg->physical_size();
        if (!seg->is_load()) return;

        const bool is_alias = paddr == last_seg_start;
        last_seg_start = paddr;

        if (psize == 0 || is_alias) return;

        if (last_seg_end) {
            if (paddr != last_seg_end) {
                if (verbose) printf("squashing %08x to %08x\n", paddr, last_seg_end);
                seg->paddr = last_seg_end;
            }
        }
        // May have been modified, so read again
        last_seg_end = seg->physical_address() + seg->physical_size();
    };

    for(auto &seg : sorted_segments_modifiable()) {
        const uint32_t paddr = seg->physical_address();
        if (paddr >= model->xip_sram_start() && paddr < model->xip_sram_end()) {
            // XIP SRAM segments go at end, as we assume either the entry point
            // is in main SRAM, or there is no main SRAM
            xip_sram_segs.push_back(seg);
            continue;
        }

        squash_seg(seg);
    }

    for (auto &seg : xip_sram_segs) {
        squash_seg(seg);
    }
}

// Appends a new segment and section - filled with zeros
// Use content to replace the content
const elf32_ph_entry& elf_file::append_segment(uint32_t vaddr, uint32_t paddr, uint32_t size, const std::string &name) {
    elf32_ph_entry ph;
    read_sh_data(); // Convert the section data back into discreet chunks
    uint32_t sh_name = append_section_name(name);

    ph.type = PT_LOAD;
    ph.flags = PF_R; // Readable segment
    ph.paddr = paddr;
    ph.vaddr = vaddr;
    ph.filez = size;
    ph.memsz = size;
    ph.align = 2;

    if (verbose) {
        std::cout << "new segment " << name <<
            " paddr " << std::hex << paddr <<
            " vaddr " << std::hex << vaddr <<
            " size " << std::hex << size << std::endl;
    }
    ph_entries.push_back(ph);
    eh.ph_num++;

    // There's normally space between the end of the program header table and the start of data to
    // squeeze in another program header. If not, shuffle everything by 4K;
    uint32_t lso = lowest_section_offset();
    if (lso < eh.ph_offset + eh.ph_entry_size * eh.ph_num) {

        // Move the segment offsets
        for (auto &ph: ph_entries) {
            ph.offset += 0x1000;
        }

        // Move section header table and each section offset
        eh.sh_offset += 0x1000;
        for (auto &sh : sh_entries) {
            sh.offset += 0x1000;
        }
    }

    // Append the new signature section
    elf32_sh_entry sh = {};
    sh.name = sh_name;
    sh.type = SHT_PROGBITS;
    sh.flags = SHF_ALLOC;
    sh.addr = ph.vaddr;
    sh.size = size;
    uint32_t hso = highest_section_offset();
    sh.offset = hso;

    // Add the new segment for the signature and point to offset in file for data
    sh_entries.push_back(sh);
    sh_data.push_back(std::vector<uint8_t>(size));
    ph_entries.back().offset = sh.offset;

    eh.sh_offset = sh.offset + sh.size;
    eh.sh_num++;

    if (verbose) printf("%s sig offset %08x num sections %u\n", __func__, sh.offset, eh.sh_num);
    flatten();
    return ph_entries.back();
}

 std::vector<uint8_t> elf_file::read_binfile(std::shared_ptr<std::iostream> in) {
    std::vector<uint8_t> data;
    in->exceptions(std::iostream::failbit | std::iostream::badbit);
    in->seekg(0, in->end);
    data.resize(in->tellg());
    in->seekg(0, in->beg);
    in->read(reinterpret_cast<char *>(&data[0]), data.size());
    return data;
}
