Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elf.c
index 85a4b6b348dc77547416bc709f1f45c83eca5519..619a640b275f3a51d91d4bfee2462b0e05b026df 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -342,7 +342,7 @@ bfd_elf_string_from_elf_section (bfd *abfd,
                              abfd, shindex);
          return NULL;
        }
-  
+
       if (bfd_elf_get_str_section (abfd, shindex) == NULL)
        return NULL;
     }
@@ -855,6 +855,31 @@ bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
   return elf_next_in_group (sec) != NULL;
 }
 
+static char *
+convert_debug_to_zdebug (bfd *abfd, const char *name)
+{
+  unsigned int len = strlen (name);
+  char *new_name = bfd_alloc (abfd, len + 2);
+  if (new_name == NULL)
+    return NULL;
+  new_name[0] = '.';
+  new_name[1] = 'z';
+  memcpy (new_name + 2, name + 1, len);
+  return new_name;
+}
+
+static char *
+convert_zdebug_to_debug (bfd *abfd, const char *name)
+{
+  unsigned int len = strlen (name);
+  char *new_name = bfd_alloc (abfd, len);
+  if (new_name == NULL)
+    return NULL;
+  new_name[0] = '.';
+  memcpy (new_name + 1, name + 2, len - 1);
+  return new_name;
+}
+
 /* Make a BFD section from an ELF section.  We store a pointer to the
    BFD section in the bfd_section field of the header.  */
 
@@ -1041,11 +1066,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
          || (name[1] == 'z' && name[7] == '_')))
     {
       enum { nothing, compress, decompress } action = nothing;
-      char *new_name;
       int compression_header_size;
+      bfd_size_type uncompressed_size;
       bfd_boolean compressed
        = bfd_is_section_compressed_with_header (abfd, newsect,
-                                                &compression_header_size);
+                                                &compression_header_size,
+                                                &uncompressed_size);
 
       if (compressed)
        {
@@ -1061,6 +1087,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
          if (newsect->size != 0
              && (abfd->flags & BFD_COMPRESS)
              && compression_header_size >= 0
+             && uncompressed_size > 0
              && (!compressed
                  || ((compression_header_size > 0)
                      != ((abfd->flags & BFD_COMPRESS_GABI) != 0))))
@@ -1090,42 +1117,26 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
            }
        }
 
-      new_name = NULL;
-      if (action == decompress
-          || (action == compress
-              && (abfd->flags & BFD_COMPRESS_GABI) != 0))
+      if (abfd->is_linker_input)
        {
-         if (name[1] == 'z')
+         if (name[1] == 'z'
+             && (action == decompress
+                 || (action == compress
+                     && (abfd->flags & BFD_COMPRESS_GABI) != 0)))
            {
-             unsigned int len = strlen (name);
-
-             new_name = bfd_alloc (abfd, len);
+             /* Convert section name from .zdebug_* to .debug_* so
+                that linker will consider this section as a debug
+                section.  */
+             char *new_name = convert_zdebug_to_debug (abfd, name);
              if (new_name == NULL)
                return FALSE;
-             new_name[0] = '.';
-             memcpy (new_name + 1, name + 2, len - 1);
+             bfd_rename_section (abfd, newsect, new_name);
            }
        }
-      else if (action == compress
-              && newsect->compress_status == COMPRESS_SECTION_DONE)
-       {
-         /* PR binutils/18087: Compression does not always make a section
-            smaller.  So only rename the section when compression has
-            actually taken place.  */
-         if (name[1] != 'z')
-           {
-             unsigned int len = strlen (name);
-
-             new_name = bfd_alloc (abfd, len + 2);
-             if (new_name == NULL)
-               return FALSE;
-             new_name[0] = '.';
-             new_name[1] = 'z';
-             memcpy (new_name + 2, name + 1, len);
-           }
-       }
-      if (new_name != NULL)
-       bfd_rename_section (abfd, newsect, new_name);
+      else
+       /* For objdump, don't rename the section.  For objcopy, delay
+          section rename to elf_fake_sections.  */
+       newsect->flags |= SEC_ELF_RENAME;
     }
 
   return TRUE;
