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