Skip to content

Commit 8d459b2

Browse files
authored
librz/bin: fix patching relocations for RISC-V ELFs
* fix unused return value in patch_relocs_riscv and unreachable code in extension parser
1 parent 09cab09 commit 8d459b2

File tree

3 files changed

+124
-64
lines changed

3 files changed

+124
-64
lines changed

librz/arch/p/arch_riscv_extension_parser.inc

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
* RISC-V Extension Parser Using a Trie trick
1010
* Generated from arch/RISCV/RISCVGenSubtargetInfo.inc in Capstone sources
1111
*
12-
* This function parses a single RISC-V extension name and ORs the corresponding
13-
* feature flags with an accumulator 'mode'.
12+
* This function parses a single RISC-V extension name and returns the corresponding
13+
* feature flag.
1414
*
1515
* Trie Diagram:
1616
* ROOT
@@ -556,13 +556,27 @@ typedef enum {
556556
} \
557557
} while (0)
558558

559+
/* Macro: Conditionally invoke a macro if the current character is not on a given blacklist*/
560+
#define DO_IF_NOT_ANY_OF(blacklist, thing) \
561+
do { \
562+
bool __will_do__ = true; \
563+
char *__curr__ = blacklist; \
564+
while (*__curr__ != '\0') { \
565+
if (*p == *__curr__++) { \
566+
__will_do__ = false; \
567+
} \
568+
} \
569+
if (__will_do__) { \
570+
thing; \
571+
} \
572+
} while (0)
573+
559574
/**
560575
* Main parse routine: Try to consume a RISC-V extension name from the architecture string at a given position.
561576
*
562577
* @param arch_str: The full architecture string
563578
* @param idx: Pointer to current index (will be updated to show consumed length)
564-
* @param mode: Pointer to the feature accumulator (will be ORed with the feature flag if extension found)
565-
* @return: Parse result indicating why parsing stopped and whether a match was found
579+
* @param mode: Pointer to the feature result * @return: Parse result indicating why parsing stopped and whether a match was found
566580
*
567581
* Stopping conditions:
568582
* - '\0' (end of string)
@@ -1031,7 +1045,7 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
10311045
}
10321046
} else if (*p == 'h') {
10331047
p++;
1034-
STOP_WITH_MATCH(RISCV_FeatureStdExtZfh);
1048+
DO_IF_NOT_ANY_OF("m", STOP_WITH_MATCH(RISCV_FeatureStdExtZfh));
10351049

10361050
/* State: 'zfh' expecting [m] */
10371051
if (*p == 'm') {
@@ -1087,7 +1101,7 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
10871101
/* State: 'zhin' expecting [x] */
10881102
if (*p == 'x') {
10891103
p++;
1090-
STOP_WITH_MATCH(RISCV_FeatureStdExtZhinx);
1104+
DO_IF_NOT_ANY_OF("m", STOP_WITH_MATCH(RISCV_FeatureStdExtZhinx));
10911105

10921106
/* State: 'zhinx' expecting [m] */
10931107
if (*p == 'm') {
@@ -1473,12 +1487,12 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
14731487
}
14741488
} else if (*p == 'k') {
14751489
p++;
1476-
STOP_WITH_MATCH(RISCV_FeatureStdExtZk);
1490+
DO_IF_NOT_ANY_OF("nrst", STOP_WITH_MATCH(RISCV_FeatureStdExtZk));
14771491

14781492
/* State: 'zk' expecting [nrst] */
14791493
if (*p == 'n') {
14801494
p++;
1481-
STOP_WITH_MATCH(RISCV_FeatureStdExtZkn);
1495+
DO_IF_NOT_ANY_OF("deh", STOP_WITH_MATCH(RISCV_FeatureStdExtZkn));
14821496

14831497
/* State: 'zkn' expecting [deh] */
14841498
if (*p == 'd') {
@@ -1499,7 +1513,7 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
14991513
STOP_WITH_MATCH(RISCV_FeatureStdExtZkr);
15001514
} else if (*p == 's') {
15011515
p++;
1502-
STOP_WITH_MATCH(RISCV_FeatureStdExtZks);
1516+
DO_IF_NOT_ANY_OF("eh", STOP_WITH_MATCH(RISCV_FeatureStdExtZks));
15031517

15041518
/* State: 'zks' expecting [eh] */
15051519
if (*p == 'e') {
@@ -1686,7 +1700,7 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
16861700
}
16871701
} else if (*p == 'h') {
16881702
p++;
1689-
STOP_WITH_MATCH(RISCV_FeatureStdExtZvfh);
1703+
DO_IF_NOT_ANY_OF("m", STOP_WITH_MATCH(RISCV_FeatureStdExtZvfh));
16901704

16911705
/* State: 'zvfh' expecting [m] */
16921706
if (*p == 'm') {
@@ -1725,7 +1739,7 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
17251739
STOP_WITH_MATCH(RISCV_FeatureStdExtZvkg);
17261740
} else if (*p == 'n') {
17271741
p++;
1728-
STOP_WITH_MATCH(RISCV_FeatureStdExtZvkn);
1742+
DO_IF_NOT_ANY_OF("cegh", STOP_WITH_MATCH(RISCV_FeatureStdExtZvkn));
17291743

17301744
/* State: 'zvkn' expecting [cegh] */
17311745
if (*p == 'c') {
@@ -1763,7 +1777,7 @@ try_consume_riscv_ext_from(const char *ext_name, size_t *idx, ut64 *mode) {
17631777
}
17641778
} else if (*p == 's') {
17651779
p++;
1766-
STOP_WITH_MATCH(RISCV_FeatureStdExtZvks);
1780+
DO_IF_NOT_ANY_OF("cegh", STOP_WITH_MATCH(RISCV_FeatureStdExtZvks));
17671781

17681782
/* State: 'zvks' expecting [cegh] */
17691783
if (*p == 'c') {

librz/bin/format/elf/elf_relocs_patching.c

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "elf/glibc_elf.h"
88
#include "rz_types.h"
99
#include "rz_types_base.h"
10+
#include "rz_util/rz_assert.h"
1011
#include "rz_util/rz_buf.h"
1112
#include "rz_util/rz_log.h"
1213

@@ -2342,25 +2343,31 @@ static void patch_reloc_riscv(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_a
23422343
case R_RISCV_NONE:
23432344
return;
23442345

2345-
case R_RISCV_32:
2346+
case R_RISCV_32: {
23462347
val = S + A;
2347-
rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian);
2348+
bool success = rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian);
2349+
rz_return_if_fail(success);
23482350
break;
2349-
2350-
case R_RISCV_64:
2351+
}
2352+
case R_RISCV_64: {
23512353
val = S + A;
2352-
rz_buf_write_ble64_at(buf_patched, patch_addr, val, big_endian);
2354+
bool success = rz_buf_write_ble64_at(buf_patched, patch_addr, val, big_endian);
2355+
rz_return_if_fail(success);
23532356
break;
2354-
2357+
}
23552358
case R_RISCV_RELATIVE:
23562359
val = A + B;
23572360
switch (bits) {
2358-
case 32:
2359-
rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian);
2361+
case 32: {
2362+
bool success = rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian);
2363+
rz_return_if_fail(success);
23602364
break;
2361-
case 64:
2362-
rz_buf_write_ble64_at(buf_patched, patch_addr, val, big_endian);
2365+
}
2366+
case 64: {
2367+
bool success = rz_buf_write_ble64_at(buf_patched, patch_addr, val, big_endian);
2368+
rz_return_if_fail(success);
23632369
break;
2370+
}
23642371
default:
23652372
RZ_LOG_WARN("Unsupported number of bits for R_RISCV_RELATIVE: %d, only 32 bits and 64 bits are supported", bits);
23662373
return;
@@ -2412,22 +2419,28 @@ static void patch_reloc_riscv(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_a
24122419

24132420
case R_RISCV_JUMP_SLOT:
24142421
switch (bits) {
2415-
case 32:
2416-
rz_buf_write_ble32_at(buf_patched, patch_addr, S, big_endian);
2422+
case 32: {
2423+
bool success = rz_buf_write_ble32_at(buf_patched, patch_addr, S, big_endian);
2424+
rz_return_if_fail(success);
24172425
break;
2418-
case 64:
2419-
rz_buf_write_ble64_at(buf_patched, patch_addr, S, big_endian);
2426+
}
2427+
case 64: {
2428+
bool success = rz_buf_write_ble64_at(buf_patched, patch_addr, S, big_endian);
2429+
rz_return_if_fail(success);
24202430
break;
2431+
}
24212432
default:
24222433
RZ_LOG_WARN("Unsupported number of bits for R_RISCV_JUMP_SLOT: %d, only 32 bits and 64 bits are supported", bits);
24232434
break;
24242435
}
24252436
break;
24262437

2427-
case R_RISCV_32_PCREL:
2438+
case R_RISCV_32_PCREL: {
24282439
val = S + A - P;
2429-
rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian);
2440+
bool success = rz_buf_write_ble32_at(buf_patched, patch_addr, val, big_endian);
2441+
rz_return_if_fail(success);
24302442
break;
2443+
}
24312444

24322445
case R_RISCV_GOT_HI20: {
24332446
val = fs->G + fs->GOT + A - P;
@@ -2506,91 +2519,111 @@ static void patch_reloc_riscv(RZ_INOUT RzBuffer *buf_patched, const ut64 patch_a
25062519
rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian);
25072520
ut64 result = ((ut64)old_val) + S + A;
25082521
unsigned long long addr = patch_addr;
2509-
rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)result, big_endian);
2522+
bool success = rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)result, big_endian);
2523+
rz_return_if_fail(success);
25102524
break;
25112525
}
25122526

25132527
case R_RISCV_ADD16: {
25142528
ut16 old_val = 0;
2515-
rz_buf_read_ble16_at(buf_patched, patch_addr, &old_val, big_endian);
2529+
bool success = rz_buf_read_ble16_at(buf_patched, patch_addr, &old_val, big_endian);
2530+
rz_return_if_fail(success);
25162531
ut64 result = ((ut64)old_val) + S + A;
2517-
rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)result, big_endian);
2532+
success = rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)result, big_endian);
2533+
rz_return_if_fail(success);
25182534
break;
25192535
}
25202536

