- /* 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;
+ }