merge elf loading and adc streaming
commit
989f4038c6
@ -0,0 +1,14 @@
|
|||||||
|
all:
|
||||||
|
@arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE -c test.cpp
|
||||||
|
@arm-none-eabi-ld -shared -n -N -z max-page-size=512 -Ttext-segment=0 \
|
||||||
|
test.o -o test.so
|
||||||
|
@arm-none-eabi-strip -s -S --strip-unneeded test.so
|
||||||
|
@arm-none-eabi-objcopy --remove-section .dynsym \
|
||||||
|
--remove-section .dynstr \
|
||||||
|
--remove-section .dynamic \
|
||||||
|
--remove-section .hash \
|
||||||
|
--remove-section .ARM.exidx \
|
||||||
|
--remove-section .ARM.attributes \
|
||||||
|
--remove-section .comment \
|
||||||
|
test.so
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
using adcsample_t = uint16_t;
|
||||||
|
__attribute__((section(".process_data")))
|
||||||
|
void process_data(adcsample_t *samples, unsigned int size);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void process_data(adcsample_t *samples, unsigned int size)
|
||||||
|
{
|
||||||
|
size--;
|
||||||
|
for (unsigned int i = 0; i < size; i++)
|
||||||
|
samples[i] = samples[i] * 80 / 100 + samples[i + 1] * 20 / 100;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
|||||||
|
#ifndef STMDSP_ELF_FORMAT_HPP_
|
||||||
|
#define STMDSP_ELF_FORMAT_HPP_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
#define PT_NULL 0
|
||||||
|
#define PT_LOAD 1
|
||||||
|
#define PT_DYNAMIC 2
|
||||||
|
#define PT_INTERP 3
|
||||||
|
#define PT_NOTE 4
|
||||||
|
#define PT_SHLIB 5
|
||||||
|
#define PT_PHDR 6
|
||||||
|
#define PT_RESERVED 0x70000000
|
||||||
|
|
||||||
|
#define ELF32_ST_BIND(i) ((i) >> 4)
|
||||||
|
#define ELF32_ST_TYPE(i) ((i) & 0xF)
|
||||||
|
#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xF))
|
||||||
|
|
||||||
|
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||||
|
#define ELF32_R_TYPE(i) ((i) & 0xFF)
|
||||||
|
#define ELF32_R_INFO(s, t) (((s) << 8) + ((t) & 0xFF))
|
||||||
|
|
||||||
|
typedef uint32_t Elf32_Addr;
|
||||||
|
typedef uint16_t Elf32_Half;
|
||||||
|
typedef uint32_t Elf32_Off;
|
||||||
|
typedef uint32_t Elf32_Sword;
|
||||||
|
typedef uint32_t Elf32_Word;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
Elf32_Half e_type;
|
||||||
|
Elf32_Half e_machine;
|
||||||
|
Elf32_Word e_version;
|
||||||
|
Elf32_Addr e_entry;
|
||||||
|
Elf32_Off e_phoff;
|
||||||
|
Elf32_Off e_shoff;
|
||||||
|
Elf32_Word e_flags;
|
||||||
|
Elf32_Half e_ehsize;
|
||||||
|
Elf32_Half e_phentsize;
|
||||||
|
Elf32_Half e_phnum;
|
||||||
|
Elf32_Half e_shentsize;
|
||||||
|
Elf32_Half e_shnum;
|
||||||
|
Elf32_Half e_shstrndx;
|
||||||
|
} __attribute__((packed)) Elf32_Ehdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word sh_name;
|
||||||
|
Elf32_Word sh_type;
|
||||||
|
Elf32_Word sh_flags;
|
||||||
|
Elf32_Addr sh_addr;
|
||||||
|
Elf32_Off sh_offset;
|
||||||
|
Elf32_Word sh_size;
|
||||||
|
Elf32_Word sh_link;
|
||||||
|
Elf32_Word sh_info;
|
||||||
|
Elf32_Word sh_addralign;
|
||||||
|
Elf32_Word sh_entsize;
|
||||||
|
} __attribute__((packed)) Elf32_Shdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word st_name;
|
||||||
|
Elf32_Addr st_value;
|
||||||
|
Elf32_Word st_size;
|
||||||
|
unsigned char st_info;
|
||||||
|
unsigned char st_other;
|
||||||
|
Elf32_Half st_shndx;
|
||||||
|
} __attribute__((packed)) Elf32_Sym;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Addr r_offset;
|
||||||
|
Elf32_Word r_info;
|
||||||
|
} __attribute__((packed)) Elf32_Rel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Addr r_offset;
|
||||||
|
Elf32_Word r_info;
|
||||||
|
Elf32_Sword r_addend;
|
||||||
|
} __attribute__((packed)) Elf32_Rela;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word p_type;
|
||||||
|
Elf32_Off p_offset;
|
||||||
|
Elf32_Addr p_vaddr;
|
||||||
|
Elf32_Addr p_paddr;
|
||||||
|
Elf32_Word p_filesz;
|
||||||
|
Elf32_Word p_memsz;
|
||||||
|
Elf32_Word p_flags;
|
||||||
|
Elf32_Word p_align;
|
||||||
|
} __attribute__((packed)) Elf32_Phdr;
|
||||||
|
|
||||||
|
#endif // STMDSP_ELF_FORMAT_HPP_
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
#include "elf_load.hpp"
|
||||||
|
#include "elf_format.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
extern void *elf_load_offset;
|
||||||
|
static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' };
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr static auto ptr_from_offset(void *base, uint32_t offset)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T>(reinterpret_cast<uint8_t *>(base) + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name);
|
||||||
|
|
||||||
|
namespace elf {
|
||||||
|
|
||||||
|
entry_t elf_load(void *elf_data)
|
||||||
|
{
|
||||||
|
auto ehdr = reinterpret_cast<Elf32_Ehdr *>(elf_data);
|
||||||
|
if (std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto phdr = ptr_from_offset<Elf32_Phdr *>(elf_data, ehdr->e_phoff);
|
||||||
|
for (Elf32_Half i = 0; i < ehdr->e_phnum; i++) {
|
||||||
|
if (phdr->p_type == PT_LOAD) {
|
||||||
|
std::memcpy(ptr_from_offset<void *>(elf_load_offset, phdr->p_vaddr),
|
||||||
|
ptr_from_offset<void *>(elf_data, phdr->p_offset),
|
||||||
|
phdr->p_filesz);
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero .bss section
|
||||||
|
if (auto bss_section = find_section(ehdr, ".bss"); bss_section) {
|
||||||
|
auto bss = ptr_from_offset<uint32_t *>(elf_load_offset, bss_section->sh_addr);
|
||||||
|
std::fill(bss, bss + bss_section->sh_size / sizeof(uint32_t), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix global offset table (GOT) entries
|
||||||
|
if (auto got_section = find_section(ehdr, ".got"); got_section) {
|
||||||
|
auto got = ptr_from_offset<void **>(elf_load_offset, got_section->sh_addr);
|
||||||
|
for (size_t i = 0; i < got_section->sh_size / sizeof(void *); i++)
|
||||||
|
got[i] = ptr_from_offset<void *>(got[i], reinterpret_cast<uint32_t>(elf_load_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Run any initial constructors
|
||||||
|
//if (auto init_section = find_section(ehdr, ".init_array"); init_section) {
|
||||||
|
// auto init_array = reinterpret_cast<void (**)()>(elf_load_offset + init_section->sh_addr);
|
||||||
|
// std::for_each(init_array, init_array + init_section->sh_size / sizeof(void (*)()),
|
||||||
|
// [elf_load_offset](auto func) { (func + elf_load_offset)(); });
|
||||||
|
//}
|
||||||
|
|
||||||
|
return ptr_from_offset<entry_t>(elf_load_offset, ehdr->e_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
|
||||||
|
Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name)
|
||||||
|
{
|
||||||
|
auto shdr = ptr_from_offset<Elf32_Shdr *>(ehdr, ehdr->e_shoff);
|
||||||
|
auto shdr_str = ptr_from_offset<Elf32_Shdr *>(ehdr,
|
||||||
|
ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
|
||||||
|
|
||||||
|
for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) {
|
||||||
|
char *section = ptr_from_offset<char *>(ehdr, shdr_str->sh_offset) + shdr->sh_name;
|
||||||
|
if (!strcmp(section, name))
|
||||||
|
return shdr;
|
||||||
|
|
||||||
|
shdr = ptr_from_offset<Elf32_Shdr *>(shdr, ehdr->e_shentsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef ELF_LOAD_HPP_
|
||||||
|
#define ELF_LOAD_HPP_
|
||||||
|
|
||||||
|
namespace elf
|
||||||
|
{
|
||||||
|
using entry_t = void (*)();
|
||||||
|
|
||||||
|
entry_t load(void *file_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ELF_LOAD_HPP_
|
||||||
|
|
Loading…
Reference in New Issue