patches/binutils/2.16.1/130-callahan.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Fri Jul 25 14:08:03 2008 +0000 (2008-07-25)
changeset 722 37968404e9b9
permissions -rw-r--r--
When dumping the DokuWiki table of samples, don't leave the kernel headers version empty if using a custom headers set., and say so.

/trunk/scripts/showSamples.sh | 6 5 1 0 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
yann@402
     1
Signed-off-by: dank@kegel.com
yann@402
     2
Fixes ld speed issue. 
yann@402
     3
See http://weblogs.mozillazine.org/roc/archives/2005/02/optimizing_gnu.html
yann@402
     4
See thread "Re: optimizations for 3x speedup in ld",
yann@402
     5
http://sources.redhat.com/ml/binutils/2005-03/msg00847.html
yann@402
     6
yann@402
     7
Wildcard section matching enhancement, backported from the binutils CVS tree.
yann@402
     8
Here's the CVS log comment from the original change to ldlang.c:
yann@402
     9
yann@402
    10
revision 1.177
yann@402
    11
date: 2005/04/06 15:33:02;  author: jakub;  state: Exp;  lines: +438 -51
yann@402
    12
2005-04-06  Jakub Jelinek  <jakub@redhat.com>
yann@402
    13
yann@402
    14
        * ldlang.c: Formatting.
yann@402
    15
        (walk_wild_consider_section): Remember return value from wildcardp.
yann@402
    16
        (is_simple_wild): Use strcspn instead of 2 strpbrk calls and strlen.
yann@402
    17
        (wild_spec_can_overlap): Use strcspn instead of strpbrk and strlen.
yann@402
    18
yann@402
    19
2005-04-06  Robert O'Callahan  <rocallahan@novell.com>
yann@402
    20
yann@402
    21
        * ld.h (lean_section_userdata_type): Remove.
yann@402
    22
        (fat_section_userdata_type): Remove file field.
yann@402
    23
        (SECTION_USERDATA_SIZE): Remove.
yann@402
    24
        * ldlang.c (init_os): Eliminate initialization of unused
yann@402
    25
        lean_section_userdata_type.
yann@402
    26
yann@402
    27
        * ldlang.h (callback_t, walk_wild_section_handler_t): New
yann@402
    28
        typedefs.
yann@402
    29
        (struct lang_wild_statement_struct): Add walk_wild_section_handler
yann@402
    30
        and handler_data fields.
yann@402
    31
        * ldlang.c (callback_t): Removed.
yann@402
    32
        (walk_wild_consider_section, walk_wild_section_general,
yann@402
    33
        section_iterator_callback, find_section, is_simple_wild,
yann@402
    34
        match_simple_wild, walk_wild_section_specs1_wild0,
yann@402
    35
        walk_wild_section_specs1_wild1, walk_wild_section_specs2_wild1,
yann@402
    36
        walk_wild_section_specs3_wild2, walk_wild_section_specs4_wild2,
yann@402
    37
        wild_spec_can_overlap, analyze_walk_wild_section_handler): New
yann@402
    38
        functions.
yann@402
    39
        (lang_add_wild): Call analyze_walk_wild_section_handler.
yann@402
    40
        (walk_wild_section): Renamed to walk_wild_section_general and
yann@402
    41
        created a wrapper function.
yann@402
    42
        (section_iterator_callback_data): New typedef.
yann@402
    43
yann@402
    44
yann@402
    45
Index: src/ld/ld.h
yann@402
    46
===================================================================
yann@402
    47
RCS file: /cvs/src/src/ld/ld.h,v
yann@402
    48
retrieving revision 1.26
yann@402
    49
retrieving revision 1.27
yann@402
    50
diff -u -r1.26 -r1.27
yann@402
    51
--- binutils/ld/ld.h.old	16 Mar 2005 21:52:42 -0000	1.26
yann@402
    52
+++ binutils/ld/ld.h	6 Apr 2005 15:33:02 -0000	1.27
yann@402
    53
@@ -1,6 +1,6 @@
yann@402
    54
 /* ld.h -- general linker header file
yann@402
    55
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
yann@402
    56
-   2001, 2002, 2003, 2004
yann@402
    57
+   2001, 2002, 2003, 2004, 2005
yann@402
    58
    Free Software Foundation, Inc.
yann@402
    59
 
yann@402
    60
    This file is part of GLD, the Gnu Linker.
yann@402
    61
@@ -89,28 +89,15 @@
yann@402
    62
   struct map_symbol_def *next;
yann@402
    63
 };
yann@402
    64
 
yann@402
    65
-/* Extra information we hold on sections */
yann@402
    66
