648606
commit 73bd9636d0e76a4d255776b7733667198b9ef585
648606
Author: Panu Matilainen <pmatilai@redhat.com>
648606
Date:   Mon Jan 7 15:52:43 2013 +0200
648606
648606
    Filter ELF dependencies by name
648606
    
648606
    - Instead of vain heuristics on DT_SONAME presence, filter out
648606
      irregular sonames from all dependencies: linkable library names generally
648606
      must contain ".so" and start with "lib" for the linker to find it at all,
648606
      anything else is an exception of one kind or another (the prime exception
648606
      of ld.so variants we handle here). This weeds out provides for most
648606
      dlopen()'ed modules etc, and filtering both provides and requires
648606
      by the same rules means we wont generate requires for things that wont be
648606
      provided.  Of course this also means we can omit things that are in
648606
      DT_NEEDED, but these should be rare exceptions which the new
648606
      --no-filter-soname switch is for.
648606
648606
diff --git a/tools/elfdeps.c b/tools/elfdeps.c
648606
index fc9a905..a0db9f7 100644
648606
--- a/tools/elfdeps.c
648606
+++ b/tools/elfdeps.c
648606
@@ -15,6 +15,7 @@
648606
 int filter_private = 0;
648606
 int soname_only = 0;
648606
 int fake_soname = 1;
648606
+int filter_soname = 1;
648606
 
648606
 typedef struct elfInfo_s {
648606
     Elf *elf;
648606
@@ -36,6 +37,31 @@ static int skipPrivate(const char *s)
648606
     return (filter_private && rstreq(s, "GLIBC_PRIVATE"));
648606
 }
648606
 
648606
+/*
648606
+ * Rough soname sanity filtering: all sane soname's dependencies need to
648606
+ * contain ".so", and normal linkable libraries start with "lib",
648606
+ * everything else is an exception of some sort. The most notable
648606
+ * and common exception is the dynamic linker itself, which we allow
648606
+ * here, the rest can use --no-filter-soname.
648606
+ */
648606
+static int skipSoname(const char *soname)
648606
+{
648606
+    if (filter_soname) {
648606
+	if (!strstr(soname, ".so"))
648606
+	    return 1;
648606
+
648606
+	if (rstreqn(soname, "ld.", 3) || rstreqn(soname, "ld-", 3))
648606
+	    return 0;
648606
+
648606
+	if (rstreqn(soname, "lib", 3))
648606
+	    return 0;
648606
+	else
648606
+	    return 1;
648606
+    }
648606
+
648606
+    return 0;
648606
+}
648606
+
648606
 static const char *mkmarker(GElf_Ehdr *ehdr)
648606
 {
648606
     const char *marker = NULL;
648606
@@ -58,6 +84,10 @@ static void addDep(ARGV_t *deps,
648606
 		   const char *soname, const char *ver, const char *marker)
648606
 {
648606
     char *dep = NULL;
648606
+
648606
+    if (skipSoname(soname))
648606
+	return;
648606
+
648606
     if (ver || marker) {
648606
 	rasprintf(&dep,
648606
 		  "%s(%s)%s", soname, ver ? ver : "", marker ? marker : "");
648606
@@ -293,6 +323,7 @@ int main(int argc, char *argv[])
648606
 	{ "filter-private", 0, POPT_ARG_VAL, &filter_private, -1, NULL, NULL },
648606
 	{ "soname-only", 0, POPT_ARG_VAL, &soname_only, -1, NULL, NULL },
648606
 	{ "no-fake-soname", 0, POPT_ARG_VAL, &fake_soname, 0, NULL, NULL },
648606
+	{ "no-filter-soname", 0, POPT_ARG_VAL, &filter_soname, 0, NULL, NULL },
648606
 	POPT_AUTOHELP 
648606
 	POPT_TABLEEND
648606
     };