gdb/doc/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Wed, 27 Apr 2011 20:03:04 +0000 (20:03 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Wed, 27 Apr 2011 20:03:04 +0000 (20:03 +0000)
* gdb.texinfo (Index Section Format): Change the version to 5.
Describe the different formula.

gdb/
Case insensitive lookups implementation.
* dwarf2read.c: Include ctype.h.
(struct mapped_index): New field version.
(mapped_index_string_hash): New parameter index_version.  New comment
for it.  Call tolower appropriately.
(find_slot_in_mapped_hash): New variable cmp, initialize it, use it.
Choose the right index version for mapped_index_string_hash.
(dwarf2_read_index): Support also the index version 5.  Initialize the
new struct mapped_index field version.
(hash_strtab_entry): Pass INT_MAX for the new parameter, explain why.
(find_slot): Explain the version needs.  Pass INT_MAX for the new
parameter.
(write_psymtabs_to_index): Produce version 5.
* minsyms.c (lookup_minimal_symbol): New variable cmp, initialize it,
use it.  New comment for SYMBOL_MATCHES_SEARCH_NAME.
* psymtab.c (lookup_partial_symbol): Find the
SYMBOL_MATCHES_SEARCH_NAME start of the found block of matching
entries.
* symtab.c (lookup_symbol_in_language): Remove the case_sensitive_off
NAME lowercasing.
(search_symbols): Pass REG_ICASE to regcomp for case_sensitive_off.
(completion_list_add_name): New variable ncmp, initialize it, use it.
* symtab.h (SYMBOL_HASH_NEXT): Always call tolower.
* utils.c (strcmp_iw): Support case_sensitive_off.
(strcmp_iw_ordered): Sort in a way compatible with case_sensitive_off.
New function comment part.  New variables saved_string1,
saved_string2 and case_pass.  Add a proper second pass.

gdb/testsuite/
* gdb.base/fortran-sym-case.c: New file.
* gdb.base/fortran-sym-case.exp: New file.
* gdb.dwarf2/dw2-case-insensitive-debug.S: New file.
* gdb.dwarf2/dw2-case-insensitive.c: New file.
* gdb.dwarf2/dw2-case-insensitive.exp: New file.

15 files changed:
gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/dwarf2read.c
gdb/minsyms.c
gdb/psymtab.c
gdb/symtab.c
gdb/symtab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/fortran-sym-case.c [new file with mode: 0644]
gdb/testsuite/gdb.base/fortran-sym-case.exp [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp [new file with mode: 0644]
gdb/utils.c

index beed476293c0876d45538ec9c4031f154aa266b2..d6e583541655b0f2aa6957d7c35c198913de6534 100644 (file)
@@ -1,3 +1,33 @@
+2011-04-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Case insensitive lookups implementation.
+       * dwarf2read.c: Include ctype.h.
+       (struct mapped_index): New field version.
+       (mapped_index_string_hash): New parameter index_version.  New comment
+       for it.  Call tolower appropriately.
+       (find_slot_in_mapped_hash): New variable cmp, initialize it, use it.
+       Choose the right index version for mapped_index_string_hash.
+       (dwarf2_read_index): Support also the index version 5.  Initialize the
+       new struct mapped_index field version.
+       (hash_strtab_entry): Pass INT_MAX for the new parameter, explain why.
+       (find_slot): Explain the version needs.  Pass INT_MAX for the new
+       parameter.
+       (write_psymtabs_to_index): Produce version 5.
+       * minsyms.c (lookup_minimal_symbol): New variable cmp, initialize it,
+       use it.  New comment for SYMBOL_MATCHES_SEARCH_NAME.
+       * psymtab.c (lookup_partial_symbol): Find the
+       SYMBOL_MATCHES_SEARCH_NAME start of the found block of matching
+       entries.
+       * symtab.c (lookup_symbol_in_language): Remove the case_sensitive_off
+       NAME lowercasing.
+       (search_symbols): Pass REG_ICASE to regcomp for case_sensitive_off.
+       (completion_list_add_name): New variable ncmp, initialize it, use it.
+       * symtab.h (SYMBOL_HASH_NEXT): Always call tolower.
+       * utils.c (strcmp_iw): Support case_sensitive_off.
+       (strcmp_iw_ordered): Sort in a way compatible with case_sensitive_off.
+       New function comment part.  New variables saved_string1,
+       saved_string2 and case_pass.  Add a proper second pass.
+
 2011-04-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Replace re_comp/re_exec by regcomp/regexec.
index aa3c89347f08c896c5e1f89cc6f9ed57f8221333..514d584782478a010f8017831a0cea42105b6d97 100644 (file)
@@ -1,3 +1,9 @@
+2011-04-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+           Eli Zaretskii  <eliz@gnu.org>
+
+       * gdb.texinfo (Index Section Format): Change the version to 5.
+       Describe the different formula.
+
 2011-04-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
            Eli Zaretskii  <eliz@gnu.org>
 
index 15ccf2ef0205309b430bb123c730f55156853708..ff5b7cb5f721efb0cf15a9526bd9a10bfd91495d 100644 (file)
@@ -36993,7 +36993,8 @@ unless otherwise noted:
 
 @enumerate
 @item
-The version number, currently 4.  Versions 1, 2 and 3 are obsolete.
+The version number, currently 5.  Versions 1, 2 and 3 are obsolete.
+Version 4 differs by its hashing function.
 
 @item
 The offset, from the start of the file, of the CU list.
@@ -37061,9 +37062,18 @@ valid index for both a string and a CU vector.
 The hash value for a table entry is computed by applying an
 iterative hash function to the symbol's name.  Starting with an
 initial value of @code{r = 0}, each (unsigned) character @samp{c} in
-the string is incorporated into the hash using the formula
-@code{r = r * 67 + c - 113}.  The terminating @samp{\0} is not
-incorporated into the hash.
+the string is incorporated into the hash using the formula depending on the
+index version:
+
+@table @asis
+@item Version 4
+The formula is @code{r = r * 67 + c - 113}.
+
+@item Version 5
+The formula is @code{r = r * 67 + tolower (c) - 113}.
+@end table
+
+The terminating @samp{\0} is not incorporated into the hash.
 
 The step size used in the hash table is computed via
 @code{((hash * 17) & (size - 1)) | 1}, where @samp{hash} is the hash
index 0ca9532f70ecf4c6270ecc582ae984d3ffc7c184..fdab83d649f68b400e9a46af04129d342580dc00 100644 (file)
@@ -149,6 +149,9 @@ DEF_VEC_I (offset_type);
    a comment by the code that writes the index.  */
 struct mapped_index
 {
+  /* Index data format version.  */
+  int version;
+
   /* The total length of the buffer.  */
   off_t total_size;
 
@@ -1972,17 +1975,23 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
    SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
    implementation.  This is necessary because the hash function is tied to the
    format of the mapped index file.  The hash values do not have to match with
-   SYMBOL_HASH_NEXT.  */
+   SYMBOL_HASH_NEXT.
+   
+   Use INT_MAX for INDEX_VERSION if you generate the current index format.  */
 
 static hashval_t
-mapped_index_string_hash (const void *p)
+mapped_index_string_hash (int index_version, const void *p)
 {
   const unsigned char *str = (const unsigned char *) p;
   hashval_t r = 0;
   unsigned char c;
 
   while ((c = *str++) != 0)
-    r = r * 67 + c - 113;
+    {
+      if (index_version >= 5)
+       c = tolower (c);
+      r = r * 67 + c - 113;
+    }
 
   return r;
 }
@@ -1998,6 +2007,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   offset_type hash;
   offset_type slot, step;
+  int (*cmp) (const char *, const char *);
 
   if (current_language->la_language == language_cplus
       || current_language->la_language == language_java
@@ -2020,9 +2030,17 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
        }
     }
 
-  hash = mapped_index_string_hash (name);
+  /* Index version 4 did not support case insensitive searches.  But the
+     indexes for case insensitive languages are built in lowercase, therefore
+     simulate our NAME being searched is also lowercased.  */
+  hash = mapped_index_string_hash ((index->version == 4
+                                    && case_sensitivity == case_sensitive_off
+                                   ? 5 : index->version),
+                                  name);
+
   slot = hash & (index->symbol_table_slots - 1);
   step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1;
+  cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
 
   for (;;)
     {
@@ -2036,7 +2054,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
        }
 
       str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]);
