~netblock-deactivatedaccount/ubuntu/natty/binutils/rtems-support

« back to all changes in this revision

Viewing changes to debian/patches/163_gold_1.11.patch

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-01-25 02:26:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110125022654-yqsghx5npuupixz2
Tags: 2.21-5ubuntu0
Intermediate upload to natty to change the soversion on powerpc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
2011-01-18  Ian Lance Taylor  <iant@google.com>
 
2
 
 
3
        * plugin.cc (class Plugin_rescan): Define new class.
 
4
        (Plugin_manager::claim_file): Set any_claimed_.
 
5
        (Plugin_manager::save_archive): New function.
 
6
        (Plugin_manager::save_input_group): New function.
 
7
        (Plugin_manager::all_symbols_read): Create Plugin_rescan task if
 
8
        necessary.
 
9
        (Plugin_manager::new_undefined_symbol): New function.
 
10
        (Plugin_manager::rescan): New function.
 
11
        (Plugin_manager::rescannable_defines): New function.
 
12
        (Plugin_manager::add_input_file): Set any_added_.
 
13
        * plugin.h (class Plugin_manager): define new fields rescannable_,
 
14
        undefined_symbols_, any_claimed_, and any_added_.  Declare
 
15
        Plugin_rescan as friend.  Declare new functions.
 
16
        (Plugin_manager::Rescannable): Define type.
 
17
        (Plugin_manager::Rescannable_list): Define type.
 
18
        (Plugin_manager::Undefined_symbol_list): Define type.
 
19
        (Plugin_manager::Plugin_manager): Initialize new fields.
 
20
        * archive.cc (Archive::defines_symbol): New function.
 
21
        (Add_archive_symbols::run): Pass archive to plugins if any.
 
22
        * archive.h (class Archive): Declare defines_symbol.
 
23
        * readsyms.cc (Input_group::~Input_group): New function.
 
24
        (Finish_group::run): Pass input_group to plugins if any.
 
25
        * readsyms.h (class Input_group): Declare destructor.
 
26
        * symtab.cc (add_from_object): Pass undefined symbol to plugins if
 
27
        any.
 
28
 
 
29
2011-01-24  Ian Lance Taylor  <iant@google.com>
 
30
 
 
31
        * version.cc (version_string): Bump to 1.11.
 
32
 
 
33
 
 
34
--- a/gold/archive.h
 
35
+++ b/gold/archive.h
 
36
@@ -152,6 +152,10 @@ class Archive
 
37
   bool
 
38
   add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*);
 
39
 
 
40
+  // Return whether the archive defines the symbol.
 
41
+  bool
 
42
+  defines_symbol(Symbol*) const;
 
43
+
 
44
   // Dump statistical information to stderr.
 
45
   static void
 
46
   print_stats();
 
47
--- a/gold/archive.cc
 
48
+++ b/gold/archive.cc
 
49
@@ -779,6 +779,42 @@ Archive::add_symbols(Symbol_table* symta
 
50
   return true;
 
51
 }
 
52
 
 
53
+// Return whether the archive includes a member which defines the
 
54
+// symbol SYM.
 
55
+
 
56
+bool
 
57
+Archive::defines_symbol(Symbol* sym) const
 
58
+{
 
59
+  const char* symname = sym->name();
 
60
+  size_t symname_len = strlen(symname);
 
61
+  size_t armap_size = this->armap_.size();
 
62
+  for (size_t i = 0; i < armap_size; ++i)
 
63
+    {
 
64
+      if (this->armap_checked_[i])
 
65
+       continue;
 
66
+      const char* archive_symname = (this->armap_names_.data()
 
67
+                                    + this->armap_[i].name_offset);
 
68
+      if (strncmp(archive_symname, symname, symname_len) != 0)
 
69
+       continue;
 
70
+      char c = archive_symname[symname_len];
 
71
+      if (c == '\0' && sym->version() == NULL)
 
72
+       return true;
 
73
+      if (c == '@')
 
74
+       {
 
75
+         const char* ver = archive_symname + symname_len + 1;
 
76
+         if (*ver == '@')
 
77
+           {
 
78
+             if (sym->version() == NULL)
 
79
+               return true;
 
80
+             ++ver;
 
81
+           }
 
82
+         if (sym->version() != NULL && strcmp(sym->version(), ver) == 0)
 
83
+           return true;
 
84
+       }
 
85
+    }
 
86
+  return false;
 
87
+}
 
