unset ld env before running command
[ginge.git] / loader / dl.c
index 154e012..6b0df2f 100644 (file)
@@ -1,4 +1,9 @@
-// vim:shiftwidth=2:expandtab
+/*
+ * GINGE - GINGE Is Not Gp2x Emulator
+ * (C) notaz, 2010-2011
+ *
+ * This work is licensed under the MAME license, see COPYING file for details.
+ */
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #define DL
 #include "override.c"
 
+static void next_line(FILE *f)
+{
+  int c;
+  do {
+    c = fgetc(f);
+  } while (c != EOF && c != '\n');
+}
+
 __attribute__((constructor))
 static void ginge_init(void)
 {
-  unsigned int lowest_segment = (unsigned int)-1;
+  void *lowest_segments[2] = { NULL, NULL };
   unsigned int start, end;
   int i, ret;
   FILE *f;
@@ -32,26 +45,29 @@ static void ginge_init(void)
     exit(1);
   }
 
-  ret = fscanf(f, "%x-%x %*s %*s %*s %*s %*s\n", &start, &end);
+  ret = fscanf(f, "%x-%x ", &start, &end);
   if (ret != 2) {
     perror("parse maps");
     exit(1);
   }
-  lowest_segment = start;
-
-  // assume first entry lists program's text section.
-  // unprotect it in case we need some patching.
-  ret = mprotect((void *)start, end - start, PROT_READ|PROT_WRITE|PROT_EXEC);
-  if (ret != 0)
-    perror("warning: mprotect");
+  lowest_segments[0] = (void *)start;
 
   while (1) {
+    next_line(f);
+
     ret = fscanf(f, "%x-%*s %*s %*s %*s %*s %*s\n", &start);
     if (ret <= 0)
       break;
 
-    if (start < lowest_segment)
-      lowest_segment = start;
+    if (lowest_segments[0] == NULL || (void *)start < lowest_segments[0])
+      lowest_segments[0] = (void *)start;
+    else if (lowest_segments[1] == NULL
+             && (char *)start - (char *)lowest_segments[0] > 0x800000)
+    {
+      // an offset is needed because ld-linux also
+      // tends to put stuff here
+      lowest_segments[1] = (void *)(start - 0x20000);
+    }
   }
 
 #if 0
@@ -62,6 +78,12 @@ static void ginge_init(void)
 #endif
   fclose(f);
 
-  emu_init((void *)lowest_segment);
+  // remove self from preload, further commands (from system() and such)
+  // will be handled by ginge_prep.
+  unsetenv("LD_PRELOAD");
+  unsetenv("LD_LIBRARY_PATH");
+
+  emu_init(lowest_segments, 1);
 }
 
+// vim:shiftwidth=2:expandtab