@@ -592,6 +592,7 @@ static int read_erl(int elf_handle, u8 * elf_mem, u32 addr, struct erl_record_t
592592 u32 fullsize = 0 ;
593593 struct erl_record_t * erl_record = 0 ;
594594 struct symbol_t * s ;
595+ u32 addend = 0 ;
595596
596597 int has_next_reloc = 0 ;
597598
@@ -843,6 +844,8 @@ return code
843844 for (j = 0 ; (u32 )j < (sec [i ].sh_size / sec [i ].sh_entsize ); j ++ ) {
844845 int sym_n , next_sym_n ;
845846
847+ addend = (sec [i ].sh_type == RELA ? ((struct elf_rela_t * )(reloc_section + j * sec [i ].sh_entsize ))-> r_addend : 0 );
848+
846849 reloc = * ((struct elf_reloc_t * ) (reloc_section + j * sec [i ].sh_entsize ));
847850
848851 sym_n = reloc .r_info >> 8 ;
@@ -864,7 +867,7 @@ return code
864867 add_loosy (erl_record , erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , strtab_names + sym [sym_n ].st_name );
865868 } else {
866869 dprintf ("Found symbol at %08X, relocating.\n" , s -> address );
867- if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , s -> address ) < 0 ) {
870+ if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , s -> address + addend ) < 0 ) {
868871 dprintf ("Something went wrong in relocation." );
869872 free_and_return (-1 );
870873 }
@@ -878,13 +881,13 @@ return code
878881 if ((reloc .r_info & 255 ) == R_MIPS_HI16 &&
879882 (has_next_reloc && ((next_reloc .r_info & 255 ) == R_MIPS_LO16 )) &&
880883 (sec [sym [sym_n ].st_shndx ].sh_addr == sec [sym [next_sym_n ].st_shndx ].sh_addr ) &&
881- (* (u16 * )(erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + next_reloc .r_offset ) + ((u32 ) (erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr ) & 0x0000ffff )) >= 0x8000
884+ (* (u16 * )(erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + next_reloc .r_offset ) + ((( u32 ) (erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr ) + addend ) & 0x0000ffff )) >= 0x8000
882885 ) {
883886 u32 data = * (u32 * )(erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset );
884887 * (u32 * )(erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset ) = data + !(data & 0xf );
885888 }
886889
887- if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , (u32 ) (erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr )) < 0 ) {
890+ if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , (u32 ) (erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr )+ addend ) < 0 ) {
888891 dprintf ("Something went wrong in relocation." );
889892 free_and_return (-1 );
890893 }
@@ -894,14 +897,14 @@ return code
894897 rprintf ("internal relocation to symbol %s\n" , strtab_names + sym [sym_n ].st_name );
895898 if ((s = erl_find_symbol (strtab_names + sym [sym_n ].st_name ))) {
896899 dprintf ("Symbol already exists at %08X. Let's use it instead.\n" , s -> address );
897- if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , s -> address ) < 0 ) {
900+ if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , s -> address + addend ) < 0 ) {
898901 dprintf ("Something went wrong in relocation." );
899902 free_and_return (-1 );
900903 }
901904 add_dependancy (erl_record , s -> provider );
902905 } else {
903906 dprintf ("Relocating at %08X.\n" , erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr + sym [sym_n ].st_value );
904- if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , (u32 ) (erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr + sym [sym_n ].st_value )) < 0 ) {
907+ if (apply_reloc (erl_record -> bytes + sec [sec [i ].sh_info ].sh_addr + reloc .r_offset , reloc .r_info & 255 , (u32 ) (erl_record -> bytes + sec [sym [sym_n ].st_shndx ].sh_addr + sym [sym_n ].st_value )+ addend ) < 0 ) {
905908 dprintf ("Something went wrong in relocation." );
906909 free_and_return (-1 );
907910 }
0 commit comments