improved elf loading

pull/3/head
Clyne 4 years ago
parent 09b2c79ed6
commit d568f7ca9d

@ -751,6 +751,9 @@
/* Port-specific settings (override port settings defaulted in chcore.h). */ /* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/ /*===========================================================================*/
// Enable syscall support
#define PORT_USE_SYSCALL TRUE
#endif /* CHCONF_H */ #endif /* CHCONF_H */
/** @} */ /** @} */

@ -181,18 +181,13 @@ void MainFrame::prepareEditor()
static const char *makefile_text = R"make( static const char *makefile_text = R"make(
all: all:
@arm-none-eabi-g++ -x c++ -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE -c $0 -o $0.o @arm-none-eabi-g++ -x c++ -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE $0 -o $0.o -Wl,-Ttext-segment=0 -Wl,-eprocess_data_entry -Wl,-zmax-page-size=512
@arm-none-eabi-ld -shared -n -N -z max-page-size=512 -Ttext-segment=0 \ @arm-none-eabi-strip -s -S --strip-unneeded $0.o
$0.o -o $0.so @arm-none-eabi-objcopy --remove-section .ARM.exidx \
@arm-none-eabi-strip -s -S --strip-unneeded $0.so --remove-section .ARM.attributes \
@arm-none-eabi-objcopy --remove-section .dynsym \ --remove-section .comment \
--remove-section .dynstr \ --remove-section .noinit \
--remove-section .dynamic \ $0.o
--remove-section .hash \
--remove-section .ARM.exidx \
--remove-section .ARM.attributes \
--remove-section .comment \
$0.so
)make"; )make";
static const char *file_header = R"cpp( static const char *file_header = R"cpp(
@ -200,10 +195,21 @@ static const char *file_header = R"cpp(
using adcsample_t = uint16_t; using adcsample_t = uint16_t;
__attribute__((section(".process_data"))) void process_data(adcsample_t *samples, unsigned int size); static void process_data(adcsample_t *samples, unsigned int size);
// End stmdspgui header code __attribute__((optimize("-O0")))
static void *alloc(unsigned int count) {
void *result = nullptr;
asm("mov r0, %0; mov r1, %1; svc 0" :: "r" (&result), "r" (count));
return result;
}
extern "C" void process_data_entry() {
auto func = (void (*)())process_data;
func();
}
// End stmdspgui header code
)cpp"; )cpp";
wxString MainFrame::compileEditorCode() wxString MainFrame::compileEditorCode()
@ -223,7 +229,7 @@ wxString MainFrame::compileEditorCode()
wxString make_command = wxString("make -C ") + file_name.BeforeLast('/') + wxString make_command = wxString("make -C ") + file_name.BeforeLast('/') +
" -f " + file_name + "make"; " -f " + file_name + "make";
if (system(make_command.ToAscii()) == 0) if (system(make_command.ToAscii()) == 0)
return file_name + ".so"; return file_name + ".o";
else else
return ""; return "";
} }

@ -54,29 +54,25 @@ entry_t load(void *elf_data, void *elf_load_offset)
// [elf_load_offset](auto func) { (func + elf_load_offset)(); }); // [elf_load_offset](auto func) { (func + elf_load_offset)(); });
//} //}
// Find filter code start return ptr_from_offset<entry_t>(elf_load_offset, ehdr->e_entry);
if (auto filter = find_section(ehdr, ".process_data"); filter)
return ptr_from_offset<entry_t>(elf_load_offset, filter->sh_addr | 1); // OR 1 to enable thumb
else
return nullptr;
} }
} // namespace elf } // namespace elf
Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name) Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name)
{ {
auto shdr = ptr_from_offset<Elf32_Shdr *>(ehdr, ehdr->e_shoff); auto shdr = ptr_from_offset<Elf32_Shdr *>(ehdr, ehdr->e_shoff);
auto shdr_str = ptr_from_offset<Elf32_Shdr *>(ehdr, auto shdr_str = ptr_from_offset<Elf32_Shdr *>(ehdr,
ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize); ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) { for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) {
char *section = ptr_from_offset<char *>(ehdr, shdr_str->sh_offset) + shdr->sh_name; char *section = ptr_from_offset<char *>(ehdr, shdr_str->sh_offset) + shdr->sh_name;
if (!strcmp(section, name)) if (!strcmp(section, name))
return shdr; return shdr;
shdr = ptr_from_offset<Elf32_Shdr *>(shdr, ehdr->e_shentsize); shdr = ptr_from_offset<Elf32_Shdr *>(shdr, ehdr->e_shentsize);
} }
return 0; return 0;
} }

@ -111,12 +111,52 @@ int main()
} }
} }
void quick_freeall();
void signal_operate(adcsample_t *buffer, size_t count) void signal_operate(adcsample_t *buffer, size_t count)
{ {
if (elf_entry) if (elf_entry) {
elf_entry(buffer, count); elf_entry(buffer, count);
quick_freeall();
}
auto dac_buffer = &dac_samples[buffer == &adc_samples[0] ? 0 : 1024]; auto dac_buffer = &dac_samples[buffer == &adc_samples[0] ? 0 : 1024];
std::copy(buffer, buffer + count, dac_buffer); std::copy(buffer, buffer + count, dac_buffer);
signal_operate_done = buffer == &adc_samples[1024]; signal_operate_done = buffer == &adc_samples[1024];
} }
// Dynamic memory allocation below
uint8_t quick_malloc_heap[8192];
uint8_t *quick_malloc_next = quick_malloc_heap;
void *quick_malloc(unsigned int size)
{
if (auto free = std::distance(quick_malloc_next, quick_malloc_heap + 8192); free < 0 || size > static_cast<unsigned int>(free))
return nullptr;
auto ptr = quick_malloc_next;
quick_malloc_next += size;
return ptr;
}
void quick_freeall()
{
if (quick_malloc_next != quick_malloc_heap)
quick_malloc_next = quick_malloc_heap;
}
void port_syscall(struct port_extctx *ctxp, uint32_t n)
{
switch (n) {
case 0:
*reinterpret_cast<void **>(ctxp->r0) = quick_malloc(ctxp->r1);
break;
case 1:
quick_freeall();
break;
}
chSysHalt("svc");
}

Loading…
Cancel
Save