@@ -2681,6 +2692,27 @@ _bfd_elf_single_rel_hdr (asection *sec)
     return elf_section_data (sec)->rela.hdr;
 }
 
+static bfd_boolean
+_bfd_elf_set_reloc_sh_name (bfd *abfd,
+                           Elf_Internal_Shdr *rel_hdr,
+                           const char *sec_name,
+                           bfd_boolean use_rela_p)
+{
+  char *name = (char *) bfd_alloc (abfd,
+                                  sizeof ".rela" + strlen (sec_name));
+  if (name == NULL)
+    return FALSE;
+
+  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", sec_name);
+  rel_hdr->sh_name =
+    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
+                                       FALSE);
+  if (rel_hdr->sh_name == (unsigned int) -1)
+    return FALSE;
+
+  return TRUE;
+}
+
 /* Allocate and initialize a section-header for a new reloc section,
    containing relocations against ASECT.  It is stored in RELDATA.  If
    USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
@@ -2689,11 +2721,11 @@ _bfd_elf_single_rel_hdr (asection *sec)
 static bfd_boolean
 _bfd_elf_init_reloc_shdr (bfd *abfd,
                          struct bfd_elf_section_reloc_data *reldata,
-                         asection *asect,
-                         bfd_boolean use_rela_p)
+                         const char *sec_name,
+                         bfd_boolean use_rela_p,
+                         bfd_boolean delay_st_name_p)
 {
   Elf_Internal_Shdr *rel_hdr;
-  char *name;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   bfd_size_type amt;
 
@@ -2702,15 +2734,10 @@ _bfd_elf_init_reloc_shdr (bfd *abfd,
   rel_hdr = bfd_zalloc (abfd, amt);
   reldata->hdr = rel_hdr;
 
-  amt = sizeof ".rela" + strlen (asect->name);
-  name = (char *) bfd_alloc (abfd, amt);
-  if (name == NULL)
-    return FALSE;
-  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
-  rel_hdr->sh_name =
-    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
-                                       FALSE);
-  if (rel_hdr->sh_name == (unsigned int) -1)
+  if (delay_st_name_p)
+    rel_hdr->sh_name = (unsigned int) -1;
+  else if (!_bfd_elf_set_reloc_sh_name (abfd, rel_hdr, sec_name,
+                                       use_rela_p))
     return FALSE;
   rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
   rel_hdr->sh_entsize = (use_rela_p
@@ -2753,6 +2780,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
   Elf_Internal_Shdr *this_hdr;
   unsigned int sh_type;
   const char *name = asect->name;
+  bfd_boolean delay_st_name_p = FALSE;
 
   if (arg->failed)
     {
@@ -2763,42 +2791,72 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 
   this_hdr = &esd->this_hdr;
 
-  /* For linking, compress DWARF debug sections with names: .debug_*.  */
-  if (arg->link_info
-      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
-      && (asect->flags & SEC_DEBUGGING)
-      && name[1] == 'd'
-      && name[6] == '_')
+  if (arg->link_info)
     {
-      /* Set SEC_ELF_COMPRESS to indicate this section should be
-        compressed.  */
-      asect->flags |= SEC_ELF_COMPRESS;
+      /* ld: compress DWARF debug sections with names: .debug_*.  */
+      if ((arg->link_info->compress_debug & COMPRESS_DEBUG)
+         && (asect->flags & SEC_DEBUGGING)
+         && name[1] == 'd'
+         && name[6] == '_')
+       {
+         /* Set SEC_ELF_COMPRESS to indicate this section should be
+            compressed.  */
+         asect->flags |= SEC_ELF_COMPRESS;
 
-      if (arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB)
+         /* If this section will be compressed, delay adding setion
+            name to section name section after it is compressed in
+            _bfd_elf_assign_file_positions_for_non_load.  */
+         delay_st_name_p = TRUE;
+       }
+    }
+  else if ((asect->flags & SEC_ELF_RENAME))
+    {
+      /* objcopy: rename output DWARF debug section.  */
+      if ((abfd->flags & (BFD_DECOMPRESS | BFD_COMPRESS_GABI)))
        {
-         /* If SHF_COMPRESSED isn't used, rename compressed DWARF
-            debug section to .zdebug_*.  */
-         unsigned int len = strlen (name);
-         char *new_name = bfd_alloc (abfd, len + 2);
+         /* When we decompress or compress with SHF_COMPRESSED,
+            convert section name from .zdebug_* to .debug_* if
+            needed.  */
+         if (name[1] == 'z')
+           {
+             char *new_name = convert_zdebug_to_debug (abfd, name);
+             if (new_name == NULL)
+               {
+                 arg->failed = TRUE;
+                 return;
+               }
+             name = new_name;
+           }
+       }
+      else if (asect->compress_status == COMPRESS_SECTION_DONE)
+       {
+         /* PR binutils/18087: Compression does not always make a
+            section smaller.  So only rename the section when
+            compression has actually taken place.  If input section
+            name is .zdebug_*, we should never compress it again.  */
+         char *new_name = convert_debug_to_zdebug (abfd, name);
          if (new_name == NULL)
            {
              arg->failed = TRUE;
              return;
            }
-         new_name[0] = '.';
-         new_name[1] = 'z';
-         memcpy (new_name + 2, name + 1, len);
-         bfd_rename_section (abfd, asect, new_name);
-         name = asect->name;
+         BFD_ASSERT (name[1] != 'z');
+         name = new_name;
        }
     }
 
