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