Skip to content

Commit

Permalink
Update prev and add more relocs
Browse files Browse the repository at this point in the history
  • Loading branch information
pelijah authored and XVilka committed Jan 31, 2024
1 parent ceb8b6a commit d21b6a6
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 27 deletions.
67 changes: 55 additions & 12 deletions librz/bin/p/bin_elf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ static void patch_reloc_hexagon(RZ_INOUT RzBuffer *buf_patched, const ut64 patch

static void patch_reloc(struct Elf_(rz_bin_elf_obj_t) * obj, RzBinElfReloc *rel, ut64 S, ut64 B, ut64 L, ut64 GOT) {
ut16 e_machine = obj->ehdr.e_machine;
ut64 val = 0, keep, orig;
ut64 val = 0;
ut64 A = rel->addend, P = rel->vaddr;
RzBinRelocFormularSymbols formular_sym = { .A = A, .B = B, .GOT = GOT, .L = L, .S = S, .P = P, .MB = 0, .G = 0, .GP = 0, .T = 0, .TLS = 0 };
ut64 patch_addr = rel->paddr != UT64_MAX ? rel->paddr : Elf_(rz_bin_elf_v2p)(obj, rel->vaddr);
Expand All @@ -1048,40 +1048,81 @@ static void patch_reloc(struct Elf_(rz_bin_elf_obj_t) * obj, RzBinElfReloc *rel,
}
rz_buf_write_ble32_at(obj->buf_patched, patch_addr, val, obj->big_endian);
break;
case EM_AARCH64:
case EM_AARCH64: {
ut32 keep;
ut32 nbytes = 4;
rz_buf_read_at(obj->buf_patched, patch_addr, buf, 8);
switch (rel->type) {
case RZ_AARCH64_ABS16:
val = S + A;
rz_write_le16(buf, val);
nbytes = 2;
break;
case RZ_AARCH64_ABS32:
val = S + A;
rz_write_le32(buf, val);
break;
case RZ_AARCH64_GLOB_DAT:
case RZ_AARCH64_ABS64:
case RZ_AARCH64_JUMP_SLOT:
val = S + A;
rz_write_le64(buf, val);
nbytes = 8;
break;
case RZ_AARCH64_PREL16:
val = S + A - P;
rz_write_le16(buf, val);
nbytes = 2;
break;
case RZ_AARCH64_PREL32:
val = S + A - P;
rz_write_le32(buf, val);
break;
case RZ_AARCH64_PREL64:
val = S + A - P;
rz_write_le64(buf, val);
nbytes = 8;
break;
case RZ_AARCH64_RELATIVE:
val = B + A;
rz_write_le64(buf, val);
nbytes = 8;
break;
case RZ_AARCH64_ADR_PREL_PG_HI21:
case RZ_AARCH64_ADR_PREL_PG_HI21_NC:
case RZ_AARCH64_ADR_GOT_PAGE:
// Reencode ADR imm
orig = rz_read_le32(buf);
keep = orig & ~(ADR_IMM_MASK1 | ADR_IMM_MASK2);
val = PG(S + A) - PG(P);
keep = rz_read_le32(buf) & ~(ADR_IMM_MASK1 | ADR_IMM_MASK2);
val = ((st64)(PG(S + A) - PG(P))) >> 12;
rz_write_le32(buf, keep | ((val & RZ_BIT_MASK32(2, 0)) << 29) | ((val & ADR_IMM_MASK3) << 3));
orig = rz_read_le32(buf);
break;
case RZ_AARCH64_JUMP26:
case RZ_AARCH64_CALL26:
// Reencode 26 bits of the offset
keep = rz_read_le32(buf) & ~RZ_BIT_MASK32(26, 0);
val = S + A;
val = ((st64)(S + A - P)) >> 2;
rz_write_le32(buf, keep | (val & RZ_BIT_MASK32(26, 0)));
break;
case RZ_AARCH64_LDST8_ABS_LO12_NC:
case RZ_AARCH64_ADD_ABS_LO12_NC:
case RZ_AARCH64_LD64_GOT_LO12_NC:
// Reencode ADD or LD/ST imm
keep = rz_read_le32(buf) & ~(RZ_BIT_MASK32(12, 0) << 10);
val = PG_OFFSET(S + A);
rz_write_le32(buf, keep | ((val & RZ_BIT_MASK32(12, 0)) << 10));
break;
case RZ_AARCH64_LD64_GOT_LO12_NC:
case RZ_AARCH64_LDST64_ABS_LO12_NC:
// Reencode LD/ST imm
keep = rz_read_le32(buf) & ~(RZ_BIT_MASK32(12, 0) << 10);
val = PG_OFFSET(S + A) >> 3;
rz_write_le32(buf, keep | ((val & RZ_BIT_MASK32(12, 0)) << 10));
break;
default:
val = S + A;
rz_write_le64(buf, val);
nbytes = 0;
break;
}
rz_buf_write_at(obj->buf_patched, patch_addr, buf, 8);
rz_buf_write_at(obj->buf_patched, patch_addr, buf, nbytes);
break;
}
case EM_PPC64: {
int low = 0, word = 0;
switch (rel->type) {
Expand Down Expand Up @@ -1408,9 +1449,11 @@ static RzBinReloc *reloc_convert(ELFOBJ *bin, RzBinElfReloc *rel, ut64 GOT) {
case RZ_AARCH64_GLOB_DAT: SET(64);
case RZ_AARCH64_JUMP_SLOT: SET(64);
case RZ_AARCH64_RELATIVE: ADD(64, B);
case RZ_AARCH64_LDST8_ABS_LO12_NC: ADD(16, 0);
case RZ_AARCH64_ADD_ABS_LO12_NC: ADD(16, 0);
case RZ_AARCH64_JUMP26: ADD(32, 0);
case RZ_AARCH64_CALL26: ADD(32, 0);
case RZ_AARCH64_LDST64_ABS_LO12_NC: ADD(32, 0);
case RZ_AARCH64_LD64_GOT_LO12_NC: ADD(32, 0);
// Page-relative relocations
case RZ_AARCH64_ADR_GOT_PAGE: ADD(32, 0);
Expand Down
30 changes: 15 additions & 15 deletions test/db/formats/elf/elf-relarm
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ EXPECT=<<EOF
;-- section..init_array:
;-- segment.LOAD1:
;-- .datadiv_decode9958896245423089702:
0x00126510 .qword 0x0000000000005a6c ; reloc.target..datadiv_decode9958896245423089702 ; sym..datadiv_decode9958896245423089702; RELOC 64 .datadiv_decode9958896245423089702 @ 0x00005a6c ; [13] -rw- section size 728 named .init_array
0x00126510 .qword 0x0000000000005a6c ; reloc.target..datadiv_decode9958896245423089702 ; sym..datadiv_decode9958896245423089702; RELOC 64 .datadiv_decode9958896245423089702 @ 0x00005a6c ; [12] -rw- section size 728 named .init_array
;-- .datadiv_decode10476194973746341988:
0x00126518 .qword 0x0000000000005a80 ; reloc.target..datadiv_decode10476194973746341988 ; sym..datadiv_decode10476194973746341988; RELOC 64 .datadiv_decode10476194973746341988 @ 0x00005a80
;-- .datadiv_decode16323044921667855934:
Expand Down Expand Up @@ -190,22 +190,22 @@ EXPECT=<<EOF
0x08000444 = 0x00
0x08000445 = 0x00
0x08000446 = 0x00
0x08000447 = 0xb0
adrp x0, 0x8001000
0x08000460 = 0x28
0x08000461 = 0x4a
0x08000447 = 0xf0
adrp x0, 0x8003000
0x08000460 = 0x1c
0x08000461 = 0x0d
0x08000462 = 0x00
0x08000463 = 0x54
b.hi stackCursor
0x0800046c = 0x20
0x0800046d = 0x58
0x0800046e = 0x60
0x0800046f = 0xb8
ldr w0, [x1, w0, uxtw 2]
0x080003d8 = 0x36
0x080003d9 = 0x04
0x08000463 = 0x94
bl reloc.target.stackCursor
0x0800046c = 0x00
0x0800046d = 0x64
0x0800046e = 0x44
0x0800046f = 0xf9
ldr x0, [x0, 0x8c8]
0x080003d8 = 0x3a
0x080003d9 = 0x0d
0x080003da = 0x00
0x080003db = 0x94
bl fputs
bl reloc.target.fputs
EOF
RUN

0 comments on commit d21b6a6

Please sign in to comment.