aboutsummaryrefslogtreecommitdiff
path: root/cleanc.c
diff options
context:
space:
mode:
Diffstat (limited to 'cleanc.c')
-rw-r--r--cleanc.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/cleanc.c b/cleanc.c
new file mode 100644
index 0000000..bc73574
--- /dev/null
+++ b/cleanc.c
@@ -0,0 +1,129 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <elf.h>
+#include <libelf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include "Clean.h"
+
+void call_funcname(char*);
+
+void hello(void) {
+ printf("Hello world!\n");
+}
+
+void* parameters[100];
+uint8_t param_ptr = 0;
+
+void init(void) {
+ parameters[0] = NULL;
+ param_ptr = 0;
+}
+
+void puti(long i) {
+ printf("puti %d %d\n", param_ptr, i);
+ parameters[param_ptr] = malloc(sizeof(long));
+ *((long*)parameters[param_ptr]) = i;
+ param_ptr++;
+}
+
+char* cleantocstring(CleanString s) {
+ char* cs = malloc(sizeof(char) * CleanStringLength(s) + 1);
+ int i;
+ for (i = 0; i < CleanStringLength(s); i++)
+ cs[i] = CleanStringCharacters(s)[i];
+ cs[i] = 0;
+ return cs;
+}
+
+void call(CleanString fname) {
+ char*f = cleantocstring(fname);
+ call_funcname(f);
+ param_ptr = 0;
+ // todo
+}
+
+long geti(void) {
+ printf("geti %d\n", param_ptr);
+ return (long)*((long*)parameters[param_ptr++]);
+}
+
+void call_funcname(char* fname) {
+ // http://stackoverflow.com/a/1118808/1544337
+ Elf64_Shdr * shdr;
+ Elf64_Ehdr * ehdr;
+ Elf * elf;
+ Elf_Scn * scn;
+ Elf_Data * data;
+ int cnt;
+ void (*fp)() = NULL;
+
+ int fd = 0;
+
+ /* This is probably Linux specific - Read in our own executable*/
+ if ((fd = open("/proc/self/exe", O_RDONLY)) == -1)
+ exit(1);
+
+ elf_version(EV_CURRENT);
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ fprintf(stderr, "file is not an ELF binary\n");
+ exit(1);
+ }
+ /* Let's get the elf sections */
+ if (((ehdr = elf64_getehdr(elf)) == NULL) ||
+ ((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) ||
+ ((data = elf_getdata(scn, NULL)) == NULL)) {
+ fprintf(stderr, "Failed to get SOMETHING\n");
+ exit(1);
+ }
+
+ /* Let's go through each elf section looking for the symbol table */
+ for (cnt = 1, scn = NULL; scn = elf_nextscn(elf, scn); cnt++) {
+ if ((shdr = elf64_getshdr(scn)) == NULL)
+ exit(1);
+
+ if (shdr->sh_type == SHT_SYMTAB) {
+ char *name;
+ char *strName;
+ data = 0;
+ if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0) {
+ fprintf(stderr, "No data in symbol table\n");
+ continue;
+ }
+
+ Elf64_Sym *esym = (Elf64_Sym*) data->d_buf;
+ Elf64_Sym *lastsym = (Elf64_Sym*) ((char*) data->d_buf + data->d_size);
+
+ /* Look through all symbols */
+ for (; esym < lastsym; esym++) {
+ if ((esym->st_value == 0) ||
+ (ELF64_ST_BIND(esym->st_info)== STB_WEAK) ||
+ (ELF64_ST_BIND(esym->st_info)== STB_NUM) ||
+ (ELF64_ST_TYPE(esym->st_info)!= STT_FUNC))
+ continue;
+
+ name = elf_strptr(elf,shdr->sh_link , (size_t)esym->st_name);
+
+ if(!name){
+ fprintf(stderr,"%s\n",elf_errmsg(elf_errno()));
+ //exit(-1);
+ } else if(strcmp(fname, name) == 0 ) {
+ fp = (void(*)(void)) esym->st_value;
+ }
+ }
+
+ /* Call and hope we don't segfault!*/
+ if (fp != NULL) {
+ fp();
+ return;
+ }
+ }
+ }
+
+ elf_end(elf);
+
+ fprintf(stderr, "done, nothing found\n");
+}
+