diff --git a/libsframe/sframe.c b/libsframe/sframe.c index c2693b978ec..c1bc692829a 100644 --- a/libsframe/sframe.c +++ b/libsframe/sframe.c @@ -372,40 +372,27 @@ sframe_fre_check_range_p (sframe_func_desc_entry *fdep, int32_t start_ip_offset, int32_t end_ip_offset, int32_t pc) { - int32_t start_ip, end_ip; int32_t func_start_addr; uint8_t rep_block_size; uint32_t fde_type; - int32_t masked_pc; + int32_t pc_offset; bool mask_p; - bool ret; - - ret = false; if (!fdep) - return ret; + return false; func_start_addr = fdep->sfde_func_start_address; fde_type = sframe_get_fde_type (fdep); mask_p = (fde_type == SFRAME_FDE_TYPE_PCMASK); rep_block_size = fdep->sfde_func_rep_size; - if (!mask_p) - { - start_ip = start_ip_offset + func_start_addr; - end_ip = end_ip_offset + func_start_addr; - ret = ((start_ip <= pc) && (end_ip >= pc)); - } - else - { - /* For FDEs for repetitive pattern of insns, we need to return the FRE - where pc % rep_block_size is between start_ip_offset and - end_ip_offset. */ - masked_pc = pc % rep_block_size; - ret = ((start_ip_offset <= masked_pc) && (end_ip_offset >= masked_pc)); - } + pc_offset = pc - func_start_addr; + /* For SFrame FDEs encoding information for repetitive pattern of insns, + masking with the rep_block_size is necessary to find the matching FRE. */ + if (mask_p) + pc_offset = pc_offset % rep_block_size; - return ret; + return (start_ip_offset <= pc_offset) && (end_ip_offset >= pc_offset); } static int diff --git a/libsframe/testsuite/libsframe.find/plt-findfre-1.c b/libsframe/testsuite/libsframe.find/plt-findfre-1.c index c84b46f4d35..60037fd67ea 100644 --- a/libsframe/testsuite/libsframe.find/plt-findfre-1.c +++ b/libsframe/testsuite/libsframe.find/plt-findfre-1.c @@ -28,12 +28,13 @@ #include static int -add_plt_fde1 (sframe_encoder_ctx *ectx, int idx) +add_plt_fde1 (sframe_encoder_ctx *ectx, uint32_t plt_vaddr, + uint32_t sframe_vaddr, int idx) { - int i, err; /* A contiguous block containing 3 FREs. The start_ip_offset must remain less than 16 bytes. */ - sframe_frame_row_entry fres[] +#define PLT1_NUM_FRES 3 + sframe_frame_row_entry fres[PLT1_NUM_FRES] = { {0x0, {0x1, 0, 0}, 0x3}, {0x6, {0x2, 0xf0, 0}, 0x5}, {0xc, {0x3, 0xf0, 0}, 0x4} @@ -41,19 +42,26 @@ add_plt_fde1 (sframe_encoder_ctx *ectx, int idx) unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1, SFRAME_FDE_TYPE_PCMASK); + int32_t func_start_addr = plt_vaddr - sframe_vaddr; + /* 5 pltN entries of 16 bytes each. */ - err = sframe_encoder_add_funcdesc_v2 (ectx, 0x1000, 16*5, finfo, 16, 3); + int err = sframe_encoder_add_funcdesc_v2 (ectx, func_start_addr, + 16 * 5 /* func size in bytes. */, + finfo, + 16 /* rep block size in bytes. */, + PLT1_NUM_FRES); if (err == -1) return err; - for (i = 0; i < 3; i++) - if (sframe_encoder_add_fre (ectx, idx, fres+i) == SFRAME_ERR) + for (unsigned i = 0; i < PLT1_NUM_FRES; i++) + if (sframe_encoder_add_fre (ectx, idx, fres + i) == SFRAME_ERR) return -1; return 0; } -int main (void) +static +void test_plt_findfre (uint32_t plt_vaddr, uint32_t sframe_vaddr) { sframe_encoder_ctx *ectx; sframe_decoder_ctx *dctx; @@ -61,7 +69,7 @@ int main (void) char *sframe_buf; size_t sf_size; int err = 0; - unsigned int fde_cnt = 0; + uint32_t fde_cnt = 0; #define TEST(name, cond) \ do \ @@ -78,7 +86,7 @@ int main (void) -8, /* Fixed RA offset for AMD64. */ &err); - err = add_plt_fde1 (ectx, 0); + err = add_plt_fde1 (ectx, plt_vaddr, sframe_vaddr, 0); TEST ("plt-findfre-1: Adding FDE1 for plt", err == 0); fde_cnt = sframe_encoder_get_num_fidx (ectx); @@ -88,40 +96,53 @@ int main (void) TEST ("plt-findfre-1: Encoder write", err == 0); dctx = sframe_decode (sframe_buf, sf_size, &err); - TEST("plt-findfre-1: Decoder setup", dctx != NULL); + TEST ("plt-findfre-1: Decoder setup", dctx != NULL); /* Find the first FRE in PLT1. */ - err = sframe_find_fre (dctx, (0x1000 + 0x0), &frep); - TEST("plt-findfre-1: Find first FRE in PLT1", - ((err == 0) && (sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x1))); + err = sframe_find_fre (dctx, (plt_vaddr + 0x0 - sframe_vaddr), &frep); + TEST ("plt-findfre-1: Find first FRE in PLT1", + (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x1)); /* Find the second FRE. */ - err = sframe_find_fre (dctx, (0x1000 + 0x6), &frep); - TEST("plt-findfre-1: Find second FRE in PLT1", - ((err == 0) && (sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2))); + err = sframe_find_fre (dctx, (plt_vaddr + 0x6 - sframe_vaddr), &frep); + TEST ("plt-findfre-1: Find second FRE in PLT1", + (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2)); /* Find the last FRE. */ - err = sframe_find_fre (dctx, (0x1000 + 0xc), &frep); - TEST("plt-findfre-1: Find last FRE in PLT1", - ((err == 0) && (sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3))); + err = sframe_find_fre (dctx, (plt_vaddr + 0xc - sframe_vaddr), &frep); + TEST ("plt-findfre-1: Find last FRE in PLT1", + (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3)); /* Find the first FRE in PLT4. */ - err = sframe_find_fre (dctx, (0x1000 + 16*3 + 0x0), &frep); - TEST("plt-findfre-1: Find first FRE in PLT4", - ((err == 0) && (sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x1))); + err = sframe_find_fre (dctx, (plt_vaddr + 16*3 + 0x0 - sframe_vaddr), &frep); + TEST ("plt-findfre-1: Find first FRE in PLT4", + (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x1)); /* Find the second FRE in PLT4. */ - err = sframe_find_fre (dctx, (0x1000 + 16*3 + 0x6), &frep); - TEST("plt-findfre-1: Find second FRE in PLT4", - ((err == 0) && (sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2))); + err = sframe_find_fre (dctx, (plt_vaddr + 16*3 + 0x6 - sframe_vaddr), &frep); + TEST ("plt-findfre-1: Find second FRE in PLT4", + (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2)); /* Find the last FRE in PLT4. */ - err = sframe_find_fre (dctx, (0x1000 + 16*3 + 0xc), &frep); - TEST("plt-findfre-1: Find last FRE in PLT4", - ((err == 0) && (sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3))); + err = sframe_find_fre (dctx, (plt_vaddr + 16*3 + 0xc - sframe_vaddr), &frep); + TEST ("plt-findfre-1: Find last FRE in PLT4", + (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3)); sframe_encoder_free (&ectx); sframe_decoder_free (&dctx); - - return 0; +} + +int main (void) +{ + uint32_t sframe_vaddr = 0x402220; + uint32_t plt_vaddr = 0x401020; + printf ("Testing with plt_vaddr = %#x; sframe_vaddr = %#x\n", plt_vaddr, + sframe_vaddr); + test_plt_findfre (plt_vaddr, sframe_vaddr); + + sframe_vaddr = 0x401020; + plt_vaddr = 0x402220; + printf ("Testing with plt_vaddr = %#x; sframe_vaddr = %#x\n", plt_vaddr, + sframe_vaddr); + test_plt_findfre (plt_vaddr, sframe_vaddr); }