88
+
 
89
 // Include all the archive members in the link.  This is for --whole-archive.
 
90
 
 
91
 bool
 
92
@@ -1001,8 +1037,18 @@ Add_archive_symbols::run(Workqueue* work
 
93
       if (incremental_inputs != NULL)
 
94
        incremental_inputs->report_archive_end(this->archive_);
 
95
 
 
96
-      // We no longer need to know about this archive.
 
97
-      delete this->archive_;
 
98
+      if (!parameters->options().has_plugins()
 
99
+         || this->archive_->input_file()->options().whole_archive())
 
100
+       {
 
101
+         // We no longer need to know about this archive.
 
102
+         delete this->archive_;
 
103
+       }
 
104
+      else
 
105
+       {
 
106
+         // The plugin interface may want to rescan this archive.
 
107
+         parameters->options().plugins()->save_archive(this->archive_);
 
108
+       }
 
109
+
 
110
       this->archive_ = NULL;
 
111
     }
 
112
 }
 
113
--- a/gold/plugin.h
 
114
+++ b/gold/plugin.h
 
115
@@ -36,12 +36,17 @@ namespace gold
 
116
 class General_options;
 
117
 class Input_file;
 
118
 class Input_objects;
 
119
+class Archive;
 
120
+class Input_group;
 
121
+class Symbol;
 
122
 class Symbol_table;
 
123
 class Layout;
 
124
 class Dirsearch;
 
125
 class Mapfile;
 
126
+class Task;
 
127
 class Task_token;
 
128
 class Pluginobj;
 
129
+class Plugin_rescan;
 
130
 
 
131
 // This class represents a single plugin library.
 
132
 
 
133
@@ -124,7 +129,8 @@ class Plugin_manager
 
134
  public:
 
135
   Plugin_manager(const General_options& options)
 
136
     : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
 
137
-      plugin_input_file_(), in_replacement_phase_(false),
 
138
+      plugin_input_file_(), rescannable_(), undefined_symbols_(),
 
139
+      any_claimed_(false), in_replacement_phase_(false), any_added_(false),
 
140
       options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
 
141
       symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
 
142
       this_blocker_(NULL), extra_search_path_()
 
143
@@ -153,6 +159,16 @@ class Plugin_manager
 
144
   Pluginobj*
 
145
   claim_file(Input_file* input_file, off_t offset, off_t filesize);
 
146
 
 
147
+  // Let the plugin manager save an archive for later rescanning.
 
148
+  // This takes ownership of the Archive pointer.
 
149
+  void
 
150
+  save_archive(Archive*);
 
151
+
 
152
+  // Let the plugin manager save an input group for later rescanning.
 
153
+  // This takes ownership of the Input_group pointer.
 
154
+  void
 
155
+  save_input_group(Input_group*);
 
156
+
 
157
   // Call the all-symbols-read handlers.
 
158
   void
 
159
   all_symbols_read(Workqueue* workqueue, Task* task,
 
160
@@ -160,6 +176,11 @@ class Plugin_manager
 
161
                    Layout* layout, Dirsearch* dirpath, Mapfile* mapfile,
 
162
                    Task_token** last_blocker);
 
163
 
 
164
+  // Tell the plugin manager that we've a new undefined symbol which
 
165
+  // may require rescanning.
 
166
+  void
 
167
+  new_undefined_symbol(Symbol*);
 
168
+
 
169
   // Run deferred layout.
 
170
   void
 
171
   layout_deferred_objects();
 
172
@@ -245,9 +266,42 @@ class Plugin_manager
 
