• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

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

修訂c150ea49ac8ea95059e5ae1c516b0cef39472366 (tree)
時間2019-09-23 22:12:54
作者Nick Alcock <nick.alcock@orac...>
CommiterNick Alcock

Log Message

libctf: map from old to corresponding newly-added types in ctf_add_type

This lets you call ctf_type_mapping (dest_fp, src_fp, src_type_id)
and get told what type ID the corresponding type has in the target
ctf_file_t. This works even if it was added by a recursive call, and
because it is stored in the target ctf_file_t it works even if we
had to add one type to multiple ctf_file_t's as part of conflicting
type handling.

We empty out this mapping after every archive is linked: because it maps
input to output fps, and we only visit each input fp once, its contents
are rendered entirely useless every time the source fp changes.

v3: add several missing mapping additions. Add ctf_dynhash_empty, and

empty after every input archive.

libctf/
* ctf-impl.h (ctf_file_t): New field ctf_link_type_mapping.
(struct ctf_link_type_mapping_key): New.
(ctf_hash_type_mapping_key): Likewise.
(ctf_hash_eq_type_mapping_key): Likewise.
(ctf_add_type_mapping): Likewise.
(ctf_type_mapping): Likewise.
(ctf_dynhash_empty): Likewise.
* ctf-open.c (ctf_file_close): Update accordingly.
* ctf-create.c (ctf_update): Likewise.
(ctf_add_type): Populate the mapping.
* ctf-hash.c (ctf_hash_type_mapping_key): Hash a type mapping key.
(ctf_hash_eq_type_mapping_key): Check the key for equality.
(ctf_dynhash_insert): Fix comment typo.
(ctf_dynhash_empty): New.
* ctf-link.c (ctf_add_type_mapping): New.
(ctf_type_mapping): Likewise.
(empty_link_type_mapping): New.
(ctf_link_one_input_archive): Call it.

Change Summary

差異

