| 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/scanelf.c,v 1.190 2008/04/19 22:31:49 solar Exp $ |
4 | * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.191 2008/06/17 17:07:57 solar 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 | |
| 10 | static const char *rcsid = "$Id: scanelf.c,v 1.190 2008/04/19 22:31:49 solar Exp $"; |
10 | static const char *rcsid = "$Id: scanelf.c,v 1.191 2008/06/17 17:07:57 solar Exp $"; |
| 11 | const char * const argv0 = "scanelf"; |
11 | const char * const 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 == '+') |
| … | |
… | |
| 49 | static char show_bind = 0; |
49 | static char show_bind = 0; |
| 50 | static char show_soname = 0; |
50 | static char show_soname = 0; |
| 51 | static char show_textrels = 0; |
51 | static char show_textrels = 0; |
| 52 | static char show_banner = 1; |
52 | static char show_banner = 1; |
| 53 | static char show_endian = 0; |
53 | static char show_endian = 0; |
|
|
54 | static char show_osabi = 0; |
|
|
55 | static char show_eabi = 0; |
| 54 | static char be_quiet = 0; |
56 | static char be_quiet = 0; |
| 55 | static char be_verbose = 0; |
57 | static char be_verbose = 0; |
| 56 | static char be_wewy_wewy_quiet = 0; |
58 | static char be_wewy_wewy_quiet = 0; |
| 57 | static char be_semi_verbose = 0; |
59 | static char be_semi_verbose = 0; |
| 58 | static char *find_sym = NULL, *versioned_symname = NULL; |
60 | static char *find_sym = NULL, *versioned_symname = NULL; |
| … | |
… | |
| 1152 | case 's': prints("SYM "); break; |
1154 | case 's': prints("SYM "); break; |
| 1153 | case 'N': prints("LIB "); break; |
1155 | case 'N': prints("LIB "); break; |
| 1154 | case 'T': prints("TEXTRELS "); break; |
1156 | case 'T': prints("TEXTRELS "); break; |
| 1155 | case 'k': prints("SECTION "); break; |
1157 | case 'k': prints("SECTION "); break; |
| 1156 | case 'a': prints("ARCH "); break; |
1158 | case 'a': prints("ARCH "); break; |
|
|
1159 | case 'I': prints("OSABI "); break; |
|
|
1160 | case 'Y': prints("EABI "); break; |
| 1157 | case 'O': prints("PERM "); break; |
1161 | case 'O': prints("PERM "); break; |
| 1158 | case 'D': prints("ENDIAN "); break; |
1162 | case 'D': prints("ENDIAN "); break; |
| 1159 | default: warnf("'%c' has no title ?", out_format[i]); |
1163 | default: warnf("'%c' has no title ?", out_format[i]); |
| 1160 | } |
1164 | } |
| 1161 | } |
1165 | } |
| … | |
… | |
| 1224 | case 'b': out = scanelf_file_bind(elf, &found_bind); break; |
1228 | case 'b': out = scanelf_file_bind(elf, &found_bind); break; |
| 1225 | case 'S': out = scanelf_file_soname(elf, &found_soname); break; |
1229 | case 'S': out = scanelf_file_soname(elf, &found_soname); break; |
| 1226 | case 's': out = scanelf_file_sym(elf, &found_sym); break; |
1230 | case 's': out = scanelf_file_sym(elf, &found_sym); break; |
| 1227 | case 'k': out = scanelf_file_sections(elf, &found_section); break; |
1231 | case 'k': out = scanelf_file_sections(elf, &found_section); break; |
| 1228 | case 'a': out = get_elfemtype(elf); break; |
1232 | case 'a': out = get_elfemtype(elf); break; |
|
|
1233 | case 'I': out = get_elfosabi(elf); break; |
|
|
1234 | case 'Y': out = get_elf_eabi(elf); break; |
| 1229 | case 'Z': snprintf(ubuf, sizeof(ubuf), "%lu", elf->len); out = ubuf; break;; |
1235 | case 'Z': snprintf(ubuf, sizeof(ubuf), "%lu", elf->len); out = ubuf; break;; |
| 1230 | default: warnf("'%c' has no scan code?", out_format[i]); |
1236 | default: warnf("'%c' has no scan code?", out_format[i]); |
| 1231 | } |
1237 | } |
| 1232 | if (out) { |
1238 | if (out) { |
| 1233 | /* hack for comma delimited output like `scanelf -s sym1,sym2,sym3` */ |
1239 | /* hack for comma delimited output like `scanelf -s sym1,sym2,sym3` */ |
| … | |
… | |
| 1589 | } |
1595 | } |
| 1590 | |
1596 | |
| 1591 | free(path); |
1597 | free(path); |
| 1592 | } |
1598 | } |
| 1593 | |
1599 | |
| 1594 | /* usage / invocation handling functions */ /* Free Flags: c d j u w C G H I J K P Q U W Y */ |
1600 | /* usage / invocation handling functions */ /* Free Flags: c d j u w C G H J K P Q U W */ |
| 1595 | #define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DO:ZBhV" |
1601 | #define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DIYO:ZBhV" |
| 1596 | #define a_argument required_argument |
1602 | #define a_argument required_argument |
| 1597 | static struct option const long_opts[] = { |
1603 | static struct option const long_opts[] = { |
| 1598 | {"path", no_argument, NULL, 'p'}, |
1604 | {"path", no_argument, NULL, 'p'}, |
| 1599 | {"ldpath", no_argument, NULL, 'l'}, |
1605 | {"ldpath", no_argument, NULL, 'l'}, |
| 1600 | {"recursive", no_argument, NULL, 'R'}, |
1606 | {"recursive", no_argument, NULL, 'R'}, |
| … | |
… | |
| 1618 | {"gmatch", no_argument, NULL, 'g'}, |
1624 | {"gmatch", no_argument, NULL, 'g'}, |
| 1619 | {"textrels", no_argument, NULL, 'T'}, |
1625 | {"textrels", no_argument, NULL, 'T'}, |
| 1620 | {"etype", a_argument, NULL, 'E'}, |
1626 | {"etype", a_argument, NULL, 'E'}, |
| 1621 | {"bits", a_argument, NULL, 'M'}, |
1627 | {"bits", a_argument, NULL, 'M'}, |
| 1622 | {"endian", no_argument, NULL, 'D'}, |
1628 | {"endian", no_argument, NULL, 'D'}, |
|
|
1629 | {"osabi", no_argument, NULL, 'I'}, |
|
|
1630 | {"eabi", no_argument, NULL, 'Y'}, |
| 1623 | {"perms", a_argument, NULL, 'O'}, |
1631 | {"perms", a_argument, NULL, 'O'}, |
| 1624 | {"size", no_argument, NULL, 'Z'}, |
1632 | {"size", no_argument, NULL, 'Z'}, |
| 1625 | {"all", no_argument, NULL, 'a'}, |
1633 | {"all", no_argument, NULL, 'a'}, |
| 1626 | {"quiet", no_argument, NULL, 'q'}, |
1634 | {"quiet", no_argument, NULL, 'q'}, |
| 1627 | {"verbose", no_argument, NULL, 'v'}, |
1635 | {"verbose", no_argument, NULL, 'v'}, |
| … | |
… | |
| 1658 | "Use strncmp to match libraries. (use with -N)", |
1666 | "Use strncmp to match libraries. (use with -N)", |
| 1659 | "Locate cause of TEXTREL", |
1667 | "Locate cause of TEXTREL", |
| 1660 | "Print only ELF files matching etype ET_DYN,ET_EXEC ...", |
1668 | "Print only ELF files matching etype ET_DYN,ET_EXEC ...", |
| 1661 | "Print only ELF files matching numeric bits", |
1669 | "Print only ELF files matching numeric bits", |
| 1662 | "Print Endianness", |
1670 | "Print Endianness", |
|
|
1671 | "Print OSABI", |
|
|
1672 | "Print EABI (EM_ARM Only)", |
| 1663 | "Print only ELF files matching octal permissions", |
1673 | "Print only ELF files matching octal permissions", |
| 1664 | "Print ELF file size", |
1674 | "Print ELF file size", |
| 1665 | "Print all scanned info (-x -e -t -r -b)\n", |
1675 | "Print all scanned info (-x -e -t -r -b)\n", |
| 1666 | "Only output 'bad' things", |
1676 | "Only output 'bad' things", |
| 1667 | "Be verbose (can be specified more than once)", |
1677 | "Be verbose (can be specified more than once)", |
| … | |
… | |
| 1831 | case 'T': show_textrels = 1; break; |
1841 | case 'T': show_textrels = 1; break; |
| 1832 | case 'q': be_quiet = 1; break; |
1842 | case 'q': be_quiet = 1; break; |
| 1833 | case 'v': be_verbose = (be_verbose % 20) + 1; break; |
1843 | case 'v': be_verbose = (be_verbose % 20) + 1; break; |
| 1834 | case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = show_endian = 1; break; |
1844 | case 'a': show_perms = show_pax = show_phdr = show_textrel = show_rpath = show_bind = show_endian = 1; break; |
| 1835 | case 'D': show_endian = 1; break; |
1845 | case 'D': show_endian = 1; break; |
|
|
1846 | case 'I': show_osabi = 1; break; |
|
|
1847 | case 'Y': show_eabi = 1; break; |
| 1836 | case ':': |
1848 | case ':': |
| 1837 | err("Option '%c' is missing parameter", optopt); |
1849 | err("Option '%c' is missing parameter", optopt); |
| 1838 | case '?': |
1850 | case '?': |
| 1839 | err("Unknown option '%c' or argument missing", optopt); |
1851 | err("Unknown option '%c' or argument missing", optopt); |
| 1840 | default: |
1852 | default: |
| … | |
… | |
| 1847 | } |
1859 | } |
| 1848 | /* let the format option override all other options */ |
1860 | /* let the format option override all other options */ |
| 1849 | if (out_format) { |
1861 | if (out_format) { |
| 1850 | show_pax = show_phdr = show_textrel = show_rpath = \ |
1862 | show_pax = show_phdr = show_textrel = show_rpath = \ |
| 1851 | show_needed = show_interp = show_bind = show_soname = \ |
1863 | show_needed = show_interp = show_bind = show_soname = \ |
| 1852 | show_textrels = show_perms = show_endian = show_size = 0; |
1864 | show_textrels = show_perms = show_endian = show_size = \ |
|
|
1865 | show_osabi = show_eabi = 0; |
| 1853 | for (i = 0; out_format[i]; ++i) { |
1866 | for (i = 0; out_format[i]; ++i) { |
| 1854 | if (!IS_MODIFIER(out_format[i])) continue; |
1867 | if (!IS_MODIFIER(out_format[i])) continue; |
| 1855 | |
1868 | |
| 1856 | switch (out_format[++i]) { |
1869 | switch (out_format[++i]) { |
| 1857 | case '+': break; |
1870 | case '+': break; |
| … | |
… | |
| 1866 | case 'o': break; |
1879 | case 'o': break; |
| 1867 | case 'a': break; |
1880 | case 'a': break; |
| 1868 | case 'M': break; |
1881 | case 'M': break; |
| 1869 | case 'Z': show_size = 1; break; |
1882 | case 'Z': show_size = 1; break; |
| 1870 | case 'D': show_endian = 1; break; |
1883 | case 'D': show_endian = 1; break; |
|
|
1884 | case 'I': show_osabi = 1; break; |
|
|
1885 | case 'Y': show_eabi = 1; break; |
| 1871 | case 'O': show_perms = 1; break; |
1886 | case 'O': show_perms = 1; break; |
| 1872 | case 'x': show_pax = 1; break; |
1887 | case 'x': show_pax = 1; break; |
| 1873 | case 'e': show_phdr = 1; break; |
1888 | case 'e': show_phdr = 1; break; |
| 1874 | case 't': show_textrel = 1; break; |
1889 | case 't': show_textrel = 1; break; |
| 1875 | case 'r': show_rpath = 1; break; |
1890 | case 'r': show_rpath = 1; break; |
| … | |
… | |
| 1891 | if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); |
1906 | if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); |
| 1892 | if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); |
1907 | if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); |
| 1893 | if (show_perms) xstrcat(&out_format, "%O ", &fmt_len); |
1908 | if (show_perms) xstrcat(&out_format, "%O ", &fmt_len); |
| 1894 | if (show_size) xstrcat(&out_format, "%Z ", &fmt_len); |
1909 | if (show_size) xstrcat(&out_format, "%Z ", &fmt_len); |
| 1895 | if (show_endian) xstrcat(&out_format, "%D ", &fmt_len); |
1910 | if (show_endian) xstrcat(&out_format, "%D ", &fmt_len); |
|
|
1911 | if (show_osabi) xstrcat(&out_format, "%I ", &fmt_len); |
|
|
1912 | if (show_eabi) xstrcat(&out_format, "%Y ", &fmt_len); |
| 1896 | if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len); |
1913 | if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len); |
| 1897 | if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len); |
1914 | if (show_textrel) xstrcat(&out_format, "%t ", &fmt_len); |
| 1898 | if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); |
1915 | if (show_rpath) xstrcat(&out_format, "%r ", &fmt_len); |
| 1899 | if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); |
1916 | if (show_needed) xstrcat(&out_format, "%n ", &fmt_len); |
| 1900 | if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); |
1917 | if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); |