@@ -119,26 +119,39 @@ AArch64MCSymbolizer::adjustRelocation(const Relocation &Rel,
119
119
// The ADRP+LDR sequence was converted into ADRP+ADD. We are looking at the
120
120
// second instruction and have to use the relocation type for ADD.
121
121
AdjustedRel.Type = ELF::R_AARCH64_ADD_ABS_LO12_NC;
122
- } else {
123
- // For instructions that reference GOT, ignore the referenced symbol and
124
- // use value at the relocation site. FixRelaxationPass will look at
125
- // instruction pairs and will perform necessary adjustments.
122
+ return AdjustedRel;
123
+ }
124
+
125
+ // ADRP is a special case since the linker can leave the instruction opcode
126
+ // intact and modify only the operand. We are doing our best to detect when
127
+ // such conversion has happened without looking at the next instruction.
128
+ //
129
+ // If we detect that a page referenced by the ADRP cannot belong to GOT, and
130
+ // that it matches the symbol from the relocation, then we can be certain
131
+ // that the linker converted the GOT reference into the local one. Otherwise,
132
+ // we leave the disambiguation resolution to FixRelaxationPass.
133
+ //
134
+ // Note that ADRP relaxation described above cannot happen for TLS relocation.
135
+ // Since TLS relocations may not even have a valid symbol (not supported by
136
+ // BOLT), we explicitly exclude them from the check.
137
+ if (BC.MIB ->isADRP (Inst) && Rel.Addend == 0 && !Relocation::isTLS (Rel.Type )) {
126
138
ErrorOr<uint64_t > SymbolValue = BC.getSymbolValue (*Rel.Symbol );
127
139
assert (SymbolValue && " Symbol value should be set" );
128
140
const uint64_t SymbolPageAddr = *SymbolValue & ~0xfffULL ;
129
141
130
- // Check if defined symbol and GOT are on the same page. If they are not,
131
- // disambiguate the operand.
132
- if (BC.MIB ->isADRP (Inst) && Rel.Addend == 0 &&
133
- SymbolPageAddr == Rel.Value &&
142
+ if (SymbolPageAddr == Rel.Value &&
134
143
!isPageAddressValidForGOT (SymbolPageAddr)) {
135
144
AdjustedRel.Type = ELF::R_AARCH64_ADR_PREL_PG_HI21;
136
- } else {
137
- AdjustedRel.Symbol = BC.registerNameAtAddress (" __BOLT_got_zero" , 0 , 0 , 0 );
138
- AdjustedRel.Addend = Rel.Value ;
145
+ return AdjustedRel;
139
146
}
140
147
}
141
148
149
+ // For instructions that reference GOT, ignore the referenced symbol and
150
+ // use value at the relocation site. FixRelaxationPass will look at
151
+ // instruction pairs and will perform necessary adjustments.
152
+ AdjustedRel.Symbol = BC.registerNameAtAddress (" __BOLT_got_zero" , 0 , 0 , 0 );
153
+ AdjustedRel.Addend = Rel.Value ;
154
+
142
155
return AdjustedRel;
143
156
}
144
157
0 commit comments