From b1fa9dd630eeb0a8282207cbbe399a25b2491412 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 24 Apr 2015 15:17:13 +0100 Subject: [PATCH] Extend test for local labels to include fake symbols and local labels with a numeric suffix. * elf.c (_bfd_elf_is_local_label_name): Extend test for assembler local labels to include local labels with a numeric suffix and fake symbols. --- bfd/ChangeLog | 6 ++++++ bfd/elf.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b3dcd0e..11a74de 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2015-04-24 Nick Clifton + + * elf.c (_bfd_elf_is_local_label_name): Extend test for assembler + local labels to include local labels with a numeric suffix and + fake symbols. + 2015-04-24 H.J. Lu PR binutils/18316 diff --git a/bfd/elf.c b/bfd/elf.c index 2ba43f4..dbdc474 100644 --- 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; } @@ -5370,7 +5370,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, { 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); @@ -7930,9 +7930,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; } -- 2.7.4