This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Commit: _bfd_is_local_label_name: Include assembler local labels
- From: Nicholas Clifton <nickc at redhat dot com>
- To: Andreas Schwab <schwab at suse dot de>, "H.J. Lu" <hjl dot tools at gmail dot com>
- Cc: binutils at sourceware dot org
- Date: Wed, 08 Apr 2015 17:31:09 +0100
- Subject: Re: Commit: _bfd_is_local_label_name: Include assembler local labels
- Authentication-results: sourceware.org; auth=none
- References: <87384cck6h dot fsf at redhat dot com> <mvmr3rwf6o2 dot fsf at hawking dot suse dot de>
Hi Andreas, Hi H.J.,
>> + /* Treat assembler generated local labels as local. */
>> + if (name[0] == 'L' && name[strlen (name) - 1] < 32)
Do you have a testcase for this?
Not specifically for this feature, but lots of tests in the gas, ld and
binutils testsuites involve invoking this function.
I thought assembler generated local label
on ELF targets started with ".L", not "L".
Only if the target defines LOCAL_LABEL_PREFIX as '.'. Not all targets
do this. For targets that do define LOCAL_LABEL_PREFIX this way the
test at the start of _bfd_elf_is_local_label_name will have already
caught them.
Local/dollar labels have a trailing instance number after the ^B/^A.
Ah - I had not come across this before.
Whilst rechecking the patch, I also came across assembler generated fake
symbol names, which are also supposed to be treated as locals. So,
before I check it in, what do you guys think of this reworking of the
assembler local symbol patch ?
Cheers
Nick
diff --git a/bfd/elf.c b/bfd/elf.c
index 5fad4f1..b986a60 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7751,9 +7751,46 @@ _bfd_elf_is_local_label_name (bfd *abfd
ATTRIBUTE_UNUSED,
if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] ==
'_')
return TRUE;
- /* Treat assembler generated local labels as local. */
- if (name[0] == 'L' && name[strlen (name) - 1] < 32)
- return TRUE;
+ /* Treat assembler generated fake symbols, dollar local labels and
+ forward-backward labels (aka local labels) as locals.
+ These labels have the form:
+
+ L0^A.* (fake symbols)
+
+ [.]?L[0123456789]+{^A|^B}[0123456789]* (local labels)
+
+ Versions which start with .L will have already been matched above,
+ so we only need to match the rest. */
+ if (name[0] == 'L' && ISDIGIT (name[1]))
+ {
+ bfd_boolean ret = FALSE;
+ const char * p;
+ char c;
+
+ for (p = name + 2; (c = *p); p++)
+ {
+ if (c == 1 || c == 2)
+ {
+ if (c == 1 && p == name + 2)
+ /* A fake symbol. */
+ return TRUE;
+
+ /* FIXME: We are being paranoid here and treating symbols like
+ L0^Bfoo as if there were non-local, on the grounds that the
+ assembler will never generate them. But can any symbol
+ containing an ASCII value in the range 1-31 ever be anything
+ other than some kind of local ? */
+ ret = TRUE;
+ }
+
+ if (! ISDIGIT (c))
+ {
+ ret = FALSE;
+ break;
+ }
+ }
+ return ret;
+ }
return FALSE;
}