-typedef struct lean_user_section_struct {
yann@402
    67
-  /* For output sections: pointer to the section where this data will go.  */
yann@402
    68
-  struct lang_input_statement_struct *file;
yann@402
    69
-} lean_section_userdata_type;
yann@402
    70
-
yann@402
    71
 /* The initial part of fat_user_section_struct has to be idential with
yann@402
    72
    lean_user_section_struct.  */
yann@402
    73
 typedef struct fat_user_section_struct {
yann@402
    74
-  /* For output sections: pointer to the section where this data will go.  */
yann@402
    75
-  struct lang_input_statement_struct *file;
yann@402
    76
   /* For input sections, when writing a map file: head / tail of a linked
yann@402
    77
      list of hash table entries for symbols defined in this section.  */
yann@402
    78
   struct map_symbol_def *map_symbol_def_head;
yann@402
    79
   struct map_symbol_def **map_symbol_def_tail;
yann@402
    80
 } fat_section_userdata_type;
yann@402
    81
 
yann@402
    82
-#define SECTION_USERDATA_SIZE \
yann@402
    83
- (command_line.reduce_memory_overheads \
yann@402
    84
-  ? sizeof (lean_section_userdata_type) \
yann@402
    85
-  : sizeof (fat_section_userdata_type))
yann@402
    86
-
yann@402
    87
 #define get_userdata(x) ((x)->userdata)
yann@402
    88
 
yann@402
    89
 #define BYTE_SIZE	(1)
yann@402
    90
Index: src/ld/ldlang.c
yann@402
    91
===================================================================
yann@402
    92
RCS file: /cvs/src/src/ld/ldlang.c,v
yann@402
    93
retrieving revision 1.176
yann@402
    94
retrieving revision 1.177
yann@402
    95
diff -u -r1.176 -r1.177
yann@402
    96
--- binutils/ld/ldlang.c.old	18 Mar 2005 13:56:26 -0000	1.176
yann@402
    97
+++ binutils/ld/ldlang.c	6 Apr 2005 15:33:02 -0000	1.177
yann@402
    98
@@ -84,9 +84,6 @@
yann@402
    99
 static void lang_record_phdrs (void);
yann@402
   100
 static void lang_do_version_exports_section (void);
yann@402
   101
 
yann@402
   102
-typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
yann@402
   103
-			    asection *, lang_input_statement_type *, void *);
yann@402
   104
-
yann@402
   105
 /* Exported variables.  */
yann@402
   106
 lang_output_section_statement_type *abs_output_section;
yann@402
   107
 lang_statement_list_type lang_output_section_statement;
yann@402
   108
@@ -155,21 +152,71 @@
yann@402
   109
 
yann@402
   110
 /* Generic traversal routines for finding matching sections.  */
yann@402
   111
 
yann@402
   112
+/* Try processing a section against a wildcard.  This just calls
yann@402
   113
+   the callback unless the filename exclusion list is present
yann@402
   114
+   and excludes the file.  It's hardly ever present so this
yann@402
   115
+   function is very fast.  */
yann@402
   116
+
yann@402
   117
+static void
yann@402
   118
+walk_wild_consider_section (lang_wild_statement_type *ptr,
yann@402
   119
+			    lang_input_statement_type *file,
yann@402
   120
+			    asection *s,
yann@402
   121
+			    struct wildcard_list *sec,
yann@402
   122
+			    callback_t callback,
yann@402
   123
+			    void *data)
yann@402
   124
+{
yann@402
   125
+  bfd_boolean skip = FALSE;
yann@402
   126
+  struct name_list *list_tmp;
yann@402
   127
+
yann@402
   128
+  /* Don't process sections from files which were
yann@402
   129
+     excluded.  */
yann@402
   130
+  for (list_tmp = sec->spec.exclude_name_list;
yann@402
   131
+       list_tmp;
yann@402
   132
+       list_tmp = list_tmp->next)
yann@402
   133
+    {
yann@402
   134
+      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
yann@402
   135
+      if (is_wildcard)
yann@402
   136
+	skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
yann@402
   137
+      else
yann@402
   138
+	skip = strcmp (list_tmp->name, file->filename) == 0;
yann@402
   139
+
yann@402
   140
+      /* If this file is part of an archive, and the archive is
yann@402
   141
+	 excluded, exclude this file.  */
yann@402
   142
+      if (! skip && file->the_bfd != NULL
yann@402
   143
+	  && file->the_bfd->my_archive != NULL
yann@402
   144
+	  && file->the_bfd->my_archive->filename != NULL)
yann@402
   145
+	{
yann@402
   146
+	  if (is_wildcard)
yann@402
   147
+	    skip = fnmatch (list_tmp->name,
yann@402
   148
+			    file->the_bfd->my_archive->filename,
yann@402
   149
+			    0) == 0;
yann@402
   150
+	  else
yann@402
   151
+	    skip = strcmp (list_tmp->name,
yann@402
   152
+			   file->the_bfd->my_archive->filename) == 0;
yann@402
   153
+	}
yann@402
   154
+
yann@402
   155
+      if (skip)
yann@402
   156
+	break;
yann@402
   157
+    }
yann@402
   158
+
yann@402
   159
+  if (!skip)
yann@402
   160
+    (*callback) (ptr, sec, s, file, data);
yann@402
   161
+}
yann@402
   162
