195 lines
7.7 KiB
Diff
195 lines
7.7 KiB
Diff
From e6c0416cd6abd3b7493630fd1ead68a46121ff74 Mon Sep 17 00:00:00 2001
|
|
From: Nick Alcock <nick.alcock@oracle.com>
|
|
Date: Wed, 23 Jul 2025 14:20:26 +0100
|
|
Subject: [PATCH 23/23] libctf: link: rejig lazy opening to not need weak
|
|
symbols
|
|
|
|
The ctf_link_add_ctf API function has a 'lazy opening' feature whereby,
|
|
if you pass in the file but not a CTF archive, the archive is opened
|
|
as late as possible during links. This is valuable mostly in
|
|
cu-mapped links (a feature not accessible via GNU ld), where it
|
|
ensures that, rather than eventually needing memory for the original
|
|
link inputs, the smushed-together cu-mapped intermediate outputs,
|
|
*and* the final output, we only need enough memory for the smushed-
|
|
together outputs, the final output, and one input, since the inputs
|
|
can be closed immediately after they are smushed together.
|
|
|
|
(In GNU ld, the feature is useless because it loads all sections into
|
|
memory anyway.)
|
|
|
|
The lazy-opening feature uses libctf's ctf_open function, which uses
|
|
BFD: so it is not available in libctf-nobfd -- except that I thought I
|
|
had a cunning trick, and used a weak symbol so that if you linked
|
|
libctf-nobfd into your program and then also linked in bfd, the feature
|
|
stayed enabled.
|
|
|
|
This is silly -- if your program is licensed such that you can link in
|
|
BFD, you can just link in libctf.so and not bother with libctf-nobfd.so
|
|
in the first place. Worse, the weak symbol usage broke MacOS builds,
|
|
since MacOS's system compiler uses a different means of introducing weak
|
|
symbols. We could test for and use it, but this is the only place in
|
|
libctf to use weak symbols at all, and the feature of lazy-opening with
|
|
libctf-nobfd is so marginal we might as well drop it: it's almost
|
|
certain there are zero users, certainly fewer users than users of MacOS
|
|
with the system compiler.
|
|
|
|
While we're at it, simplify things by deleting the never-implemented
|
|
feature (not exposed in the API) to allow linking together raw buffers
|
|
of CTF data. If we need it we can bring it back, but all it's doing
|
|
right now is complicating the code to no end at all.
|
|
|
|
libctf/
|
|
PR libctf/33194
|
|
* ctf-link.c (ctf_open): Delete weak pragma.
|
|
(ctf_link_add): Fuse with...
|
|
(ctf_link_add_ctf): ... this function. Drop BUF, N args
|
|
and corresponding unimplemented feature warnings. Only check
|
|
NOBFD to see whether lazy loading is available, not PIC as
|
|
well.
|
|
(ctf_link_lazy_open): Likewise.
|
|
|
|
(cherry picked from commit d3e582895b2038feb47b68f1e03efaa0d9dae325)
|
|
(cherry picked from commit 2b2e51a31ec7c48ef830f7e8415b42d4b95e335a)
|
|
---
|
|
libctf/ctf-link.c | 88 +++++++++++++++--------------------------------
|
|
1 file changed, 27 insertions(+), 61 deletions(-)
|
|
|
|
diff --git a/libctf/ctf-link.c b/libctf/ctf-link.c
|
|
index 2d4401d2210..524ed7e2466 100644
|
|
--- a/libctf/ctf-link.c
|
|
+++ b/libctf/ctf-link.c
|
|
@@ -20,10 +20,6 @@
|
|
#include <ctf-impl.h>
|
|
#include <string.h>
|
|
|
|
-#if defined (PIC)
|
|
-#pragma weak ctf_open
|
|
-#endif
|
|
-
|
|
/* CTF linking consists of adding CTF archives full of content to be merged into
|
|
this one to the current file (which must be writable) by calling
|
|
ctf_link_add_ctf. Once this is done, a call to ctf_link will merge the type
|
|
@@ -145,56 +141,33 @@ ctf_link_add_ctf_internal (ctf_dict_t *fp, ctf_archive_t *ctf,
|
|
return ctf_set_errno (fp, ENOMEM);
|
|
}
|
|
|
|
-/* Add a file, memory buffer, or unopened file (by name) to a link.
|
|
-
|
|
- You can call this with:
|
|
-
|
|
- CTF and NAME: link the passed ctf_archive_t, with the given NAME.
|
|
- NAME alone: open NAME as a CTF file when needed.
|
|
- BUF and NAME: open the BUF (of length N) as CTF, with the given NAME. (Not
|
|
- yet implemented.)
|
|
+/* Add an opened CTF archive or unopened file (by name) to a link.
|
|
+ If CTF is NULL and NAME is non-null, an unopened file is meant:
|
|
+ otherwise, the specified archive is assumed to have the given NAME.
|
|
|
|
- Passed in CTF args are owned by the dictionary and will be freed by it.
|
|
- The BUF arg is *not* owned by the dictionary, and the user should not free
|
|
- its referent until the link is done.
|
|
+ If CTF is NULL, the NAME is only opened when needed, and is closed when no
|
|
+ longer needed, so that large cu-mapped links will only use memory for their
|
|
+ cu-mapped inputs briefly (compensating for the memory usage of the
|
|
+ smushed-together cu-mapped verion).
|
|
|
|
- The order of calls to this function influences the order of types in the
|
|
- final link output, but otherwise is not important.
|
|
+ Passed in CTF args are owned by the dictionary and will be freed by it.
|
|
|
|
- Repeated additions of the same NAME have no effect; repeated additions of
|
|
- different dicts with the same NAME add all the dicts with unique NAMEs
|
|
- derived from NAME.
|
|
+ The order of calls to this function influences the order of types in the
|
|
+ final link output, but otherwise is not important.
|
|
|
|
- Private for now, but may in time become public once support for BUF is
|
|
- implemented. */
|
|
+ Repeated additions of the same NAME have no effect; repeated additions of
|
|
+ different dicts with the same NAME add all the dicts with unique NAMEs
|
|
+ derived from NAME. */
|
|
|
|
-static int
|
|
-ctf_link_add (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name,
|
|
- void *buf _libctf_unused_, size_t n _libctf_unused_)
|
|
+int
|
|
+ctf_link_add_ctf (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name)
|
|
{
|
|
- if (buf)
|
|
- return (ctf_set_errno (fp, ECTF_NOTYET));
|
|
-
|
|
- if (!((ctf && name && !buf)
|
|
- || (name && !buf && !ctf)
|
|
- || (buf && name && !ctf)))
|
|
+ if (!name)
|
|
return (ctf_set_errno (fp, EINVAL));
|
|
|
|
- /* We can only lazily open files if libctf.so is in use rather than
|
|
- libctf-nobfd.so. This is a little tricky: in shared libraries, we can use
|
|
- a weak symbol so that -lctf -lctf-nobfd works, but in static libraries we
|
|
- must distinguish between the two libraries explicitly. */
|
|
-
|
|
-#if defined (PIC)
|
|
- if (!buf && !ctf && name && !ctf_open)
|
|
- return (ctf_set_errno (fp, ECTF_NEEDSBFD));
|
|
-#elif NOBFD
|
|
- if (!buf && !ctf && name)
|
|
- return (ctf_set_errno (fp, ECTF_NEEDSBFD));
|
|
-#endif
|
|
-
|
|
if (fp->ctf_link_outputs)
|
|
return (ctf_set_errno (fp, ECTF_LINKADDEDLATE));
|
|
+
|
|
if (fp->ctf_link_inputs == NULL)
|
|
fp->ctf_link_inputs = ctf_dynhash_create (ctf_hash_string,
|
|
ctf_hash_eq_string, free,
|
|
@@ -203,22 +176,15 @@ ctf_link_add (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name,
|
|
if (fp->ctf_link_inputs == NULL)
|
|
return (ctf_set_errno (fp, ENOMEM));
|
|
|
|
- return ctf_link_add_ctf_internal (fp, ctf, NULL, name);
|
|
-}
|
|
-
|
|
-/* Add an opened CTF archive or unopened file (by name) to a link.
|
|
- If CTF is NULL and NAME is non-null, an unopened file is meant:
|
|
- otherwise, the specified archive is assumed to have the given NAME.
|
|
-
|
|
- Passed in CTF args are owned by the dictionary and will be freed by it.
|
|
+ /* We can only lazily open files if libctf.so is in use rather than
|
|
+ libctf-nobfd.so. */
|
|
|
|
- The order of calls to this function influences the order of types in the
|
|
- final link output, but otherwise is not important. */
|
|
+#if NOBFD
|
|
+ if (!ctf)
|
|
+ return (ctf_set_errno (fp, ECTF_NEEDSBFD));
|
|
+#endif
|
|
|
|
-int
|
|
-ctf_link_add_ctf (ctf_dict_t *fp, ctf_archive_t *ctf, const char *name)
|
|
-{
|
|
- return ctf_link_add (fp, ctf, name, NULL, 0);
|
|
+ return ctf_link_add_ctf_internal (fp, ctf, NULL, name);
|
|
}
|
|
|
|
/* Lazily open a CTF archive for linking, if not already open.
|
|
@@ -238,12 +204,12 @@ ctf_link_lazy_open (ctf_dict_t *fp, ctf_link_input_t *input)
|
|
return 1;
|
|
|
|
/* See ctf_link_add_ctf. */
|
|
-#if defined (PIC) || !NOBFD
|
|
- input->clin_arc = ctf_open (input->clin_filename, NULL, &err);
|
|
-#else
|
|
+#if NOBFD
|
|
ctf_err_warn (fp, 0, ECTF_NEEDSBFD, _("cannot open %s lazily"),
|
|
input->clin_filename);
|
|
return ctf_set_errno (fp, ECTF_NEEDSBFD);
|
|
+#else
|
|
+ input->clin_arc = ctf_open (input->clin_filename, NULL, &err);
|
|
#endif
|
|
|
|
/* Having no CTF sections is not an error. We just don't need to do
|
|
--
|
|
2.49.1
|
|
|