173
   Plugin_manager(const Plugin_manager&);
 
174
   Plugin_manager& operator=(const Plugin_manager&);
 
175
 
 
176
+  // Plugin_rescan is a Task which calls the private rescan method.
 
177
+  friend class Plugin_rescan;
 
178
+
 
179
+  // An archive or input group which may have to be rescanned if a
 
180
+  // plugin adds a new file.
 
181
+  struct Rescannable
 
182
+  {
 
183
+    bool is_archive;
 
184
+    union
 
185
+    {
 
186
+      Archive* archive;
 
187
+      Input_group* input_group;
 
188
+    } u;
 
189
+
 
190
+    Rescannable(Archive* archive)
 
191
+      : is_archive(true)
 
192
+    { this->u.archive = archive; }
 
193
+
 
194
+    Rescannable(Input_group* input_group)
 
195
+      : is_archive(false)
 
196
+    { this->u.input_group = input_group; }
 
197
+  };
 
198
+
 
199
   typedef std::list<Plugin*> Plugin_list;
 
200
   typedef std::vector<Pluginobj*> Object_list;
 
201
   typedef std::vector<Relobj*> Deferred_layout_list;
 
202
+  typedef std::vector<Rescannable> Rescannable_list;
 
203
+  typedef std::vector<Symbol*> Undefined_symbol_list;
 
204
+
 
205
+  // Rescan archives for undefined symbols.
 
206
+  void
 
207
+  rescan(Task*);
 
208
+
 
209
+  // See whether the rescannable at index I defines SYM.
 
210
+  bool
 
211
+  rescannable_defines(size_t i, Symbol* sym);
 
212
 
 
213
   // The list of plugin libraries.
 
214
   Plugin_list plugins_;
 
215
@@ -265,11 +319,24 @@ class Plugin_manager
 
216
   Input_file* input_file_;
 
217
   struct ld_plugin_input_file plugin_input_file_;
 
218
 
 
219
-  // TRUE after the all symbols read event; indicates that we are
 
220
-  // processing replacement files whose symbols should replace the
 
221
+  // A list of archives and input groups being saved for possible
 
222
+  // later rescanning.
 
223
+  Rescannable_list rescannable_;
 
224
+
 
225
+  // A list of undefined symbols found in added files.
 
226
+  Undefined_symbol_list undefined_symbols_;
 
227
+
 
228
+  // Whether any input files have been claimed by a plugin.
 
229
+  bool any_claimed_;
 
230
+
 
231
+  // Set to true after the all symbols read event; indicates that we
 
232
+  // are processing replacement files whose symbols should replace the
 
233
   // placeholder symbols from the Pluginobj objects.
 
234
   bool in_replacement_phase_;
 
235
 
 
236
+  // Whether any input files or libraries were added by a plugin.
 
237
+  bool any_added_;
 
238
+
 
239
   const General_options& options_;
 
240
   Workqueue* workqueue_;
 
241
   Task* task_;
 
242
--- a/gold/plugin.cc
 
243
+++ b/gold/plugin.cc
 
244
@@ -261,6 +261,45 @@ Plugin::cleanup()
 
245
     }
 
246
 }
 
247
 
 
248
+// This task is used to rescan archives as needed.
 
249
+
 
250
+class Plugin_rescan : public Task
 
251
+{
 
252
+ public:
 
253
+  Plugin_rescan(Task_token* this_blocker, Task_token* next_blocker)
 
254
+    : this_blocker_(this_blocker), next_blocker_(next_blocker)
 
255
+  { }
 
256
+
 
257
+  ~Plugin_rescan()
 
258
+  {
 
259
+    delete this->this_blocker_;
 
260
+  }
 
261
+
 
262
+  Task_token*
 
263
+  is_runnable()
 
264
+  {
 
265
+    if (this->this_blocker_->is_blocked())
 
266
+      return this->this_blocker_;
 
267
+    return NULL;
 
268
+  }
 
269
+
 
270
+  void
 
271
+  locks(Task_locker* tl)
 
272
+  { tl->add(this, this->next_blocker_); }
 
273
+
 
274
+  void
 
275
+  run(Workqueue*)
 
276
+  { parameters->options().plugins()->rescan(this); }
 
277
+
 
278
+  std::string
 
279
+  get_name() const
 
280
+  { return "Plugin_rescan"; }
 
281
+
 
282
+ private:
 
283
+  Task_token* this_blocker_;
 
284
+  Task_token* next_blocker_;
 
285
+};
 