+
yann@402
   163
+/* Lowest common denominator routine that can handle everything correctly,
yann@402
   164
+   but slowly.  */
yann@402
   165
+
yann@402
   166
 static void
yann@402
   167
-walk_wild_section (lang_wild_statement_type *ptr,
yann@402
   168
-		   lang_input_statement_type *file,
yann@402
   169
-		   callback_t callback,
yann@402
   170
-		   void *data)
yann@402
   171
+walk_wild_section_general (lang_wild_statement_type *ptr,
yann@402
   172
+			   lang_input_statement_type *file,
yann@402
   173
+			   callback_t callback,
yann@402
   174
+			   void *data)
yann@402
   175
 {
yann@402
   176
   asection *s;
yann@402
   177
-
yann@402
   178
-  if (file->just_syms_flag)
yann@402
   179
-    return;
yann@402
   180
+  struct wildcard_list *sec;
yann@402
   181
 
yann@402
   182
   for (s = file->the_bfd->sections; s != NULL; s = s->next)
yann@402
   183
     {
yann@402
   184
-      struct wildcard_list *sec;
yann@402
   185
-
yann@402
   186
       sec = ptr->section_list;
yann@402
   187
       if (sec == NULL)
yann@402
   188
 	(*callback) (ptr, sec, s, file, data);
yann@402
   189
@@ -177,39 +224,8 @@
yann@402
   190
       while (sec != NULL)
yann@402
   191
 	{
yann@402
   192
 	  bfd_boolean skip = FALSE;
yann@402
   193
-	  struct name_list *list_tmp;
yann@402
   194
 
yann@402
   195
-	  /* Don't process sections from files which were
yann@402
   196
-	     excluded.  */
yann@402
   197
-	  for (list_tmp = sec->spec.exclude_name_list;
yann@402
   198
-	       list_tmp;
yann@402
   199
-	       list_tmp = list_tmp->next)
yann@402
   200
-	    {
yann@402
   201
-	      if (wildcardp (list_tmp->name))
yann@402
   202
-		skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
yann@402
   203
-	      else
yann@402
   204
-		skip = strcmp (list_tmp->name, file->filename) == 0;
yann@402
   205
-
yann@402
   206
-	      /* If this file is part of an archive, and the archive is
yann@402
   207
-		 excluded, exclude this file.  */
yann@402
   208
-	      if (! skip && file->the_bfd != NULL
yann@402
   209
-		  && file->the_bfd->my_archive != NULL
yann@402
   210
-		  && file->the_bfd->my_archive->filename != NULL)
yann@402
   211
-		{
yann@402
   212
-		  if (wildcardp (list_tmp->name))
yann@402
   213
-		    skip = fnmatch (list_tmp->name,
yann@402
   214
-				    file->the_bfd->my_archive->filename,
yann@402
   215
-				    0) == 0;
yann@402
   216
-		  else
yann@402
   217
-		    skip = strcmp (list_tmp->name,
yann@402
   218
-				   file->the_bfd->my_archive->filename) == 0;
yann@402
   219
-		}
yann@402
   220
-
yann@402
   221
-	      if (skip)
yann@402
   222
-		break;
yann@402
   223
-	    }
yann@402
   224
-
yann@402
   225
-	  if (!skip && sec->spec.name != NULL)
yann@402
   226
+	  if (sec->spec.name != NULL)
yann@402
   227
 	    {
yann@402
   228
 	      const char *sname = bfd_get_section_name (file->the_bfd, s);
yann@402
   229
 
yann@402
   230
@@ -220,13 +236,381 @@
yann@402
   231
 	    }
yann@402
   232
 
yann@402
   233
 	  if (!skip)
yann@402
   234
-	    (*callback) (ptr, sec, s, file, data);
yann@402
   235
+	    walk_wild_consider_section (ptr, file, s, sec, callback, data);
yann@402
   236
 
yann@402
   237
 	  sec = sec->next;
yann@402
   238
 	}
yann@402
   239
     }
yann@402
   240
 }
yann@402
   241
 
yann@402
   242
+/* Routines to find a single section given its name.  If there's more
yann@402
   243
+   than one section with that name, we report that.  */
yann@402
   244
+
yann@402
   245
+typedef struct
yann@402
   246
