summaryrefslogtreecommitdiffstats
path: root/trunk/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/main.c')
-rw-r--r--trunk/src/main.c89
1 files changed, 82 insertions, 7 deletions
diff --git a/trunk/src/main.c b/trunk/src/main.c
index 8251e9e..15c1d53 100644
--- a/trunk/src/main.c
+++ b/trunk/src/main.c
@@ -59,12 +59,14 @@ const char *ld_library_path;
const char *prelink_conf = PRELINK_CONF;
const char *prelink_cache = PRELINK_CACHE;
const char *undo_output;
+int noreexecinit;
+time_t initctime;
-const char *argp_program_version = "prelink 1.0";
+const char *argp_program_version = PRELINK_PROG PKGVERSION " 1.0";
-const char *argp_program_bug_address = "<jakub@redhat.com>";
+const char *argp_program_bug_address = REPORT_BUGS_TO;
-static char argp_doc[] = "prelink -- program to relocate and prelink ELF shared libraries and programs";
+static char argp_doc[] = PRELINK_PROG " -- program to relocate and prelink ELF shared libraries and programs";
#define OPT_DYNAMIC_LINKER 0x80
#define OPT_LD_LIBRARY_PATH 0x81
@@ -79,6 +81,9 @@ static char argp_doc[] = "prelink -- program to relocate and prelink ELF shared
#define OPT_SHA 0x8a
#define OPT_COMPUTE_CHECKSUM 0x8b
#define OPT_LAYOUT_PAGE_SIZE 0x8c
+#define OPT_SYSROOT 0x8d
+#define OPT_RTLD 0x8e
+#define OPT_ALLOW_TEXTREL 0x8f
static struct argp_option options[] = {
{"all", 'a', 0, 0, "Prelink all binaries" },
@@ -96,6 +101,7 @@ static struct argp_option options[] = {
{"quick", 'q', 0, 0, "Quick scan" },
{"random", 'R', 0, 0, "Choose random base for libraries" },
{"reloc-only", 'r', "BASE_ADDRESS", 0, "Relocate library to given address, don't prelink" },
+ {"root", OPT_SYSROOT, "ROOT_PATH", 0, "Prefix all paths with ROOT_PATH" },
{"undo", 'u', 0, 0, "Undo prelink" },
{"verbose", 'v', 0, 0, "Produce verbose output" },
{"verify", 'y', 0, 0, "Verify file consistency by undoing and redoing prelink and printing original to standard output" },
@@ -114,6 +120,9 @@ static struct argp_option options[] = {
{"mmap-region-end", OPT_MMAP_REG_END, "BASE_ADDRESS", OPTION_HIDDEN, "" },
{"seed", OPT_SEED, "SEED", OPTION_HIDDEN, "" },
{"compute-checksum", OPT_COMPUTE_CHECKSUM, 0, OPTION_HIDDEN, "" },
+ {"rtld", OPT_RTLD, "RTLD", OPTION_HIDDEN, "" },
+ {"init", 'i', 0, 0, "Do not re-execute init" },
+ {"allow-textrel", OPT_ALLOW_TEXTREL, 0, 0, "Allow text relocations even on architectures where they may not work" },
{ 0 }
};
@@ -229,6 +238,17 @@ parse_opt (int key, char *arg, struct argp_state *state)
layout_page_size = strtoull (arg, &endarg, 0);
if (endarg != strchr (arg, '\0') || (layout_page_size & (layout_page_size - 1)))
error (EXIT_FAILURE, 0, "--layout-page-size option requires numberic power-of-two argument");
+ case OPT_SYSROOT:
+ sysroot = arg;
+ break;
+ case OPT_RTLD:
+ prelink_rtld = arg;
+ break;
+ case 'i':
+ noreexecinit=1;
+ break;
+ case OPT_ALLOW_TEXTREL:
+ allow_bad_textrel = 1;
break;
default:
return ARGP_ERR_UNKNOWN;
@@ -236,9 +256,26 @@ parse_opt (int key, char *arg, struct argp_state *state)
return 0;
}
+time_t get_ctime(const char *file) {
+ struct stat st;
+ if(stat(file,&st) == 0)
+ return st.st_ctime;
+ return 0;
+}
+
+void checkinit() {
+ if(initctime != get_ctime("/sbin/init")) {
+ printf("Executing /sbin/init U\n");
+ system("/sbin/init U");
+ }
+}
+
static struct argp argp = { options, parse_opt, "[FILES]", argp_doc };
-#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__)
+const char *prelink_rtld = NULL;
+
+/* Disable detection, this is not appropriate when cross prelinking. */
+#if 0 && (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__)
static void
set_default_layout_page_size (void)
{
@@ -283,9 +320,7 @@ main (int argc, char *argv[])
setlocale (LC_ALL, "");
- /* Set the default for exec_shield. */
- if (! access ("/proc/sys/kernel/exec-shield", F_OK))
- exec_shield = 1;
+ exec_shield = 2;
set_default_layout_page_size ();
@@ -295,6 +330,11 @@ main (int argc, char *argv[])
argp_parse (&argp, argc, argv, 0, &remaining, 0);
+ if(!noreexecinit) {
+ initctime = get_ctime("/sbin/init");
+ atexit(checkinit);
+ }
+
if (ld_library_path == NULL)
ld_library_path = getenv ("LD_LIBRARY_PATH");
@@ -309,6 +349,41 @@ main (int argc, char *argv[])
if ((undo || verify) && quick)
error (EXIT_FAILURE, 0, "--undo and --quick options are incompatible");
+ /* Set the default for exec_shield. */
+ if (exec_shield == 2)
+ {
+ if (sysroot == NULL && ! access ("/proc/sys/kernel/exec-shield", F_OK))
+ exec_shield = 1;
+ else
+ exec_shield = 0;
+ }
+
+#ifdef DEFAULT_SYSROOT
+ if (sysroot == NULL)
+ {
+ extern char *make_relative_prefix (const char *, const char *, const char *);
+ sysroot = make_relative_prefix (argv[0], BINDIR, DEFAULT_SYSROOT);
+ }
+#endif
+
+ if (sysroot)
+ {
+ sysroot = canonicalize_file_name (sysroot);
+ if (sysroot == NULL)
+ error (EXIT_FAILURE, 0, "Could not canonicalize --root argument");
+ asprintf ((char **) &prelink_conf, "%s%s", sysroot, prelink_conf);
+ }
+ if (prelink_rtld != NULL && prelink_rtld[0] == 0)
+ prelink_rtld = NULL;
+ else
+ if (prelink_rtld == NULL)
+ {
+ extern char *make_relative_prefix (const char *, const char *, const char *);
+ const char *path = make_relative_prefix (argv[0], BINDIR, BINDIR);
+ asprintf ((char **) &prelink_rtld, "%s/%s", path,
+ PRELINK_RTLD_PROG EXEEXT);
+ }
+
if (print_cache)
{
prelink_load_cache ();