-  this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-                                                         name, FALSE);
-  if (this_hdr->sh_name == (unsigned int) -1)
+  if (delay_st_name_p)
+    this_hdr->sh_name = (unsigned int) -1;
+  else
     {
-      arg->failed = TRUE;
-      return;
+      this_hdr->sh_name
+       = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+                                             name, FALSE);
+      if (this_hdr->sh_name == (unsigned int) -1)
+       {
+         arg->failed = TRUE;
+         return;
+       }
     }
 
   /* Don't clear sh_flags. Assembler may set additional bits.  */
@@ -2972,13 +3030,15 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
          && (arg->link_info->relocatable || arg->link_info->emitrelocations))
        {
          if (esd->rel.count && esd->rel.hdr == NULL
-             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
+             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name, FALSE,
+                                           delay_st_name_p))
            {
              arg->failed = TRUE;
              return;
            }
          if (esd->rela.count && esd->rela.hdr == NULL
-             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
+             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name, TRUE,
+                                           delay_st_name_p))
            {
              arg->failed = TRUE;
              return;
@@ -2987,8 +3047,9 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
       else if (!_bfd_elf_init_reloc_shdr (abfd,
                                          (asect->use_rela_p
                                           ? &esd->rela : &esd->rel),
-                                         asect,
-                                         asect->use_rela_p))
+                                         name,
+                                         asect->use_rela_p,
+                                         delay_st_name_p))
          arg->failed = TRUE;
     }
 
@@ -3173,7 +3234,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 {
   struct elf_obj_tdata *t = elf_tdata (abfd);
   asection *sec;
-  unsigned int section_number, secn;
+  unsigned int section_number;
   Elf_Internal_Shdr **i_shdrp;
   struct bfd_elf_section_data *d;
   bfd_boolean need_symtab;
@@ -3210,11 +3271,13 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 
       if (d->this_hdr.sh_type != SHT_GROUP)
        d->this_idx = section_number++;
-      _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
+      if (d->this_hdr.sh_name != (unsigned int) -1)
+       _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
       if (d->rel.hdr)
        {
          d->rel.idx = section_number++;
-         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
+         if (d->rel.hdr->sh_name != (unsigned int) -1)
+           _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
        }
       else
        d->rel.idx = 0;
@@ -3222,7 +3285,8 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       if (d->rela.hdr)
        {
          d->rela.idx = section_number++;
-         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
+         if (d->rela.hdr->sh_name != (unsigned int) -1)
+           _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
        }
       else
        d->rela.idx = 0;
@@ -3260,9 +3324,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       return FALSE;
     }
 