25212537
case R_RISCV_ADD32: {
25222538
ut32 old_val = 0;
2523-
rz_buf_read_ble32_at(buf_patched, patch_addr, &old_val, big_endian);
2539+
bool success = rz_buf_read_ble32_at(buf_patched, patch_addr, &old_val, big_endian);
2540+
rz_return_if_fail(success);
25242541
ut64 result = ((ut64)old_val) + S + A;
2525-
rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)result, big_endian);
2542+
success = rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)result, big_endian);
2543+
rz_return_if_fail(success);
25262544
break;
25272545
}
25282546

25292547
case R_RISCV_ADD64: {
25302548
ut64 old_val = 0;
2531-
rz_buf_read_ble64_at(buf_patched, patch_addr, &old_val, big_endian);
2549+
bool success = rz_buf_read_ble64_at(buf_patched, patch_addr, &old_val, big_endian);
2550+
rz_return_if_fail(success);
25322551
ut64 result = old_val + S + A;
2533-
rz_buf_write_ble64_at(buf_patched, patch_addr, result, big_endian);
2552+
success = rz_buf_write_ble64_at(buf_patched, patch_addr, result, big_endian);
2553+
rz_return_if_fail(success);
25342554
break;
25352555
}
25362556

25372557
case R_RISCV_SUB8: {
25382558
ut8 old_val = 0;
2539-
rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian);
2559+
bool success = rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian);
2560+
rz_return_if_fail(success);
25402561
ut64 result = ((ut64)old_val) - S - A;
25412562
unsigned long long addr = patch_addr;
2542-
rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)result, big_endian);
2563+
success = rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)result, big_endian);
2564+
rz_return_if_fail(success);
25432565
break;
25442566
}
25452567