286
+
 
287
 // Plugin_manager methods.
 
288
 
 
289
 Plugin_manager::~Plugin_manager()
 
290
@@ -311,6 +350,8 @@ Plugin_manager::claim_file(Input_file* i
 
291
     {
 
292
       if ((*this->current_)->claim_file(&this->plugin_input_file_))
 
293
         {
 
294
+         this->any_claimed_ = true;
 
295
+
 
296
           if (this->objects_.size() > handle)
 
297
             return this->objects_[handle];
 
298
 
 
299
@@ -324,6 +365,31 @@ Plugin_manager::claim_file(Input_file* i
 
300
   return NULL;
 
301
 }
 
302
 
 
303
+// Save an archive.  This is used so that a plugin can add a file
 
304
+// which refers to a symbol which was not previously referenced.  In
 
305
+// that case we want to pretend that the symbol was referenced before,
 
306
+// and pull in the archive object.
 
307
+
 
308
+void
 
309
+Plugin_manager::save_archive(Archive* archive)
 
310
+{
 
311
+  if (this->in_replacement_phase_ || !this->any_claimed_)
 
312
+    delete archive;
 
313
+  else
 
314
+    this->rescannable_.push_back(Rescannable(archive));
 
315
+}
 
316
+
 
317
+// Save an Input_group.  This is like save_archive.
 
318
+
 
319
+void
 
320
+Plugin_manager::save_input_group(Input_group* input_group)
 
321
+{
 
322
+  if (this->in_replacement_phase_ || !this->any_claimed_)
 
323
+    delete input_group;
 
324
+  else
 
325
+    this->rescannable_.push_back(Rescannable(input_group));
 
326
+}
 
327
+
 
328
 // Call the all-symbols-read handlers.
 
329
 
 
330
 void
 
331
@@ -348,9 +414,146 @@ Plugin_manager::all_symbols_read(Workque
 
332
        ++this->current_)
 
333
     (*this->current_)->all_symbols_read();
 
334
 
 
335
+  if (this->any_added_)
 
336
+    {
 
337
+      Task_token* next_blocker = new Task_token(true);
 
338
+      next_blocker->add_blocker();
 
339
+      workqueue->queue(new Plugin_rescan(this->this_blocker_, next_blocker));
 
340
+      this->this_blocker_ = next_blocker;
 
341
+    }
 
342
+
 
343
   *last_blocker = this->this_blocker_;
 
344
 }
 
345
 
 
346
+// This is called when we see a new undefined symbol.  If we are in
 
347
+// the replacement phase, this means that we may need to rescan some
 
348
+// archives we have previously seen.
 
349
+
 
350
+void
 
351
+Plugin_manager::new_undefined_symbol(Symbol* sym)
 
352
+{
 
353
+  if (this->in_replacement_phase_)
 
354
+    this->undefined_symbols_.push_back(sym);
 
355
+}
 
356
+
 
357
+// Rescan archives as needed.  This handles the case where a new
 
358
+// object file added by a plugin has an undefined reference to some
 
359
+// symbol defined in an archive.
 
360
+
 
361
+void
 
362
+Plugin_manager::rescan(Task* task)
 
363
+{
 
364
+  size_t rescan_pos = 0;
 
365
+  size_t rescan_size = this->rescannable_.size();
 
366
+  while (!this->undefined_symbols_.empty())
 
367
+    {
 
368
+      if (rescan_pos >= rescan_size)
 
369
+       {
 
370
+         this->undefined_symbols_.clear();
 
371
+         return;
 
372
+       }
 
373
+
 
374
+      Undefined_symbol_list undefs;
 
375
+      undefs.reserve(this->undefined_symbols_.size());
 
376
+      this->undefined_symbols_.swap(undefs);
 
377
+
 
378
+      size_t min_rescan_pos = rescan_size;
 
379
+
 
380
+      for (Undefined_symbol_list::const_iterator p = undefs.begin();
 
381
+          p != undefs.end();
 
382
+          ++p)
 
383
+       {
 
384
+         if (!(*p)->is_undefined())
 
385
+           continue;
 
386
+
 
387
+         this->undefined_symbols_.push_back(*p);
 
388
+
 
389
+         // Find the first rescan archive which defines this symbol,
 
390
+         // starting at the current rescan position.  The rescan position
 
391
+         // exists so that given -la -lb -lc we don't look for undefined
 
392
+         // symbols in -lb back in -la, but instead get the definition
 
393
+         // from -lc.  Don't bother to look past the current minimum
 
394
+         // rescan position.
 
395
+         for (size_t i = rescan_pos; i < min_rescan_pos; ++i)
 
396
+           {
 
397
+             if (this->rescannable_defines(i, *p))
 
398
+               {
 
399
+                 min_rescan_pos = i;
 
400
+                 break;
 
401
+               }
 
402
+           }
 
403
+       }
 
404
+
 
405
+      if (min_rescan_pos >= rescan_size)
 
406
+       {
 
407
+         // We didn't find any rescannable archives which define any
 
408
+         // undefined symbols.
 
409
+         return;
 
410
+       }
 
411
+
 
412
+      const Rescannable& r(this->rescannable_[min_rescan_pos]);
 
413
+      if (r.is_archive)
 
414
+       {
 
415
+         Task_lock_obj<Archive> tl(task, r.u.archive);
 
416
+         r.u.archive->add_symbols(this->symtab_, this->layout_,
 
417
+                                  this->input_objects_, this->mapfile_);
 
418
+       }
 
419
+      else
 
420
+       {
 
421
+         size_t next_saw_undefined = this->symtab_->saw_undefined();
 
422
+         size_t saw_undefined;
 
423
+         do
 
424
+           {
 
425
+             saw_undefined = next_saw_undefined;
 
426
+
 
427
+             for (Input_group::const_iterator p = r.u.input_group->begin();
 
428
+                  p != r.u.input_group->end();
 
429
+                  ++p)
 
430
+               {
 
431
+                 Task_lock_obj<Archive> tl(task, *p);
 
432
+
 
433
+                 (*p)->add_symbols(this->symtab_, this->layout_,
 
434
+                                   this->input_objects_, this->mapfile_);
 
435
+               }
 
436
+
 
437
+             next_saw_undefined = this->symtab_->saw_undefined();
 
438
+           }
 
439
+         while (saw_undefined != next_saw_undefined);
 
440
+       }
 
441
+
 
442
+      for (size_t i = rescan_pos; i < min_rescan_pos + 1; ++i)
 
443
+       {
 
444
+         if (this->rescannable_[i].is_archive)
 
445
+           delete this->rescannable_[i].u.archive;
 
446
+         else
 
447
+           delete this->rescannable_[i].u.input_group;
 
448
+       }
 
449
+
 
450
+      rescan_pos = min_rescan_pos + 1;
 
451
+    }
 
452
+}
 
453
+
 
454
+// Return whether the rescannable at index I defines SYM.
 
455
+
 
456
+bool
 
457
+Plugin_manager::rescannable_defines(size_t i, Symbol* sym)
 
458
+{
 
459
+  const Rescannable& r(this->rescannable_[i]);
 
460
+  if (r.is_archive)
 
461
+    return r.u.archive->defines_symbol(sym);
 
462
+  else
 
463
+    {
 
464
+      for (Input_group::const_iterator p = r.u.input_group->begin();
 
465
+          p != r.u.input_group->end();
 
466
+          ++p)
 
467
+       {
 
468
+         if ((*p)->defines_symbol(sym))
 
469
+           return true;
 
470
+       }
 
471
+      return false;
 
472
+    }
 
473
+}
 
474
+
 
475
 // Layout deferred objects.
 
476
 
 
477
 void
 
478
@@ -473,6 +676,7 @@ Plugin_manager::add_input_file(const cha
 
479
                                                 this->this_blocker_,
 
480
                                                 next_blocker));
 
481
   this->this_blocker_ = next_blocker;
 
482
+  this->any_added_ = true;
 
483
   return LDPS_OK;
 
484
 }
 
