@@ -85,6 +85,16 @@ pub enum RelocationKind {
85
85
LArchAbs64Hi12 ,
86
86
/// LoongArch absolute low 20bit
87
87
LArchAbs64Lo20 ,
88
+ /// LoongArch PC-relative call 38bit
89
+ LArchCall36 ,
90
+ /// LoongArch PC-relative high 20bit
91
+ LArchPCAlaHi20 ,
92
+ /// LoongArch PC-relative low 12bit
93
+ LArchPCAlaLo12 ,
94
+ /// LoongArch PC64-relative high 12bit
95
+ LArchPCAla64Hi12 ,
96
+ /// LoongArch PC64-relative low 20bit
97
+ LArchPCAla64Lo20 ,
88
98
/// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol.
89
99
ElfX86_64TlsGd ,
90
100
// /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry.
@@ -115,6 +125,11 @@ impl fmt::Display for RelocationKind {
115
125
Self :: LArchAbsLo12 => write ! ( f, "LArchAbsLo12" ) ,
116
126
Self :: LArchAbs64Hi12 => write ! ( f, "LArchAbs64Hi12" ) ,
117
127
Self :: LArchAbs64Lo20 => write ! ( f, "LArchAbs64Lo20" ) ,
128
+ Self :: LArchCall36 => write ! ( f, "LArchCall36" ) ,
129
+ Self :: LArchPCAlaHi20 => write ! ( f, "LArchPCAlaHi20" ) ,
130
+ Self :: LArchPCAlaLo12 => write ! ( f, "LArchPCAlaLo12" ) ,
131
+ Self :: LArchPCAla64Hi12 => write ! ( f, "LArchPCAla64Hi12" ) ,
132
+ Self :: LArchPCAla64Lo20 => write ! ( f, "LArchPCAla64Lo20" ) ,
118
133
Self :: Aarch64AdrPrelLo21 => write ! ( f, "Aarch64AdrPrelLo21" ) ,
119
134
Self :: Aarch64AdrPrelPgHi21 => write ! ( f, "Aarch64AdrPrelPgHi21" ) ,
120
135
Self :: Aarch64AddAbsLo12Nc => write ! ( f, "Aarch64AddAbsLo12Nc" ) ,
@@ -172,7 +187,12 @@ pub trait RelocationLike {
172
187
| RelocationKind :: Arm64Movw3
173
188
| RelocationKind :: RiscvPCRelLo12I
174
189
| RelocationKind :: Aarch64Ldst128AbsLo12Nc
175
- | RelocationKind :: Aarch64Ldst64AbsLo12Nc => {
190
+ | RelocationKind :: Aarch64Ldst64AbsLo12Nc
191
+ | RelocationKind :: LArchAbsHi20
192
+ | RelocationKind :: LArchAbsLo12
193
+ | RelocationKind :: LArchAbs64Lo20
194
+ | RelocationKind :: LArchAbs64Hi12
195
+ | RelocationKind :: LArchPCAlaLo12 => {
176
196
let reloc_address = start + self . offset ( ) as usize ;
177
197
let reloc_addend = self . addend ( ) as isize ;
178
198
let reloc_abs = target_func_address
@@ -239,6 +259,45 @@ pub trait RelocationLike {
239
259
let pc_page = reloc_address & !( 0xFFF ) ;
240
260
( reloc_address, target_page. wrapping_sub ( pc_page) as u64 )
241
261
}
262
+ RelocationKind :: LArchCall36 => {
263
+ let reloc_address = start + self . offset ( ) as usize ;
264
+ let reloc_addend = self . addend ( ) as isize ;
265
+ let reloc_delta = target_func_address
266
+ . wrapping_sub ( reloc_address as u64 )
267
+ . wrapping_add ( reloc_addend as u64 ) ;
268
+ (
269
+ reloc_address,
270
+ reloc_delta. wrapping_add ( ( reloc_delta & 0x20000 ) << 1 ) ,
271
+ )
272
+ }
273
+ RelocationKind :: LArchPCAlaHi20 => {
274
+ let reloc_address = start + self . offset ( ) as usize ;
275
+ let reloc_addend = self . addend ( ) as isize ;
276
+ let target_page = ( target_func_address
277
+ . wrapping_add ( reloc_addend as u64 )
278
+ . wrapping_add ( 0x800 )
279
+ & !( 0xFFF ) ) as usize ;
280
+ let pc_page = reloc_address & !( 0xFFF ) ;
281
+ ( reloc_address, target_page. wrapping_sub ( pc_page) as u64 )
282
+ }
283
+ RelocationKind :: LArchPCAla64Hi12 | RelocationKind :: LArchPCAla64Lo20 => {
284
+ let reloc_address = start + self . offset ( ) as usize ;
285
+ let reloc_addend = self . addend ( ) as isize ;
286
+ let reloc_offset = match self . kind ( ) {
287
+ RelocationKind :: LArchPCAla64Lo20 => 8 ,
288
+ RelocationKind :: LArchPCAla64Hi12 => 12 ,
289
+ _ => 0 ,
290
+ } ;
291
+ let target_func_address = target_func_address. wrapping_add ( reloc_addend as u64 ) ;
292
+ let target_page = ( target_func_address & !( 0xFFF ) ) as usize ;
293
+ let pc_page = ( reloc_address - reloc_offset) & !( 0xFFF ) ;
294
+ let mut reloc_delta = target_page. wrapping_sub ( pc_page) as u64 ;
295
+ reloc_delta = reloc_delta
296
+ . wrapping_add ( ( target_func_address & 0x800 ) << 1 )
297
+ . wrapping_sub ( ( target_func_address & 0x800 ) << 21 ) ;
298
+ reloc_delta = reloc_delta. wrapping_add ( ( reloc_delta & 0x80000000 ) << 1 ) ;
299
+ ( reloc_address, reloc_delta)
300
+ }
242
301
_ => panic ! ( "Relocation kind unsupported" ) ,
243
302
}
244
303
}
0 commit comments