This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Commit: _bfd_is_local_label_name: Include assembler local labels


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;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]