Use PIE format for user program
This commit is contained in:
parent
da5ff236bb
commit
67201cd226
|
@ -3,6 +3,7 @@
|
|||
# Tools
|
||||
COMPILER := sh3eb-elf-
|
||||
CC := $(COMPILER)gcc
|
||||
LD := $(COMPILER)ld
|
||||
OBJCOPY := $(COMPILER)objcopy
|
||||
OBJDUMP := $(COMPILER)objdump
|
||||
WRAPPER := g1a-wrapper
|
||||
|
|
|
@ -11,5 +11,6 @@
|
|||
extern int loader(struct process *process, const char *path);
|
||||
extern int loader_get_header(FILE *file, Elf32_Ehdr *header);
|
||||
extern int loader_load_image(struct process *process, FILE *file, Elf32_Ehdr *header);
|
||||
extern int loader_reloc_sym(struct process *process, FILE *file, Elf32_Ehdr *header);
|
||||
|
||||
#endif /*__KERNEL_LOADER_H__*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,20 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// CMDBLOCK()
|
||||
// Generate a "command block" stored in ".cmd.cahce" section.
|
||||
// We need to "hide" the block, so we generate anonyme name using
|
||||
// __COUNTER__ macros.
|
||||
#define gen_name(n) _##n
|
||||
#define anonym_name(n) gen_name(n)
|
||||
#define VHEX_BUILTIN(builtin) \
|
||||
static int builtin(int argc, char **argv); \
|
||||
__attribute__((section(".builtin.cache"))) \
|
||||
static const struct builtin_s anonym_name(__COUNTER__) = { \
|
||||
.name = #builtin, \
|
||||
.entry = builtin \
|
||||
}; \
|
||||
static int builtin(int argc, char **argv)
|
||||
|
||||
// Define builtin struct.
|
||||
struct builtin_s
|
||||
|
@ -13,8 +27,8 @@ struct builtin_s
|
|||
};
|
||||
|
||||
// Builtin list
|
||||
extern int builtin_proc(void);
|
||||
extern int builtin_ram(void);
|
||||
//extern int builtin_proc(void);
|
||||
//extern int builtin_ram(void);
|
||||
|
||||
|
||||
#endif /*__USER_BUILTIN_H__*/
|
||||
|
|
|
@ -39,5 +39,13 @@ int loader(struct process *process, const char *path)
|
|||
DBG_WAIT;
|
||||
return (-3);
|
||||
}
|
||||
|
||||
// Relocalise sections / symbols
|
||||
if (loader_reloc_sym(process, &file, &header) != 0)
|
||||
{
|
||||
earlyterm_write("loader: ELF relo error !");
|
||||
DBG_WAIT;
|
||||
return (-4);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -9,28 +9,28 @@ int loader_get_header(FILE *file, Elf32_Ehdr *header)
|
|||
return (-1);
|
||||
|
||||
// Check magic number
|
||||
if (header->e_ident[EI_MAG0] != 0x7f ||
|
||||
header->e_ident[EI_MAG1] != 'E' ||
|
||||
header->e_ident[EI_MAG2] != 'L' ||
|
||||
header->e_ident[EI_MAG3] != 'F')
|
||||
if (header->e_ident[EI_MAG0] != ELFMAG0 ||
|
||||
header->e_ident[EI_MAG1] != ELFMAG1 ||
|
||||
header->e_ident[EI_MAG2] != ELFMAG2 ||
|
||||
header->e_ident[EI_MAG3] != ELFMAG3)
|
||||
return (-2);
|
||||
|
||||
// Check class
|
||||
if (header->e_ident[EI_CLASS] != 1)
|
||||
if (header->e_ident[EI_CLASS] != ELFCLASS32)
|
||||
return (-3);
|
||||
|
||||
//TODO: Check OSABI (?)
|
||||
|
||||
// Check ELF type.
|
||||
if (header->e_type != ET_EXEC)
|
||||
if (header->e_type != ET_DYN)
|
||||
return (-4);
|
||||
|
||||
// Check ELF specifique instruction
|
||||
if (header->e_machine != 0x2A)
|
||||
if (header->e_machine != EM_SH)
|
||||
return (-5);
|
||||
|
||||
// Check ELF version
|
||||
if (header->e_version != 0x01)
|
||||
if (header->e_version != EV_CURRENT)
|
||||
return (-6);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
#include <kernel/loader.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/fs/vfs.h>
|
||||
|
||||
static char *get_shstrtab(FILE *file, Elf32_Ehdr *header)
|
||||
{
|
||||
Elf32_Shdr shdr;
|
||||
char *shstrtab;
|
||||
|
||||
// Get sections string header tables
|
||||
vfs_lseek(file, header->e_shoff + (header->e_shstrndx * sizeof(shdr)), SEEK_SET);
|
||||
if (vfs_read(file, &shdr, sizeof(shdr)) != sizeof(shdr))
|
||||
{
|
||||
earlyterm_write("loader_relo_sym: section header table error\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Allocate dump area
|
||||
shstrtab = (char*)pm_alloc(shdr.sh_size);
|
||||
if (shstrtab == NULL)
|
||||
{
|
||||
earlyterm_write("loader_relo_sym: memory error\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Get string tables
|
||||
vfs_lseek(file, shdr.sh_offset, SEEK_SET);
|
||||
if (vfs_read(file, shstrtab, shdr.sh_size) != (ssize_t)shdr.sh_size)
|
||||
{
|
||||
earlyterm_write("loader_relo_sym: shstrtab size error\n");
|
||||
pm_free(shstrtab);
|
||||
return (NULL);
|
||||
}
|
||||
return (shstrtab);
|
||||
}
|
||||
|
||||
static int reloc_section(struct process *process, FILE *file, Elf32_Shdr *shdr)
|
||||
{
|
||||
Elf32_Rela rela;
|
||||
uint32_t *prog;
|
||||
|
||||
// List symbols
|
||||
prog = (void*)process->memory.program.start;
|
||||
for (uint32_t i = 0 ; i < shdr->sh_size / shdr->sh_entsize ; ++i)
|
||||
{
|
||||
// Get relocatable entry
|
||||
vfs_lseek(file, shdr->sh_offset + (i * sizeof(rela)), SEEK_SET);
|
||||
if (vfs_read(file, &rela, sizeof(rela)) != sizeof(rela))
|
||||
{
|
||||
earlyterm_write("reloc_section: reloc section size error\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Relocalise symbols
|
||||
//earlyterm_write("* [%d] %p, %#x\n", i, rela.r_offset, rela.r_addend);
|
||||
prog[rela.r_offset >> 2] = rela.r_addend + process->memory.program.start;
|
||||
//DBG_WAIT;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int loader_reloc_sym(struct process *process, FILE *file, Elf32_Ehdr *header)
|
||||
{
|
||||
Elf32_Shdr shdr;
|
||||
char *shstrtab;
|
||||
|
||||
//TODO
|
||||
(void)process;
|
||||
|
||||
// DEBUG
|
||||
//earlyterm_write("e_shnum = %d\n", header->e_shnum);
|
||||
//earlyterm_write("e_shstrndx = %d\n", header->e_shstrndx);
|
||||
|
||||
|
||||
// Get the shstrtab
|
||||
shstrtab = get_shstrtab(file, header);
|
||||
if (shstrtab == NULL)
|
||||
return (-1);
|
||||
|
||||
// List header tables
|
||||
for (int i = 1 ; i < header->e_shnum ; ++i)
|
||||
{
|
||||
// Get next section header
|
||||
vfs_lseek(file, header->e_shoff + (i * sizeof(shdr)), SEEK_SET);
|
||||
if (vfs_read(file, &shdr, sizeof(shdr)) != sizeof(shdr))
|
||||
{
|
||||
earlyterm_write("loader_reloc_sym: section header\n");
|
||||
return (-2);
|
||||
}
|
||||
|
||||
// Check relocatable sections
|
||||
if (shdr.sh_type != SHT_RELA)
|
||||
continue;
|
||||
|
||||
// Diplay section name
|
||||
earlyterm_write("[%d] %s - %d\n", i, &shstrtab[shdr.sh_name], shdr.sh_size / shdr.sh_entsize);
|
||||
if (reloc_section(process, file, &shdr) != 0)
|
||||
return (-3);
|
||||
}
|
||||
pm_free(shstrtab);
|
||||
//earlyterm_write("start = %p\n", process->memory.program.start);
|
||||
//DBG_WAIT;
|
||||
//DBG_WAIT;
|
||||
//DBG_WAIT;
|
||||
return (0);
|
||||
}
|
|
@ -45,9 +45,7 @@ OBJ := $(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))
|
|||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ) | $(DEBUG)
|
||||
$(CC) -fPIC -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -S $(DEBUG)/$(NAME).elf.big $@
|
||||
rm -f $(DEBUG)/$(NAME).elf.big
|
||||
$(CC) -pie -Wl,-M $(LDFLAG) $(CFLAGS) -o $@ $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
|
||||
|
||||
$(BUILD) $(DEBUG):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
|
@ -77,7 +75,7 @@ sec:
|
|||
define rule-src
|
||||
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1 | $(BUILD)
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) -fPIC $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ $(CC) -pie $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*#include "builtin.h"
|
||||
#include "builtin.h"
|
||||
#include <lib/display.h>
|
||||
|
||||
VHEX_BUILTIN(fxdb)
|
||||
|
@ -7,9 +7,9 @@ VHEX_BUILTIN(fxdb)
|
|||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
dclear();
|
||||
dprint(0, 0, "FXDB - entry !!");
|
||||
dupdate();
|
||||
//dclear();
|
||||
//dprint(0, 0, "FXDB - entry !!");
|
||||
//dupdate();
|
||||
for (int i = 0 ; i < 9000000 ; i = i + 1);
|
||||
return (0);
|
||||
|
||||
|
@ -32,5 +32,5 @@ VHEX_BUILTIN(fxdb)
|
|||
|
||||
// Power OFF UBC module.
|
||||
// ubc_close();
|
||||
return (0);
|
||||
}*/
|
||||
// return (0);
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
#include <lib/unistd.h>
|
||||
#include "util.h"
|
||||
|
||||
// @note
|
||||
// For now all kernel invocation is
|
||||
// made by the `unistd` library.
|
||||
|
||||
//TODO: documentation.
|
||||
int main(void)
|
||||
{
|
||||
|
@ -40,7 +36,7 @@ int main(void)
|
|||
__asm__ volatile ("sleep");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Shell main loop.
|
||||
write(fd, "Boot Complete !\n", 16);
|
||||
while (1)
|
||||
|
@ -54,11 +50,14 @@ int main(void)
|
|||
input[cmd_size - 1] = '\0';
|
||||
|
||||
// Check buit-in.
|
||||
//if (check_builtin(input) != 0)
|
||||
//{
|
||||
if (check_builtin(input) != 0)
|
||||
{
|
||||
write(fd, input, cmd_size - 1);
|
||||
write(fd, ": command not found\n", 20);
|
||||
//}
|
||||
} else {
|
||||
write(fd, input, cmd_size - 1);
|
||||
write(fd, ": command found :D !\n", 21);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
|
||||
OUTPUT_ARCH(sh3)
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
ENTRY(_main)
|
||||
|
||||
/*
|
||||
|
@ -11,26 +11,57 @@ MEMORY
|
|||
userram (WX) : o = 0x00000000, l = 256k
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD ;
|
||||
data PT_LOAD ;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections */
|
||||
.text : {
|
||||
/* Code */
|
||||
*(.text);
|
||||
*(.text.*);
|
||||
} : text
|
||||
|
||||
.rodata : {
|
||||
/* Read-Only data */
|
||||
*(.rodata);
|
||||
*(.rodata.*);
|
||||
}
|
||||
|
||||
/* Dynamic symbols */
|
||||
*(.hash)
|
||||
*(.dynsym)
|
||||
*(.dynstr)
|
||||
*(.dynbss)
|
||||
*(.dynamic)
|
||||
|
||||
/* Procedure Linkage Table */
|
||||
*(.plt)
|
||||
|
||||
/* GLobal Offset Table */
|
||||
*(.got.plt)
|
||||
*(.got.*)
|
||||
*(.got)
|
||||
|
||||
/* ???? */
|
||||
*(.rofixup)
|
||||
|
||||
/* Internal builtin cache */
|
||||
PROVIDE (_builtin_list = ALIGN(4));
|
||||
*(.builtin)
|
||||
*(.builtin.*)
|
||||
PROVIDE (_builtin_list_end = . );
|
||||
} > userram
|
||||
|
||||
/* Relocatable sections */
|
||||
.rela.dyn : {
|
||||
*(.rela.plt)
|
||||
*(.rela.got)
|
||||
*(.rela.got.*)
|
||||
*(.rela.*)
|
||||
*(.rela.text)
|
||||
*(.real.data)
|
||||
} > userram
|
||||
|
||||
/* readable / writable data */
|
||||
.data ALIGN(4) : {
|
||||
*(.plt);
|
||||
|
||||
/* Data sections */
|
||||
*(.data);
|
||||
*(.data.*);
|
||||
|
||||
|
@ -38,18 +69,11 @@ SECTIONS
|
|||
*(.bss);
|
||||
*(.bss.*);
|
||||
*(COMMON);
|
||||
} : data
|
||||
|
||||
|
||||
.relocgot : {
|
||||
BRELOC_GOT = . ;
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
ERELOC_GOT = . ;
|
||||
}
|
||||
} > userram
|
||||
|
||||
/* unwanted section */
|
||||
/DISCARD/ : {
|
||||
*(.gnu.*)
|
||||
*(.debug_info)
|
||||
*(.debug_abbrev)
|
||||
*(.debug_loc)
|
||||
|
@ -61,5 +85,6 @@ SECTIONS
|
|||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
*(.comment)
|
||||
*(.interp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,20 +7,46 @@
|
|||
// Internal builtin list
|
||||
// FIXME: due to PIE binary format, we can not
|
||||
// FIXME: use address of builtin_proc !!
|
||||
/*struct builtin_s list[1] = {
|
||||
struct builtin_s builtin[2] = {
|
||||
{
|
||||
.name = "proc",
|
||||
.entry = (void*)&builtin_proc
|
||||
.entry = NULL
|
||||
},
|
||||
//{
|
||||
// .name = "ram",
|
||||
// .entry = (void *)&builtin_ram
|
||||
//}
|
||||
};*/
|
||||
{
|
||||
.name = "ram",
|
||||
.entry = NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//TODO: use agc, argv.
|
||||
int check_builtin(char *cmd)
|
||||
{
|
||||
/* extern struct builtin_s *builtin_list;
|
||||
extern struct builtin_s *builtin_list_end;
|
||||
int i;
|
||||
|
||||
// Try to find builtin
|
||||
i = -1;
|
||||
while (&builtin_list[++i] < builtin_list_end)
|
||||
{
|
||||
// Check builtin name
|
||||
if (strcmp(builtin_list[i].name, cmd) != 0)
|
||||
continue;
|
||||
|
||||
// Execute builtin
|
||||
builtin_list[i].entry(0, NULL);
|
||||
return (0);
|
||||
}*/
|
||||
for (int i = 0 ; i < 2 ; ++i) {
|
||||
if (strcmp(builtin[i].name, cmd) != 0)
|
||||
continue;
|
||||
if (builtin[i].entry != NULL)
|
||||
(*builtin[i].entry)(0, NULL);
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
|
||||
// Process test
|
||||
/* dclear();
|
||||
|
@ -56,11 +82,11 @@ int check_builtin(char *cmd)
|
|||
// Try to find builtin
|
||||
/* for (int i = 0 ; i < 1 ; i++)
|
||||
{
|
||||
if (strcmp(list[i].name, cmd) != 0)
|
||||
if (strcmp(builtin[i].name, cmd) != 0)
|
||||
continue;
|
||||
|
||||
// Execute builtin
|
||||
list[i].entry(0, NULL);
|
||||
builtin[i].entry(0, NULL);
|
||||
return (0);
|
||||
}*/
|
||||
return (-1);
|
||||
|
|
Loading…
Reference in New Issue