-      if (!strcmp (name, str))
+      if (!cmp (name, str))
        {
          *vec_out = (offset_type *) (index->constant_pool
                                      + MAYBE_SWAP (index->symbol_table[i + 1]));
@@ -2080,15 +2098,17 @@ dwarf2_read_index (struct objfile *objfile)
   /* Versions earlier than 3 emitted every copy of a psymbol.  This
      causes the index to behave very poorly for certain requests.  Version 3
      contained incomplete addrmap.  So, it seems better to just ignore such
-     indices.  */
+     indices.  Index version 4 uses a different hash function than index
+     version 5 and later.  */
   if (version < 4)
     return 0;
   /* Indexes with higher version than the one supported by GDB may be no
      longer backward compatible.  */
-  if (version > 4)
+  if (version > 5)
     return 0;
 
   map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+  map->version = version;
   map->total_size = dwarf2_per_objfile->gdb_index.size;
 
   metadata = (offset_type *) (addr + sizeof (offset_type));
@@ -15256,13 +15276,16 @@ struct strtab_entry
   const char *str;
 };
 
-/* Hash function for a strtab_entry.  */
+/* Hash function for a strtab_entry.
+
+   Function is used only during write_hash_table so no index format backward
+   compatibility is needed.  */
 
 static hashval_t
 hash_strtab_entry (const void *e)
 {
   const struct strtab_entry *entry = e;
-  return mapped_index_string_hash (entry->str);
+  return mapped_index_string_hash (INT_MAX, entry->str);
 }
 
 /* Equality function for a strtab_entry.  */
