diff options
-rw-r--r-- | ld/testsuite/ld-ctf/array-char-conflicting-1.c | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/array-char-conflicting-2.c | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/array-conflicted-ordering.d | 26 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/array-extern.c | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/array-extern.d | 32 | ||||
-rw-r--r-- | ld/testsuite/ld-ctf/conflicting-typedefs.d | 2 | ||||
-rw-r--r-- | libctf/ctf-dedup.c | 21 |
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) |