25462568
case R_RISCV_SUB16: {
25472569
ut16 old_val = 0;
2548-
rz_buf_read_ble16_at(buf_patched, patch_addr, &old_val, big_endian);
2570+
bool success = rz_buf_read_ble16_at(buf_patched, patch_addr, &old_val, big_endian);
2571+
rz_return_if_fail(success);
25492572
ut64 result = ((ut64)old_val) - S - A;
2550-
rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)result, big_endian);
2573+
success = rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)result, big_endian);
2574+
rz_return_if_fail(success);
25512575
break;
25522576
}
25532577

25542578
case R_RISCV_SUB32: {
25552579
ut32 old_val = 0;
2556-
rz_buf_read_ble32_at(buf_patched, patch_addr, &old_val, big_endian);
2580+
bool success = rz_buf_read_ble32_at(buf_patched, patch_addr, &old_val, big_endian);
2581+
rz_return_if_fail(success);
25572582
ut64 result = ((ut64)old_val) - S - A;
2558-
rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)result, big_endian);
2583+
success = rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)result, big_endian);
2584+
rz_return_if_fail(success);
25592585
break;
25602586
}
25612587

25622588
case R_RISCV_SUB64: {
25632589
ut64 old_val = 0;
2564-
rz_buf_read_ble64_at(buf_patched, patch_addr, &old_val, big_endian);
2590+
bool success = rz_buf_read_ble64_at(buf_patched, patch_addr, &old_val, big_endian);
2591+
rz_return_if_fail(success);
25652592
ut64 result = ((ut64)old_val) - S - A;
2566-
rz_buf_write_ble64_at(buf_patched, patch_addr, result, big_endian);
2593+
success = rz_buf_write_ble64_at(buf_patched, patch_addr, result, big_endian);
2594+
rz_return_if_fail(success);
25672595
break;
25682596
}
25692597