485
 
 
486
--- a/gold/readsyms.h
 
487
+++ b/gold/readsyms.h
 
488
@@ -191,6 +191,8 @@ class Input_group
 
489
     : archives_()
 
490
   { }
 
491
 
 
492
+  ~Input_group();
 
493
+
 
494
   // Add an archive to the group.
 
495
   void
 
496
   add_archive(Archive* arch)
 
497
--- a/gold/readsyms.cc
 
498
+++ b/gold/readsyms.cc
 
499
@@ -599,6 +599,19 @@ Add_symbols::run(Workqueue*)
 
500
     }
 
501
 }
 
502
 
 
503
+// Class Input_group.
 
504
+
 
505
+// When we delete an Input_group we can delete the archive
 
506
+// information.
 
507
+
 
508
+Input_group::~Input_group()
 
509
+{
 
510
+  for (Input_group::const_iterator p = this->begin();
 
511
+       p != this->end();
 
512
+       ++p)
 
513
+    delete *p;
 
514
+}
 
515
+
 
516
 // Class Start_group.
 
517
 
 
518
 Start_group::~Start_group()
 
519
@@ -680,8 +693,8 @@ Finish_group::run(Workqueue*)
 
520
        }
 
521
     }
 
522
 
 
523
-  // Now that we're done with the archives, record the incremental layout
 
