@@ -14,7 +14,7 @@ use rabbitizer::{
1414} ;
1515
1616use crate :: {
17- arch:: Arch ,
17+ arch:: { Arch , RelocationOverride , RelocationOverrideTarget } ,
1818 diff:: { DiffObjConfig , MipsAbi , MipsInstrCategory , display:: InstructionPart } ,
1919 obj:: {
2020 InstructionArg , InstructionArgValue , InstructionRef , Relocation , RelocationFlags ,
@@ -225,53 +225,67 @@ impl Arch for ArchMips {
225225 Ok ( ( ) )
226226 }
227227
228- fn implcit_addend (
228+ fn relocation_override (
229229 & self ,
230230 file : & object:: File < ' _ > ,
231231 section : & object:: Section ,
232232 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+ }
246252
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) ?;
262269
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 } ) )
267283 } else {
268- ( addend & 0x0000FFFF ) as i16 as i64
284+ Ok ( None )
269285 }
270286 }
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+ }
275289 }
276290
277291 fn demangle ( & self , name : & str ) -> Option < String > {
0 commit comments