-  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
-  t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
-
   elf_numsections (abfd) = section_number;
   elf_elfheader (abfd)->e_shnum = section_number;
 
@@ -3478,12 +3539,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
        }
     }
 
-  for (secn = 1; secn < section_number; ++secn)
-    if (i_shdrp[secn] == NULL)
-      i_shdrp[secn] = i_shdrp[0];
-    else
-      i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
-                                                      i_shdrp[secn]->sh_name);
+  /* Delay setting sh_name to _bfd_elf_write_object_contents so that
+     _bfd_elf_assign_file_positions_for_non_load can convert DWARF
+     debug section name from .debug_* to .zdebug_* if needed.  */
+
   return TRUE;
 }
 
@@ -3740,7 +3799,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
   shstrtab_hdr->sh_entsize = 0;
   shstrtab_hdr->sh_link = 0;
   shstrtab_hdr->sh_info = 0;
-  /* sh_offset is set in assign_file_positions_except_relocs.  */
+  /* sh_offset is set in _bfd_elf_assign_file_positions_for_non_load.  */
   shstrtab_hdr->sh_addralign = 1;
 
   if (!assign_file_positions_except_relocs (abfd, link_info))
@@ -5101,7 +5160,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   Elf_Internal_Shdr **i_shdrpp;
-  Elf_Internal_Shdr **hdrpp;
+  Elf_Internal_Shdr **hdrpp, **end_hdrpp;
   Elf_Internal_Phdr *phdrs;
   Elf_Internal_Phdr *p;
   struct elf_segment_map *m;
@@ -5109,14 +5168,12 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
   bfd_vma filehdr_vaddr, filehdr_paddr;
   bfd_vma phdrs_vaddr, phdrs_paddr;
   file_ptr off;
-  unsigned int num_sec;
-  unsigned int i;
   unsigned int count;
 
   i_shdrpp = elf_elfsections (abfd);
-  num_sec = elf_numsections (abfd);
+  end_hdrpp = i_shdrpp + elf_numsections (abfd);
   off = elf_next_file_pos (abfd);
-  for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
+  for (hdrpp = i_shdrpp + 1; hdrpp < end_hdrpp; hdrpp++)
     {
       Elf_Internal_Shdr *hdr;
 
@@ -5152,7 +5209,8 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
                   /* Compress DWARF debug sections.  */
               || hdr == i_shdrpp[elf_onesymtab (abfd)]
               || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
-              || hdr == i_shdrpp[elf_strtab_sec (abfd)])
+              || hdr == i_shdrpp[elf_strtab_sec (abfd)]
+              || hdr == i_shdrpp[elf_shstrtab_sec (abfd)])
        hdr->sh_offset = -1;
       else
        off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
