@@ -14,7 +14,7 @@ use rabbitizer::{
14
14
} ;
15
15
16
16
use crate :: {
17
- arch:: Arch ,
17
+ arch:: { Arch , RelocationOverride , RelocationOverrideTarget } ,
18
18
diff:: { DiffObjConfig , MipsAbi , MipsInstrCategory , display:: InstructionPart } ,
19
19
obj:: {
20
20
InstructionArg , InstructionArgValue , InstructionRef , Relocation , RelocationFlags ,
@@ -225,53 +225,67 @@ impl Arch for ArchMips {
225
225
Ok ( ( ) )
226
226
}
227
227
228
- fn implcit_addend (
228
+ fn relocation_override (
229
229
& self ,
230
230
file : & object:: File < ' _ > ,
231
231
section : & object:: Section ,
232
232
address : u64 ,
233
- reloc : & object:: Relocation ,
234
- flags : RelocationFlags ,
235
- ) -> Result < Option < i64 > > {
236
- // Check for paired R_MIPS_HI16 and R_MIPS_LO16 relocations.
237
- if let RelocationFlags :: Elf ( elf:: R_MIPS_HI16 | elf:: R_MIPS_LO16 ) = flags {
238
- if let Some ( addend) = self
239
- . paired_relocations
240
- . get ( section. index ( ) . 0 )
241
- . and_then ( |m| m. get ( & address) . copied ( ) )
242
- {
243
- return Ok ( Some ( addend) ) ;
244
- }
245
- }
233
+ relocation : & object:: Relocation ,
234
+ ) -> Result < Option < RelocationOverride > > {
235
+ match relocation. flags ( ) {
236
+ // Handle ELF implicit relocations
237
+ object:: RelocationFlags :: Elf { r_type } => {
238
+ if relocation. has_implicit_addend ( ) {
239
+ // Check for paired R_MIPS_HI16 and R_MIPS_LO16 relocations.
240
+ if let elf:: R_MIPS_HI16 | elf:: R_MIPS_LO16 = r_type {
241
+ if let Some ( addend) = self
242
+ . paired_relocations
243
+ . get ( section. index ( ) . 0 )
244
+ . and_then ( |m| m. get ( & address) . copied ( ) )
245
+ {
246
+ return Ok ( Some ( RelocationOverride {
247
+ target : RelocationOverrideTarget :: Keep ,
248
+ addend,
249
+ } ) ) ;
250
+ }
251
+ }
246
252
247
- let data = section. data ( ) ?;
248
- let code = data[ address as usize ..address as usize + 4 ] . try_into ( ) ?;
249
- let addend = self . endianness . read_u32_bytes ( code) ;
250
- Ok ( Some ( match flags {
251
- RelocationFlags :: Elf ( elf:: R_MIPS_32 ) => addend as i64 ,
252
- RelocationFlags :: Elf ( elf:: R_MIPS_26 ) => ( ( addend & 0x03FFFFFF ) << 2 ) as i64 ,
253
- RelocationFlags :: Elf ( elf:: R_MIPS_HI16 ) => ( ( addend & 0x0000FFFF ) << 16 ) as i32 as i64 ,
254
- RelocationFlags :: Elf ( elf:: R_MIPS_LO16 | elf:: R_MIPS_GOT16 | elf:: R_MIPS_CALL16 ) => {
255
- ( addend & 0x0000FFFF ) as i16 as i64
256
- }
257
- RelocationFlags :: Elf ( elf:: R_MIPS_GPREL16 | elf:: R_MIPS_LITERAL ) => {
258
- let object:: RelocationTarget :: Symbol ( idx) = reloc. target ( ) else {
259
- bail ! ( "Unsupported R_MIPS_GPREL16 relocation against a non-symbol" ) ;
260
- } ;
261
- let sym = file. symbol_by_index ( idx) ?;
253
+ let data = section. data ( ) ?;
254
+ let code = self
255
+ . endianness
256
+ . read_u32_bytes ( data[ address as usize ..address as usize + 4 ] . try_into ( ) ?) ;
257
+ let addend = match r_type {
258
+ elf:: R_MIPS_32 => code as i64 ,
259
+ elf:: R_MIPS_26 => ( ( code & 0x03FFFFFF ) << 2 ) as i64 ,
260
+ elf:: R_MIPS_HI16 => ( ( code & 0x0000FFFF ) << 16 ) as i32 as i64 ,
261
+ elf:: R_MIPS_LO16 | elf:: R_MIPS_GOT16 | elf:: R_MIPS_CALL16 => {
262
+ ( code & 0x0000FFFF ) as i16 as i64
263
+ }
264
+ elf:: R_MIPS_GPREL16 | elf:: R_MIPS_LITERAL => {
265
+ let object:: RelocationTarget :: Symbol ( idx) = relocation. target ( ) else {
266
+ bail ! ( "Unsupported R_MIPS_GPREL16 relocation against a non-symbol" ) ;
267
+ } ;
268
+ let sym = file. symbol_by_index ( idx) ?;
262
269
263
- // if the symbol we are relocating against is in a local section we need to add
264
- // the ri_gp_value from .reginfo to the addend.
265
- if sym. section ( ) . index ( ) . is_some ( ) {
266
- ( ( addend & 0x0000FFFF ) as i16 as i64 ) + self . ri_gp_value as i64
270
+ // if the symbol we are relocating against is in a local section we need to add
271
+ // the ri_gp_value from .reginfo to the addend.
272
+ if sym. section ( ) . index ( ) . is_some ( ) {
273
+ ( ( code & 0x0000FFFF ) as i16 as i64 ) + self . ri_gp_value as i64
274
+ } else {
275
+ ( code & 0x0000FFFF ) as i16 as i64
276
+ }
277
+ }
278
+ elf:: R_MIPS_PC16 => 0 , // PC-relative relocation
279
+ R_MIPS15_S3 => ( ( code & 0x001FFFC0 ) >> 3 ) as i64 ,
280
+ flags => bail ! ( "Unsupported MIPS implicit relocation {flags:?}" ) ,
281
+ } ;
282
+ Ok ( Some ( RelocationOverride { target : RelocationOverrideTarget :: Keep , addend } ) )
267
283
} else {
268
- ( addend & 0x0000FFFF ) as i16 as i64
284
+ Ok ( None )
269
285
}
270
286
}
271
- RelocationFlags :: Elf ( elf:: R_MIPS_PC16 ) => 0 , // PC-relative relocation
272
- RelocationFlags :: Elf ( R_MIPS15_S3 ) => ( ( addend & 0x001FFFC0 ) >> 3 ) as i64 ,
273
- flags => bail ! ( "Unsupported MIPS implicit relocation {flags:?}" ) ,
274
- } ) )
287
+ _ => Ok ( None ) ,
288
+ }
275
289
}
276
290
277
291
fn demangle ( & self , name : & str ) -> Option < String > {
0 commit comments