[PATCH] elf: Avoid conflicts with local symbol names of "XXX.COUNT"
H.J. Lu
hjl.tools@gmail.com
Wed May 5 18:31:56 GMT 2021
On Wed, May 5, 2021 at 8:48 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> When appending ".COUNT" to duplicated local symbol names of "XXX",
> increment COUNT if there is an existing local symbol name of "XXX.COUNT".
>
> bfd/
>
> PR ld/27825
> * elflink.c (elf_link_output_symstrtab): Avoid conflicts with
> local symbol names of "XXX.COUNT".
>
> ld/
>
> PR ld/27825
> * testsuite/ld-elf/pr27825.d: New file.
> * testsuite/ld-elf/pr27825a.s: Likewise.
> * testsuite/ld-elf/pr27825b.s: Likewise.
> ---
> bfd/elflink.c | 31 ++++++++++++++++++++++++++++---
> ld/testsuite/ld-elf/pr27825.d | 18 ++++++++++++++++++
> ld/testsuite/ld-elf/pr27825a.s | 7 +++++++
> ld/testsuite/ld-elf/pr27825b.s | 5 +++++
> 4 files changed, 58 insertions(+), 3 deletions(-)
> create mode 100644 ld/testsuite/ld-elf/pr27825.d
> create mode 100644 ld/testsuite/ld-elf/pr27825a.s
> create mode 100644 ld/testsuite/ld-elf/pr27825b.s
>
> diff --git a/bfd/elflink.c b/bfd/elflink.c
> index cb38a025349..ac46585f0ab 100644
> --- a/bfd/elflink.c
> +++ b/bfd/elflink.c
> @@ -9845,22 +9845,47 @@ elf_link_output_symstrtab (void *finf,
> /* Append ".COUNT" to duplicated local symbols. */
> size_t count_len;
> size_t base_len = lh->size;
> - char buf[30];
> - sprintf (buf, "%lx", lh->count);
> + char buf[20];
> + if (snprintf (buf, sizeof (buf), "%lx", lh->count)
> + >= (int) sizeof (buf))
> + return 0;
> if (!base_len)
> {
> base_len = strlen (name);
> lh->size = base_len;
> }
> count_len = strlen (buf);
> + /* NB: Allocate the extra suffix buffer for possible
> + change. */
> versioned_name = bfd_alloc (flinfo->output_bfd,
> - base_len + count_len + 2);
> + base_len + sizeof (buf)
> + + 2);
> if (versioned_name == NULL)
> return 0;
> memcpy (versioned_name, name, base_len);
> versioned_name[base_len] = '.';
> memcpy (versioned_name + base_len + 1, buf,
> count_len + 1);
> + do
> + {
> + /* Avoid conflicts with local symbol names of
> + "XXX.COUNT". */
> + struct local_hash_entry *lvh
> + = (struct local_hash_entry *) bfd_hash_lookup
> + (&flinfo->local_hash_table, versioned_name,
> + false, false);
> + if (lvh == NULL)
> + break;
> + lh->count++;
> + if (snprintf (buf, sizeof (buf), "%lx",
> + lh->count) >= (int) sizeof (buf))
> + return 0;
> + count_len = strlen (buf);
> + /* NB: Use the existing suffix buffer. */
> + memcpy (versioned_name + base_len + 1, buf,
> + count_len + 1);
> + }
> + while (1);
> }
> lh->count++;
> break;
> diff --git a/ld/testsuite/ld-elf/pr27825.d b/ld/testsuite/ld-elf/pr27825.d
> new file mode 100644
> index 00000000000..da9832be850
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr27825.d
> @@ -0,0 +1,18 @@
> +#source: pr27825a.s
> +#source: pr27825b.s
> +#ld: -e _start --emit-relocs -z unique-symbol
> +#nm: --defined-only
> +
> +#...
> +[0-9a-f]+ t bar
> +#...
> +[0-9a-f]+ t bar.1
> +#...
> +[0-9a-f]+ t bar.1.1
> +#...
> +[0-9a-f]+ t bar.2
> +#...
> +[0-9a-f]+ t bar.2.1
> +#...
> +[0-9a-f]+ t bar.3
> +#pass
> diff --git a/ld/testsuite/ld-elf/pr27825a.s b/ld/testsuite/ld-elf/pr27825a.s
> new file mode 100644
> index 00000000000..e6940e17430
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr27825a.s
> @@ -0,0 +1,7 @@
> + .text
> + .globl _start
> +_start:
> +bar:
> +bar.1:
> +bar.2:
> + .nop
> diff --git a/ld/testsuite/ld-elf/pr27825b.s b/ld/testsuite/ld-elf/pr27825b.s
> new file mode 100644
> index 00000000000..2128e802d4b
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr27825b.s
> @@ -0,0 +1,5 @@
> + .text
> +bar:
> +bar.1:
> +bar.2:
> + .nop
> --
> 2.31.1
>
This scheme doesn't work.
--
H.J.
More information about the Binutils
mailing list