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