/[gentoo-projects]/pax-utils/scanelf.c
Gentoo

Diff of /pax-utils/scanelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.229 Revision 1.233
1/* 1/*
2 * Copyright 2003-2007 Gentoo Foundation 2 * Copyright 2003-2007 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.229 2011/09/27 19:29:19 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.233 2011/10/03 16:19:18 vapier Exp $
5 * 5 *
6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
10static const char *rcsid = "$Id: scanelf.c,v 1.229 2011/09/27 19:29:19 vapier Exp $"; 10static const char rcsid[] = "$Id: scanelf.c,v 1.233 2011/10/03 16:19:18 vapier Exp $";
11const char argv0[] = "scanelf"; 11const char argv0[] = "scanelf";
12 12
13#include "paxinc.h" 13#include "paxinc.h"
14 14
15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+') 15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+')
57static char use_ldcache = 0; 57static char use_ldcache = 0;
58 58
59static char **qa_textrels = NULL; 59static char **qa_textrels = NULL;
60static char **qa_execstack = NULL; 60static char **qa_execstack = NULL;
61static char **qa_wx_load = NULL; 61static char **qa_wx_load = NULL;
62static char *root; 62static int root_fd = AT_FDCWD;
63 63
64static int match_bits = 0; 64static int match_bits = 0;
65static unsigned int match_perms = 0; 65static unsigned int match_perms = 0;
66static void *ldcache = NULL; 66static void *ldcache = NULL;
67static size_t ldcache_size = 0; 67static size_t ldcache_size = 0;
68static unsigned long setpax = 0UL; 68static unsigned long setpax = 0UL;
69 69
70static int has_objdump = 0; 70static int has_objdump = 0;
71 71
72/* find the path to a file by name */ 72/* find the path to a file by name */
73static char *which(const char *fname) 73static int bin_in_path(const char *fname)
74{ 74{
75 static char fullpath[__PAX_UTILS_PATH_MAX]; 75 char fullpath[__PAX_UTILS_PATH_MAX];
76 char *path, *p; 76 char *path, *p;
77 77
78 path = getenv("PATH"); 78 path = getenv("PATH");
79 if (!path) 79 if (!path)
80 return NULL; 80 return 0;
81 81
82 path = xstrdup(path);
83 while ((p = strrchr(path, ':')) != NULL) { 82 while ((p = strrchr(path, ':')) != NULL) {
84 snprintf(fullpath, sizeof(fullpath), "%s/%s", p + 1, fname); 83 snprintf(fullpath, sizeof(fullpath), "%s/%s", p + 1, fname);
85 *p = 0; 84 *p = 0;
86 if (access(fullpath, R_OK) != -1) { 85 if (access(fullpath, R_OK) != -1)
87 free(path); 86 return 1;
88 return fullpath;
89 } 87 }
90 } 88
91 free(path); 89 return 0;
90}
91
92static FILE *fopenat_r(int dir_fd, const char *path)
93{
94 int fd = openat(dir_fd, path, O_RDONLY|O_CLOEXEC);
95 if (fd == -1)
92 return NULL; 96 return NULL;
97 return fdopen(fd, "re");
98}
99
100static const char *root_rel_path(const char *path)
101{
102 /*
103 * openat() will ignore the dirfd if path starts with
104 * a /, so consume all of that noise
105 *
106 * XXX: we don't handle relative paths like ../ that
107 * break out of the --root option, but for now, just
108 * don't do that :P.
109 */
110 if (root_fd != AT_FDCWD) {
111 while (*path == '/')
112 ++path;
113 if (*path == '\0')
114 path = ".";
115 }
116
117 return path;
93} 118}
94 119
95/* 1 on failure. 0 otherwise */ 120/* 1 on failure. 0 otherwise */
96static int rematch(const char *regex, const char *match, int cflags) 121static int rematch(const char *regex, const char *match, int cflags)
97{ 122{
115 regfree(&preg); 140 regfree(&preg);
116 141
117 return ret; 142 return ret;
118} 143}
119 144
120/* sub-funcs for scanelf_file() */ 145/* sub-funcs for scanelf_fileat() */
121static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) 146static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
122{ 147{
123 /* find the best SHT_DYNSYM and SHT_STRTAB sections */ 148 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
124 149
125 /* debug sections */ 150 /* debug sections */
467 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \ 492 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
468 if (be_verbose && has_objdump) { \ 493 if (be_verbose && has_objdump) { \
469 Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \ 494 Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \
470 char *sysbuf; \ 495 char *sysbuf; \
471 size_t syslen; \ 496 size_t syslen; \
472 int sysret; \
473 const char sysfmt[] = "objdump -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \ 497 const char sysfmt[] = "objdump -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \
474 syslen = sizeof(sysfmt) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \ 498 syslen = sizeof(sysfmt) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \
475 sysbuf = xmalloc(syslen); \ 499 sysbuf = xmalloc(syslen); \
476 if (end_addr < r_offset) \ 500 if (end_addr < r_offset) \
477 /* not uncommon when things are optimized out */ \ 501 /* not uncommon when things are optimized out */ \
480 (unsigned long)offset_tmp, \ 504 (unsigned long)offset_tmp, \
481 (unsigned long)end_addr, \ 505 (unsigned long)end_addr, \
482 elf->filename, \ 506 elf->filename, \
483 (unsigned long)r_offset); \ 507 (unsigned long)r_offset); \
484 fflush(stdout); \ 508 fflush(stdout); \
485 sysret = system(sysbuf); \ 509 if (system(sysbuf)) /* don't care */; \
486 fflush(stdout); \ 510 fflush(stdout); \
487 free(sysbuf); \ 511 free(sysbuf); \
488 } \ 512 } \
489 } \ 513 } \
490 } } 514 } }
689static char *lookup_cache_lib(elfobj *elf, char *fname) 713static char *lookup_cache_lib(elfobj *elf, char *fname)
690{ 714{
691 int fd; 715 int fd;
692 char *strs; 716 char *strs;
693 static char buf[__PAX_UTILS_PATH_MAX] = ""; 717 static char buf[__PAX_UTILS_PATH_MAX] = "";
694 const char cachefile[] = "/etc/ld.so.cache"; 718 const char *cachefile = root_rel_path("/etc/ld.so.cache");
695 struct stat st; 719 struct stat st;
696 720
697 typedef struct { 721 typedef struct {
698 char magic[LDSO_CACHE_MAGIC_LEN]; 722 char magic[LDSO_CACHE_MAGIC_LEN];
699 char version[LDSO_CACHE_VER_LEN]; 723 char version[LDSO_CACHE_VER_LEN];
710 734
711 if (fname == NULL) 735 if (fname == NULL)
712 return NULL; 736 return NULL;
713 737
714 if (ldcache == NULL) { 738 if (ldcache == NULL) {
715 if (stat(cachefile, &st)) 739 if (fstatat(root_fd, cachefile, &st, 0))
716 return NULL; 740 return NULL;
717 741
718 fd = open(cachefile, O_RDONLY); 742 fd = openat(root_fd, cachefile, O_RDONLY);
719 if (fd == -1) 743 if (fd == -1)
720 return NULL; 744 return NULL;
721 745
722 /* cache these values so we only map/unmap the cache file once */ 746 /* cache these values so we only map/unmap the cache file once */
723 ldcache_size = st.st_size; 747 ldcache_size = st.st_size;
1483 munmap(ar_buffer, len); 1507 munmap(ar_buffer, len);
1484 1508
1485 return 0; 1509 return 0;
1486} 1510}
1487/* scan a file which may be an elf or an archive or some other magical beast */ 1511/* scan a file which may be an elf or an archive or some other magical beast */
1488static int scanelf_file(const char *filename, const struct stat *st_cache) 1512static int scanelf_fileat(int dir_fd, const char *filename, const struct stat *st_cache)
1489{ 1513{
1490 const struct stat *st = st_cache; 1514 const struct stat *st = st_cache;
1491 struct stat symlink_st; 1515 struct stat symlink_st;
1492 int fd; 1516 int fd;
1493 1517
1494 /* always handle regular files and handle symlinked files if no -y */ 1518 /* always handle regular files and handle symlinked files if no -y */
1495 if (S_ISLNK(st->st_mode)) { 1519 if (S_ISLNK(st->st_mode)) {
1496 if (!scan_symlink) return 1; 1520 if (!scan_symlink)
1521 return 1;
1497 stat(filename, &symlink_st); 1522 fstatat(dir_fd, filename, &symlink_st, 0);
1498 st = &symlink_st; 1523 st = &symlink_st;
1499 } 1524 }
1500 1525
1501 if (!S_ISREG(st->st_mode)) { 1526 if (!S_ISREG(st->st_mode)) {
1502 if (be_verbose > 2) printf("%s: skipping non-file\n", filename); 1527 if (be_verbose > 2) printf("%s: skipping non-file\n", filename);
1505 1530
1506 if (match_perms) { 1531 if (match_perms) {
1507 if ((st->st_mode | match_perms) != st->st_mode) 1532 if ((st->st_mode | match_perms) != st->st_mode)
1508 return 1; 1533 return 1;
1509 } 1534 }
1510 if ((fd=open(filename, (fix_elf ? O_RDWR : O_RDONLY))) == -1) 1535 fd = openat(dir_fd, filename, (fix_elf ? O_RDWR : O_RDONLY) | O_CLOEXEC);
1536 if (fd == -1)
1511 return 1; 1537 return 1;
1512 1538
1513 if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives) 1539 if (scanelf_elf(filename, fd, st->st_size) == 1 && scan_archives)
1514 /* if it isn't an ELF, maybe it's an .a archive */ 1540 /* if it isn't an ELF, maybe it's an .a archive */
1515 scanelf_archive(filename, fd, st->st_size); 1541 scanelf_archive(filename, fd, st->st_size);
1516 1542
1543 /* XXX: unreadelf() implicitly closes its fd */
1517 close(fd); 1544 close(fd);
1518 return 0; 1545 return 0;
1519} 1546}
1520 1547
1521static const char *maybe_add_root(const char *fname, char *buf)
1522{
1523 if (root && strncmp(fname, root, strlen(root))) {
1524 strcpy(buf, root);
1525 strncat(buf, fname, __PAX_UTILS_PATH_MAX - strlen(root) - 1);
1526 fname = buf;
1527 }
1528 return fname;
1529}
1530
1531/* scan a directory for ET_EXEC files and print when we find one */ 1548/* scan a directory for ET_EXEC files and print when we find one */
1532static int scanelf_dir(const char *path) 1549static int scanelf_dirat(int dir_fd, const char *path)
1533{ 1550{
1534 register DIR *dir; 1551 register DIR *dir;
1535 register struct dirent *dentry; 1552 register struct dirent *dentry;
1536 struct stat st_top, st; 1553 struct stat st_top, st;
1537 char buf[__PAX_UTILS_PATH_MAX]; 1554 char buf[__PAX_UTILS_PATH_MAX], *subpath;
1538 char _path[__PAX_UTILS_PATH_MAX];
1539 size_t pathlen = 0, len = 0; 1555 size_t pathlen = 0, len = 0;
1540 int ret = 0; 1556 int ret = 0;
1541 1557 int subdir_fd;
1542 path = maybe_add_root(path, _path);
1543 1558
1544 /* make sure path exists */ 1559 /* make sure path exists */
1545 if (lstat(path, &st_top) == -1) { 1560 if (fstatat(dir_fd, path, &st_top, AT_SYMLINK_NOFOLLOW) == -1) {
1546 if (be_verbose > 2) printf("%s: does not exist\n", path); 1561 if (be_verbose > 2) printf("%s: does not exist\n", path);
1547 return 1; 1562 return 1;
1548 } 1563 }
1549 1564
1550 /* ok, if it isn't a directory, assume we can open it */ 1565 /* ok, if it isn't a directory, assume we can open it */
1551 if (!S_ISDIR(st_top.st_mode)) { 1566 if (!S_ISDIR(st_top.st_mode))
1552 return scanelf_file(path, &st_top); 1567 return scanelf_fileat(dir_fd, path, &st_top);
1553 }
1554 1568
1555 /* now scan the dir looking for fun stuff */ 1569 /* now scan the dir looking for fun stuff */
1556 if ((dir = opendir(path)) == NULL) { 1570 subdir_fd = openat(dir_fd, path, O_RDONLY|O_CLOEXEC);
1571 if (subdir_fd == -1)
1572 dir = NULL;
1573 else
1574 dir = fdopendir(subdir_fd);
1575 if (dir == NULL) {
1576 if (subdir_fd != -1)
1577 close(subdir_fd);
1557 warnf("could not opendir %s: %s", path, strerror(errno)); 1578 warnf("could not opendir %s: %s", path, strerror(errno));
1558 return 1; 1579 return 1;
1559 } 1580 }
1560 if (be_verbose > 1) printf("%s: scanning dir\n", path); 1581 if (be_verbose > 1) printf("%s: scanning dir\n", path);
1561 1582
1562 pathlen = strlen(path); 1583 subpath = stpcpy(buf, path);
1584 *subpath++ = '/';
1585 pathlen = subpath - buf;
1563 while ((dentry = readdir(dir))) { 1586 while ((dentry = readdir(dir))) {
1564 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) 1587 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
1565 continue; 1588 continue;
1566 len = (pathlen + 1 + strlen(dentry->d_name) + 1); 1589
1567 if (len >= sizeof(buf)) { 1590 if (fstatat(subdir_fd, dentry->d_name, &st, AT_SYMLINK_NOFOLLOW) == -1)
1568 warnf("Skipping '%s': len > sizeof(buf); %lu > %lu\n", path,
1569 (unsigned long)len, (unsigned long)sizeof(buf));
1570 continue; 1591 continue;
1592
1593 len = strlen(dentry->d_name);
1594 if (len + pathlen + 1 >= sizeof(buf)) {
1595 warnf("Skipping '%s%s': len > sizeof(buf); %zu > %zu\n",
1596 path, dentry->d_name, len + pathlen + 1, sizeof(buf));
1597 continue;
1571 } 1598 }
1572 snprintf(buf, sizeof(buf), "%s%s%s", path, (path[pathlen-1] == '/') ? "" : "/", dentry->d_name); 1599 memcpy(subpath, dentry->d_name, len);
1573 if (lstat(buf, &st) != -1) { 1600 subpath[len] = '\0';
1601
1574 if (S_ISREG(st.st_mode)) 1602 if (S_ISREG(st.st_mode))
1575 ret = scanelf_file(buf, &st); 1603 ret = scanelf_fileat(dir_fd, buf, &st);
1576 else if (dir_recurse && S_ISDIR(st.st_mode)) { 1604 else if (dir_recurse && S_ISDIR(st.st_mode)) {
1577 if (dir_crossmount || (st_top.st_dev == st.st_dev)) 1605 if (dir_crossmount || (st_top.st_dev == st.st_dev))
1578 ret = scanelf_dir(buf); 1606 ret = scanelf_dirat(dir_fd, buf);
1579 }
1580 } 1607 }
1581 } 1608 }
1582 closedir(dir); 1609 closedir(dir);
1610
1583 return ret; 1611 return ret;
1584} 1612}
1613static int scanelf_dir(const char *path)
1614{
1615 return scanelf_dirat(root_fd, root_rel_path(path));
1616}
1585 1617
1586static int scanelf_from_file(const char *filename) 1618static int scanelf_from_file(const char *filename)
1587{ 1619{
1588 FILE *fp = NULL; 1620 FILE *fp;
1589 char *p; 1621 char *p, *path;
1590 char path[__PAX_UTILS_PATH_MAX]; 1622 size_t len;
1591 int ret = 0; 1623 int ret;
1592 1624
1593 if (strcmp(filename, "-") == 0) 1625 if (strcmp(filename, "-") == 0)
1594 fp = stdin; 1626 fp = stdin;
1595 else if ((fp = fopen(filename, "r")) == NULL) 1627 else if ((fp = fopen(filename, "r")) == NULL)
1596 return 1; 1628 return 1;
1597 1629
1598 while ((fgets(path, __PAX_UTILS_PATH_MAX, fp)) != NULL) { 1630 path = NULL;
1631 len = 0;
1632 ret = 0;
1633 while (getline(&path, &len, fp) != -1) {
1599 if ((p = strchr(path, '\n')) != NULL) 1634 if ((p = strchr(path, '\n')) != NULL)
1600 *p = 0; 1635 *p = 0;
1601 search_path = path; 1636 search_path = path;
1602 ret = scanelf_dir(path); 1637 ret = scanelf_dir(path);
1603 } 1638 }
1639 free(path);
1640
1604 if (fp != stdin) 1641 if (fp != stdin)
1605 fclose(fp); 1642 fclose(fp);
1643
1606 return ret; 1644 return ret;
1607} 1645}
1608 1646
1609#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__NetBSD__) 1647#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__NetBSD__)
1610 1648
1611static int load_ld_cache_config(int i, const char *fname) 1649static int load_ld_cache_config(int i, const char *fname)
1612{ 1650{
1613 FILE *fp = NULL; 1651 FILE *fp = NULL;
1614 char *p; 1652 char *p, *path;
1615 char path[__PAX_UTILS_PATH_MAX]; 1653 size_t len;
1616 char _fname[__PAX_UTILS_PATH_MAX]; 1654 int curr_fd = -1;
1617 1655
1618 fname = maybe_add_root(fname, _fname); 1656 fp = fopenat_r(root_fd, root_rel_path(fname));
1619 1657 if (fp == NULL)
1620 if ((fp = fopen(fname, "r")) == NULL)
1621 return i; 1658 return i;
1622 1659
1623 while ((fgets(path, __PAX_UTILS_PATH_MAX, fp)) != NULL) { 1660 path = NULL;
1661 len = 0;
1662 while (getline(&path, &len, fp) != -1) {
1624 if ((p = strrchr(path, '\r')) != NULL) 1663 if ((p = strrchr(path, '\r')) != NULL)
1625 *p = 0; 1664 *p = 0;
1626 if ((p = strchr(path, '\n')) != NULL) 1665 if ((p = strchr(path, '\n')) != NULL)
1627 *p = 0; 1666 *p = 0;
1628 1667
1629 /* recursive includes of the same file will make this segfault. */ 1668 /* recursive includes of the same file will make this segfault. */
1630 if ((memcmp(path, "include", 7) == 0) && isblank(path[7])) { 1669 if ((memcmp(path, "include", 7) == 0) && isblank(path[7])) {
1631 glob_t gl; 1670 glob_t gl;
1632 size_t x; 1671 size_t x;
1633 char gpath[__PAX_UTILS_PATH_MAX]; 1672 const char *gpath;
1634 1673
1635 memset(gpath, 0, sizeof(gpath)); 1674 /* re-use existing path buffer ... need to be creative */
1636 if (root)
1637 strcpy(gpath, root);
1638
1639 if (path[8] != '/') 1675 if (path[8] != '/')
1640 snprintf(gpath+strlen(gpath), sizeof(gpath)-strlen(gpath), "/etc/%s", &path[8]); 1676 gpath = memcpy(path + 3, "/etc/", 5);
1641 else 1677 else
1642 strncpy(gpath+strlen(gpath), &path[8], sizeof(gpath)-strlen(gpath)); 1678 gpath = path + 8;
1679 if (root_fd != AT_FDCWD) {
1680 if (curr_fd == -1) {
1681 curr_fd = open(".", O_RDONLY|O_CLOEXEC);
1682 if (fchdir(root_fd))
1683 errp("unable to change to root dir");
1684 }
1685 gpath = root_rel_path(gpath);
1686 }
1643 1687
1644 if (glob(gpath, 0, NULL, &gl) == 0) { 1688 if (glob(gpath, 0, NULL, &gl) == 0) {
1645 for (x = 0; x < gl.gl_pathc; ++x) { 1689 for (x = 0; x < gl.gl_pathc; ++x) {
1646 /* try to avoid direct loops */ 1690 /* try to avoid direct loops */
1647 if (strcmp(gl.gl_pathv[x], fname) == 0) 1691 if (strcmp(gl.gl_pathv[x], fname) == 0)
1648 continue; 1692 continue;
1649 i = load_ld_cache_config(i, gl.gl_pathv[x]); 1693 i = load_ld_cache_config(i, gl.gl_pathv[x]);
1650 } 1694 }
1651 globfree(&gl); 1695 globfree(&gl);
1652 continue;
1653 } 1696 }
1697
1698 /* failed globs are ignored by glibc */
1699 continue;
1654 } 1700 }
1655 1701
1656 if (*path != '/') 1702 if (*path != '/')
1657 continue; 1703 continue;
1658 1704
1659 xarraypush(ldpaths, path, strlen(path)); 1705 xarraypush_str(ldpaths, path);
1660 } 1706 }
1707 free(path);
1661 1708
1662 fclose(fp); 1709 fclose(fp);
1710
1711 if (curr_fd != -1) {
1712 if (fchdir(curr_fd))
1713 /* don't care */;
1714 close(curr_fd);
1715 }
1716
1663 return i; 1717 return i;
1664} 1718}
1665 1719
1666#elif defined(__FreeBSD__) || defined(__DragonFly__) 1720#elif defined(__FreeBSD__) || defined(__DragonFly__)
1667 1721
1668static int load_ld_cache_config(int i, const char *fname) 1722static int load_ld_cache_config(int i, const char *fname)
1669{ 1723{
1670 FILE *fp = NULL; 1724 FILE *fp = NULL;
1671 char *b = NULL, *p; 1725 char *b = NULL, *p;
1672 struct elfhints_hdr hdr; 1726 struct elfhints_hdr hdr;
1673 char _fname[__PAX_UTILS_PATH_MAX];
1674 1727
1675 fname = maybe_add_root(fname, _fname); 1728 fp = fopenat_r(root_fd, root_rel_path(fname));
1676 1729 if (fp == NULL)
1677 if ((fp = fopen(fname, "r")) == NULL)
1678 return i; 1730 return i;
1679 1731
1680 if (fread(&hdr, 1, sizeof(hdr), fp) != sizeof(hdr) || 1732 if (fread(&hdr, 1, sizeof(hdr), fp) != sizeof(hdr) ||
1681 hdr.magic != ELFHINTS_MAGIC || hdr.version != 1 || 1733 hdr.magic != ELFHINTS_MAGIC || hdr.version != 1 ||
1682 fseek(fp, hdr.strtab + hdr.dirlist, SEEK_SET) == -1) 1734 fseek(fp, hdr.strtab + hdr.dirlist, SEEK_SET) == -1)
1693 } 1745 }
1694 1746
1695 while ((p = strsep(&b, ":"))) { 1747 while ((p = strsep(&b, ":"))) {
1696 if (*p == '\0') 1748 if (*p == '\0')
1697 continue; 1749 continue;
1698 xarraypush(ldpaths, p, strlen(p)); 1750 xarraypush_str(ldpaths, p);
1699 } 1751 }
1700 1752
1701 free(b); 1753 free(b);
1702 fclose(fp); 1754 fclose(fp);
1703 return i; 1755 return i;
1920 if (freopen(optarg, "w", stdout) == NULL) 1972 if (freopen(optarg, "w", stdout) == NULL)
1921 err("Could not open output stream '%s': %s", optarg, strerror(errno)); 1973 err("Could not open output stream '%s': %s", optarg, strerror(errno));
1922 break; 1974 break;
1923 } 1975 }
1924 case 'k': 1976 case 'k':
1925 xarraypush(find_section_arr, optarg, strlen(optarg)); 1977 xarraypush_str(find_section_arr, optarg);
1926 break; 1978 break;
1927 case 's': { 1979 case 's': {
1928 if (find_sym) warn("You prob don't want to specify -s twice"); 1980 if (find_sym) warn("You prob don't want to specify -s twice");
1929 find_sym = optarg; 1981 find_sym = optarg;
1930 break; 1982 break;
1931 } 1983 }
1932 case 'N': 1984 case 'N':
1933 xarraypush(find_lib_arr, optarg, strlen(optarg)); 1985 xarraypush_str(find_lib_arr, optarg);
1934 break; 1986 break;
1935 case 'F': { 1987 case 'F': {
1936 if (out_format) warn("You prob don't want to specify -F twice"); 1988 if (out_format) warn("You prob don't want to specify -F twice");
1937 out_format = optarg; 1989 out_format = optarg;
1938 break; 1990 break;
2006 case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = show_endian = 1; break; 2058 case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = show_endian = 1; break;
2007 case 'D': show_endian = 1; break; 2059 case 'D': show_endian = 1; break;
2008 case 'I': show_osabi = 1; break; 2060 case 'I': show_osabi = 1; break;
2009 case 'Y': show_eabi = 1; break; 2061 case 'Y': show_eabi = 1; break;
2010 case 128: 2062 case 128:
2011 root = optarg; 2063 root_fd = open(optarg, O_RDONLY|O_CLOEXEC);
2064 if (root_fd == -1)
2065 err("Could not open root: %s", optarg);
2012 break; 2066 break;
2013 case ':': 2067 case ':':
2014 err("Option '%c' is missing parameter", optopt); 2068 err("Option '%c' is missing parameter", optopt);
2015 case '?': 2069 case '?':
2016 err("Unknown option '%c' or argument missing", optopt); 2070 err("Unknown option '%c' or argument missing", optopt);
2017 default: 2071 default:
2018 err("Unhandled option '%c'; please report this", i); 2072 err("Unhandled option '%c'; please report this", i);
2019 } 2073 }
2020 } 2074 }
2021 if (show_textrels && be_verbose) { 2075 if (show_textrels && be_verbose)
2022 if (which("objdump") != NULL) 2076 has_objdump = bin_in_path("objdump");
2023 has_objdump = 1;
2024 }
2025 /* flatten arrays for display */ 2077 /* flatten arrays for display */
2026 if (array_cnt(find_lib_arr)) 2078 if (array_cnt(find_lib_arr))
2027 find_lib = array_flatten_str(find_lib_arr); 2079 find_lib = array_flatten_str(find_lib_arr);
2028 if (array_cnt(find_section_arr)) 2080 if (array_cnt(find_section_arr))
2029 find_section = array_flatten_str(find_section_arr); 2081 find_section = array_flatten_str(find_section_arr);
2187 ret = parseargs(argc, argv); 2239 ret = parseargs(argc, argv);
2188 fclose(stdout); 2240 fclose(stdout);
2189#ifdef __PAX_UTILS_CLEANUP 2241#ifdef __PAX_UTILS_CLEANUP
2190 cleanup(); 2242 cleanup();
2191 warn("The calls to add/delete heap should be off:\n" 2243 warn("The calls to add/delete heap should be off:\n"
2192 "\t- 1 due to the out_buffer not being freed in scanelf_file()\n" 2244 "\t- 1 due to the out_buffer not being freed in scanelf_fileat()\n"
2193 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD"); 2245 "\t- 1 per QA_TEXTRELS/QA_EXECSTACK/QA_WX_LOAD");
2194#endif 2246#endif
2195 return ret; 2247 return ret;
2196} 2248}
2197 2249

Legend:
Removed from v.1.229  
changed lines
  Added in v.1.233

  ViewVC Help
Powered by ViewVC 1.1.20