+{
yann@402
   247
+  asection *found_section;
yann@402
   248
+  bfd_boolean multiple_sections_found;
yann@402
   249
+} section_iterator_callback_data;
yann@402
   250
+
yann@402
   251
+static bfd_boolean
yann@402
   252
+section_iterator_callback (bfd *bfd ATTRIBUTE_UNUSED, asection *s, void *data)
yann@402
   253
+{
yann@402
   254
+  section_iterator_callback_data *d = data;
yann@402
   255
+
yann@402
   256
+  if (d->found_section != NULL)
yann@402
   257
+    {
yann@402
   258
+      d->multiple_sections_found = TRUE;
yann@402
   259
+      return TRUE;
yann@402
   260
+    }
yann@402
   261
+
yann@402
   262
+  d->found_section = s;
yann@402
   263
+  return FALSE;
yann@402
   264
+}
yann@402
   265
+
yann@402
   266
+static asection *
yann@402
   267
+find_section (lang_input_statement_type *file,
yann@402
   268
+	      struct wildcard_list *sec,
yann@402
   269
+	      bfd_boolean *multiple_sections_found)
yann@402
   270
+{
yann@402
   271
+  section_iterator_callback_data cb_data = { NULL, FALSE };
yann@402
   272
+
yann@402
   273
+  bfd_get_section_by_name_if (file->the_bfd, sec->spec.name, 
yann@402
   274
+			      section_iterator_callback, &cb_data);
yann@402
   275
+  *multiple_sections_found = cb_data.multiple_sections_found;
yann@402
   276
+  return cb_data.found_section;
yann@402
   277
+}
yann@402
   278
+
yann@402
   279
+/* Code for handling simple wildcards without going through fnmatch,
yann@402
   280
+   which can be expensive because of charset translations etc.  */
yann@402
   281
+
yann@402
   282
+/* A simple wild is a literal string followed by a single '*',
yann@402
   283
+   where the literal part is at least 4 characters long.  */
yann@402
   284
+
yann@402
   285
+static bfd_boolean
yann@402
   286
+is_simple_wild (const char *name)
yann@402
   287
+{
yann@402
   288
+  size_t len = strcspn (name, "*?[");
yann@402
   289
+  return len >= 4 && name[len] == '*' && name[len + 1] == '\0';
yann@402
   290
+}
yann@402
   291
+
yann@402
   292
+static bfd_boolean
yann@402
   293
+match_simple_wild (const char *pattern, const char *name)
yann@402
   294
+{
yann@402
   295
+  /* The first four characters of the pattern are guaranteed valid
yann@402
   296
+     non-wildcard characters.  So we can go faster.  */
yann@402
   297
+  if (pattern[0] != name[0] || pattern[1] != name[1]
yann@402
   298
+      || pattern[2] != name[2] || pattern[3] != name[3])
yann@402
   299
+    return FALSE;
yann@402
   300
+
yann@402
   301
+  pattern += 4;
yann@402
   302
+  name += 4;
yann@402
   303
+  while (*pattern != '*')
yann@402
   304
+    if (*name++ != *pattern++)
yann@402
   305
+      return FALSE;
yann@402
   306
+
yann@402
   307
+  return TRUE;
yann@402
   308
+}
yann@402
   309
+
yann@402
   310
+/* Specialized, optimized routines for handling different kinds of
yann@402
   311
+   wildcards */
yann@402
   312
+
yann@402
   313
+static void
yann@402
   314
+walk_wild_section_specs1_wild0 (lang_wild_statement_type *ptr,
yann@402
   315
+				lang_input_statement_type *file,
yann@402
   316
+				callback_t callback,
yann@402
   317
+				void *data)
yann@402
   318
+{
yann@402
   319
+  /* We can just do a hash lookup for the section with the right name.
yann@402
   320
+     But if that lookup discovers more than one section with the name
yann@402
   321
+     (should be rare), we fall back to the general algorithm because
yann@402
   322
+     we would otherwise have to sort the sections to make sure they
yann@402
   323
+     get processed in the bfd's order.  */
yann@402
   324
+  bfd_boolean multiple_sections_found;
yann@402
   325
+  struct wildcard_list *sec0 = ptr->handler_data[0];
yann@402
   326
+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
yann@402
   327
+
yann@402
   328
+  if (multiple_sections_found)
yann@402
   329
+    walk_wild_section_general (ptr, file, callback, data);
yann@402
   330
+  else if (s0)
yann@402
   331
+    walk_wild_consider_section (ptr, file, s0, sec0, callback, data);
yann@402
   332
+}
yann@402
   333
+
yann@402
   334
+static void
yann@402
   335
+walk_wild_section_specs1_wild1 (lang_wild_statement_type *ptr,
yann@402
   336
+				lang_input_statement_type *file,
yann@402
   337
+				callback_t callback,
yann@402
   338
+				void *data)
yann@402
   339
