/[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.95 Revision 1.96
1/* 1/*
2 * Copyright 2003-2005 Gentoo Foundation 2 * Copyright 2003-2005 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.95 2005/12/10 06:08:22 vapier Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/scanelf.c,v 1.96 2005/12/28 22:26:47 solar Exp $
5 * 5 *
6 * Copyright 2003-2005 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2005 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2005 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2005 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
14#include <limits.h> 14#include <limits.h>
15#include <string.h> 15#include <string.h>
16#include <errno.h> 16#include <errno.h>
17#include <unistd.h> 17#include <unistd.h>
18#include <sys/stat.h> 18#include <sys/stat.h>
19#include <sys/mman.h>
20#include <fcntl.h>
19#include <dirent.h> 21#include <dirent.h>
20#include <getopt.h> 22#include <getopt.h>
21#include <assert.h> 23#include <assert.h>
22#include "paxinc.h" 24#include "paxinc.h"
23 25
24static const char *rcsid = "$Id: scanelf.c,v 1.95 2005/12/10 06:08:22 vapier Exp $"; 26static const char *rcsid = "$Id: scanelf.c,v 1.96 2005/12/28 22:26:47 solar Exp $";
25#define argv0 "scanelf" 27#define argv0 "scanelf"
26 28
27#define IS_MODIFIER(c) (c == '%' || c == '#') 29#define IS_MODIFIER(c) (c == '%' || c == '#')
28 30
29 31
64static char *find_sym = NULL, *versioned_symname = NULL; 66static char *find_sym = NULL, *versioned_symname = NULL;
65static char *find_lib = NULL; 67static char *find_lib = NULL;
66static char *out_format = NULL; 68static char *out_format = NULL;
67static char *search_path = NULL; 69static char *search_path = NULL;
68static char gmatch = 0; 70static char gmatch = 0;
71static char printcache = 0;
69 72
73
74caddr_t ldcache = 0;
75size_t ldcache_size = 0;
70 76
71/* sub-funcs for scanelf_file() */ 77/* sub-funcs for scanelf_file() */
72static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab) 78static void scanelf_file_get_symtabs(elfobj *elf, void **sym, void **tab)
73{ 79{
74 /* find the best SHT_DYNSYM and SHT_STRTAB sections */ 80 /* find the best SHT_DYNSYM and SHT_STRTAB sections */
477 } else if (rpath || runpath) 483 } else if (rpath || runpath)
478 xstrcat(ret, (runpath ? runpath : rpath), ret_len); 484 xstrcat(ret, (runpath ? runpath : rpath), ret_len);
479 else if (!be_quiet) 485 else if (!be_quiet)
480 xstrcat(ret, " - ", ret_len); 486 xstrcat(ret, " - ", ret_len);
481} 487}
488
489#define LDSO_CACHE_MAGIC "ld.so-"
490#define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1)
491#define LDSO_CACHE_VER "1.7.0"
492#define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1)
493
494static char *lookup_cache_lib(char *);
495static char *lookup_cache_lib(char *fname)
496{
497 int fd = 0;
498 char *strs;
499 static char buf[_POSIX_PATH_MAX] = "";
500 const char *cachefile = "/etc/ld.so.cache";
501 struct stat st;
502
503 typedef struct {
504 char magic[LDSO_CACHE_MAGIC_LEN];
505 char version[LDSO_CACHE_VER_LEN];
506 int nlibs;
507 } header_t;
508
509 typedef struct {
510 int flags;
511 int sooffset;
512 int liboffset;
513 } libentry_t;
514
515 header_t *header;
516 libentry_t *libent;
517
518 if (fname == NULL)
519 return NULL;
520
521 if (ldcache == 0) {
522 if (stat(cachefile, &st) || (fd = open(cachefile, O_RDONLY)) < 0)
523 return NULL;
524 /* save the cache size for latter unmapping */
525 ldcache_size = st.st_size;
526
527 if ((ldcache = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == (caddr_t) -1)
528 return NULL;
529
530 close(fd);
531
532 if (memcmp(((header_t *) ldcache)->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN))
533 return NULL;
534
535 if (memcmp (((header_t *) ldcache)->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN))
536 return NULL;
537 }
538
539 header = (header_t *) ldcache;
540 libent = (libentry_t *) (ldcache + sizeof(header_t));
541 strs = (char *) &libent[header->nlibs];
542
543 for (fd = 0; fd < header->nlibs; fd++) {
544 if (strcmp(fname, strs + libent[fd].sooffset) != 0)
545 continue;
546 strncpy(buf, strs + libent[fd].liboffset, sizeof(buf));
547 }
548 return buf;
549}
550
551
482static const char *scanelf_file_needed_lib(elfobj *elf, char *found_needed, char *found_lib, int op, char **ret, size_t *ret_len) 552static const char *scanelf_file_needed_lib(elfobj *elf, char *found_needed, char *found_lib, int op, char **ret, size_t *ret_len)
483{ 553{
484 unsigned long i; 554 unsigned long i;
485 char *needed; 555 char *needed;
486 void *strtbl_void; 556 void *strtbl_void;
557 char *p;
487 558
488 if ((op==0 && !show_needed) || (op==1 && !find_lib)) return NULL; 559 if ((op==0 && !show_needed) || (op==1 && !find_lib)) return NULL;
489 560
490 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 561 strtbl_void = elf_findsecbyname(elf, ".dynstr");
491 562
511 } \ 582 } \
512 needed = (char*)(elf->data + offset); \ 583 needed = (char*)(elf->data + offset); \
513 if (op == 0) { \ 584 if (op == 0) { \
514 if (!be_wewy_wewy_quiet) { \ 585 if (!be_wewy_wewy_quiet) { \
515 if (*found_needed) xchrcat(ret, ',', ret_len); \ 586 if (*found_needed) xchrcat(ret, ',', ret_len); \
587 if (printcache) \
588 if ((p = lookup_cache_lib(needed)) != NULL) \
589 needed = p; \
516 xstrcat(ret, needed, ret_len); \ 590 xstrcat(ret, needed, ret_len); \
517 } \ 591 } \
518 *found_needed = 1; \ 592 *found_needed = 1; \
519 } else { \ 593 } else { \
520 if (!strncmp(find_lib, needed, strlen( !gmatch ? needed : find_lib))) { \ 594 if (!strncmp(find_lib, needed, strlen( !gmatch ? needed : find_lib))) { \
1019 1093
1020 free(path); 1094 free(path);
1021} 1095}
1022 1096
1023 1097
1024
1025/* usage / invocation handling functions */ 1098/* usage / invocation handling functions */
1026#define PARSE_FLAGS "plRmyxetrnibSs:gN:TaqvF:f:o:BhV" 1099#define PARSE_FLAGS "plRmyxetrnLibSs:gN:TaqvF:f:o:BhV"
1027#define a_argument required_argument 1100#define a_argument required_argument
1028static struct option const long_opts[] = { 1101static struct option const long_opts[] = {
1029 {"path", no_argument, NULL, 'p'}, 1102 {"path", no_argument, NULL, 'p'},
1030 {"ldpath", no_argument, NULL, 'l'}, 1103 {"ldpath", no_argument, NULL, 'l'},
1031 {"recursive", no_argument, NULL, 'R'}, 1104 {"recursive", no_argument, NULL, 'R'},
1034 {"pax", no_argument, NULL, 'x'}, 1107 {"pax", no_argument, NULL, 'x'},
1035 {"header", no_argument, NULL, 'e'}, 1108 {"header", no_argument, NULL, 'e'},
1036 {"textrel", no_argument, NULL, 't'}, 1109 {"textrel", no_argument, NULL, 't'},
1037 {"rpath", no_argument, NULL, 'r'}, 1110 {"rpath", no_argument, NULL, 'r'},
1038 {"needed", no_argument, NULL, 'n'}, 1111 {"needed", no_argument, NULL, 'n'},
1112 {"ldcache", no_argument, NULL, 'L'},
1039 {"interp", no_argument, NULL, 'i'}, 1113 {"interp", no_argument, NULL, 'i'},
1040 {"bind", no_argument, NULL, 'b'}, 1114 {"bind", no_argument, NULL, 'b'},
1041 {"soname", no_argument, NULL, 'S'}, 1115 {"soname", no_argument, NULL, 'S'},
1042 {"symbol", a_argument, NULL, 's'}, 1116 {"symbol", a_argument, NULL, 's'},
1043 {"lib", a_argument, NULL, 'N'}, 1117 {"lib", a_argument, NULL, 'N'},
1064 "Print PaX markings", 1138 "Print PaX markings",
1065 "Print GNU_STACK/PT_LOAD markings", 1139 "Print GNU_STACK/PT_LOAD markings",
1066 "Print TEXTREL information", 1140 "Print TEXTREL information",
1067 "Print RPATH information", 1141 "Print RPATH information",
1068 "Print NEEDED information", 1142 "Print NEEDED information",
1143 "Resolve NEEDED information (use with -n)",
1069 "Print INTERP information", 1144 "Print INTERP information",
1070 "Print BIND information", 1145 "Print BIND information",
1071 "Print SONAME information", 1146 "Print SONAME information",
1072 "Find a specified symbol", 1147 "Find a specified symbol",
1073 "Find a specified library", 1148 "Find a specified library",
1162 if (out_format) warn("You prob don't want to specify -F twice"); 1237 if (out_format) warn("You prob don't want to specify -F twice");
1163 out_format = optarg; 1238 out_format = optarg;
1164 break; 1239 break;
1165 } 1240 }
1166 1241
1167 case 'g': gmatch = 1; 1242 case 'g': gmatch = 1; /* break; any reason we dont breal; here ? */
1243 case 'L': printcache = 1; break;
1168 case 'y': scan_symlink = 0; break; 1244 case 'y': scan_symlink = 0; break;
1169 case 'B': show_banner = 0; break; 1245 case 'B': show_banner = 0; break;
1170 case 'l': scan_ldpath = 1; break; 1246 case 'l': scan_ldpath = 1; break;
1171 case 'p': scan_envpath = 1; break; 1247 case 'p': scan_envpath = 1; break;
1172 case 'R': dir_recurse = 1; break; 1248 case 'R': dir_recurse = 1; break;
1264 1340
1265 /* clean up */ 1341 /* clean up */
1266 if (versioned_symname) free(versioned_symname); 1342 if (versioned_symname) free(versioned_symname);
1267 for (i = 0; ldpaths[i]; ++i) 1343 for (i = 0; ldpaths[i]; ++i)
1268 free(ldpaths[i]); 1344 free(ldpaths[i]);
1345
1346 if (ldcache != 0)
1347 munmap(ldcache, ldcache_size);
1269} 1348}
1270 1349
1271 1350
1272 1351
1273/* utility funcs */ 1352/* utility funcs */

Legend:
Removed from v.1.95  
changed lines
  Added in v.1.96

  ViewVC Help
Powered by ViewVC 1.1.20