Index: scanelf.c =================================================================== RCS file: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v retrieving revision 1.156 diff -u -B -r1.156 scanelf.c --- scanelf.c 11 Jun 2006 00:23:11 -0000 1.156 +++ scanelf.c 25 Jul 2006 18:28:40 -0000 @@ -85,7 +85,11 @@ size_t ldcache_size = 0; unsigned long setpax = 0UL; - +/* pdhr rewrite */ +struct convert_t { + unsigned long long to, from, pflags; + int it; +} convert; /* sub-funcs for scanelf_file() */ static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) @@ -1010,6 +1015,35 @@ return (char *)" - "; } + +int rewrite_phdr(elfobj *); +int rewrite_phdr(elfobj *elf) +{ + int ret = 1; + unsigned long i; + + if (!fix_elf || !elf->phdr || !convert.it) + return ret; + +#define REWRITE_PHDR(B) \ + if (elf->elf_class == ELFCLASS ## B) { \ + Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ + Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ + for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ + if (EGET(phdr[i].p_type) != convert.from) \ + continue; \ + ESET(phdr[i].p_type, convert.to); \ + ESET(phdr[i].p_flags, convert.pflags); \ + ret = 0; \ + } \ + } + + REWRITE_PHDR(32) + REWRITE_PHDR(64) + + return ret; +} + /* scan an elf file and show all the fun stuff */ #define prints(str) write(fileno(stdout), str, strlen(str)) static int scanelf_elfobj(elfobj *elf) @@ -1073,6 +1107,9 @@ show_banner = 0; } + if (convert.it) + rewrite_phdr(elf); + /* dump all the good stuff */ for (i = 0; out_format[i]; ++i) { const char *out; @@ -1343,8 +1380,14 @@ if (i + 1 == ARRAY_SIZE(ldpaths)) return i; - if ((fp = fopen(fname, "r")) == NULL) + if ((fp = fopen(fname, "r")) == NULL) { + if (i == 0) { + ldpaths[i] = xstrdup("/lib"); + ldpaths[i++] = xstrdup("/usr/lib"); + ldpaths[i++] = xstrdup("/usr/local/lib"); + } return i; + } while ((fgets(path, __PAX_UTILS_PATH_MAX, fp)) != NULL) { if ((p = strrchr(path, '\r')) != NULL) @@ -1492,7 +1535,7 @@ } /* usage / invocation handling functions */ -#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:BhV" +#define PARSE_FLAGS "plRmyAXc:z:xetrnLibSs:k:gN:TaqvF:f:o:E:M:BhV" #define a_argument required_argument static struct option const long_opts[] = { {"path", no_argument, NULL, 'p'}, @@ -1503,6 +1546,7 @@ {"archives", no_argument, NULL, 'A'}, {"ldcache", no_argument, NULL, 'L'}, {"fix", no_argument, NULL, 'X'}, + {"convert", a_argument, NULL, 'c'}, {"setpax", a_argument, NULL, 'z'}, {"pax", no_argument, NULL, 'x'}, {"header", no_argument, NULL, 'e'}, @@ -1539,7 +1583,8 @@ "Don't scan symlinks", "Scan archives (.a files)", "Utilize ld.so.cache information (use with -r/-n)", - "Try and 'fix' bad things (use with -r/-e)", + "Try and 'fix' bad things (use with -r/-e/-c)", + "Rename a phdr. (-Xc FROM:TO:VALUE)", "Sets EI_PAX/PT_PAX_FLAGS to (use with -Xx)\n", "Print PaX markings", "Print GNU_STACK/PT_LOAD markings", @@ -1608,6 +1653,8 @@ int i; const char *from_file = NULL; + memset(&convert, 0, sizeof(convert)); + opterr = 0; while ((i=getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) { switch (i) { @@ -1656,6 +1703,17 @@ out_format = optarg; break; } + case 'c': + convert.it = 0; + if ((sscanf(optarg, "%llu %llu %llu", &convert.from, &convert.to, &convert.pflags)) == 3) + convert.it = 1; +#if 0 + if (!convert.it && *optarg == 'P') { + opt = xstrdup(optarg); + get_elfptype(); + } +#endif + break; case 'z': { unsigned long flags = (PF_NOEMUTRAMP | PF_NORANDEXEC); size_t x;