@@ -6,10 +6,10 @@ use alloc::{
66 vec:: Vec ,
77} ;
88
9- use anyhow:: { Result , bail, ensure} ;
9+ use anyhow:: { Result , anyhow , bail, ensure} ;
1010use cwextab:: { ExceptionTableData , decode_extab} ;
1111use flagset:: Flags ;
12- use object:: { Endian as _ , Object as _, ObjectSection as _, ObjectSymbol as _, elf, pe} ;
12+ use object:: { Object as _, ObjectSection as _, ObjectSymbol as _, elf, pe} ;
1313
1414use crate :: {
1515 arch:: { Arch , DataType } ,
@@ -210,32 +210,35 @@ impl Arch for ArchPpc {
210210
211211 fn implcit_addend (
212212 & self ,
213- file : & object:: File < ' _ > ,
213+ _file : & object:: File < ' _ > ,
214214 section : & object:: Section ,
215215 address : u64 ,
216216 _relocation : & object:: Relocation ,
217217 flags : RelocationFlags ,
218- ) -> Result < i64 > {
219- let section_data = section. data ( ) ?;
220- let address = address as usize ;
221- let data = section_data
222- . get ( address..address + 4 )
223- . ok_or_else ( || anyhow:: anyhow!( "Invalid address {address} for section data" ) ) ?
224- . try_into ( ) ?;
225- let code = file. endianness ( ) . read_u32_bytes ( data) ;
226- Ok ( match flags {
218+ ) -> Result < Option < i64 > > {
219+ match flags {
220+ // IMAGE_REL_PPC_PAIR contains the REF{HI,LO} displacement instead of a symbol index
227221 RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_REFHI )
228- | RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_REFLO ) => ( code & 0xffff ) as i16 as i32 ,
229- RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_REL24 ) => {
230- // let addend = (((code & 0x3fffffc) << 6) as i32) >> 6;
231- // println!("PPC_REL24 addend: {data:?} => {addend}");
232- // addend
233- 0
234- }
235- RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_ADDR32 ) => code as i32 ,
236- RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_PAIR ) => 0 ,
237- flags => bail ! ( "Unsupported PPC implicit relocation {flags:?}" ) ,
238- } as i64 )
222+ | RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_REFLO ) => section
223+ . relocations ( )
224+ . skip_while ( |& ( a, _) | a < address)
225+ . take_while ( |& ( a, _) | a == address)
226+ . find ( |( _, reloc) | {
227+ matches ! ( reloc. flags( ) , object:: RelocationFlags :: Coff {
228+ typ: pe:: IMAGE_REL_PPC_PAIR
229+ } )
230+ } )
231+ . map_or ( Ok ( Some ( 0 ) ) , |( _, reloc) | match reloc. target ( ) {
232+ object:: RelocationTarget :: Symbol ( index) => {
233+ Ok ( Some ( index. 0 as u16 as i16 as i64 ) )
234+ }
235+ target => Err ( anyhow ! ( "Unsupported IMAGE_REL_PPC_PAIR target {target:?}" ) ) ,
236+ } ) ,
237+ // Skip PAIR relocations as they are handled by the previous case
238+ RelocationFlags :: Coff ( pe:: IMAGE_REL_PPC_PAIR ) => Ok ( None ) ,
239+ RelocationFlags :: Coff ( _) => Ok ( Some ( 0 ) ) ,
240+ flags => Err ( anyhow ! ( "Unsupported PPC implicit relocation {flags:?}" ) ) ,
241+ }
239242 }
240243
241244 fn demangle ( & self , name : & str ) -> Option < String > {
@@ -263,7 +266,15 @@ impl Arch for ArchPpc {
263266 elf:: R_PPC_REL14 => Some ( "R_PPC_REL14" ) ,
264267 _ => None ,
265268 } ,
266- _ => None ,
269+ RelocationFlags :: Coff ( r_type) => match r_type {
270+ pe:: IMAGE_REL_PPC_ADDR32 => Some ( "IMAGE_REL_PPC_ADDR32" ) ,
271+ pe:: IMAGE_REL_PPC_REFHI => Some ( "IMAGE_REL_PPC_REFHI" ) ,
272+ pe:: IMAGE_REL_PPC_REFLO => Some ( "IMAGE_REL_PPC_REFLO" ) ,
273+ pe:: IMAGE_REL_PPC_REL24 => Some ( "IMAGE_REL_PPC_REL24" ) ,
274+ pe:: IMAGE_REL_PPC_REL14 => Some ( "IMAGE_REL_PPC_REL14" ) ,
275+ pe:: IMAGE_REL_PPC_PAIR => Some ( "IMAGE_REL_PPC_PAIR" ) ,
276+ _ => None ,
277+ } ,
267278 }
268279 }
269280
0 commit comments