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