@@ -45,24 +45,15 @@ bool AArch64MCSymbolizer::tryAddingSymbolicOperand(
4545 BC.MIB ->getTargetExprFor (Inst, Expr, *Ctx, RelType)));
4646 };
4747
48- // The linker can convert ADRP+ADD and ADRP+LDR instruction sequences into
49- // NOP+ADR. After the conversion, the linker might keep the relocations and
50- // if we try to symbolize ADR's operand using outdated relocations, we might
51- // get unexpected results. Hence, we check for the conversion/relaxation, and
52- // ignore the relocation. The symbolization is done based on the PC-relative
53- // value of the operand instead.
54- if (Relocation && BC.MIB ->isADR (Inst)) {
55- if (Relocation->Type == ELF::R_AARCH64_ADD_ABS_LO12_NC ||
56- Relocation->Type == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
57- LLVM_DEBUG (dbgs () << " BOLT-DEBUG: ignoring relocation at 0x"
58- << Twine::utohexstr (InstAddress) << ' \n ' );
59- Relocation = nullptr ;
48+ if (Relocation) {
49+ auto AdjustedRel = adjustRelocation (*Relocation, Inst);
50+ if (AdjustedRel) {
51+ addOperand (AdjustedRel->Symbol , AdjustedRel->Addend , AdjustedRel->Type );
52+ return true ;
6053 }
61- }
6254
63- if (Relocation) {
64- addOperand (Relocation->Symbol , Relocation->Addend , Relocation->Type );
65- return true ;
55+ LLVM_DEBUG (dbgs () << " BOLT-DEBUG: ignoring relocation at 0x"
56+ << Twine::utohexstr (InstAddress) << ' \n ' );
6657 }
6758
6859 if (!BC.MIB ->hasPCRelOperand (Inst))
@@ -88,6 +79,63 @@ bool AArch64MCSymbolizer::tryAddingSymbolicOperand(
8879 return true ;
8980}
9081
82+ std::optional<Relocation>
83+ AArch64MCSymbolizer::adjustRelocation (const Relocation &Rel,
84+ const MCInst &Inst) const {
85+ BinaryContext &BC = Function.getBinaryContext ();
86+
87+ // The linker can convert ADRP+ADD and ADRP+LDR instruction sequences into
88+ // NOP+ADR. After the conversion, the linker might keep the relocations and
89+ // if we try to symbolize ADR's operand using outdated relocations, we might
90+ // get unexpected results. Hence, we check for the conversion/relaxation, and
91+ // ignore the relocation. The symbolization is done based on the PC-relative
92+ // value of the operand instead.
93+ if (BC.MIB ->isADR (Inst) && (Rel.Type == ELF::R_AARCH64_ADD_ABS_LO12_NC ||
94+ Rel.Type == ELF::R_AARCH64_LD64_GOT_LO12_NC))
95+ return std::nullopt ;
96+
97+ // The linker might perform TLS relocations relaxations, such as
98+ // changed TLS access model (e.g. changed global dynamic model
99+ // to initial exec), thus changing the instructions. The static
100+ // relocations might be invalid at this point and we might no
101+ // need to process these relocations anymore.
102+ // More information could be found by searching
103+ // elfNN_aarch64_tls_relax in bfd
104+ if (BC.MIB ->isMOVW (Inst)) {
105+ switch (Rel.Type ) {
106+ default :
107+ break ;
108+ case ELF::R_AARCH64_TLSDESC_LD64_LO12:
109+ case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
110+ case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
111+ case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
112+ return std::nullopt ;
113+ }
114+ }
115+
116+ if (!Relocation::isGOT (Rel.Type ))
117+ return Rel;
118+
119+ Relocation AdjustedRel = Rel;
120+ if (Rel.Type == ELF::R_AARCH64_LD64_GOT_LO12_NC && BC.MIB ->isAddXri (Inst)) {
121+ // The ADRP+LDR sequence was converted into ADRP+ADD. We are looking at the
122+ // second instruction and have to use the relocation type for ADD.
123+ AdjustedRel.Type = ELF::R_AARCH64_ADD_ABS_LO12_NC;
124+ } else {
125+ // For instructions that reference GOT, ignore the referenced symbol and
126+ // use value at the relocation site. FixRelaxationPass will look at
127+ // instruction pairs and will perform necessary adjustments.
128+ ErrorOr<uint64_t > SymbolValue = BC.getSymbolValue (*Rel.Symbol );
129+ assert (SymbolValue && " Symbol value should be set" );
130+ const uint64_t SymbolPageAddr = *SymbolValue & ~0xfffULL ;
131+
132+ AdjustedRel.Symbol = BC.registerNameAtAddress (" __BOLT_got_zero" , 0 , 0 , 0 );
133+ AdjustedRel.Addend = Rel.Value ;
134+ }
135+
136+ return AdjustedRel;
137+ }
138+
91139void AArch64MCSymbolizer::tryAddingPcLoadReferenceComment (raw_ostream &CStream,
92140 int64_t Value,
93141 uint64_t Address) {}
0 commit comments