• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修订版c37135b645c3344808641a91422bad0cb916a514 (tree)
时间2019-09-23 22:12:54
作者Nick Alcock <nick.alcock@orac...>
CommiterNick Alcock

Log Message

libctf: teach ctf_add_type how forwards work

This machinery has been broken for as long as Solaris has existed.
Forwards are meant to encode "struct foo;", "enum foo;" or "union
foo;". Obviously these all exist in distinct namespaces, so forwards
store the type kind they forward to in their ctt_type member
(which makes conceptual sense if you squint at it). The addition
machinery uses this to promote forwards to the appropriate type as
needed.

Unfortunately ctf_add_type does not: it checks the global namespace
(which is always wrong), and so fails with a spurious conflict if you
have, say, a typedef and then a forward comes along with the same name,
even if it's a forward to something like a struct. (This was observed
with <libio.h>, which has "struct _IO_FILE;" and also
"typedef struct _IO_FILE _IO_FILE"). We should look at the recorded
type kind and look in the appropriate namespace. We should also,
when creating the forward in the new container, use that type kind,
rather than just defaulting to CTF_K_STRUCT and hoping that what
eventually comes along is a struct.

This bug is as old as the first implementation of ctf_add_type in
Solaris. But we also want a new feature for the linker, closely-related
and touching the same code so we add it here: not only do we want a
forward followed by a struct/union/enum to promote the forward, but
we want want a struct/union/enum followed by a forward to act as a NOP
and return the existing type, because when we're adding many files
in succession to a target link, there will often be already-promoted
forwards (in the shape of a struct/union/enum) that want to unify
with duplicate forwards coming from other object files.

libctf/
* ctf-create.c (ctf_add_type): Look up and use the forwarded-to

type kind. Allow forwards to unify with pre-existing structs/
unions/enums.

更改概述

差异

--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,9 @@
1+2019-08-03 Nick Alcock <nick.alcock@oracle.com>
2+
3+ * ctf-create.c (ctf_add_type): Look up and use the forwarded-to
4+ type kind. Allow forwards to unify with pre-existing structs/
5+ unions/enums.
6+
17 2019-07-30 Nick Alcock <nick.alcock@oracle.com>
28
39 * ctf-impl.h (ctf_file_t) <ctf_link_cu_mappping>: New.
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -1552,7 +1552,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
15521552 ctf_id_t tmp;
15531553
15541554 const char *name;
1555- uint32_t kind, flag, vlen;
1555+ uint32_t kind, forward_kind, flag, vlen;
15561556
15571557 const ctf_type_t *src_tp, *dst_tp;
15581558 ctf_bundle_t src, dst;
@@ -1576,7 +1576,11 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
15761576 flag = LCTF_INFO_ISROOT (src_fp, src_tp->ctt_info);
15771577 vlen = LCTF_INFO_VLEN (src_fp, src_tp->ctt_info);
15781578
1579- switch (kind)
1579+ forward_kind = kind;
1580+ if (kind == CTF_K_FORWARD)
1581+ forward_kind = src_tp->ctt_type;
1582+
1583+ switch (forward_kind)
15801584 {
15811585 case CTF_K_STRUCT:
15821586 hp = dst_fp->ctf_structs;
@@ -1605,16 +1609,30 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16051609
16061610 /* If an identically named dst_type exists, fail with ECTF_CONFLICT
16071611 unless dst_type is a forward declaration and src_type is a struct,
1608- union, or enum (i.e. the definition of the previous forward decl). */
1612+ union, or enum (i.e. the definition of the previous forward decl).
16091613
1610- if (dst_type != CTF_ERR && dst_kind != kind
1611- && (dst_kind != CTF_K_FORWARD
1612- || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1613- && kind != CTF_K_UNION)))
1614+ We also allow addition in the opposite order (addition of a forward when a
1615+ struct, union, or enum already exists), which is a NOP and returns the
1616+ already-present struct, union, or enum. */
1617+
1618+ if (dst_type != CTF_ERR && dst_kind != kind)
16141619 {
1615- ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1616- "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1617- return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1620+ if (kind == CTF_K_FORWARD
1621+ && (dst_kind == CTF_K_ENUM || dst_kind == CTF_K_STRUCT
1622+ || dst_kind == CTF_K_UNION))
1623+ {
1624+ ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1625+ return dst_type;
1626+ }
1627+
1628+ if (dst_kind != CTF_K_FORWARD
1629+ || (kind != CTF_K_ENUM && kind != CTF_K_STRUCT
1630+ && kind != CTF_K_UNION))
1631+ {
1632+ ctf_dprintf ("Conflict for type %s: kinds differ, new: %i; "
1633+ "old (ID %lx): %i\n", name, kind, dst_type, dst_kind);
1634+ return (ctf_set_errno (dst_fp, ECTF_CONFLICT));
1635+ }
16181636 }
16191637
16201638 /* We take special action for an integer, float, or slice since it is
@@ -1924,10 +1942,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
19241942
19251943 case CTF_K_FORWARD:
19261944 if (dst_type == CTF_ERR)
1927- {
1928- dst_type = ctf_add_forward (dst_fp, flag,
1929- name, CTF_K_STRUCT); /* Assume STRUCT. */
1930- }
1945+ dst_type = ctf_add_forward (dst_fp, flag, name, forward_kind);
19311946 break;
19321947
19331948 case CTF_K_TYPEDEF: