Skip to content

Commit 7ba7c3f

Browse files
authored
Merge pull request #741 from DanielSant0s/erl-rela-addend-support
feat: add addend to target relocation address
2 parents ed8e4e9 + 2a52e8a commit 7ba7c3f

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

ee/erl/src/erl.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)