Files

494 lines
8.9 KiB
C
Raw Permalink Normal View History

2025-06-27 00:32:57 +08:00
#include <stdio.h>
/**
* hello.c
*/
#include <stdlib.h>
#include <string.h>
#include <elf.h>
#include <errno.h>
#include "rtthread.h"
//#define FILE ft_file_struct
//#define fclose ft_if_fclose
//#define fopen ft_if_fopen
//#define fread ft_if_fread
//#define fseek ft_if_fseek
//#define ftell ft_if_ftell
static appm_list_struct g_app_list={0};
2025-07-05 19:47:28 +08:00
//<2F>ҵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>յ<EFBFBD>app<70><EFBFBD><E1B9B9>
2025-06-27 00:32:57 +08:00
static app_struct *appm_new(void)
{
if(g_app_list.used<APPM_LIST_MAXLEN)
{
for(int i=0;i<APPM_LIST_MAXLEN;i++)
{
app_struct *ptr=&g_app_list.app[i];
if(ptr->exe_addr==0)
{
g_app_list.used++;
return ptr;
}
}
}
return 0;
}
static int appm_delete (app_struct *app)
{
if(app==0) return -1;
for(int i=0;i<APPM_LIST_MAXLEN;i++)
{
app_struct *ptr=&g_app_list.app[i];
if(ptr==app)
{
memset(ptr,0,sizeof(app_struct));
g_app_list.used--;
return 0;
}
}
return -1;
}
app_struct * appm_find (char *name)
{
for(int i=0;i<APPM_LIST_MAXLEN;i++)
{
app_struct *ptr=&g_app_list.app[i];
if(strcmp(ptr->app_info->name,name)==0)
{
return ptr;
}
}
return 0;
}
app_struct *appm_get(int index)
{
if(index>=0&&index<APPM_LIST_MAXLEN)
{
if(g_app_list.app[index].exe_addr)
return &g_app_list.app[index];
else
return 0;
}
return 0;
}
2025-07-05 19:47:28 +08:00
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>app<70><70>Ŀ
2025-06-27 00:32:57 +08:00
int appm_get_running_num(void)
{
int ret=0;
for(int i=0;i<APPM_LIST_MAXLEN;i++)
{
app_struct *ptr=&g_app_list.app[i];
if(ptr->run_state) ret++;
}
return ret;
}
2025-07-05 19:47:28 +08:00
/**elf <20>ļ<EFBFBD>ͷ<EFBFBD><CDB7>section<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>***/
2025-06-27 00:32:57 +08:00
static int check_elf_head(app_struct * app )
{
if(app==0) return -1;
FILE *file_elf = app->file;
if(file_elf==0) return -1;
int i = 0;
int MagNum = 0;
unsigned long file_size = 0;
int sechnum = 0;
uint32_t symsize = 0;
uint32_t symoff = 0;
uint32_t nSyms = 0,kk=0;
Elf32_Ehdr *Elf_header = malloc(sizeof(Elf32_Ehdr));
2025-07-05 19:47:28 +08:00
/*<2A>ļ<EFBFBD><C4BC><EFBFBD>С*/
2025-06-27 00:32:57 +08:00
fseek(file_elf,0,SEEK_END);
file_size = ftell(file_elf);
fseek(file_elf,0,SEEK_SET);
printf("file total size is:%ld bytes\r\n",file_size);
fread(Elf_header,sizeof(Elf32_Ehdr),1,file_elf);
2025-07-05 19:47:28 +08:00
/**ȷ<><C8B7><EFBFBD>Ƿ<EFBFBD>Ϊelf<6C><66>ʽ**/
2025-06-27 00:32:57 +08:00
if((Elf_header->e_ident[EI_MAG0] == ELFMAG0) && (Elf_header->e_ident[EI_MAG1] == ELFMAG1) \
&& (Elf_header->e_ident[EI_MAG2] == ELFMAG2) && (Elf_header->e_ident[EI_MAG3] == ELFMAG3))
{
printf("This is ELF file!\r\n");
}
else
{
printf("NOT ELF file!\r\n");
free(Elf_header);
return -1;
}
free(Elf_header);
return 0;
}
2025-07-05 19:47:28 +08:00
/* <20><><EFBFBD><EFBFBD>elf<6C>ļ<EFBFBD>segment <20><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> */
2025-06-27 00:32:57 +08:00
static int load_elf_2_mem(app_struct * app)
{
if(app==0) return -1;
Elf32_Phdr *phdr_head = NULL;
Elf32_Ehdr *Elf_header = NULL;
FILE *file1 = app->file;
uint32_t rb;
Elf_header = (Elf32_Ehdr *)malloc(sizeof(Elf32_Ehdr));
memset(Elf_header,0,sizeof(Elf32_Ehdr));
fseek(file1,0,SEEK_SET);
rb = fread(Elf_header, sizeof(Elf32_Ehdr), 1, file1);
2025-07-05 19:47:28 +08:00
/* <20><><EFBFBD><EFBFBD> Elf_header->e_phentsize Ӧ<><D3A6><EFBFBD><EFBFBD>== sizeof(Elf32_Phdr)*/
2025-06-27 00:32:57 +08:00
phdr_head=malloc(Elf_header->e_phentsize *Elf_header->e_phnum);
fseek(file1,Elf_header->e_phoff,SEEK_SET);
fread(phdr_head,Elf_header->e_phentsize,Elf_header->e_phnum,file1);
2025-07-05 19:47:28 +08:00
//Elf_header->e_phnumһ<6D><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
2025-06-27 00:32:57 +08:00
for(int i=0;i< Elf_header->e_phnum; i++)
{
2025-07-05 19:47:28 +08:00
//<2F>dz<EFBFBD><C7B3><EFBFBD><EFBFBD><EFBFBD>
//Keil<69><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪRO<52><4F>RW<52><57>ZI<5A><49>3<EFBFBD><33><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>Ƕȿ<C7B6><C8BF><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD>ںϲ<DABA>Ϊһ<CEAA><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
if(phdr_head[i].p_type == PT_LOAD )
{
2025-07-05 19:47:28 +08:00
//<2F>ڴ<EFBFBD>
2025-06-27 00:32:57 +08:00
if(app->exe_addr==0)
{
app->exe_addr=malloc(phdr_head[i].p_memsz);
fseek( file1,phdr_head[i].p_offset,SEEK_SET);
if((rb = fread(app->exe_addr,1,phdr_head[i].p_filesz,file1)) != phdr_head[i].p_filesz)
{
printf("function:%s,line:%d, read p_vaddr err!\r\n",__FUNCTION__,__LINE__);
2025-07-05 19:47:28 +08:00
printf("read <20><><EFBFBD><EFBFBD>ֵ%d\r\n",rb);
2025-06-27 00:32:57 +08:00
printf("read(file,ProHead->p_vaddr,ProHead->p_filesz) != ProHead->p_filesz %x p_filesz %d\r\n",\
phdr_head[i].p_vaddr,phdr_head[i].p_filesz);
}
2025-07-05 19:47:28 +08:00
/**<2A><><EFBFBD><EFBFBD><EFBFBD>Ŀռ<C4BF>д0<D0B4><30><EFBFBD><EFBFBD>BSS<53><53>**/
2025-06-27 00:32:57 +08:00
if((phdr_head[i].p_filesz) < (phdr_head[i].p_memsz))
{
memset((uint8_t*)app->exe_addr+phdr_head[i].p_filesz,
0,
phdr_head[i].p_memsz - phdr_head[i].p_filesz);
}
2025-07-05 19:47:28 +08:00
//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>ַ
2025-06-27 00:32:57 +08:00
app->main=(int (*)(void *))((int)app->exe_addr+Elf_header->e_entry);
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ַ
2025-06-27 00:32:57 +08:00
app->app_info=(app_info_struct *)app->exe_addr;
printf("%s:exe_addr=0X%08X,size=%d\r\n",__func__,(uint32_t)app->exe_addr,phdr_head[i].p_memsz);
printf("%s:main()=0X%08X\r\n",__func__,(uint32_t)app->main);
printf("%s:name=%s\r\n",__func__,app->app_info->name);
break;
}
}
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RW<52><57><EFBFBD>ڳ<EFBFBD><DAB3><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD>е<EFBFBD>ƫ<EFBFBD><C6AB>
2025-06-27 00:32:57 +08:00
Elf32_Shdr *sher_head=NULL;
sher_head=malloc(Elf_header->e_shentsize *Elf_header->e_shnum);
fseek(file1,Elf_header->e_shoff,SEEK_SET);
fread(sher_head,Elf_header->e_shentsize,Elf_header->e_shnum,file1);
for(int i=0;i<Elf_header->e_shnum;i++)
{
if((sher_head[i].sh_type==SHT_PROGBITS)&&(sher_head[i].sh_flags==(SHF_ALLOC|SHF_EXECINSTR)))
{
app->ro_size=sher_head[i].sh_size;
break;
}
}
free(sher_head);
free(Elf_header);
free(phdr_head);
return 0;
}
2025-07-05 19:47:28 +08:00
//<2F>ر<EFBFBD>app<70>ļ<EFBFBD>
2025-06-27 00:32:57 +08:00
static void app_close(app_struct *app)
{
if(app==0) return;
if(app->file) fclose(app->file);
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>app<70>ļ<EFBFBD>
2025-06-27 00:32:57 +08:00
static int app_open(app_struct *app,char *path)
{
if(app==0) return -1;
app->file=fopen(path,"rb");
if(app->file)
{
return 0;
}
else
return -1;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD>ļ<EFBFBD><C4BC>л<EFBFBD>ȡapp<70><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//name,<2C><><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9A3AC><EFBFBD>ȱ<EFBFBD><C8B1>С<EBB2BB><D0A1>APP_INFO_NAME_MAXLEN
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><30>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
int app_get_name_from_file(char *path,char *name)
{
if(path==0) return 0;
if(name==0) return 0;
Elf32_Phdr *phdr_head = NULL;
Elf32_Ehdr *Elf_header = NULL;
FILE *file1 = fopen(path,"rb");
uint32_t rb;
if(file1==0) return 0;
Elf_header = (Elf32_Ehdr *)malloc(sizeof(Elf32_Ehdr));
memset(Elf_header,0,sizeof(Elf32_Ehdr));
fseek(file1,0,SEEK_SET);
rb = fread(Elf_header, sizeof(Elf32_Ehdr), 1, file1);
2025-07-05 19:47:28 +08:00
/* <20><><EFBFBD><EFBFBD> Elf_header->e_phentsize Ӧ<><D3A6><EFBFBD><EFBFBD>== sizeof(Elf32_Phdr)*/
2025-06-27 00:32:57 +08:00
phdr_head=malloc(Elf_header->e_phentsize *Elf_header->e_phnum);
fseek(file1,Elf_header->e_phoff,SEEK_SET);
fread(phdr_head,Elf_header->e_phentsize,Elf_header->e_phnum,file1);
2025-07-05 19:47:28 +08:00
//Elf_header->e_phnumһ<6D><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
2025-06-27 00:32:57 +08:00
for(int i=0;i< Elf_header->e_phnum; i++)
{
2025-07-05 19:47:28 +08:00
//<2F>dz<EFBFBD><C7B3><EFBFBD><EFBFBD><EFBFBD>
//Keil<69><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪRO<52><4F>RW<52><57>ZI<5A><49>3<EFBFBD><33><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>Ƕȿ<C7B6><C8BF><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD>ںϲ<DABA>Ϊһ<CEAA><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
if(phdr_head[i].p_type == PT_LOAD )
{
fseek( file1,phdr_head[i].p_offset,SEEK_SET);
if((rb = fread(name,1,APP_INFO_NAME_MAXLEN,file1)) == APP_INFO_NAME_MAXLEN)
{
int app_type=0;
fread(&app_type,1,sizeof(int),file1);
fclose(file1);
free(Elf_header);
free(phdr_head);
return app_type;
}
}
}
fclose(file1);
free(Elf_header);
free(phdr_head);
return 0;
}
2025-07-05 19:47:28 +08:00
//app<70>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD> 0,<2C>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>ʧ<EFBFBD><CAA7>
2025-06-27 00:32:57 +08:00
int app_exit(app_struct *app)
{
if(app==0) return -1;
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>app<70><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>˳<EFBFBD>app
2025-06-27 00:32:57 +08:00
if(app->run_state&&app->exit)
{
app->exit(0);
}
if(app->run_state==0)
{
2025-07-05 19:47:28 +08:00
//<2F><>appû<70><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ſ<EFBFBD><C5BF><EFBFBD>ɾ<EFBFBD><C9BE>
2025-06-27 00:32:57 +08:00
if(app->exe_addr) free(app->exe_addr);
appm_delete(app);
return 0;
}
else
{
return -1;
}
}
2025-07-05 19:47:28 +08:00
//<2F><>ȡ<EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>r9<72>Ĵ<EFBFBD><C4B4><EFBFBD>
2025-06-27 00:32:57 +08:00
void *get_r9(void);
void set_r9(void *r9);
2025-07-05 19:47:28 +08:00
//<2F><>ռʽ<D5BC><CABD><EFBFBD><EFBFBD>app<70><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>app
2025-06-27 00:32:57 +08:00
static int app_run_seize(app_struct *app)
{
int ret=0;
app->r9=get_r9();
set_r9((void *)((int)app->exe_addr+app->ro_size));
if (app->main) app->main(app);
set_r9(app->r9);
app_exit(app);
return ret;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>app<70><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>app<70><70><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
static int app_run_hold(app_struct *app)
{
int ret=0;
if(app==0) return -1;
app->r9=get_r9();
set_r9((void *)((int)app->exe_addr+app->ro_size));
if (app->main) app->main(app);
set_r9(app->r9);
return ret;
}
static void run_thread_entry(void *t)
{
app_struct *app=t;
int ret=0;
app->r9=get_r9();
set_r9((void *)((int)app->exe_addr+app->ro_size));
if (app->main) app->main(app);
set_r9(app->r9);
app_exit(app);
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>app
2025-06-27 00:32:57 +08:00
static int app_run_thread(app_struct *app)
{
int ret=0;
rt_thread_t rt=rt_thread_create(app->app_info->name,run_thread_entry,app,
app->app_info->stack_size,app->app_info->priority,20);
rt_thread_startup(rt);
ret=0;
return ret;
}
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD>app
2025-06-27 00:32:57 +08:00
int app_run(app_struct *app)
{
int ret=0;
if(app->app_info->exe_type==APP_TYPE_SEIZE)
{
ret=app_run_seize(app);
}
else if(app->app_info->exe_type==APP_TYPE_THREAD)
{
ret=app_run_thread(app);
}
else if(app->app_info->exe_type==APP_TYPE_HOLD)
{
ret=app_run_hold(app);
}
return ret;
}
int app_run_path(char *path)
{
int ret=0;
2025-07-05 19:47:28 +08:00
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4>У<EFBFBD><D0A3><EFBFBD>ֱ<EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD>
2025-06-27 00:32:57 +08:00
char name[APP_INFO_NAME_MAXLEN]={0};
if(app_get_name_from_file(path,name)!=0)
{
app_struct *app=appm_find(name);
if(app)
{
if(app->app_info->exe_type==APP_TYPE_HOLD)
{
ret=app_run_hold(app);
}
return ret;
}
}
app_struct *app=appm_new();
if((app_open(app,path)==0)&&(check_elf_head(app)==0)&&(load_elf_2_mem(app)==0))
{
app_close(app);
app_run(app);
}
else
{
appm_delete(app);
ret=-1;
}
return ret;
}