a few more patches and a little rework
[ginge.git] / loader / dl.c
CommitLineData
499bf01c 1/*
2 * GINGE - GINGE Is Not Gp2x Emulator
3 * (C) notaz, 2010-2011
4 *
5 * This work is licensed under the MAME license, see COPYING file for details.
6 */
7fd42181 7#define _GNU_SOURCE
8#include <stdio.h>
9#include <stdlib.h>
10#include <sys/mman.h>
11#include <dlfcn.h>
12#include "header.h"
13
14#define DL
15#include "override.c"
16
4d045184 17static void next_line(FILE *f)
18{
19 int c;
20 do {
21 c = fgetc(f);
22 } while (c != EOF && c != '\n');
23}
24
7fd42181 25__attribute__((constructor))
26static void ginge_init(void)
27{
28 unsigned int lowest_segment = (unsigned int)-1;
29 unsigned int start, end;
30 int i, ret;
31 FILE *f;
32
33 for (i = 0; i < ARRAY_SIZE(real_funcs_np); i++) {
34 *real_funcs_np[i].func_ptr = dlsym(RTLD_NEXT, real_funcs_np[i].name);
35 if (*real_funcs_np[i].func_ptr == NULL) {
36 fprintf(stderr, "dlsym %s: %s\n", real_funcs_np[i].name, dlerror());
37 exit(1);
38 }
39 // dbg("%p %s\n", *real_funcs_np[i].func_ptr, real_funcs_np[i].name);
40 }
41
42 f = fopen("/proc/self/maps", "r");
43 if (f == NULL) {
44 perror("open /proc/self/maps");
45 exit(1);
46 }
47
4d045184 48 ret = fscanf(f, "%x-%x ", &start, &end);
7fd42181 49 if (ret != 2) {
50 perror("parse maps");
51 exit(1);
52 }
53 lowest_segment = start;
54
55 // assume first entry lists program's text section.
56 // unprotect it in case we need some patching.
57 ret = mprotect((void *)start, end - start, PROT_READ|PROT_WRITE|PROT_EXEC);
58 if (ret != 0)
59 perror("warning: mprotect");
60
61 while (1) {
4d045184 62 next_line(f);
63
7fd42181 64 ret = fscanf(f, "%x-%*s %*s %*s %*s %*s %*s\n", &start);
65 if (ret <= 0)
66 break;
67
68 if (start < lowest_segment)
69 lowest_segment = start;
70 }
71
72#if 0
73 rewind(f);
74 char buff[256];
75 while (fgets(buff, sizeof(buff), f))
76 fputs(buff, stdout);
77#endif
78 fclose(f);
79
4d045184 80 // remove self from preload, further commands (from system() and such)
81 // will be handled by ginge_prep.
82 unsetenv("LD_PRELOAD");
7000b522 83 unsetenv("LD_LIBRARY_PATH");
4d045184 84
7fd42181 85 emu_init((void *)lowest_segment);
86}
87
499bf01c 88// vim:shiftwidth=2:expandtab