summaryrefslogtreecommitdiff
path: root/patches/0005-gold-Handle-TLS-relocation-scan-in-garbage-collectio.patch
blob: 5fee4dda0e2f0ea3fc6a85619969f34743df2fd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From b16aa951f9e7967b4354d6a76943c7316b3a2c84 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 10 May 2020 10:44:15 -0700
Subject: [PATCH 5/7] gold: Handle TLS relocation scan in garbage collection

Similar to ICF, handle TLS relocation scan in garbage collection.  We
add a TLS relocation scan before the regular relocation scan.

	PR gold/25476
	* gold.cc (Gc_runner::run): Call queue_middle_tasks if not
	doing garbage collection, ICF, nor needing TLS relocation scan.
	(queue_initial_tasks): Always queue Gc_runner task.
	(queue_middle_tasks): Handle TLS relocation scan like garbage
	collection and ICF.
---
 gold/gold.cc | 65 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 28 deletions(-)

diff --git a/gold/gold.cc b/gold/gold.cc
index f02d2aadaf..e7f8ff0a76 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -161,9 +161,23 @@ class Gc_runner : public Task_function_runner
 void
 Gc_runner::run(Workqueue* workqueue, const Task* task)
 {
-  queue_middle_gc_tasks(this->options_, task, this->input_objects_,
-			this->symtab_, this->layout_, workqueue,
-			this->mapfile_);
+  // NB: Call queue_middle_tasks if we aren't doing garbage collection,
+  // ICF nor needing TLS relocation scan.
+  Target* target = const_cast<Target*>(&parameters->target());
+  if (parameters->options().gc_sections()
+      || parameters->options().icf_enabled()
+      || target->need_tls_process_relocs())
+    {
+      if (target->need_tls_process_relocs())
+	target->set_input_objects(this->input_objects_);
+      queue_middle_gc_tasks(this->options_, task, this->input_objects_,
+			    this->symtab_, this->layout_, workqueue,
+			    this->mapfile_);
+    }
+  else
+    queue_middle_tasks(this->options_, task, this->input_objects_,
+		       this->symtab_, this->layout_, workqueue,
+		       this->mapfile_);
 }
 
 // Queue up the initial set of tasks for this link job.
@@ -283,26 +297,15 @@ queue_initial_tasks(const General_options& options,
       && (options.gc_sections() || options.icf_enabled()))
     gold_error(_("cannot mix -r with --gc-sections or --icf"));
 
-  if (options.gc_sections() || options.icf_enabled())
-    {
-      workqueue->queue(new Task_function(new Gc_runner(options,
-						       input_objects,
-						       symtab,
-						       layout,
-						       mapfile),
-					 this_blocker,
-					 "Task_function Gc_runner"));
-    }
-  else
-    {
-      workqueue->queue(new Task_function(new Middle_runner(options,
-							   input_objects,
-							   symtab,
-							   layout,
-							   mapfile),
-					 this_blocker,
-					 "Task_function Middle_runner"));
-    }
+  // Gc_runner::run handles both queue_middle_gc_tasks and
+  // queue_middle_tasks.
+  workqueue->queue(new Task_function(new Gc_runner(options,
+						   input_objects,
+						   symtab,
+						   layout,
+						   mapfile),
+				     this_blocker,
+				     "Task_function Gc_runner"));
 }
 
 // Process an incremental input file: if it is unchanged from the previous
@@ -533,14 +536,19 @@ queue_middle_tasks(const General_options& options,
       symtab->icf()->find_identical_sections(input_objects, symtab);
     }
 
+  // TODO(csilvers): figure out a more principled way to get the target
+  Target* target = const_cast<Target*>(&parameters->target());
+
   // Call Object::layout for the second time to determine the
   // output_sections for all referenced input sections.  When
   // --gc-sections or --icf is turned on, or when certain input
   // sections have to be mapped to unique segments, Object::layout
   // is called twice.  It is called the first time when symbols
   // are added.
+  // NB: Handle TLS relocation scan in garbage collection.
   if (parameters->options().gc_sections()
       || parameters->options().icf_enabled()
+      || target->need_tls_process_relocs()
       || layout->is_unique_segment_for_sections_specified())
     {
       for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
@@ -577,8 +585,10 @@ queue_middle_tasks(const General_options& options,
 	(*p)->update_section_layout(layout->get_section_order_map());
     }
 
+  // NB: Handle TLS relocation scan in garbage collection.
   if (parameters->options().gc_sections()
-      || parameters->options().icf_enabled())
+      || parameters->options().icf_enabled()
+      || target->need_tls_process_relocs())
     {
       for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
 	   p != input_objects->relobj_end();
@@ -681,9 +691,6 @@ queue_middle_tasks(const General_options& options,
   // Define symbols from any linker scripts.
   layout->define_script_symbols(symtab);
 
-  // TODO(csilvers): figure out a more principled way to get the target
-  Target* target = const_cast<Target*>(&parameters->target());
-
   // Attach sections to segments.
   layout->attach_sections_to_segments(target);
 
@@ -718,8 +725,10 @@ queue_middle_tasks(const General_options& options,
 
   // If doing garbage collection, the relocations have already been read.
   // Otherwise, read and scan the relocations.
+  // NB: Handle TLS relocation scan in garbage collection.
   if (parameters->options().gc_sections()
-      || parameters->options().icf_enabled())
+      || parameters->options().icf_enabled()
+      || target->need_tls_process_relocs())
     {
       for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
 	   p != input_objects->relobj_end();
-- 
2.26.2