aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/testsuite/ld-ctf/array-char-conflicting-1.c9
-rw-r--r--ld/testsuite/ld-ctf/array-char-conflicting-2.c9
-rw-r--r--ld/testsuite/ld-ctf/array-conflicted-ordering.d26
-rw-r--r--ld/testsuite/ld-ctf/array-extern.c1
-rw-r--r--ld/testsuite/ld-ctf/array-extern.d32
-rw-r--r--ld/testsuite/ld-ctf/conflicting-typedefs.d2
-rw-r--r--libctf/ctf-dedup.c21
7 files changed, 98 insertions, 2 deletions
diff --git a/ld/testsuite/ld-ctf/array-char-conflicting-1.c b/ld/testsuite/ld-ctf/array-char-conflicting-1.c
new file mode 100644
index 0000000..a6736a8
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-char-conflicting-1.c
@@ -0,0 +1,9 @@
+typedef char *array[10];
+
+static array digits_names = {"zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine"};
+
+void *foo (void)
+{
+ return digits_names;
+}
diff --git a/ld/testsuite/ld-ctf/array-char-conflicting-2.c b/ld/testsuite/ld-ctf/array-char-conflicting-2.c
new file mode 100644
index 0000000..1cc46f0
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-char-conflicting-2.c
@@ -0,0 +1,9 @@
+typedef char *array[9];
+
+static array digits_names = {"one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine"};
+
+void *bar (void)
+{
+ return digits_names;
+}
diff --git a/ld/testsuite/ld-ctf/array-conflicted-ordering.d b/ld/testsuite/ld-ctf/array-conflicted-ordering.d
new file mode 100644
index 0000000..a8bbc3d
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-conflicted-ordering.d
@@ -0,0 +1,26 @@
+#as:
+#source: array-char-conflicting-1.c
+#source: array-char-conflicting-2.c
+#objdump: --ctf
+#cc: -fPIC
+#ld: -shared --ctf-variables --hash-style=sysv
+#name: Arrays (conflicted)
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+ Header:
+ Magic number: 0xdff2
+ Version: 4 \(CTF_VERSION_3\)
+#...
+ Variables:
+ digits_names -> .* \(kind 4\) char \*\[10\] .*
+#...
+ Header:
+#...
+ Parent name: .ctf
+#...
+ Variables:
+ digits_names -> .* \(kind 4\) char \*\[9\] .*
+#...
diff --git a/ld/testsuite/ld-ctf/array-extern.c b/ld/testsuite/ld-ctf/array-extern.c
new file mode 100644
index 0000000..730ba5a
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-extern.c
@@ -0,0 +1 @@
+extern char * digits_names[];
diff --git a/ld/testsuite/ld-ctf/array-extern.d b/ld/testsuite/ld-ctf/array-extern.d
new file mode 100644
index 0000000..4c9ce78
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-extern.d
@@ -0,0 +1,32 @@
+#as:
+#source: array-char.c
+#source: array-extern.c
+#objdump: --ctf
+#ld: -shared --ctf-variables --hash-style=sysv
+#name: Arrays (extern)
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+ Header:
+ Magic number: 0xdff2
+ Version: 4 \(CTF_VERSION_3\)
+#...
+ Data object section: .* \(0x[1-9a-f][0-9a-f]* bytes\)
+ Type section: .* \(0x44 bytes\)
+ String section: .*
+
+ Labels:
+
+ Data objects:
+ digits_names -> 0x[0-9a-f]*: \(kind 4\) char \*\[10\] .*
+
+ Function objects:
+
+ Variables:
+
+ Types:
+#...
+ 0x[0-9a-f]*: \(kind 4\) .*\[10\] \(size .*
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-typedefs.d b/ld/testsuite/ld-ctf/conflicting-typedefs.d
index 4ae8de4..beb1f77 100644
--- a/ld/testsuite/ld-ctf/conflicting-typedefs.d
+++ b/ld/testsuite/ld-ctf/conflicting-typedefs.d
@@ -15,8 +15,8 @@ Contents of CTF section .ctf:
#...
Types:
0x1: .*int .*
- 0x[0-9]:.*int .*
0x[0-9]: \(kind 10\) word .* -> 0x[0-9]: \(kind 1\) .*int \(format 0x1\) \(size 0x[0-9a-f]*\) \(aligned at 0x[0-9a-f]*\)
+ 0x[0-9]:.*int .*
Strings:
#...
diff --git a/libctf/ctf-dedup.c b/libctf/ctf-dedup.c
index b2fb0a1..cddf437 100644
--- a/libctf/ctf-dedup.c
+++ b/libctf/ctf-dedup.c
@@ -1502,12 +1502,17 @@ ctf_dedup_detect_name_ambiguity (ctf_dict_t *fp, ctf_dict_t **inputs)
the most-popular type on insertion, and we want conflicting structs
et al to have all forwards left intact, so the user is notified
that this type is conflicting. TODO: improve this in future by
- setting such forwards non-root-visible.) */
+ setting such forwards non-root-visible.)
+
+ If multiple distinct types are "most common", pick the one that
+ appears first on the link line, and within that, the one with the
+ lowest type ID. (See sort_output_mapping.) */
const void *key;
const void *count;
const char *hval;
long max_hcount = -1;
+ void *max_gid = NULL;
const char *max_hval = NULL;
if (ctf_dynhash_elements (name_counts) <= 1)
@@ -1517,10 +1522,24 @@ ctf_dedup_detect_name_ambiguity (ctf_dict_t *fp, ctf_dict_t **inputs)
while ((err = ctf_dynhash_cnext (name_counts, &j, &key, &count)) == 0)
{
hval = (const char *) key;
+
if ((long int) (uintptr_t) count > max_hcount)
{
max_hcount = (long int) (uintptr_t) count;
max_hval = hval;
+ max_gid = ctf_dynhash_lookup (d->cd_output_first_gid, hval);
+ }
+ else if ((long int) (uintptr_t) count == max_hcount)
+ {
+ void *gid = ctf_dynhash_lookup (d->cd_output_first_gid, hval);
+
+ if (CTF_DEDUP_GID_TO_INPUT(gid) < CTF_DEDUP_GID_TO_INPUT(max_gid)
+ || (CTF_DEDUP_GID_TO_INPUT(gid) == CTF_DEDUP_GID_TO_INPUT(max_gid)
+ && CTF_DEDUP_GID_TO_TYPE(gid) < CTF_DEDUP_GID_TO_TYPE(max_gid)))
+ {
+ max_hval = hval;
+ max_gid = ctf_dynhash_lookup (d->cd_output_first_gid, hval);
+ }
}
}
if (err != ECTF_NEXT_END)