+{
yann@402
   340
+  asection *s;
yann@402
   341
+  struct wildcard_list *wildsec0 = ptr->handler_data[0];
yann@402
   342
+
yann@402
   343
+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
yann@402
   344
+    {
yann@402
   345
+      const char *sname = bfd_get_section_name (file->the_bfd, s);
yann@402
   346
+      bfd_boolean skip = !match_simple_wild (wildsec0->spec.name, sname);
yann@402
   347
+
yann@402
   348
+      if (!skip)
yann@402
   349
+	walk_wild_consider_section (ptr, file, s, wildsec0, callback, data);
yann@402
   350
+    }
yann@402
   351
+}
yann@402
   352
+
yann@402
   353
+static void
yann@402
   354
+walk_wild_section_specs2_wild1 (lang_wild_statement_type *ptr,
yann@402
   355
+				lang_input_statement_type *file,
yann@402
   356
+				callback_t callback,
yann@402
   357
+				void *data)
yann@402
   358
+{
yann@402
   359
+  asection *s;
yann@402
   360
+  struct wildcard_list *sec0 = ptr->handler_data[0];
yann@402
   361
+  struct wildcard_list *wildsec1 = ptr->handler_data[1];
yann@402
   362
+  bfd_boolean multiple_sections_found;
yann@402
   363
+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
yann@402
   364
+
yann@402
   365
+  if (multiple_sections_found)
yann@402
   366
+    {
yann@402
   367
+      walk_wild_section_general (ptr, file, callback, data);
yann@402
   368
+      return;
yann@402
   369
+    }
yann@402
   370
+
yann@402
   371
+  /* Note that if the section was not found, s0 is NULL and
yann@402
   372
+     we'll simply never succeed the s == s0 test below.  */
yann@402
   373
+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
yann@402
   374
+    {
yann@402
   375
+      /* Recall that in this code path, a section cannot satisfy more
yann@402
   376
+	 than one spec, so if s == s0 then it cannot match
yann@402
   377
+	 wildspec1.  */
yann@402
   378
+      if (s == s0)
yann@402
   379
+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
yann@402
   380
+      else
yann@402
   381
+	{
yann@402
   382
+	  const char *sname = bfd_get_section_name (file->the_bfd, s);
yann@402
   383
+	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
yann@402
   384
+
yann@402
   385
+	  if (!skip)
yann@402
   386
+	    walk_wild_consider_section (ptr, file, s, wildsec1, callback,
yann@402
   387
+					data);
yann@402
   388
+	}
yann@402
   389
+    }
yann@402
   390
+}
yann@402
   391
+
yann@402
   392
+static void
yann@402
   393
+walk_wild_section_specs3_wild2 (lang_wild_statement_type *ptr,
yann@402
   394
+				lang_input_statement_type *file,
yann@402
   395
+				callback_t callback,
yann@402
   396
+				void *data)
yann@402
   397
+{
yann@402
   398
+  asection *s;
yann@402
   399
+  struct wildcard_list *sec0 = ptr->handler_data[0];
yann@402
   400
+  struct wildcard_list *wildsec1 = ptr->handler_data[1];
yann@402
   401
+  struct wildcard_list *wildsec2 = ptr->handler_data[2];
yann@402
   402
+  bfd_boolean multiple_sections_found;
yann@402
   403
+  asection *s0 = find_section (file, sec0, &multiple_sections_found);
yann@402
   404
+
yann@402
   405
+  if (multiple_sections_found)
yann@402
   406
+    {
yann@402
   407
+      walk_wild_section_general (ptr, file, callback, data);
yann@402
   408
+      return;
yann@402
   409
+    }
yann@402
   410
+
yann@402
   411
+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
yann@402
   412
+    {
yann@402
   413
+      if (s == s0)
yann@402
   414
+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
yann@402
   415
+      else
yann@402
   416
+	{
yann@402
   417
+	  const char *sname = bfd_get_section_name (file->the_bfd, s);
yann@402
   418
+	  bfd_boolean skip = !match_simple_wild (wildsec1->spec.name, sname);
yann@402
   419
+
yann@402
   420
+	  if (!skip)
yann@402
   421
+	    walk_wild_consider_section (ptr, file, s, wildsec1, callback, data);
yann@402
   422
+	  else
yann@402
   423
+	    {
yann@402
   424
+	      skip = !match_simple_wild (wildsec2->spec.name, sname);
yann@402
   425
+	      if (!skip)
yann@402
   426
+		walk_wild_consider_section (ptr, file, s, wildsec2, callback,
yann@402
   427
+					    data);
yann@402
   428
+	    }
yann@402
   429
+	}
yann@402
   430
+    }
yann@402
   431
+}
yann@402
   432