@@ -15400,12 +15423,15 @@ cleanup_mapped_symtab (void *p)
 }
 
 /* Find a slot in SYMTAB for the symbol NAME.  Returns a pointer to
-   the slot.  */
+   the slot.
+   
+   Function is used only during write_hash_table so no index format backward
+   compatibility is needed.  */
 
 static struct symtab_index_entry **
 find_slot (struct mapped_symtab *symtab, const char *name)
 {
-  offset_type index, step, hash = mapped_index_string_hash (name);
+  offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);
 
   index = hash & (symtab->size - 1);
   step = ((hash * 17) & (symtab->size - 1)) | 1;
@@ -15934,7 +15960,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
   total_len = size_of_contents;
 
   /* The version number.  */
-  val = MAYBE_SWAP (4);
+  val = MAYBE_SWAP (5);
   obstack_grow (&contents, &val, sizeof (val));
 
   /* The offset of the CU list from the start of the file.  */
index a2c5ebc0b1ded70d262d78fc27e41fe7fb55fe9f..249675bb3da1f76c3fc03c056072d1516ae3163d 100644 (file)
@@ -239,11 +239,16 @@ lookup_minimal_symbol (const char *name, const char *sfile,
 
                  if (pass == 1)
                    {
-                     match = strcmp (SYMBOL_LINKAGE_NAME (msymbol),
-                                     modified_name) == 0;
+                     int (*cmp) (const char *, const char *);
+
+                     cmp = (case_sensitivity == case_sensitive_on
+                            ? strcmp : strcasecmp);
+                     match = cmp (SYMBOL_LINKAGE_NAME (msymbol),
+                                  modified_name) == 0;
                    }
                  else
                    {
+                     /* The function respects CASE_SENSITIVITY.  */
                      match = SYMBOL_MATCHES_SEARCH_NAME (msymbol,
                                                          modified_name);
                    }
index 93a7ea26a1505caa93657055f94a6549ade7e185..ea690ef644969f6334314114dd11bc4310b2312a 100644 (file)
@@ -691,8 +691,15 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
        internal_error (__FILE__, __LINE__,
                        _("failed internal consistency check"));
 
-      while (top <= real_top
-            && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
+      /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
+        search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
+      while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
+       top--;
+
+      /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
+      top++;
+
+      while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
        {
          if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
                                     SYMBOL_DOMAIN (*top), domain))
index ebc822167ae45cb276e9e855b7cf957b0e10a3c9..f9e2bca8dbc97e534e1b8dd7374ad1df36e53c77 100644 (file)
@@ -1056,19 +1056,6 @@ lookup_symbol_in_language (const char *name, const struct block *block,
        }
     }
 
-  if (case_sensitivity == case_sensitive_off)
-    {
-      char *copy;
-      int len, i;
-
-      len = strlen (name);
-      copy = (char *) alloca (len + 1);
-      for (i= 0; i < len; i++)
-        copy[i] = tolower (name[i]);
-      copy[len] = 0;
-      modified_name = copy;
-    }
-
   returnval = lookup_symbol_aux (modified_name, block, domain, lang,
                                 is_a_field_of_this);
   do_cleanups (cleanup);
