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