@@ -476,34 +476,47 @@ fn get_offset_and_addr_gpr_for_possible_pool_reference(
476476fn make_fake_pool_reloc ( offset : i16 , cur_addr : u32 , pool_reloc : & ObjReloc ) -> Option < ObjReloc > {
477477 let offset_from_pool = pool_reloc. addend + offset as i64 ;
478478 let target_address = pool_reloc. target . address . checked_add_signed ( offset_from_pool) ?;
479- let orig_section_index = pool_reloc. target . orig_section_index ?;
480- // We also need to create a fake target symbol to go inside our fake relocation.
481- // This is because we don't have access to list of all symbols in this section, so we can't find
482- // the real symbol yet. Instead we make a placeholder that has the correct `orig_section_index`
483- // and `address` fields, and then later on when this information is displayed to the user, we
484- // can find the real symbol by searching through the object's section's symbols for one that
485- // contains this address.
486- let fake_target_symbol = ObjSymbol {
487- name : "" . to_string ( ) ,
488- demangled_name : None ,
489- address : target_address,
490- section_address : 0 ,
491- size : 0 ,
492- size_known : false ,
493- kind : Default :: default ( ) ,
494- flags : Default :: default ( ) ,
495- orig_section_index : Some ( orig_section_index) ,
496- virtual_address : None ,
497- original_index : None ,
498- bytes : vec ! [ ] ,
479+ let target_symbol = if pool_reloc. target . orig_section_index . is_some ( ) {
480+ // If the target symbol is within this current object, then we also need to create a fake
481+ // target symbol to go inside our fake relocation. This is because we don't have access to
482+ // list of all symbols in this section, so we can't find the real symbol within the pool
483+ // based on its address yet. Instead we make a placeholder that has the correct
484+ // `orig_section_index` and `address` fields, and then later on when this information is
485+ // displayed to the user, we can find the real symbol by searching through the object's
486+ // section's symbols for one that contains this address.
487+ ObjSymbol {
488+ name : "" . to_string ( ) ,
489+ demangled_name : None ,
490+ address : target_address,
491+ section_address : 0 ,
492+ size : 0 ,
493+ size_known : false ,
494+ kind : Default :: default ( ) ,
495+ flags : Default :: default ( ) ,
496+ orig_section_index : pool_reloc. target . orig_section_index ,
497+ virtual_address : None ,
498+ original_index : None ,
499+ bytes : vec ! [ ] ,
500+ }
501+ } else {
502+ // But if the target symbol is in a different object (extern), then we simply copy the pool
503+ // relocation's target. This is because it won't be possible to locate the actual symbol
504+ // later on based only off of an offset without knowing the object or section it's in. And
505+ // doing that for external symbols would also be unnecessary, because when the compiler
506+ // generates an instruction that accesses an external "pool" plus some offset, that won't be
507+ // a normal pool that contains other symbols within it that we want to display. It will be
508+ // something like a vtable for a class with multiple inheritance (for example, dCcD_Cyl in
509+ // The Wind Waker). So just showing that vtable symbol plus an addend to represent the
510+ // offset into it works fine in this case, no fake symbol to hold an address is necessary.
511+ pool_reloc. target . clone ( )
499512 } ;
500513 // The addend is also fake because we don't know yet if the `target_address` here is the exact
501514 // start of the symbol or if it's in the middle of it.
502515 let fake_addend = 0 ;
503516 Some ( ObjReloc {
504517 flags : RelocationFlags :: Elf { r_type : elf:: R_PPC_NONE } ,
505518 address : cur_addr as u64 ,
506- target : fake_target_symbol ,
519+ target : target_symbol ,
507520 addend : fake_addend,
508521 } )
509522}
0 commit comments