add elf load draft, filter program template

pull/3/head
Clyne 4 years ago
parent d060dce4ec
commit 29e4b4cf09

1
.gitignore vendored

@ -3,5 +3,6 @@ ChibiOS_*
**/.*
gui/stmdspgui
**/*.o
**/*.so
perf*

@ -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…
Cancel
Save