MIPS/Gas: Support .L/$ as the mark of local symbol
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Testing passed
|
Commit Message
In as.texi, there are lines:
A local symbol is any symbol beginning with certain local
label prefixes. By default, the local label prefix is
@samp{.L} for ELF systems or @samp{L} for traditional a.out
systems, but each target may have its own set of local
label prefixes.
Let's support it for MIPS:
1) For OldABI, GCC uses "$" to mark local symbols, and
for NewABI, ".L" is used. So let's support both for
OldABI, and ".L" only for NewABI.
2) Emit an fatal error, if a local symbol is used, while
not defined, just like LLVM does.
---
gas/config/tc-mips.c | 10 ++++++++++
1 file changed, 10 insertions(+)
Comments
YunQiang Su <syq@gcc.gnu.org> 于2024年2月5日周一 18:14写道:
>
> In as.texi, there are lines:
> A local symbol is any symbol beginning with certain local
> label prefixes. By default, the local label prefix is
> @samp{.L} for ELF systems or @samp{L} for traditional a.out
> systems, but each target may have its own set of local
> label prefixes.
>
> Let's support it for MIPS:
> 1) For OldABI, GCC uses "$" to mark local symbols, and
> for NewABI, ".L" is used. So let's support both for
> OldABI, and ".L" only for NewABI.
> 2) Emit an fatal error, if a local symbol is used, while
> not defined, just like LLVM does.
@Maciej W. Rozycki ping.
> ---
> gas/config/tc-mips.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
> index 43c12de2c8a..a84b13e1815 100644
> --- a/gas/config/tc-mips.c
> +++ b/gas/config/tc-mips.c
> @@ -17725,6 +17725,16 @@ pic_need_relax (symbolS *sym)
> if (symbol_section_p (sym))
> return true;
>
> + if (strstr (S_GET_NAME (sym), ".L") == S_GET_NAME (sym)
> + || ((mips_abi == O64_ABI || mips_abi == O32_ABI)
> + && strstr (S_GET_NAME (sym), "$") == S_GET_NAME (sym)))
> + {
> + if (!S_IS_DEFINED (sym))
> + as_fatal (_("undefined temporary symbol: %s"),
> + S_GET_NAME (sym));
> + return true;
> + }
> +
> symsec = S_GET_SEGMENT (sym);
>
> /* This must duplicate the test in adjust_reloc_syms. */
> --
> 2.39.2
>
On Mon, 5 Feb 2024, YunQiang Su wrote:
> In as.texi, there are lines:
> A local symbol is any symbol beginning with certain local
> label prefixes. By default, the local label prefix is
> @samp{.L} for ELF systems or @samp{L} for traditional a.out
> systems, but each target may have its own set of local
> label prefixes.
>
> Let's support it for MIPS:
> 1) For OldABI, GCC uses "$" to mark local symbols, and
> for NewABI, ".L" is used. So let's support both for
> OldABI, and ".L" only for NewABI.
> 2) Emit an fatal error, if a local symbol is used, while
> not defined, just like LLVM does.
I gather you want to avoid a case of an undefined reference making it to
output for a symbol whose name suggests its a local label, right?
But that seems like material for the generic part of GAS rather than the
MIPS backend only (and then specifically SVR4 PIC only and not non-PIC or
VxWorks, according to your code as submitted), so that all targets behave
consistently, and I can't see e.g. i386 GAS doing it.
So a question raises: what problem are you trying to solve? Can you give
us a piece of code that you think is handled incorrectly by GAS, and why?
Maciej
Maciej W. Rozycki <macro@orcam.me.uk> 于2024年2月21日周三 21:33写道:
>
> On Mon, 5 Feb 2024, YunQiang Su wrote:
>
> > In as.texi, there are lines:
> > A local symbol is any symbol beginning with certain local
> > label prefixes. By default, the local label prefix is
> > @samp{.L} for ELF systems or @samp{L} for traditional a.out
> > systems, but each target may have its own set of local
> > label prefixes.
> >
> > Let's support it for MIPS:
> > 1) For OldABI, GCC uses "$" to mark local symbols, and
> > for NewABI, ".L" is used. So let's support both for
> > OldABI, and ".L" only for NewABI.
> > 2) Emit an fatal error, if a local symbol is used, while
> > not defined, just like LLVM does.
>
> I gather you want to avoid a case of an undefined reference making it to
> output for a symbol whose name suggests its a local label, right?
>
> But that seems like material for the generic part of GAS rather than the
> MIPS backend only (and then specifically SVR4 PIC only and not non-PIC or
> VxWorks, according to your code as submitted), so that all targets behave
> consistently, and I can't see e.g. i386 GAS doing it.
>
> So a question raises: what problem are you trying to solve? Can you give
> us a piece of code that you think is handled incorrectly by GAS, and why?
>
main:
la $4,$hello
$ mipsel-linux-gnu-as -KPIC tt.s && objdump -dr a.out
00000000 <main>:
0: 8f840000 lw a0,0(gp)
0: R_MIPS_GOT16 $hello
In this case, GAS treat $hello as an external symbol, so only a single
R_MIPS_GOT16 is used.
> Maciej
On Wed, 21 Feb 2024, YunQiang Su wrote:
> > > In as.texi, there are lines:
> > > A local symbol is any symbol beginning with certain local
> > > label prefixes. By default, the local label prefix is
> > > @samp{.L} for ELF systems or @samp{L} for traditional a.out
> > > systems, but each target may have its own set of local
> > > label prefixes.
> > >
> > > Let's support it for MIPS:
> > > 1) For OldABI, GCC uses "$" to mark local symbols, and
> > > for NewABI, ".L" is used. So let's support both for
> > > OldABI, and ".L" only for NewABI.
> > > 2) Emit an fatal error, if a local symbol is used, while
> > > not defined, just like LLVM does.
> >
> > I gather you want to avoid a case of an undefined reference making it to
> > output for a symbol whose name suggests its a local label, right?
> >
> > But that seems like material for the generic part of GAS rather than the
> > MIPS backend only (and then specifically SVR4 PIC only and not non-PIC or
> > VxWorks, according to your code as submitted), so that all targets behave
> > consistently, and I can't see e.g. i386 GAS doing it.
> >
> > So a question raises: what problem are you trying to solve? Can you give
> > us a piece of code that you think is handled incorrectly by GAS, and why?
> >
>
> main:
> la $4,$hello
>
> $ mipsel-linux-gnu-as -KPIC tt.s && objdump -dr a.out
>
> 00000000 <main>:
> 0: 8f840000 lw a0,0(gp)
> 0: R_MIPS_GOT16 $hello
>
> In this case, GAS treat $hello as an external symbol, so only a single
> R_MIPS_GOT16 is used.
So that's indeed a waste of a GOT entry if `$hello' does end up local in
the link, but I fail to see it being a problem itself. It's no different
from where you have forced an ordinary symbol local via a linker script
really: it will have retained its individual GOT entry even though it
cannot be preempted anymore and could well use a shared entry with an
offset.
If you're concerned as to the piece of GAS documentation you quoted, then
refer to the paragraph that follows:
"Local symbols are defined and used within the assembler, but they are
normally not saved in object files. Thus, they are not visible when
debugging. You may use the `-L' option (see Section 2.7 [Include Local
Symbols], page 26) to retain the local symbols in the object files."
-- which clarifies that this is specifically about symbols automatically
produced internally by GAS for its own use, e.g. referring to `.' will
emit such a symbol. In addition to the prefix described in the previous
paragraph they use a non-printable character immediately following so as
to make sure they don't clash with a symbol provided by assembly code
supplied, cf. LOCAL_LABEL_CHAR.
Then symbols supplied by assembly code are interpreted according to their
attributes and an undefined symbol is necessarily global. If the supplier
of code produced non-compliant code, then the GIGO principle applies, GAS
just does what it's been told to, just as will say a C compiler when you
use a symbol from a reserved namespace in ordinary user code. Tools must
not stand in the way.
If you think a warning would be useful here, then I guess that might be
acceptable, but as I say that would have to go into a generic part of GAS.
Maciej
@@ -17725,6 +17725,16 @@ pic_need_relax (symbolS *sym)
if (symbol_section_p (sym))
return true;
+ if (strstr (S_GET_NAME (sym), ".L") == S_GET_NAME (sym)
+ || ((mips_abi == O64_ABI || mips_abi == O32_ABI)
+ && strstr (S_GET_NAME (sym), "$") == S_GET_NAME (sym)))
+ {
+ if (!S_IS_DEFINED (sym))
+ as_fatal (_("undefined temporary symbol: %s"),
+ S_GET_NAME (sym));
+ return true;
+ }
+
symsec = S_GET_SEGMENT (sym);
/* This must duplicate the test in adjust_reloc_syms. */