ram-segments.c
00001 #ifndef __RAM_SEGMENTS_C__1POIF5E8U4__
00002 #define __RAM_SEGMENTS_C__1POIF5E8U4__
00003
00004 #include <loader/elfloader-otf.h>
00005 #include <loader/codeprop-otf.h>
00006 #include <sys/types.h>
00007 #include <string.h>
00008 #include <stdio.h>
00009
00010 struct ram_output
00011 {
00012 struct elfloader_output output;
00013 char *base;
00014 unsigned int offset;
00015 void *text;
00016 void *rodata;
00017 void *data;
00018 void *bss;
00019 };
00020
00021 static void *
00022 allocate_segment(struct elfloader_output * const output,
00023 unsigned int type, int size)
00024 {
00025 struct ram_output * const ram = (struct ram_output *)output;
00026 void *block = malloc(size);
00027 if (!block) return NULL;
00028 switch(type) {
00029 case ELFLOADER_SEG_TEXT:
00030 if (ram->text) free(ram->text);
00031 ram->text = block;
00032 break;
00033 case ELFLOADER_SEG_RODATA:
00034 if (ram->rodata) free(ram->rodata);
00035 ram->rodata = block;
00036 break;
00037 case ELFLOADER_SEG_DATA:
00038 if (ram->data) free(ram->data);
00039 ram->data = block;
00040 break;
00041 case ELFLOADER_SEG_BSS:
00042 if (ram->bss) free(ram->bss);
00043 ram->bss = block;
00044 break;
00045 default:
00046 free(block);
00047 return NULL;
00048 }
00049 return block;
00050 }
00051
00052 static int
00053 start_segment(struct elfloader_output *output,
00054 unsigned int type, void *addr, int size)
00055 {
00056 ((struct ram_output*)output)->base = addr;
00057 ((struct ram_output*)output)->offset = 0;
00058 return ELFLOADER_OK;
00059 }
00060
00061 static int
00062 end_segment(struct elfloader_output *output)
00063 {
00064 return ELFLOADER_OK;
00065 }
00066
00067 static int
00068 write_segment(struct elfloader_output *output, const char *buf,
00069 unsigned int len)
00070 {
00071 struct ram_output * const ram = (struct ram_output *)output;
00072 memcpy(ram->base + ram->offset, buf, len);
00073 ram->offset += len;
00074 return len;
00075 }
00076
00077 static unsigned int
00078 segment_offset(struct elfloader_output *output)
00079 {
00080 return ((struct ram_output*)output)->offset;
00081 }
00082
00083 static const struct elfloader_output_ops elf_output_ops =
00084 {
00085 allocate_segment,
00086 start_segment,
00087 end_segment,
00088 write_segment,
00089 segment_offset
00090 };
00091
00092
00093 static struct ram_output seg_output = {
00094 {&elf_output_ops},
00095 NULL,
00096 0,
00097 NULL,
00098 NULL,
00099 NULL,
00100 NULL
00101 };
00102
00103 PROCESS(ram_segments_cleanup_process, "RAM segments cleanup process");
00104
00105 PROCESS_THREAD(ram_segments_cleanup_process, ev, data)
00106 {
00107 PROCESS_BEGIN();
00108 while(1) {
00109 PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXITED
00110 || ev == PROCESS_EVENT_EXIT);
00111 if (ev == PROCESS_EVENT_EXIT) break;
00112 if (elfloader_autostart_processes ||
00113 elfloader_autostart_processes[0] == data) {
00114 PROCESS_PAUSE();
00115 if (seg_output.text) {
00116 free(seg_output.text);
00117 seg_output.text = NULL;
00118 }
00119 if (seg_output.rodata) {
00120 free(seg_output.rodata);
00121 seg_output.rodata = NULL;
00122 }
00123 if (seg_output.data) {
00124 free(seg_output.data);
00125 seg_output.data = NULL;
00126 }
00127
00128 if (seg_output.bss) {
00129 free(seg_output.bss);
00130 seg_output.bss = NULL;
00131 }
00132 elfloader_autostart_processes = NULL;
00133 }
00134 }
00135 PROCESS_END();
00136 }
00137 struct elfloader_output *codeprop_output = &seg_output.output;
00138
00139 #endif