--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,26 @@
11 2019-07-13 Nick Alcock <nick.alcock@oracle.com>
22
3+ * ctf-impl.h (ctf_file_t): New field ctf_link_type_mapping.
4+ (struct ctf_link_type_mapping_key): New.
5+ (ctf_hash_type_mapping_key): Likewise.
6+ (ctf_hash_eq_type_mapping_key): Likewise.
7+ (ctf_add_type_mapping): Likewise.
8+ (ctf_type_mapping): Likewise.
9+ (ctf_dynhash_empty): Likewise.
10+ * ctf-open.c (ctf_file_close): Update accordingly.
11+ * ctf-create.c (ctf_update): Likewise.
12+ (ctf_add_type): Populate the mapping.
13+ * ctf-hash.c (ctf_hash_type_mapping_key): Hash a type mapping key.
14+ (ctf_hash_eq_type_mapping_key): Check the key for equality.
15+ (ctf_dynhash_insert): Fix comment typo.
16+ (ctf_dynhash_empty): New.
17+ * ctf-link.c (ctf_add_type_mapping): New.
18+ (ctf_type_mapping): Likewise.
19+ (empty_link_type_mapping): New.
20+ (ctf_link_one_input_archive): Call it.
21+
22+2019-07-13 Nick Alcock <nick.alcock@oracle.com>
23+
324 * ctf-link.c: New file, linking of the string and type sections.
425 * Makefile.am (libctf_a_SOURCES): Add it.
526 * Makefile.in: Regenerate.
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -473,6 +473,7 @@ ctf_update (ctf_file_t *fp)
473473 nfp->ctf_link_inputs = fp->ctf_link_inputs;
474474 nfp->ctf_link_outputs = fp->ctf_link_outputs;
475475 nfp->ctf_syn_ext_strtab = fp->ctf_syn_ext_strtab;
476+ nfp->ctf_link_type_mapping = fp->ctf_link_type_mapping;
476477
477478 nfp->ctf_snapshot_lu = fp->ctf_snapshots;
478479
@@ -485,6 +486,7 @@ ctf_update (ctf_file_t *fp)
485486 fp->ctf_link_inputs = NULL;
486487 fp->ctf_link_outputs = NULL;
487488 fp->ctf_syn_ext_strtab = NULL;
489+ fp->ctf_link_type_mapping = NULL;
488490
489491 fp->ctf_dvhash = NULL;
490492 memset (&fp->ctf_dvdefs, 0, sizeof (ctf_list_t));
@@ -1557,6 +1559,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
15571559 ctf_funcinfo_t ctc;
15581560
15591561 ctf_hash_t *hp;
1562+ ctf_id_t orig_src_type = src_type;
15601563
15611564 if (!(dst_fp->ctf_flags & LCTF_RDWR))
15621565 return (ctf_set_errno (dst_fp, ECTF_RDONLY));
@@ -1640,7 +1643,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16401643 if (memcmp (&src_en, &dst_en, sizeof (ctf_encoding_t)) == 0)
16411644 {
16421645 if (kind != CTF_K_SLICE)
1643- return dst_type;
1646+ {
1647+ ctf_add_type_mapping (src_fp, src_type, dst_fp, dst_type);
1648+ return dst_type;
1649+ }
16441650 }
16451651 else
16461652 {
@@ -1679,7 +1685,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16791685 int match; /* Do the encodings match? */
16801686
16811687 if (kind != CTF_K_INTEGER && kind != CTF_K_FLOAT && kind != CTF_K_SLICE)
1682- return dtd->dtd_type;
1688+ {
1689+ ctf_add_type_mapping (src_fp, src_type, dst_fp, dtd->dtd_type);
1690+ return dtd->dtd_type;
1691+ }
16831692
16841693 sroot = (flag & CTF_ADD_ROOT);
16851694 droot = (LCTF_INFO_ISROOT (dst_fp,
@@ -1698,7 +1707,10 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
16981707 if (match && sroot == droot)
16991708 {
17001709 if (kind != CTF_K_SLICE)
1701- return dtd->dtd_type;
1710+ {
1711+ ctf_add_type_mapping (src_fp, src_type, dst_fp, dtd->dtd_type);
1712+ return dtd->dtd_type;
1713+ }
17021714 }
17031715 else if (!match && sroot && droot)
17041716 {
@@ -1939,6 +1951,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
19391951 return (ctf_set_errno (dst_fp, ECTF_CORRUPT));
19401952 }
19411953
1954+ if (dst_type != CTF_ERR)
1955+ ctf_add_type_mapping (src_fp, orig_src_type, dst_fp, dst_type);
19421956 return dst_type;
19431957 }
19441958
--- a/libctf/ctf-hash.c
+++ b/libctf/ctf-hash.c
@@ -82,6 +82,28 @@ ctf_hash_eq_string (const void *a, const void *b)
8282 return !strcmp((const char *) hep_a->key, (const char *) hep_b->key);
8383 }
8484
85+/* Hash a type_mapping_key. */
86+unsigned int
87+ctf_hash_type_mapping_key (const void *ptr)
88+{
89+ ctf_helem_t *hep = (ctf_helem_t *) ptr;
90+ ctf_link_type_mapping_key_t *k = (ctf_link_type_mapping_key_t *) hep->key;
91+
92+ return htab_hash_pointer (k->cltm_fp) + 59 * htab_hash_pointer ((void *) k->cltm_idx);
93+}
94+
95+int
96+ctf_hash_eq_type_mapping_key (const void *a, const void *b)
97+{
98+ ctf_helem_t *hep_a = (ctf_helem_t *) a;
99+ ctf_helem_t *hep_b = (ctf_helem_t *) b;
100+ ctf_link_type_mapping_key_t *key_a = (ctf_link_type_mapping_key_t *) hep_a->key;
101+ ctf_link_type_mapping_key_t *key_b = (ctf_link_type_mapping_key_t *) hep_b->key;
102+
103+ return (key_a->cltm_fp == key_b->cltm_fp)
104+ && (key_a->cltm_idx == key_b->cltm_idx);
105+}
106+
85107 /* The dynhash, used for hashes whose size is not known at creation time. */
86108
87109 /* Free a single ctf_helem. */
@@ -164,7 +186,7 @@ ctf_dynhash_insert (ctf_dynhash_t *hp, void *key, void *value)
164186 return errno;
165187
166188 /* We need to keep the key_free and value_free around in each item because the
167- del function has no visiblity into the hash as a whole, only into the
189+ del function has no visibility into the hash as a whole, only into the
168190 individual items. */
169191
170192 slot->key_free = hp->key_free;
@@ -180,6 +202,12 @@ ctf_dynhash_remove (ctf_dynhash_t *hp, const void *key)
180202 htab_remove_elt (hp->htab, &hep);
181203 }
182204
205+void
206+ctf_dynhash_empty (ctf_dynhash_t *hp)
207+{
208+ htab_empty (hp->htab);
209+}
210+
183211 void *
184212 ctf_dynhash_lookup (ctf_dynhash_t *hp, const void *key)
185213 {
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -204,6 +204,17 @@ typedef struct ctf_str_atom_ref
204204 uint32_t *caf_ref; /* A single ref to this string. */
205205 } ctf_str_atom_ref_t;
206206
207+/* The structure used as the key in a ctf_link_type_mapping, which lets the
208+ linker machinery determine which type IDs on the input side of a link map to
209+ which types on the output side. (The value is a ctf_id_t: another
210+ index, not a type.) */
211+
212+typedef struct ctf_link_type_mapping_key
213+{
214+ ctf_file_t *cltm_fp;
215+ ctf_id_t cltm_idx;
216+} ctf_link_type_mapping_key_t;
217+
207218 /* The ctf_file is the structure used to represent a CTF container to library
208219 clients, who see it only as an opaque pointer. Modifications can therefore
209220 be made freely to this structure without regard to client versioning. The
@@ -269,6 +280,7 @@ struct ctf_file
269280 ctf_archive_t *ctf_archive; /* Archive this ctf_file_t came from. */
270281 ctf_dynhash_t *ctf_link_inputs; /* Inputs to this link. */
271282 ctf_dynhash_t *ctf_link_outputs; /* Additional outputs from this link. */
283+ ctf_dynhash_t *ctf_link_type_mapping; /* Map input types to output types. */
272284 char *ctf_tmp_typeslice; /* Storage for slicing up type names. */
273285 size_t ctf_tmp_typeslicelen; /* Size of the typeslice. */
274286 void *ctf_specific; /* Data for ctf_get/setspecific(). */
@@ -328,10 +340,12 @@ extern const ctf_type_t *ctf_lookup_by_id (ctf_file_t **, ctf_id_t);
328340 typedef unsigned int (*ctf_hash_fun) (const void *ptr);
329341 extern unsigned int ctf_hash_integer (const void *ptr);
330342 extern unsigned int ctf_hash_string (const void *ptr);
343+extern unsigned int ctf_hash_type_mapping_key (const void *ptr);
331344
332345 typedef int (*ctf_hash_eq_fun) (const void *, const void *);
333346 extern int ctf_hash_eq_integer (const void *, const void *);
334347 extern int ctf_hash_eq_string (const void *, const void *);
348+extern int ctf_hash_eq_type_mapping_key (const void *, const void *);
335349
336350 typedef void (*ctf_hash_free_fun) (void *);
337351
@@ -349,6 +363,7 @@ extern ctf_dynhash_t *ctf_dynhash_create (ctf_hash_fun, ctf_hash_eq_fun,
349363 ctf_hash_free_fun, ctf_hash_free_fun);
350364 extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *);
351365 extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *);
366+extern void ctf_dynhash_empty (ctf_dynhash_t *);
352367 extern void *ctf_dynhash_lookup (ctf_dynhash_t *, const void *);
353368 extern void ctf_dynhash_destroy (ctf_dynhash_t *);
354369 extern void ctf_dynhash_iter (ctf_dynhash_t *, ctf_hash_iter_f, void *);
@@ -371,6 +386,11 @@ extern int ctf_dvd_insert (ctf_file_t *, ctf_dvdef_t *);
371386 extern void ctf_dvd_delete (ctf_file_t *, ctf_dvdef_t *);
372387 extern ctf_dvdef_t *ctf_dvd_lookup (const ctf_file_t *, const char *);
373388
389+extern void ctf_add_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type,
390+ ctf_file_t *dst_fp, ctf_id_t dst_type);
391+extern ctf_id_t ctf_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type,
392+ ctf_file_t **dst_fp);
393+
374394 extern void ctf_decl_init (ctf_decl_t *);
375395 extern void ctf_decl_fini (ctf_decl_t *);
376396 extern void ctf_decl_push (ctf_decl_t *, ctf_file_t *, ctf_id_t);
--- a/libctf/ctf-link.c
+++ b/libctf/ctf-link.c
@@ -21,6 +21,103 @@
2121 #include <string.h>
2222
2323 /* Type tracking machinery. */
24+
25+/* Record the correspondence between a source and ctf_add_type()-added
26+ destination type: both types are translated into parent type IDs if need be,
27+ so they relate to the actual container they are in. Outside controlled
28+ circumstances (like linking) it is probably not useful to do more than
29+ compare these pointers, since there is nothing stopping the user closing the
30+ source container whenever they want to.
31+
32+ Our OOM handling here is just to not do anything, because this is called deep
33+ enough in the call stack that doing anything useful is painfully difficult:
34+ the worst consequence if we do OOM is a bit of type duplication anyway. */
35+
36+void
37+ctf_add_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type,
38+ ctf_file_t *dst_fp, ctf_id_t dst_type)
39+{
40+ if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
41+ src_fp = src_fp->ctf_parent;
42+
43+ src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
44+
45+ if (LCTF_TYPE_ISPARENT (dst_fp, dst_type) && dst_fp->ctf_parent)
46+ dst_fp = dst_fp->ctf_parent;
47+
48+ dst_type = LCTF_TYPE_TO_INDEX(dst_fp, dst_type);
49+
50+ /* This dynhash is a bit tricky: it has a multivalued (structural) key, so we
51+ need to use the sized-hash machinery to generate key hashing and equality
52+ functions. */
53+
54+ if (dst_fp->ctf_link_type_mapping == NULL)
55+ {
56+ ctf_hash_fun f = ctf_hash_type_mapping_key;
57+ ctf_hash_eq_fun e = ctf_hash_eq_type_mapping_key;
58+
59+ if ((dst_fp->ctf_link_type_mapping = ctf_dynhash_create (f, e, free,
60+ NULL)) == NULL)
61+ return;
62+ }
63+
64+ ctf_link_type_mapping_key_t *key;
65+ key = calloc (1, sizeof (struct ctf_link_type_mapping_key));
66+ if (!key)
67+ return;
68+
69+ key->cltm_fp = src_fp;
70+ key->cltm_idx = src_type;
71+
72+ ctf_dynhash_insert (dst_fp->ctf_link_type_mapping, key,
73+ (void *) (uintptr_t) dst_type);
74+}
75+
76+/* Look up a type mapping: return 0 if none. The DST_FP is modified to point to
77+ the parent if need be. The ID returned is from the dst_fp's perspective. */
78+ctf_id_t
79+ctf_type_mapping (ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t **dst_fp)
80+{
81+ ctf_link_type_mapping_key_t key;
82+ ctf_file_t *target_fp = *dst_fp;
83+ ctf_id_t dst_type = 0;
84+
85+ if (LCTF_TYPE_ISPARENT (src_fp, src_type) && src_fp->ctf_parent)
86+ src_fp = src_fp->ctf_parent;
87+
88+ src_type = LCTF_TYPE_TO_INDEX(src_fp, src_type);
89+ key.cltm_fp = src_fp;
90+ key.cltm_idx = src_type;
91+
92+ if (target_fp->ctf_link_type_mapping)
93+ dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
94+ &key);
95+
96+ if (dst_type != 0)
97+ {
98+ dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
99+ target_fp->ctf_parent != NULL);
100+ *dst_fp = target_fp;
101+ return dst_type;
102+ }
103+
104+ if (target_fp->ctf_parent)
105+ target_fp = target_fp->ctf_parent;
106+ else
107+ return 0;
108+
109+ if (target_fp->ctf_link_type_mapping)
110+ dst_type = (uintptr_t) ctf_dynhash_lookup (target_fp->ctf_link_type_mapping,
111+ &key);
112+
113+ if (dst_type)
114+ dst_type = LCTF_INDEX_TO_TYPE (target_fp, dst_type,
115+ target_fp->ctf_parent != NULL);
116+
117+ *dst_fp = target_fp;
118+ return dst_type;
119+}
120+
24121 /* Linker machinery.
25122
26123 CTF linking consists of adding CTF archives full of content to be merged into
@@ -231,6 +328,17 @@ ctf_link_one_input_archive_member (ctf_file_t *in_fp, const char *name, void *ar
231328 return 0;
232329 }
233330
331+/* Dump the unnecessary link type mapping after one input file is processed. */
332+static void
333+empty_link_type_mapping (void *key _libctf_unused_, void *value,
334+ void *arg _libctf_unused_)
335+{
336+ ctf_file_t *fp = (ctf_file_t *) value;
337+
338+ if (fp->ctf_link_type_mapping)
339+ ctf_dynhash_empty (fp->ctf_link_type_mapping);
340+}
341+
234342 /* Link one input file's types into the output file. */
235343 static void
236344 ctf_link_one_input_archive (void *key, void *value, void *arg_)
@@ -269,6 +377,11 @@ ctf_link_one_input_archive (void *key, void *value, void *arg_)
269377 ctf_set_errno (arg->out_fp, 0);
270378 }
271379 ctf_file_close (arg->main_input_fp);
380+
381+ /* Discard the now-unnecessary mapping table data. */
382+ if (arg->out_fp->ctf_link_type_mapping)
383+ ctf_dynhash_empty (arg->out_fp->ctf_link_type_mapping);
384+ ctf_dynhash_iter (arg->out_fp->ctf_link_outputs, empty_link_type_mapping, NULL);
272385 }
273386
274387 /* Merge types and variable sections in all files added to the link
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -1628,6 +1628,7 @@ ctf_file_close (ctf_file_t *fp)
16281628 ctf_dynhash_destroy (fp->ctf_syn_ext_strtab);
16291629 ctf_dynhash_destroy (fp->ctf_link_inputs);
16301630 ctf_dynhash_destroy (fp->ctf_link_outputs);
1631+ ctf_dynhash_destroy (fp->ctf_link_type_mapping);
16311632
16321633 ctf_free (fp->ctf_sxlate);
16331634 ctf_free (fp->ctf_txlate);