+
yann@402
   433
+static void
yann@402
   434
+walk_wild_section_specs4_wild2 (lang_wild_statement_type *ptr,
yann@402
   435
+				lang_input_statement_type *file,
yann@402
   436
+				callback_t callback,
yann@402
   437
+				void *data)
yann@402
   438
+{
yann@402
   439
+  asection *s;
yann@402
   440
+  struct wildcard_list *sec0 = ptr->handler_data[0];
yann@402
   441
+  struct wildcard_list *sec1 = ptr->handler_data[1];
yann@402
   442
+  struct wildcard_list *wildsec2 = ptr->handler_data[2];
yann@402
   443
+  struct wildcard_list *wildsec3 = ptr->handler_data[3];
yann@402
   444
+  bfd_boolean multiple_sections_found;
yann@402
   445
+  asection *s0 = find_section (file, sec0, &multiple_sections_found), *s1;
yann@402
   446
+
yann@402
   447
+  if (multiple_sections_found)
yann@402
   448
+    {
yann@402
   449
+      walk_wild_section_general (ptr, file, callback, data);
yann@402
   450
+      return;
yann@402
   451
+    }
yann@402
   452
+
yann@402
   453
+  s1 = find_section (file, sec1, &multiple_sections_found);
yann@402
   454
+  if (multiple_sections_found)
yann@402
   455
+    {
yann@402
   456
+      walk_wild_section_general (ptr, file, callback, data);
yann@402
   457
+      return;
yann@402
   458
+    }
yann@402
   459
+
yann@402
   460
+  for (s = file->the_bfd->sections; s != NULL; s = s->next)
yann@402
   461
+    {
yann@402
   462
+      if (s == s0)
yann@402
   463
+	walk_wild_consider_section (ptr, file, s, sec0, callback, data);
yann@402
   464
+      else
yann@402
   465
+	if (s == s1)
yann@402
   466
+	  walk_wild_consider_section (ptr, file, s, sec1, callback, data);
yann@402
   467
+	else
yann@402
   468
+	  {
yann@402
   469
+	    const char *sname = bfd_get_section_name (file->the_bfd, s);
yann@402
   470
+	    bfd_boolean skip = !match_simple_wild (wildsec2->spec.name,
yann@402
   471
+						   sname);
yann@402
   472
+
yann@402
   473
+	    if (!skip)
yann@402
   474
+	      walk_wild_consider_section (ptr, file, s, wildsec2, callback,
yann@402
   475
+					  data);
yann@402
   476
+	    else
yann@402
   477
+	      {
yann@402
   478
+		skip = !match_simple_wild (wildsec3->spec.name, sname);
yann@402
   479
+		if (!skip)
yann@402
   480
+		  walk_wild_consider_section (ptr, file, s, wildsec3,
yann@402
   481
+					      callback, data);
yann@402
   482
+	      }
yann@402
   483
+	  }
yann@402
   484
+    }
yann@402
   485
+}
yann@402
   486
+
yann@402
   487
+static void
yann@402
   488
+walk_wild_section (lang_wild_statement_type *ptr,
yann@402
   489
+		   lang_input_statement_type *file,
yann@402
   490
+		   callback_t callback,
yann@402
   491
+		   void *data)
yann@402
   492
+{
yann@402
   493
+  if (file->just_syms_flag)
yann@402
   494
+    return;
yann@402
   495
+
yann@402
   496
+  (*ptr->walk_wild_section_handler) (ptr, file, callback, data);
yann@402
   497
+}
yann@402
   498
+
yann@402
   499
+/* Returns TRUE when name1 is a wildcard spec that might match
yann@402
   500
+   something name2 can match.  We're conservative: we return FALSE
yann@402
   501
+   only if the prefixes of name1 and name2 are different up to the
yann@402
   502
+   first wildcard character.  */
yann@402
   503
+
yann@402
   504
+static bfd_boolean
yann@402
   505
+wild_spec_can_overlap (const char *name1, const char *name2)
yann@402
   506
+{
yann@402
   507
+  size_t prefix1_len = strcspn (name1, "?*[");
yann@402
   508
+  size_t prefix2_len = strcspn (name2, "?*[");
yann@402
   509
+  size_t min_prefix_len;
yann@402
   510
+
yann@402
   511
+  /* Note that if there is no wildcard character, then we treat the
yann@402
   512
+     terminating 0 as part of the prefix.  Thus ".text" won't match
yann@402
   513
+     ".text." or ".text.*", for example.  */
yann@402
   514
+  if (name1[prefix1_len] == '\0')
yann@402
   515
+    prefix1_len++;
yann@402
   516
+  if (name2[prefix2_len] == '\0')
yann@402
   517
+    prefix2_len++;
yann@402
   518
+
yann@402
   519
+  min_prefix_len = prefix1_len < prefix2_len ? prefix1_len : prefix2_len;
yann@402
   520
+
yann@402
   521
+  return memcmp (name1, name2, min_prefix_len) == 0;
yann@402
   522
+}
yann@402
   523
