public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] libctf, link: fix CU-mapped links with CTF_LINK_EMPTY_CU_MAPPINGS
@ 2023-04-08 15:49 Nick Alcock
  0 siblings, 0 replies; only message in thread
From: Nick Alcock @ 2023-04-08 15:49 UTC (permalink / raw)
  To: bfd-cvs, gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=869a750c0ec0abcab84e38a43a1ed73321ef4371

commit 869a750c0ec0abcab84e38a43a1ed73321ef4371
Author: Nick Alcock <nick.alcock@oracle.com>
Date:   Fri Apr 7 20:09:24 2023 +0100

    libctf, link: fix CU-mapped links with CTF_LINK_EMPTY_CU_MAPPINGS
    
    This is a bug in the intersection of two obscure options that cannot
    even be invoked from ld with a feature added to stop ld of the
    same input file repeatedly from crashing the linker.
    
    The latter fix involved tracking input files (internally to libctf) not
    just with their input CU name but with a version of their input CU name
    that was augmented with a numeric prefix if their linker input file name
    was changed, to prevent distinct CTF dicts with the same cuname from
    overwriting each other. (We can't use just the linker input file name
    because one linker input can contain many CU dicts, particularly under
    ld -r).  If these inputs then produced conflicting types, those types
    were emitted into similarly-named output dicts, so we needed similar
    machinery to detect clashing output dicts and add a numeric prefix to
    them as well.
    
    This works fine, except that if you used the cu-mapping feature to force
    double-linking of CTF (so that your CTF can be grouped into output dicts
    larger than a single translation unit) and then also used
    CTF_LINK_EMPTY_CU_MAPPINGS to force every possible output dict in the
    mapping to be created (even if empty), we did the creation of empty dicts
    first, and then all the actual content got considered to be a clash. So
    you ended up with a pile of useless empty dicts and then all the content
    was in full dicts with the same names suffixed with a #0.  This seems
    likely to confuse consumers that use this facility.
    
    Fixed by generating all the EMPTY_CU_MAPPINGS empty dicts after linking
    is complete, not before it runs.
    
    No impact on ld, which does not do cu-mapped links or pass
    CTF_LINK_EMPTY_CU_MAPPINGS to ctf_link().
    
    libctf/
            * ctf-link.c (ctf_create_per_cu): Don't create new dicts iff one
            already exists and we are making one for no input in particular.
            (ctf_link): Emit empty CTF dicts corresponding to no input in
            particular only after linkiing is complete.

Diff:
---
 libctf/ctf-link.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/libctf/ctf-link.c b/libctf/ctf-link.c
index 016bce5f6d6..9babec2aa37 100644
--- a/libctf/ctf-link.c
+++ b/libctf/ctf-link.c
@@ -321,12 +321,12 @@ ctf_create_per_cu (ctf_dict_t *fp, ctf_dict_t *input, const char *cu_name)
   if (ctf_name == NULL)
     ctf_name = cu_name;
 
-  /* Look up the per-CU dict.  If we don't know of one, or it is for
-     a different input CU which just happens to have the same name,
-     create a new one.  */
+  /* Look up the per-CU dict.  If we don't know of one, or it is for a different input
+     CU which just happens to have the same name, create a new one.  If we are creating
+     a dict with no input specified, anything will do.  */
 
   if ((cu_fp = ctf_dynhash_lookup (fp->ctf_link_outputs, ctf_name)) == NULL
-      || cu_fp->ctf_link_in_out != fp)
+      || (input && cu_fp->ctf_link_in_out != fp))
     {
       int err;
 
@@ -1505,11 +1505,17 @@ ctf_link (ctf_dict_t *fp, int flags)
   if (fp->ctf_link_outputs == NULL)
     return ctf_set_errno (fp, ENOMEM);
 
+  fp->ctf_flags |= LCTF_LINKING;
+  ctf_link_deduplicating (fp);
+  fp->ctf_flags &= ~LCTF_LINKING;
+
+  if ((ctf_errno (fp) != 0) && (ctf_errno (fp) != ECTF_NOCTFDATA))
+    return -1;
+
   /* Create empty CUs if requested.  We do not currently claim that multiple
      links in succession with CTF_LINK_EMPTY_CU_MAPPINGS set in some calls and
      not set in others will do anything especially sensible.  */
 
-  fp->ctf_flags |= LCTF_LINKING;
   if (fp->ctf_link_out_cu_mapping && (flags & CTF_LINK_EMPTY_CU_MAPPINGS))
     {
       ctf_next_t *i = NULL;
@@ -1535,11 +1541,6 @@ ctf_link (ctf_dict_t *fp, int flags)
 	}
     }
 
-  ctf_link_deduplicating (fp);
-
-  fp->ctf_flags &= ~LCTF_LINKING;
-  if ((ctf_errno (fp) != 0) && (ctf_errno (fp) != ECTF_NOCTFDATA))
-    return -1;
   return 0;
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-08 15:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-08 15:49 [binutils-gdb] libctf, link: fix CU-mapped links with CTF_LINK_EMPTY_CU_MAPPINGS Nick Alcock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).