@@ -5308,13 +5366,14 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
        }
       else if (m->count != 0)
        {
+         unsigned int i;
          if (p->p_type != PT_LOAD
              && (p->p_type != PT_NOTE
                  || bfd_get_format (abfd) != bfd_core))
            {
              if (m->includes_filehdr || m->includes_phdrs)
                {
-                 /* PR 17512: file: 2195325e.  */ 
+                 /* PR 17512: file: 2195325e.  */
                  (*_bfd_error_handler)
                    (_("%B: warning: non-load segment includes file header and/or program header"),
                     abfd);
@@ -5404,7 +5463,8 @@ assign_file_positions_except_relocs (bfd *abfd,
                  /* Compress DWARF debug sections.  */
              || i == elf_onesymtab (abfd)
              || i == elf_symtab_shndx (abfd)
-             || i == elf_strtab_sec (abfd))
+             || i == elf_strtab_sec (abfd)
+             || i == elf_shstrtab_sec (abfd))
            {
              hdr->sh_offset = -1;
            }
@@ -5559,36 +5619,70 @@ static bfd_boolean
 _bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
 {
   file_ptr off;
-  unsigned int i, num_sec;
-  Elf_Internal_Shdr **shdrpp;
+  Elf_Internal_Shdr **shdrpp, **end_shdrpp;
+  Elf_Internal_Shdr *shdrp;
   Elf_Internal_Ehdr *i_ehdrp;
   const struct elf_backend_data *bed;
 
   off = elf_next_file_pos (abfd);
 
-  num_sec = elf_numsections (abfd);
-  for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
+  shdrpp = elf_elfsections (abfd);
+  end_shdrpp = shdrpp + elf_numsections (abfd);
+  for (shdrpp++; shdrpp < end_shdrpp; shdrpp++)
     {
-      Elf_Internal_Shdr *shdrp;
-
       shdrp = *shdrpp;
       if (shdrp->sh_offset == -1)
        {
+         asection *sec = shdrp->bfd_section;
          bfd_boolean is_rel = (shdrp->sh_type == SHT_REL
                                || shdrp->sh_type == SHT_RELA);
          if (is_rel
-             || (shdrp->bfd_section != NULL
-                 && (shdrp->bfd_section->flags & SEC_ELF_COMPRESS)))
+             || (sec != NULL && (sec->flags & SEC_ELF_COMPRESS)))
            {
              if (!is_rel)
                {
+                 const char *name = sec->name;
+                 struct bfd_elf_section_data *d;
+
                  /* Compress DWARF debug sections.  */
-                 if (!bfd_compress_section (abfd, shdrp->bfd_section,
+                 if (!bfd_compress_section (abfd, sec,
                                             shdrp->contents))
                    return FALSE;
+
+                 if (sec->compress_status == COMPRESS_SECTION_DONE
+                     && (abfd->flags & BFD_COMPRESS_GABI) == 0)
+                   {
+                     /* If section is compressed with zlib-gnu, convert
+                        section name from .debug_* to .zdebug_*.  */
+                     char *new_name
+                       = convert_debug_to_zdebug (abfd, name);
+                     if (new_name == NULL)
+                       return FALSE;
+                     name = new_name;
+                   }
+                 /* Add setion name to section name section.  */
+                 if (shdrp->sh_name != (unsigned int) -1)
+                   abort ();
+                 shdrp->sh_name
+                   = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+                                                         name, FALSE);
+                 d = elf_section_data (sec);
+
+                 /* Add reloc setion name to section name section.  */
+                 if (d->rel.hdr
+                     && !_bfd_elf_set_reloc_sh_name (abfd,
+                                                     d->rel.hdr,
+                                                     name, FALSE))
+                   return FALSE;
+                 if (d->rela.hdr
+                     && !_bfd_elf_set_reloc_sh_name (abfd,
+                                                     d->rela.hdr,
+                                                     name, FALSE))
+                   return FALSE;
+
                  /* Update section size and contents.  */
-                 shdrp->sh_size = shdrp->bfd_section->size;
-                 shdrp->contents = shdrp->bfd_section->contents;
+                 shdrp->sh_size = sec->size;
+                 shdrp->contents = sec->contents;
                  shdrp->bfd_section->contents = NULL;
                }
              off = _bfd_elf_assign_file_position_for_section (shdrp,
@@ -5598,7 +5692,14 @@ _bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
        }
     }
 
-/* Place the section headers.  */
+  /* Place section name section after DWARF debug sections have been
+     compressed.  */
+  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
+  shdrp = &elf_tdata (abfd)->shstrtab_hdr;
+  shdrp->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
+  off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
+
+  /* Place the section headers.  */
   i_ehdrp = elf_elfheader (abfd);
   bed = get_elf_backend_data (abfd);
   off = align_file_position (off, 1 << bed->s->log_file_align);
@@ -5636,6 +5737,9 @@ _bfd_elf_write_object_contents (bfd *abfd)
   num_sec = elf_numsections (abfd);
   for (count = 1; count < num_sec; count++)
     {
+      i_shdrp[count]->sh_name
+       = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
+                                 i_shdrp[count]->sh_name);
       if (bed->elf_backend_section_processing)
        (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
       if (i_shdrp[count]->contents)
@@ -7829,9 +7933,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;
 }
This page took 0.031135 seconds and 4 git commands to generate.