+
yann@402
   524
+/* Select specialized code to handle various kinds of wildcard
yann@402
   525
+   statements.  */
yann@402
   526
+
yann@402
   527
+static void
yann@402
   528
+analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
yann@402
   529
+{
yann@402
   530
+  int sec_count = 0;
yann@402
   531
+  int wild_name_count = 0;
yann@402
   532
+  struct wildcard_list *sec;
yann@402
   533
+  int signature;
yann@402
   534
+  int data_counter;
yann@402
   535
+
yann@402
   536
+  ptr->walk_wild_section_handler = walk_wild_section_general;
yann@402
   537
+
yann@402
   538
+  /* Count how many wildcard_specs there are, and how many of those
yann@402
   539
+     actually use wildcards in the name.  Also, bail out if any of the
yann@402
   540
+     wildcard names are NULL. (Can this actually happen?
yann@402
   541
+     walk_wild_section used to test for it.)  And bail out if any
yann@402
   542
+     of the wildcards are more complex than a simple string
yann@402
   543
+     ending in a single '*'.  */
yann@402
   544
+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
yann@402
   545
+    {
yann@402
   546
+      ++sec_count;
yann@402
   547
+      if (sec->spec.name == NULL)
yann@402
   548
+	return;
yann@402
   549
+      if (wildcardp (sec->spec.name))
yann@402
   550
+	{
yann@402
   551
+	  ++wild_name_count;
yann@402
   552
+	  if (!is_simple_wild (sec->spec.name))
yann@402
   553
+	    return;
yann@402
   554
+	}
yann@402
   555
+    }
yann@402
   556
+
yann@402
   557
+  /* The zero-spec case would be easy to optimize but it doesn't
yann@402
   558
+     happen in practice.  Likewise, more than 4 specs doesn't
yann@402
   559
+     happen in practice.  */
yann@402
   560
+  if (sec_count == 0 || sec_count > 4)
yann@402
   561
+    return;
yann@402
   562
+
yann@402
   563
+  /* Check that no two specs can match the same section.  */
yann@402
   564
+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
yann@402
   565
+    {
yann@402
   566
+      struct wildcard_list *sec2;
yann@402
   567
+      for (sec2 = sec->next; sec2 != NULL; sec2 = sec2->next)
yann@402
   568
+	{
yann@402
   569
+	  if (wild_spec_can_overlap (sec->spec.name, sec2->spec.name))
yann@402
   570
+	    return;
yann@402
   571
+	}
yann@402
   572
+    }
yann@402
   573
+
yann@402
   574
+  signature = (sec_count << 8) + wild_name_count;
yann@402
   575
+  switch (signature)
yann@402
   576
+    {
yann@402
   577
+    case 0x0100:
yann@402
   578
+      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild0;
yann@402
   579
+      break;
yann@402
   580
+    case 0x0101:
yann@402
   581
+      ptr->walk_wild_section_handler = walk_wild_section_specs1_wild1;
yann@402
   582
+      break;
yann@402
   583
+    case 0x0201:
yann@402
   584
+      ptr->walk_wild_section_handler = walk_wild_section_specs2_wild1;
yann@402
   585
+      break;
yann@402
   586
+    case 0x0302:
yann@402
   587
+      ptr->walk_wild_section_handler = walk_wild_section_specs3_wild2;
yann@402
   588
+      break;
yann@402
   589
+    case 0x0402:
yann@402
   590
+      ptr->walk_wild_section_handler = walk_wild_section_specs4_wild2;
yann@402
   591
+      break;
yann@402
   592
+    default:
yann@402
   593
+      return;
yann@402
   594
+    }
yann@402
   595
+
yann@402
   596
+  /* Now fill the data array with pointers to the specs, first the
yann@402
   597
+     specs with non-wildcard names, then the specs with wildcard
yann@402
   598
+     names.  It's OK to process the specs in different order from the
yann@402
   599
+     given order, because we've already determined that no section
yann@402
   600
+     will match more than one spec.  */
yann@402
   601
+  data_counter = 0;
yann@402
   602
+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
yann@402
   603
+    if (!wildcardp (sec->spec.name))
yann@402
   604
+      ptr->handler_data[data_counter++] = sec;
yann@402
   605
+  for (sec = ptr->section_list; sec != NULL; sec = sec->next)
yann@402
   606
+    if (wildcardp (sec->spec.name))
yann@402
   607
+      ptr->handler_data[data_counter++] = sec;
yann@402
   608
+}
yann@402
   609
