/[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.225 Revision 1.226
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.225 2011/09/27 17:28:19 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.226 2011/09/27 18:37:22 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.225 2011/09/27 17:28:19 vapier Exp $"; 10static const char *rcsid = "$Id: scanelf.c,v 1.226 2011/09/27 18:37:22 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 == '+')
56static char be_verbose = 0; 56static char be_verbose = 0;
57static char be_wewy_wewy_quiet = 0; 57static char be_wewy_wewy_quiet = 0;
58static char be_semi_verbose = 0; 58static char be_semi_verbose = 0;
59static char *find_sym = NULL; 59static char *find_sym = NULL;
60static char *find_lib = NULL; 60static char *find_lib = NULL;
61static array_t _find_lib_arr = array_init_decl, *find_lib_arr = &_find_lib_arr;
61static char *find_section = NULL; 62static char *find_section = NULL;
63static array_t _find_section_arr = array_init_decl, *find_section_arr = &_find_section_arr;
62static char *out_format = NULL; 64static char *out_format = NULL;
63static char *search_path = NULL; 65static char *search_path = NULL;
64static char fix_elf = 0; 66static char fix_elf = 0;
65static char g_match = 0; 67static char g_match = 0;
66static char use_ldcache = 0; 68static char use_ldcache = 0;
812 unsigned long i; 814 unsigned long i;
813 char *needed; 815 char *needed;
814 void *strtbl_void; 816 void *strtbl_void;
815 char *p; 817 char *p;
816 818
819 /*
820 * -n -> op==0 -> print all
821 * -N -> op==1 -> print requested
822 */
817 if ((op==0 && !show_needed) || (op==1 && !find_lib)) return NULL; 823 if ((op == 0 && !show_needed) || (op == 1 && !find_lib))
824 return NULL;
818 825
819 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 826 strtbl_void = elf_findsecbyname(elf, ".dynstr");
820 827
821 if (elf->phdr && strtbl_void) { 828 if (elf->phdr && strtbl_void) {
822#define SHOW_NEEDED(B) \ 829#define SHOW_NEEDED(B) \
824 Elf ## B ## _Dyn *dyn; \ 831 Elf ## B ## _Dyn *dyn; \
825 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 832 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
826 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 833 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
827 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 834 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
828 Elf ## B ## _Off offset; \ 835 Elf ## B ## _Off offset; \
836 size_t matched = 0; \
837 /* Walk all the program headers to find the PT_DYNAMIC */ \
829 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 838 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
830 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) continue; \ 839 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) \
840 continue; \
831 offset = EGET(phdr[i].p_offset); \ 841 offset = EGET(phdr[i].p_offset); \
832 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 842 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) \
843 continue; \
844 /* Walk all the dynamic tags to find NEEDED entries */ \
833 dyn = DYN ## B (elf->vdata + offset); \ 845 dyn = DYN ## B (elf->vdata + offset); \
834 while (EGET(dyn->d_tag) != DT_NULL) { \ 846 while (EGET(dyn->d_tag) != DT_NULL) { \
835 if (EGET(dyn->d_tag) == DT_NEEDED) { \ 847 if (EGET(dyn->d_tag) == DT_NEEDED) { \
836 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 848 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
837 if (offset >= (Elf ## B ## _Off)elf->len) { \ 849 if (offset >= (Elf ## B ## _Off)elf->len) { \
838 ++dyn; \ 850 ++dyn; \
839 continue; \ 851 continue; \
840 } \ 852 } \
841 needed = elf->data + offset; \ 853 needed = elf->data + offset; \
842 if (op == 0) { \ 854 if (op == 0) { \
855 /* -n -> print all entries */ \
843 if (!be_wewy_wewy_quiet) { \ 856 if (!be_wewy_wewy_quiet) { \
844 if (*found_needed) xchrcat(ret, ',', ret_len); \ 857 if (*found_needed) xchrcat(ret, ',', ret_len); \
845 if (use_ldcache) \ 858 if (use_ldcache) \
846 if ((p = lookup_cache_lib(elf, needed)) != NULL) \ 859 if ((p = lookup_cache_lib(elf, needed)) != NULL) \
847 needed = p; \ 860 needed = p; \
848 xstrcat(ret, needed, ret_len); \ 861 xstrcat(ret, needed, ret_len); \
849 } \ 862 } \
850 *found_needed = 1; \ 863 *found_needed = 1; \
851 } else { \ 864 } else { \
852 if (!strncmp(find_lib, needed, strlen( !g_match ? needed : find_lib))) { \ 865 /* -N -> print matching entries */ \
866 size_t n; \
867 const char *find_lib_name; \
868 \
869 array_for_each(find_lib_arr, n, find_lib_name) \
870 if (!strcmp(find_lib_name, needed)) \
871 ++matched; \
872 \
873 if (matched == array_cnt(find_lib_arr)) { \
853 *found_lib = 1; \ 874 *found_lib = 1; \
854 return (be_wewy_wewy_quiet ? NULL : needed); \ 875 return (be_wewy_wewy_quiet ? NULL : find_lib); \
855 } \ 876 } \
856 } \ 877 } \
857 } \ 878 } \
858 ++dyn; \ 879 ++dyn; \
859 } \ 880 } \
1211 if (!find_section) 1232 if (!find_section)
1212 return NULL; 1233 return NULL;
1213 1234
1214#define FIND_SECTION(B) \ 1235#define FIND_SECTION(B) \
1215 if (elf->elf_class == ELFCLASS ## B) { \ 1236 if (elf->elf_class == ELFCLASS ## B) { \
1237 size_t matched, n; \
1216 int invert; \ 1238 int invert; \
1239 const char *section_name; \
1217 Elf ## B ## _Shdr *section; \ 1240 Elf ## B ## _Shdr *section; \
1241 \
1242 matched = 0; \
1243 array_for_each(find_section_arr, n, section_name) { \
1218 invert = (*find_section == '!' ? 1 : 0); \ 1244 invert = (*section_name == '!' ? 1 : 0); \
1219 section = SHDR ## B (elf_findsecbyname(elf, find_section+invert)); \ 1245 section = SHDR ## B (elf_findsecbyname(elf, section_name + invert)); \
1220 if ((section == NULL && invert) || (section != NULL && !invert)) \ 1246 if ((section == NULL && invert) || (section != NULL && !invert)) \
1247 ++matched; \
1248 } \
1249 \
1250 if (matched == array_cnt(find_section_arr)) \
1221 *found_section = 1; \ 1251 *found_section = 1; \
1222 } 1252 }
1223 FIND_SECTION(32) 1253 FIND_SECTION(32)
1224 FIND_SECTION(64) 1254 FIND_SECTION(64)
1225 1255
1820 "Print BIND information", 1850 "Print BIND information",
1821 "Print SONAME information", 1851 "Print SONAME information",
1822 "Find a specified symbol", 1852 "Find a specified symbol",
1823 "Find a specified section", 1853 "Find a specified section",
1824 "Find a specified library", 1854 "Find a specified library",
1825 "Use strncmp to match libraries. (use with -N)", 1855 "Use regex matching rather than string compare (use with -s)",
1826 "Locate cause of TEXTREL", 1856 "Locate cause of TEXTREL",
1827 "Print only ELF files matching etype ET_DYN,ET_EXEC ...", 1857 "Print only ELF files matching etype ET_DYN,ET_EXEC ...",
1828 "Print only ELF files matching numeric bits", 1858 "Print only ELF files matching numeric bits",
1829 "Print Endianness", 1859 "Print Endianness",
1830 "Print OSABI", 1860 "Print OSABI",
1916 if (freopen(optarg, "w", stdout) == NULL) 1946 if (freopen(optarg, "w", stdout) == NULL)
1917 err("Could not open output stream '%s': %s", optarg, strerror(errno)); 1947 err("Could not open output stream '%s': %s", optarg, strerror(errno));
1918 break; 1948 break;
1919 } 1949 }
1920 case 'k': 1950 case 'k':
1921 if (find_section) warn("You prob don't want to specify -k twice"); 1951 xarraypush(find_section_arr, optarg, strlen(optarg));
1922 find_section = optarg;
1923 break; 1952 break;
1924 case 's': { 1953 case 's': {
1925 if (find_sym) warn("You prob don't want to specify -s twice"); 1954 if (find_sym) warn("You prob don't want to specify -s twice");
1926 find_sym = optarg; 1955 find_sym = optarg;
1927 break; 1956 break;
1928 } 1957 }
1929 case 'N': { 1958 case 'N':
1930 if (find_lib) warn("You prob don't want to specify -N twice"); 1959 xarraypush(find_lib_arr, optarg, strlen(optarg));
1931 find_lib = optarg;
1932 break; 1960 break;
1933 }
1934
1935 case 'F': { 1961 case 'F': {
1936 if (out_format) warn("You prob don't want to specify -F twice"); 1962 if (out_format) warn("You prob don't want to specify -F twice");
1937 out_format = optarg; 1963 out_format = optarg;
1938 break; 1964 break;
1939 } 1965 }
2020 } 2046 }
2021 if (show_textrels && be_verbose) { 2047 if (show_textrels && be_verbose) {
2022 if (which("objdump") != NULL) 2048 if (which("objdump") != NULL)
2023 has_objdump = 1; 2049 has_objdump = 1;
2024 } 2050 }
2051 /* flatten arrays for display */
2052 if (array_cnt(find_lib_arr))
2053 find_lib = array_flatten_str(find_lib_arr);
2054 if (array_cnt(find_section_arr))
2055 find_section = array_flatten_str(find_section_arr);
2025 /* let the format option override all other options */ 2056 /* let the format option override all other options */
2026 if (out_format) { 2057 if (out_format) {
2027 show_pax = show_phdr = show_textrel = show_rpath = \ 2058 show_pax = show_phdr = show_textrel = show_rpath = \
2028 show_needed = show_interp = show_bind = show_soname = \ 2059 show_needed = show_interp = show_bind = show_soname = \
2029 show_textrels = show_perms = show_endian = show_size = \ 2060 show_textrels = show_perms = show_endian = show_size = \
2110 } 2141 }
2111 2142
2112 /* clean up */ 2143 /* clean up */
2113 for (i = 0; ldpaths[i]; ++i) 2144 for (i = 0; ldpaths[i]; ++i)
2114 free(ldpaths[i]); 2145 free(ldpaths[i]);
2146 free(find_lib);
2147 free(find_section);
2115 2148
2116 if (ldcache != 0) 2149 if (ldcache != 0)
2117 munmap(ldcache, ldcache_size); 2150 munmap(ldcache, ldcache_size);
2118 return ret; 2151 return ret;
2119} 2152}

Legend:
Removed from v.1.225  
changed lines
  Added in v.1.226

  ViewVC Help
Powered by ViewVC 1.1.20