From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from zmcc-2-mx.zmailcloud.com (zmcc-2-mx.zmailcloud.com [52.37.197.7]) by sourceware.org (Postfix) with ESMTPS id 363113857012 for ; Wed, 4 Nov 2020 00:33:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 363113857012 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=symas.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=hyc@symas.com Received: from zmcc-2.zmailcloud.com (zmcc-2-mta-1.zmailcloud.com [146.148.52.56]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by zmcc-2-mx.zmailcloud.com (Postfix) with ESMTPS id 5BD744054A; Tue, 3 Nov 2020 18:33:29 -0600 (CST) Received: from zmcc-2.zmailcloud.com (localhost [127.0.0.1]) by zmcc-2-mta-1.zmailcloud.com (Postfix) with ESMTPS id D9E11CFF48; Tue, 3 Nov 2020 18:33:28 -0600 (CST) Received: from localhost (localhost [127.0.0.1]) by zmcc-2-mta-1.zmailcloud.com (Postfix) with ESMTP id C16E3CFF3C; Tue, 3 Nov 2020 18:33:28 -0600 (CST) DKIM-Filter: OpenDKIM Filter v2.10.3 zmcc-2-mta-1.zmailcloud.com C16E3CFF3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=symas.com; s=37C7994C-28CA-11EA-A30F-68F90BB9D764; t=1604450008; bh=+Doup593G7ywFNq3QQTfJvtrQ871owlWYTYgTQes8S4=; h=To:From:Message-ID:Date:MIME-Version; b=nB4bMfOSN1O4fW+sBRAtwEc+OJ0ZLprgIFEpS7OIsG9bV0YUutXEiIXdY2Emu42Mh /99Oiyh0ih6VfcuplxearesTU45uoX5mCBtapzM7iNR/mf1nQ0r1gOnnIx10iI54OK UK2hlw3SYPr3NJavxr0X9q3AXpWrspjMF9vb0bDXPNoHTZjuq0abc+FYrI5Y2hESyM r1IXD3A11dls6AR5SKrxzP0LVyHzuxrqWsZyuIkk9UEEA44No+mIAVu88yzy+NICw3 bn5mqKBM2N9GuTLPNqk5sonlj6GtxT7FPR1ngc+jY8G5gYEyQahR24SmWdfnitHqei moH5kmI52tidA== Received: from zmcc-2.zmailcloud.com ([127.0.0.1]) by localhost (zmcc-2-mta-1.zmailcloud.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id UFrC-9fC2He8; Tue, 3 Nov 2020 18:33:28 -0600 (CST) Received: from [192.168.1.155] (unknown [84.203.30.144]) by zmcc-2-mta-1.zmailcloud.com (Postfix) with ESMTPSA id BDE59CF65A; Tue, 3 Nov 2020 18:33:27 -0600 (CST) Subject: [PATCH] dependency list for static libraries To: Nick Clifton Cc: binutils@sourceware.org References: <53b8973b-40a4-2550-3307-66d7f13707d5@symas.com> <64fe82bd-9c00-b232-98d2-f46182fb16ba@symas.com> <9889c54b-4dd3-2275-6621-c2391cfd268d@redhat.com> <31f9062e-175d-06e9-695a-797c7ee11420@symas.com> <58620dc1-3bb9-aaae-b476-ebb613ecb627@redhat.com> <1aaf4429-074c-7912-e6e6-4d2f82d6ef10@redhat.com> From: Howard Chu Message-ID: <7b118db2-9502-c45e-9f47-6b6f6a5f9646@symas.com> Date: Wed, 4 Nov 2020 00:33:25 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 SeaMonkey/2.53.3 MIME-Version: 1.0 In-Reply-To: <1aaf4429-074c-7912-e6e6-4d2f82d6ef10@redhat.com> Content-Type: multipart/mixed; boundary="------------98ACD6A6166BF8820B4E7853" X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RAZOR2_CF_RANGE_51_100, RAZOR2_CHECK, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_RED autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Nov 2020 00:33:32 -0000 This is a multi-part message in MIME format. --------------98ACD6A6166BF8820B4E7853 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Nick Clifton wrote: > Hi Howard, > >> Whitespace fixes done, attached. > > Sorry for the delay in reviewing this patch. This revised form > looks good to me, so I have gone ahead and applied it to the sources. A tentative patch for the corresponding linker plugin is attached. One big question I still have is how to get this plugin to be used by default? -- -- Howard Chu CTO, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/ --------------98ACD6A6166BF8820B4E7853 Content-Type: text/x-patch; name="0001-Add-libdep-linker-plugin.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Add-libdep-linker-plugin.patch" >From 0bebac309c1e5772a22a4715b2367f565236f183 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 4 Nov 2020 00:24:56 +0000 Subject: [PATCH] Add libdep linker plugin Needs ld to be linked with -E to export its symbols; the plugin uses the libbfd that ld was linked with. --- ld/Makefile.am | 5 + ld/libdep_plugin.c | 284 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 ld/libdep_plugin.c diff --git a/ld/Makefile.am b/ld/Makefile.am index 41db0c6016..1f5b73e0ce 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -947,6 +947,7 @@ ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmai ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \ $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL_DEP) ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL) $(ZLIB) +ld_new_LDFLAGS = -Wl,-E # Dependency tracking for the generated emulation files. EXTRA_ld_new_SOURCES += $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES) @@ -998,6 +999,10 @@ libldtestplug4_la_SOURCES = testplug4.c libldtestplug4_la_CFLAGS= -g -O2 libldtestplug4_la_LDFLAGS = -no-undefined -rpath /nowhere +lib_LTLIBRARIES = libdep_plugin.la +libdep_plugin_la_SOURCES = libdep_plugin.c +libdep_plugin_la_LDFLAGS = -no-undefined -rpath /nowhere + # DOCUMENTATION TARGETS # Manual configuration file; not usually attached to normal configuration, # because almost all configs use "gen" version of manual. diff --git a/ld/libdep_plugin.c b/ld/libdep_plugin.c new file mode 100644 index 0000000000..2cf00b2b25 --- /dev/null +++ b/ld/libdep_plugin.c @@ -0,0 +1,284 @@ +/* libdeps plugin for the GNU linker. + Copyright (C) 2020 Free Software Foundation, Inc. + + This file is part of the GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#if BFD_SUPPORTS_PLUGINS +#include "plugin-api.h" + +#include /* For isspace. */ + +/* Helper for calling plugin api message function. */ +#define TV_MESSAGE if (tv_message) (*tv_message) + +/* Function pointers to cache hooks passed at onload time. */ +static ld_plugin_register_claim_file tv_register_claim_file = 0; +static ld_plugin_register_cleanup tv_register_cleanup = 0; +static ld_plugin_message tv_message = 0; +static ld_plugin_add_input_library tv_add_input_library = 0; +static ld_plugin_set_extra_library_path tv_set_extra_library_path = 0; + +/* Handle/record information received in a transfer vector entry. */ +static enum ld_plugin_status +parse_tv_tag (struct ld_plugin_tv *tv) +{ +#define SETVAR(x) x = tv->tv_u.x + switch (tv->tv_tag) + { + case LDPT_REGISTER_CLAIM_FILE_HOOK: + SETVAR(tv_register_claim_file); + break; + case LDPT_REGISTER_CLEANUP_HOOK: + SETVAR(tv_register_cleanup); + break; + case LDPT_MESSAGE: + SETVAR(tv_message); + break; + case LDPT_ADD_INPUT_LIBRARY: + SETVAR(tv_add_input_library); + break; + case LDPT_SET_EXTRA_LIBRARY_PATH: + SETVAR(tv_set_extra_library_path); + break; + default: + break; + } +#undef SETVAR + return LDPS_OK; +} + +/* Turn a string into an argvec. */ +static char ** +str2vec (char *in) +{ + char **res; + char *s, *first, *end; + char *sq, *dq; + int i, total; + + end = in + strlen(in); + s = in; + while (isspace (*s)) s++; + first = s; + + i = 1; + while (s = strchr (s, ' ')) { + s++; + i++; + } + res = (char **)malloc ((i+1) * sizeof (char *)); + if (!res) + return res; + + i = 0; + sq = NULL; + dq = NULL; + res[0] = first; + for (s = first; *s; s++) { + if (*s == '\\') { + memmove (s, s+1, end-s-1); + end--; + } + if (isspace (*s)) { + if (sq || dq) + continue; + *s++ = '\0'; + while(isspace (*s)) s++; + if (*s) + res[++i] = s; + } + if (*s == '\'') { + if (!dq) { + if (sq) { + memmove (sq, sq+1, s-sq-1); + memmove (s-2, s+1, end-s-1); + end -= 2; + s--; + sq = NULL; + } else { + sq = s; + } + } + } + if (*s == '"') { + if (!sq) { + if (dq) { + memmove (dq, dq+1, s-dq-1); + memmove (s-2, s+1, end-s-1); + end -= 2; + s--; + dq = NULL; + } else { + dq = s; + } + } + } + } + res[++i] = NULL; + return res; +} + +static char *prevfile; +#define LIBDEPS "__.LIBDEP" + +/* Standard plugin API registerable hook. */ +static enum ld_plugin_status +onclaim_file (const struct ld_plugin_input_file *file, int *claimed) +{ + bfd *arch, *next, *prev; + bfd_size_type len; + char *line = NULL, **vec; + enum ld_plugin_status rv; + + /* If we've already seen this file, ignore it. */ + if (prevfile && !strcmp (file->name, prevfile)) + return LDPS_OK; + + /* If it's not an archive member, ignore it. */ + if (!file->offset) + return LDPS_OK; + + if (prevfile) + free (prevfile); + + prevfile = strdup (file->name); + if (!prevfile) + return LDPS_ERR; + + /* This hook only gets called on actual object files. + * We have to examine the archive ourselves, to find + * our LIBDEPS member. */ + arch = bfd_openr (file->name, "plugin"); + if (!arch) + return LDPS_ERR; + + bfd_check_format (arch, bfd_archive); + + prev = NULL; + while ((next = bfd_openr_next_archived_file (arch, prev))) + { + prev = next; + if (!strcmp (bfd_get_filename (next), LIBDEPS)) + break; + } + if (!next) + { + bfd_close (arch); + return LDPS_OK; + } + { + struct stat st; + bfd_stat_arch_elt (next, &st); + len = st.st_size; + } + line = malloc (len); + if (!line) + { + rv = LDPS_ERR; + goto quit; + } + + if (bfd_bread (line, len, next) != len) + { + rv = LDPS_ERR; + goto quit; + } + + rv = LDPS_OK; + vec = str2vec (line); + if (vec) { + int i; + for (i=0; vec[i]; i++) { + if (vec[i][0] != '-') + continue; + rv = LDPS_ERR; + if (vec[i][1] == 'l') { + rv = tv_add_input_library (vec[i]+2); + } else if (vec[i][1] == 'L') { + rv = tv_set_extra_library_path (vec[i]+2); + } + if (rv != LDPS_OK) + break; + } + free (vec); + } + /* Inform the user/testsuite. */ + TV_MESSAGE (LDPL_INFO, "processed deps for library %s: %s", + file->name, line); + fflush (NULL); + +quit: + if (line) + free (line); + bfd_close (arch); + + return rv; +} + +/* Standard plugin API registerable hook. */ +static enum ld_plugin_status +oncleanup (void) +{ + if (prevfile) { + free (prevfile); + prevfile = NULL; + } + return LDPS_OK; +} + +/* Standard plugin API entry point. */ +enum ld_plugin_status +onload (struct ld_plugin_tv *tv) +{ + enum ld_plugin_status rv; + + /* This plugin requires a valid tv array. */ + if (!tv) + return LDPS_ERR; + + /* First entry should always be LDPT_MESSAGE, letting us get + hold of it easily so we can send output straight away. */ + if (tv[0].tv_tag == LDPT_MESSAGE) + tv_message = tv[0].tv_u.tv_message; + + do + if ((rv = parse_tv_tag (tv)) != LDPS_OK) + return rv; + while ((tv++)->tv_tag != LDPT_NULL); + + /* Register hooks. */ + if (!tv_register_claim_file) + { + TV_MESSAGE (LDPL_FATAL, "No register_claim_file hook"); + fflush (NULL); + return LDPS_ERR; + } + (*tv_register_claim_file) (onclaim_file); + if (!tv_register_cleanup) + { + TV_MESSAGE (LDPL_FATAL, "No register_cleanup hook"); + fflush (NULL); + return LDPS_ERR; + } + (*tv_register_cleanup) (oncleanup); + fflush (NULL); + return LDPS_OK; +} +#endif /* BFD_SUPPORTS_PLUGINS */ -- 2.20.1 --------------98ACD6A6166BF8820B4E7853--