+
yann@402
   610
 /* Handle a wild statement for a single file F.  */
yann@402
   611
 
yann@402
   612
 static void
yann@402
   613
@@ -1175,17 +1559,12 @@
yann@402
   614
 static void
yann@402
   615
 init_os (lang_output_section_statement_type *s)
yann@402
   616
 {
yann@402
   617
-  lean_section_userdata_type *new;
yann@402
   618
-
yann@402
   619
   if (s->bfd_section != NULL)
yann@402
   620
     return;
yann@402
   621
 
yann@402
   622
   if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
yann@402
   623
     einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
yann@402
   624
 
yann@402
   625
-  new = stat_alloc (SECTION_USERDATA_SIZE);
yann@402
   626
-  memset (new, 0, SECTION_USERDATA_SIZE);
yann@402
   627
-
yann@402
   628
   s->bfd_section = bfd_get_section_by_name (output_bfd, s->name);
yann@402
   629
   if (s->bfd_section == NULL)
yann@402
   630
     s->bfd_section = bfd_make_section (output_bfd, s->name);
yann@402
   631
@@ -1199,7 +1578,14 @@
yann@402
   632
   /* We initialize an output sections output offset to minus its own
yann@402
   633
      vma to allow us to output a section through itself.  */
yann@402
   634
   s->bfd_section->output_offset = 0;
yann@402
   635
-  get_userdata (s->bfd_section) = new;
yann@402
   636
+  if (!command_line.reduce_memory_overheads)
yann@402
   637
+    {
yann@402
   638
+      fat_section_userdata_type *new
yann@402
   639
+	= stat_alloc (sizeof (fat_section_userdata_type));
yann@402
   640
+      memset (new, 0, sizeof (fat_section_userdata_type));
yann@402
   641
+      get_userdata (s->bfd_section) = new;
yann@402
   642
+    }
yann@402
   643
+
yann@402
   644
 
yann@402
   645
   /* If there is a base address, make sure that any sections it might
yann@402
   646
      mention are initialized.  */
yann@402
   647
@@ -4939,6 +5325,7 @@
yann@402
   648
   new->section_list = section_list;
yann@402
   649
   new->keep_sections = keep_sections;
yann@402
   650
   lang_list_init (&new->children);
yann@402
   651
+  analyze_walk_wild_section_handler (new);
yann@402
   652
 }
yann@402
   653
 
yann@402
   654
 void
yann@402
   655
Index: src/ld/ldlang.h
yann@402
   656
===================================================================
yann@402
   657
RCS file: /cvs/src/src/ld/ldlang.h,v
yann@402
   658
retrieving revision 1.44
yann@402
   659
retrieving revision 1.45
yann@402
   660
diff -u -r1.44 -r1.45
yann@402
   661
--- binutils/ld/ldlang.h.old	3 Mar 2005 11:51:58 -0000	1.44
yann@402
   662
+++ binutils/ld/ldlang.h	6 Apr 2005 15:33:03 -0000	1.45
yann@402
   663
@@ -298,7 +298,17 @@
yann@402
   664
   union lang_statement_union *file;
yann@402
   665
 } lang_afile_asection_pair_statement_type;
yann@402
   666
 
yann@402
   667
-typedef struct lang_wild_statement_struct
yann@402
   668
+typedef struct lang_wild_statement_struct lang_wild_statement_type;
yann@402
   669
+
yann@402
   670
+typedef void (*callback_t) (lang_wild_statement_type *, struct wildcard_list *,
yann@402
   671
+			    asection *, lang_input_statement_type *, void *);
yann@402
   672
+
yann@402
   673
+typedef void (*walk_wild_section_handler_t) (lang_wild_statement_type *,
yann@402
   674
+					     lang_input_statement_type *,
yann@402
   675
+					     callback_t callback,
yann@402
   676
+					     void *data);
yann@402
   677
+
yann@402
   678
+struct lang_wild_statement_struct
yann@402
   679
 {
yann@402
   680
   lang_statement_header_type header;
yann@402
   681
   const char *filename;
yann@402
   682
@@ -306,7 +316,10 @@
yann@402
   683
   struct wildcard_list *section_list;
yann@402
   684
   bfd_boolean keep_sections;
yann@402
   685
   lang_statement_list_type children;
yann@402
   686
-} lang_wild_statement_type;
yann@402
   687
+
yann@402
   688
+  walk_wild_section_handler_t walk_wild_section_handler;
yann@402
   689
+  struct wildcard_list *handler_data[4];
yann@402
   690
+};
yann@402
   691
 
yann@402
   692
 typedef struct lang_address_statement_struct
yann@402
   693
 {