forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathicf-rel.patch
181 lines (173 loc) · 6.48 KB
/
icf-rel.patch
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
commit d114b830426300f80302ca03ff4322942f63c615
Author: Roland McGrath <mcgrathr@chromium.org>
Date: Thu May 5 13:12:40 2016 -0700
2016-02-05 Sriraman Tallam <tmsriram@google.com>
PR gold/19047
* icf.cc (get_rel_addend): New function.
(get_section_contents): Move merge section addend computation to a
new function. Ignore negative values for SHT_REL and SHT_RELA addends.
Fix bug to not read past the length of the section.
Fix bug related to addend computation for MERGE sections.
(cherry picked from commit 84d543b7ed93bf6511cdf45791f4f0b717dfb718)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 92b26ba..ec8dacb 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,11 @@
+2016-02-05 Sriraman Tallam <tmsriram@google.com>
+
+ PR gold/19047
+ * icf.cc (get_rel_addend): New function.
+ (get_section_contents): Move merge section addend computation to a
+ new function. Ignore negative values for SHT_REL and SHT_RELA addends.
+ Fix bug to not read past the length of the section.
+
2015-12-17 Peter Collingbourne <pcc@google.com>
PR gold/18780
diff --git a/gold/icf.cc b/gold/icf.cc
index 96b7f2d..663d579 100644
--- a/gold/icf.cc
+++ b/gold/icf.cc
@@ -213,6 +213,45 @@ preprocess_for_unique_sections(const std::vector<Section_id>& id_section,
}
}
+// For SHF_MERGE sections that use REL relocations, the addend is stored in
+// the text section at the relocation offset. Read the addend value given
+// the pointer to the addend in the text section and the addend size.
+// Update the addend value if a valid addend is found.
+// Parameters:
+// RELOC_ADDEND_PTR : Pointer to the addend in the text section.
+// ADDEND_SIZE : The size of the addend.
+// RELOC_ADDEND_VALUE : Pointer to the addend that is updated.
+
+inline void
+get_rel_addend(const unsigned char* reloc_addend_ptr,
+ const unsigned int addend_size,
+ uint64_t* reloc_addend_value)
+{
+ switch (addend_size)
+ {
+ case 0:
+ break;
+ case 1:
+ *reloc_addend_value =
+ read_from_pointer<8>(reloc_addend_ptr);
+ break;
+ case 2:
+ *reloc_addend_value =
+ read_from_pointer<16>(reloc_addend_ptr);
+ break;
+ case 4:
+ *reloc_addend_value =
+ read_from_pointer<32>(reloc_addend_ptr);
+ break;
+ case 8:
+ *reloc_addend_value =
+ read_from_pointer<64>(reloc_addend_ptr);
+ break;
+ default:
+ gold_unreachable();
+ }
+}
+
// This returns the buffer containing the section's contents, both
// text and relocs. Relocs are differentiated as those pointing to
// sections that could be folded and those that cannot. Only relocs
@@ -397,58 +436,36 @@ get_section_contents(bool first_iteration,
uint64_t entsize =
(it_v->first)->section_entsize(it_v->second);
long long offset = it_a->first;
-
- unsigned long long addend = it_a->second;
- // Ignoring the addend when it is a negative value. See the
- // comments in Merged_symbol_value::Value in object.h.
- if (addend < 0xffffff00)
- offset = offset + addend;
-
- // For SHT_REL relocation sections, the addend is stored in the
- // text section at the relocation offset.
- uint64_t reloc_addend_value = 0;
+ // Handle SHT_RELA and SHT_REL addends, only one of these
+ // addends exists.
+ // Get the SHT_RELA addend. For RELA relocations, we have
+ // the addend from the relocation.
+ uint64_t reloc_addend_value = it_a->second;
+
+ // Handle SHT_REL addends.
+ // For REL relocations, we need to fetch the addend from the
+ // section contents.
const unsigned char* reloc_addend_ptr =
contents + static_cast<unsigned long long>(*it_o);
- switch(*it_addend_size)
- {
- case 0:
- {
- break;
- }
- case 1:
- {
- reloc_addend_value =
- read_from_pointer<8>(reloc_addend_ptr);
- break;
- }
- case 2:
- {
- reloc_addend_value =
- read_from_pointer<16>(reloc_addend_ptr);
- break;
- }
- case 4:
- {
- reloc_addend_value =
- read_from_pointer<32>(reloc_addend_ptr);
- break;
- }
- case 8:
- {
- reloc_addend_value =
- read_from_pointer<64>(reloc_addend_ptr);
- break;
- }
- default:
- gold_unreachable();
- }
- offset = offset + reloc_addend_value;
+
+ // Update the addend value with the SHT_REL addend if
+ // available.
+ get_rel_addend(reloc_addend_ptr, *it_addend_size,
+ &reloc_addend_value);
+
+ // Ignore the addend when it is a negative value. See the
+ // comments in Merged_symbol_value::value in object.h.
+ if (reloc_addend_value < 0xffffff00)
+ offset = offset + reloc_addend_value;
section_size_type secn_len;
+
const unsigned char* str_contents =
(it_v->first)->section_contents(it_v->second,
&secn_len,
false) + offset;
+ gold_assert (offset < (long long) secn_len);
+
if ((secn_flags & elfcpp::SHF_STRINGS) != 0)
{
// String merge section.
@@ -489,10 +506,14 @@ get_section_contents(bool first_iteration,
}
else
{
- // Use the entsize to determine the length.
- buffer.append(reinterpret_cast<const
+ // Use the entsize to determine the length to copy.
+ uint64_t bufsize = entsize;
+ // If entsize is too big, copy all the remaining bytes.
+ if ((offset + entsize) > secn_len)
+ bufsize = secn_len - offset;
+ buffer.append(reinterpret_cast<const
char*>(str_contents),
- entsize);
+ bufsize);
}
buffer.append("@");
}