@@ -3069,7 +3056,9 @@ search_symbols (char *regexp, enum search_domain kind,
            }
        }
 
-      errcode = regcomp (&datum.preg, regexp, REG_NOSUB);
+      errcode = regcomp (&datum.preg, regexp,
+                        REG_NOSUB | (case_sensitivity == case_sensitive_off
+                                     ? REG_ICASE : 0));
       if (errcode != 0)
        {
          char *err = get_regcomp_error (errcode, &datum.preg);
@@ -3519,10 +3508,13 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len,
                          char *text, char *word)
 {
   int newsize;
+  int (*ncmp) (const char *, const char *, size_t);
+
+  ncmp = (case_sensitivity == case_sensitive_on ? strncmp : strncasecmp);
 
   /* Clip symbols that cannot match.  */
 
-  if (strncmp (symname, sym_text, sym_text_len) != 0)
+  if (ncmp (symname, sym_text, sym_text_len) != 0)
     {
       return;
     }
index e497bed376685e2dc9b09db3d4977e3b788ccdf2..29e7d703b9ed8a95fd009c6f061814a1343459e9 100644 (file)
@@ -1012,7 +1012,8 @@ extern unsigned int msymbol_hash (const char *);
    is only a GDB in-memory computed value with no external files compatibility
    requirements.  */
 
-#define SYMBOL_HASH_NEXT(hash, c) ((hash) * 67 + (c) - 113)
+#define SYMBOL_HASH_NEXT(hash, c) \
+  ((hash) * 67 + tolower ((unsigned char) (c)) - 113)
 
 extern struct objfile * msymbol_objfile (struct minimal_symbol *sym);
 
index 4aa5513f24a01499c6a92d3e937d6a5b4e5ad3a5..47ccf633b4e8289f7c4a74cf2f09d151ea4aa74a 100644 (file)
@@ -1,3 +1,11 @@
+2011-04-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * gdb.base/fortran-sym-case.c: New file.
+       * gdb.base/fortran-sym-case.exp: New file.
+       * gdb.dwarf2/dw2-case-insensitive-debug.S: New file.
+       * gdb.dwarf2/dw2-case-insensitive.c: New file.
+       * gdb.dwarf2/dw2-case-insensitive.exp: New file.
+
 2011-04-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * lib/gdb.exp (gdb_test_multiple): Eror on newline in $message.
diff --git a/gdb/testsuite/gdb.base/fortran-sym-case.c b/gdb/testsuite/gdb.base/fortran-sym-case.c
new file mode 100644 (file)
index 0000000..ffde268
--- /dev/null
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+main (int argc, char **aRGv)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/fortran-sym-case.exp b/gdb/testsuite/gdb.base/fortran-sym-case.exp
new file mode 100644 (file)
index 0000000..4b9cf76
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set testfile fortran-sym-case
+if { [prepare_for_testing ${testfile}.exp ${testfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test "set language fortran" {Warning: the current language does not match this frame\.}
+
+gdb_test "frame" ", aRGv=.*"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive-debug.S
new file mode 100644 (file)
index 0000000..5e4cd35
--- /dev/null
@@ -0,0 +1,102 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+       .section .debug_info
+.Lcu1_begin:
+       /* CU header */
+       .4byte  .Lcu1_end - .Lcu1_start         /* Length of Compilation Unit */
+.Lcu1_start:
+       .2byte  2                               /* DWARF Version */
+       .4byte  .Labbrev1_begin                 /* Offset into abbrev section */
+       .byte   4                               /* Pointer size */
+
+       /* CU die */
+       .uleb128 1                              /* Abbrev: DW_TAG_compile_unit */
+       .ascii  "file1.txt\0"                   /* DW_AT_name */
+       .ascii  "GNU C 3.3.3\0"                 /* DW_AT_producer */
+       .byte   8                               /* DW_AT_language (DW_LANG_Fortran90) */
+       .4byte          FUNC_lang               /* DW_AT_low_pc */
+       .4byte          main                    /* DW_AT_high_pc */
+
+       .uleb128        3                       /* Abbrev: DW_TAG_subprogram */
+       .byte           1                       /* DW_AT_external */
+       .ascii          "FUNC_lang\0"           /* DW_AT_name */
+       .4byte          FUNC_lang               /* DW_AT_low_pc */
+       .4byte          main                    /* DW_AT_high_pc */
+       .byte           1                       /* DW_AT_prototyped */
+       .4byte          .Ltype - .Lcu1_begin    /* DW_AT_type */
+
+.Ltype:
+       .uleb128        0x5                     /* Abbrev: DW_TAG_base_type */
+       .byte           0x4                     /* DW_AT_byte_size */
+       .byte           0x5                     /* DW_AT_encoding */
+       .ascii          "foo\0"                 /* DW_AT_name */
+
+       .byte           0                       /* End of children of CU */
+.Lcu1_end:
+
+/* Abbrev table */
+       .section .debug_abbrev
+.Labbrev1_begin:
+       .uleb128        1                       /* Abbrev code */
+       .uleb128        0x11                    /* DW_TAG_compile_unit */
+       .byte           1                       /* has_children */
+       .uleb128        0x3                     /* DW_AT_name */
+       .uleb128        0x8                     /* DW_FORM_string */
+       .uleb128        0x25                    /* DW_AT_producer */
+       .uleb128        0x8                     /* DW_FORM_string */
+       .uleb128        0x13                    /* DW_AT_language */
+       .uleb128        0xb                     /* DW_FORM_data1 */
+       .uleb128        0x11                    /* DW_AT_low_pc */
+       .uleb128        0x1                     /* DW_FORM_addr */
+       .uleb128        0x12                    /* DW_AT_high_pc */
+       .uleb128        0x1                     /* DW_FORM_addr */
+       .byte           0x0                     /* Terminator */
+       .byte           0x0                     /* Terminator */
+
+       .uleb128        3                       /* Abbrev code */
+       .uleb128        0x2e                    /* DW_TAG_subprogram */
+       .byte           0                       /* has_children */
+       .uleb128        0x3f                    /* DW_AT_external */
+       .uleb128        0xc                     /* DW_FORM_flag */
+       .uleb128        0x3                     /* DW_AT_name */
+       .uleb128        0x8                     /* DW_FORM_string */
+       .uleb128        0x11                    /* DW_AT_low_pc */
+       .uleb128        0x1                     /* DW_FORM_addr */
+       .uleb128        0x12                    /* DW_AT_high_pc */
+       .uleb128        0x1                     /* DW_FORM_addr */
+       .uleb128        0x27                    /* DW_AT_prototyped */
+       .uleb128        0xc                     /* DW_FORM_flag */
+       .uleb128        0x49                    /* DW_AT_type */
+       .uleb128        0x13                    /* DW_FORM_ref4 */
+       .byte           0x0                     /* Terminator */
+       .byte           0x0                     /* Terminator */
+
+       .uleb128        0x5                     /* Abbrev code */
+       .uleb128        0x24                    /* DW_TAG_base_type */
+       .byte           0x0                     /* DW_children_no */
+       .uleb128        0xb                     /* DW_AT_byte_size */
+       .uleb128        0xb                     /* DW_FORM_data1 */
+       .uleb128        0x3e                    /* DW_AT_encoding */
+       .uleb128        0xb                     /* DW_FORM_data1 */
+       .uleb128        0x3                     /* DW_AT_name */
+       .uleb128        0x8                     /* DW_FORM_string */
+       .byte           0x0                     /* Terminator */
+       .byte           0x0                     /* Terminator */
+
+       .byte           0x0                     /* Terminator */
+       .byte           0x0                     /* Terminator */
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.c
new file mode 100644 (file)
index 0000000..3be9c63
--- /dev/null
@@ -0,0 +1,38 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Use DW_LANG_Fortran90 for case insensitive DWARF.  */
+
+void
+FUNC_lang (void)
+{
+}
+
+/* Symbol is present only in ELF .symtab.  */
+
+void
+FUNC_symtab (void)
+{
+}
+
+int
+main (void)
+{
+  FUNC_lang ();
+  FUNC_symtab ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp b/gdb/testsuite/gdb.dwarf2/dw2-case-insensitive.exp
new file mode 100644 (file)
index 0000000..78dc818
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0  
+}
+
+set testfile "dw2-case-insensitive"
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.c ${testfile}-debug.S] {nodebug}] } {
+    return -1
+}
+
+gdb_test "show case-sensitive" {Case sensitivity in name search is "auto; currently on"\.}
+
+gdb_test "info functions fUnC_lang" \
+        "All functions matching regular expression \"fUnC_lang\":" \
+        "regexp case-sensitive on"
+
+gdb_test "set case-sensitive off" {warning: the current case sensitivity setting does not match the language\.}
+
+gdb_test "info functions fUnC_lang" \
+        "All functions matching regular expression \"fUnC_lang\":\[\r\n\]+File file1.txt:\r\nfoo FUNC_lang\\(void\\);" \
+        "regexp case-sensitive off"
+
+gdb_test "p fuNC_lang" { = {foo \(void\)} 0x[0-9a-f]+ <FUNC_lang>}
+gdb_test "p fuNC_symtab" { = {<text variable, no debug info>} 0x[0-9a-f]+ <FUNC_symtab>}
+
+if {[gdb_breakpoint "fuNC_lang"] == 1} {
+    pass "setting breakpoint at fuNC_lang"
+}
+
+if {[gdb_breakpoint "fuNC_symtab"] == 1} {
+    pass "setting breakpoint at fuNC_symtab"
+}
index 850b80dc1e4dab6a7f2dddc463370d8ca35c546d..a1dac63a181ebfca90d88e3077bf9e556294d76f 100644 (file)
@@ -2974,10 +2974,12 @@ strcmp_iw (const char *string1, const char *string2)
        {
          string2++;
        }
-      if (*string1 != *string2)
-       {
-         break;
-       }
+      if (case_sensitivity == case_sensitive_on && *string1 != *string2)
+       break;
+      if (case_sensitivity == case_sensitive_off
+         && (tolower ((unsigned char) *string1)
+             != tolower ((unsigned char) *string2)))
+       break;
       if (*string1 != '\0')
        {
          string1++;
@@ -2998,6 +3000,10 @@ strcmp_iw (const char *string1, const char *string2)
    strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
    where this function would put NAME.
 
+   This function must be neutral to the CASE_SENSITIVITY setting as the user
+   may choose it during later lookup.  Therefore this function always sorts
+   primarily case-insensitively and secondarily case-sensitively.
+
    Here are some examples of why using strcmp to sort is a bad idea:
 
    Whitespace example:
@@ -3023,8 +3029,10 @@ strcmp_iw (const char *string1, const char *string2)
 int
 strcmp_iw_ordered (const char *string1, const char *string2)
 {
-  /* Formatting stub.  */
-  if (1)
+  const char *saved_string1 = string1, *saved_string2 = string2;
+  enum case_sensitivity case_pass = case_sensitive_off;
+
+  for (;;)
     {
       /* C1 and C2 are valid only if *string1 != '\0' && *string2 != '\0'.
         Provide stub characters if we are already at the end of one of the
@@ -3038,8 +3046,17 @@ strcmp_iw_ordered (const char *string1, const char *string2)
          while (isspace (*string2))
            string2++;
 
+         switch (case_pass)
+         {
+           case case_sensitive_off:
+             c1 = tolower ((unsigned char) *string1);
+             c2 = tolower ((unsigned char) *string2);
+             break;
+           case case_sensitive_on:
              c1 = *string1;
              c2 = *string2;
+             break;
+         }
          if (c1 != c2)
            break;
 
@@ -3057,7 +3074,7 @@ strcmp_iw_ordered (const char *string1, const char *string2)
             comparison in the cases where one of them is '\0' or '('.  */
        case '\0':
          if (*string2 == '\0')
-           return 0;
+           break;
          else
            return -1;
        case '(':
@@ -3068,9 +3085,22 @@ strcmp_iw_ordered (const char *string1, const char *string2)
        default:
          if (*string2 == '\0' || *string2 == '(')
            return 1;
-         else
-           return c1 - c2;
+         else if (c1 > c2)
+           return 1;
+         else if (c1 < c2)
+           return -1;
+         /* PASSTHRU */
        }
+
+      if (case_pass == case_sensitive_on)
+       return 0;
+      
+      /* Otherwise the strings were equal in case insensitive way, make
+        a more fine grained comparison in a case sensitive way.  */
+
+      case_pass = case_sensitive_on;
+      string1 = saved_string1;
+      string2 = saved_string2;
     }
 }