aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2024-06-11 19:51:33 +0100
committerNick Alcock <nick.alcock@oracle.com>2024-06-18 13:20:31 +0100
commitf8da1a05db64d8c5c700e07a008a1938858a7adf (patch)
tree3418ffefbfa35c3683d5279d5be87fedc0d78d17 /ld
parent0c5f03a9d5ed35731742df2c98cc5ec6aa738828 (diff)
downloadbinutils-f8da1a05db64d8c5c700e07a008a1938858a7adf.zip
binutils-f8da1a05db64d8c5c700e07a008a1938858a7adf.tar.gz
binutils-f8da1a05db64d8c5c700e07a008a1938858a7adf.tar.bz2
libctf: dedup: enums with overlapping enumerators are conflicting
The CTF deduplicator was not considering enumerators inside enum types to be things that caused type conflicts, so if the following two TUs were linked together, you would end up with the following in the resulting dict: 1.c: enum foo { A, B }; 2.c: enum bar { A, B }; linked: enum foo { A, B }; enum bar { A, B }; This does work -- but it's not something that's valid C, and the general point of the shared dict is that it is something that you could potentially get from any valid C TU. So consider such types to be conflicting, but obviously don't consider actually identical enums to be conflicting, even though they too have (all) their identifiers in common. This involves surprisingly little code. The deduplicator detects conflicting types by counting types in a hash table of hash tables: decorated identifier -> (type hash -> count) where the COUNT is the number of times a given hash has been observed: any name with more than one hash associated with it is considered conflicting (the count is used to identify the most common such name for promotion to the shared dict). Before now, those identifiers were all the identifiers of types (possibly decorated with their namespace on the front for enumerator identifiers), but we can equally well put *enumeration constant names* in there, undecorated like the identifiers of types in the global namespace, with the type hash being the hash of each enum containing that enumerator. The existing conflicting-type-detection code will then accurately identify distinct enums with enumeration constants in common. The enum that contains the most commonly-appearing enumerators will be promoted to the shared dict. libctf/ * ctf-impl.h (ctf_dedup_t) <cd_name_counts>: Extend comment. * ctf-dedup.c (ctf_dedup_count_name): New, split out of... (ctf_dedup_populate_mappings): ... here. Call it for all * enumeration constants in an enum as well as types. ld/ * testsuite/ld-ctf/enum-3.c: New test CTF. * testsuite/ld-ctf/enum-4.c: Likewise. * testsuite/ld-ctf/overlapping-enums.d: New test. * testsuite/ld-ctf/overlapping-enums-2.d: Likewise.
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ld-ctf/enum-3.c3
-rw-r--r--ld/testsuite/ld-ctf/enum-4.c3
-rw-r--r--ld/testsuite/ld-ctf/overlapping-enums-2.d36
-rw-r--r--ld/testsuite/ld-ctf/overlapping-enums.d35
4 files changed, 77 insertions, 0 deletions
diff --git a/ld/testsuite/ld-ctf/enum-3.c b/ld/testsuite/ld-ctf/enum-3.c
new file mode 100644
index 0000000..c365aaf
--- /dev/null
+++ b/ld/testsuite/ld-ctf/enum-3.c
@@ -0,0 +1,3 @@
+enum first_day_of_the_week {Sunday = 0};
+
+static enum first_day_of_the_week day __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/enum-4.c b/ld/testsuite/ld-ctf/enum-4.c
new file mode 100644
index 0000000..0063424
--- /dev/null
+++ b/ld/testsuite/ld-ctf/enum-4.c
@@ -0,0 +1,3 @@
+enum intersecting_days_of_the_week {Montag = 1, Tuesday = 2};
+
+static enum intersecting_days_of_the_week day __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/overlapping-enums-2.d b/ld/testsuite/ld-ctf/overlapping-enums-2.d
new file mode 100644
index 0000000..1adfd86
--- /dev/null
+++ b/ld/testsuite/ld-ctf/overlapping-enums-2.d
@@ -0,0 +1,36 @@
+#as:
+#source: enum.c
+#source: enum-4.c
+#objdump: --ctf
+#ld: -shared
+#name: Semioverlapping enumerators
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+ Header:
+ Magic number: 0xdff2
+ Version: 4 \(CTF_VERSION_3\)
+#...
+ Types:
+ 0x1: \(kind 8\) enum day_of_the_week \(size 0x[0-9a-f]*\) \(aligned at 0x[0-9a-f]*\)
+ Monday: 0
+ Tuesday: 1
+ Wednesday: 2
+ Thursday: 3
+ Friday: 4
+ Saturday: 5
+ Sunday: 6
+#...
+ Strings:
+#...
+CTF archive member: .*enum.*\.c:
+#...
+ Types:
+ 0x80000001: \(kind 8\) enum intersecting_days_of_the_week \(size 0x[0-9a-f]*\) \(aligned at 0x[0-9a-f]*\)
+ Montag: 1
+ Tuesday: 2
+
+ Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/overlapping-enums.d b/ld/testsuite/ld-ctf/overlapping-enums.d
new file mode 100644
index 0000000..7cf57d6
--- /dev/null
+++ b/ld/testsuite/ld-ctf/overlapping-enums.d
@@ -0,0 +1,35 @@
+#as:
+#source: enum.c
+#source: enum-3.c
+#objdump: --ctf
+#ld: -shared
+#name: Overlapping enumerators
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+ Header:
+ Magic number: 0xdff2
+ Version: 4 \(CTF_VERSION_3\)
+#...
+ Types:
+ 0x1: \(kind 8\) enum day_of_the_week \(size 0x[0-9a-f]*\) \(aligned at 0x[0-9a-f]*\)
+ Monday: 0
+ Tuesday: 1
+ Wednesday: 2
+ Thursday: 3
+ Friday: 4
+ Saturday: 5
+ Sunday: 6
+#...
+ Strings:
+#...
+CTF archive member: .*enum.*\.c:
+#...
+ Types:
+ 0x80000001: \(kind 8\) enum first_day_of_the_week \(size 0x[0-9a-f]*\) \(aligned at 0x[0-9a-f]*\)
+ Sunday: 0
+
+ Strings:
+#...