524
-  // information, then delete them.
 
525
+  // Now that we're done with the archives, record the incremental
 
526
+  // layout information.
 
527
   for (Input_group::const_iterator p = this->input_group_->begin();
 
528
        p != this->input_group_->end();
 
529
        ++p)
 
530
@@ -691,10 +704,12 @@ Finish_group::run(Workqueue*)
 
531
           this->layout_->incremental_inputs();
 
532
       if (incremental_inputs != NULL)
 
533
        incremental_inputs->report_archive_end(*p);
 
534
-
 
535
-      delete *p;
 
536
     }
 
537
-  delete this->input_group_;
 
538
+
 
539
+  if (parameters->options().has_plugins())
 
540
+    parameters->options().plugins()->save_input_group(this->input_group_);
 
541
+  else
 
542
+    delete this->input_group_;
 
543
 }
 
544
 
 
545
 // Class Read_script
 
546
--- a/gold/symtab.cc
 
547
+++ b/gold/symtab.cc
 
548
@@ -1002,7 +1002,11 @@ Symbol_table::add_from_object(Object* ob
 
549
   // Record every time we see a new undefined symbol, to speed up
 
550
   // archive groups.
 
551
   if (!was_undefined && ret->is_undefined())
 
552
-    ++this->saw_undefined_;
 
553
+    {
 
554
+      ++this->saw_undefined_;
 
555
+      if (parameters->options().has_plugins())
 
556
+       parameters->options().plugins()->new_undefined_symbol(ret);
 
557
+    }
 
558
 
 
559
   // Keep track of common symbols, to speed up common symbol
 
560
   // allocation.
 
561
--- a/gold/version.cc
 
562
+++ b/gold/version.cc
 
563
@@ -37,7 +37,7 @@ namespace gold
 
564
 // version number from configure.ac.  But it's easier to just change
 
565
 // this file for now.
 
566
 
 
567
-static const char* version_string = "1.10";
 
568
+static const char* version_string = "1.11";
 
569
 
 
570
 // Report version information.
 
571