25702598
case R_RISCV_SET8: {
25712599
val = S + A;
25722600
unsigned long long addr = patch_addr;
2573-
rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)val, big_endian);
2601+
bool success = rz_buf_write_ble8_offset(buf_patched, &addr, (ut8)val, big_endian);
2602+
rz_return_if_fail(success);
25742603
break;
25752604
}
25762605
case R_RISCV_SET16: {
25772606
val = S + A;
2578-
rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)val, big_endian);
2607+
bool success = rz_buf_write_ble16_at(buf_patched, patch_addr, (ut16)val, big_endian);
2608+
rz_return_if_fail(success);
25792609
break;
25802610
}
25812611
case R_RISCV_SET32: {
25822612
val = S + A;
2583-
rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)val, big_endian);
2613+
bool success = rz_buf_write_ble32_at(buf_patched, patch_addr, (ut32)val, big_endian);
2614+
rz_return_if_fail(success);
25842615
break;
25852616
}
25862617

25872618
case R_RISCV_SET6:
25882619
case R_RISCV_SUB6: {
25892620
ut8 old_val = 0;
2590-
rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian);
2621+
bool success = rz_buf_read_ble8_at(buf_patched, patch_addr, &old_val, big_endian);
2622+
rz_return_if_fail(success);
25912623
val = S + A;
25922624
ut8 result = (rel_type == R_RISCV_SET6) ? val : ((old_val & 0x3F) - val);
2593-
rz_buf_write_ble8_at(buf_patched, patch_addr, (old_val & 0xC0) | (result & 0x3F), big_endian);
2625+
success = rz_buf_write_ble8_at(buf_patched, patch_addr, (old_val & 0xC0) | (result & 0x3F), big_endian);
2626+
rz_return_if_fail(success);
25942627
break;
25952628
}
25962629

0 commit comments

Comments
 (0)