@@ -179,8 +179,6 @@ static const s8 bpf2a32[][2] = {
179
179
*
180
180
* prog : bpf_prog
181
181
* idx : index of current last JITed instruction.
182
- * prologue_bytes : bytes used in prologue.
183
- * epilogue_offset : offset of epilogue starting.
184
182
* offsets : array of BPF instruction offsets in
185
183
* JITed code.
186
184
* target : final JITed code.
@@ -193,8 +191,6 @@ static const s8 bpf2a32[][2] = {
193
191
struct jit_ctx {
194
192
const struct bpf_prog * prog ;
195
193
unsigned int idx ;
196
- unsigned int prologue_bytes ;
197
- unsigned int epilogue_offset ;
198
194
unsigned int cpu_architecture ;
199
195
u32 flags ;
200
196
u32 * offsets ;
@@ -417,8 +413,7 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx)
417
413
ctx -> imms [i ] = k ;
418
414
419
415
/* constants go just after the epilogue */
420
- offset = ctx -> offsets [ctx -> prog -> len - 1 ] * 4 ;
421
- offset += ctx -> prologue_bytes ;
416
+ offset = ctx -> offsets [ctx -> prog -> len ] * 4 ; /* epilogue start */
422
417
offset += ctx -> epilogue_bytes ;
423
418
offset += i * 4 ;
424
419
@@ -447,8 +442,8 @@ static inline int bpf2a32_offset(int bpf_to, int bpf_from,
447
442
448
443
if (ctx -> target == NULL )
449
444
return 0 ;
450
- to = ctx -> offsets [bpf_to ];
451
- from = ctx -> offsets [bpf_from ];
445
+ to = ctx -> offsets [bpf_to + 1 ];
446
+ from = ctx -> offsets [bpf_from + 1 ];
452
447
453
448
return to - from - 1 ;
454
449
}
@@ -499,7 +494,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
499
494
/* No need for 1st dummy run */
500
495
if (ctx -> target == NULL )
501
496
return 0 ;
502
- to = ctx -> epilogue_offset ;
497
+ to = ctx -> offsets [ ctx -> prog -> len ]; /* epilogue start */
503
498
from = ctx -> idx ;
504
499
505
500
return to - from - 2 ;
@@ -2710,23 +2705,26 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
2710
2705
const struct bpf_insn * insn = & (prog -> insnsi [i ]);
2711
2706
int ret ;
2712
2707
2708
+ /* Save start offset of each JITed insn. */
2709
+ if (ctx -> target == NULL )
2710
+ ctx -> offsets [i ] = ctx -> idx ;
2711
+
2713
2712
ret = build_insn (insn , ctx , extra_pass );
2714
2713
2715
2714
/* It's used with loading the 64 bit immediate value. */
2716
2715
if (ret > 0 ) {
2717
2716
i ++ ;
2718
- if (ctx -> target == NULL )
2719
- ctx -> offsets [i ] = ctx -> idx ;
2720
2717
continue ;
2721
2718
}
2722
2719
2723
- if (ctx -> target == NULL )
2724
- ctx -> offsets [i ] = ctx -> idx ;
2725
-
2726
2720
/* If unsuccessful, return with error code */
2727
2721
if (ret )
2728
2722
return ret ;
2729
2723
}
2724
+ /* Finally save epilogue offset. */
2725
+ if (ctx -> target == NULL )
2726
+ ctx -> offsets [i ] = ctx -> idx ;
2727
+
2730
2728
return 0 ;
2731
2729
}
2732
2730
@@ -2766,7 +2764,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
2766
2764
bool tmp_blinded = false;
2767
2765
bool extra_pass = false;
2768
2766
struct jit_ctx ctx ;
2769
- unsigned int tmp_idx ;
2770
2767
unsigned int image_size ;
2771
2768
u8 * image_ptr ;
2772
2769
@@ -2812,10 +2809,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
2812
2809
ctx .cpu_architecture = cpu_architecture ();
2813
2810
ctx .stack_size = JIT_ALIGN (prog -> aux -> stack_depth );
2814
2811
2815
- /* Not able to allocate memory for offsets[] , then
2812
+ /* Not able to allocate memory for offsets[], then
2816
2813
* we must fall back to the interpreter
2817
2814
*/
2818
- ctx .offsets = kcalloc (prog -> len , sizeof (int ), GFP_KERNEL );
2815
+ ctx .offsets = kcalloc (prog -> len + 1 , sizeof (int ), GFP_KERNEL );
2819
2816
if (ctx .offsets == NULL ) {
2820
2817
prog = orig_prog ;
2821
2818
goto out_off ;
@@ -2831,21 +2828,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
2831
2828
* being successful in the second pass, so just fall back
2832
2829
* to the interpreter.
2833
2830
*/
2831
+ build_prologue (& ctx );
2832
+
2834
2833
if (build_body (& ctx , extra_pass )) {
2835
2834
prog = orig_prog ;
2836
2835
goto out_off ;
2837
2836
}
2838
2837
2839
- tmp_idx = ctx .idx ;
2840
- build_prologue (& ctx );
2841
- ctx .prologue_bytes = (ctx .idx - tmp_idx ) * 4 ;
2842
-
2843
- ctx .epilogue_offset = ctx .idx ;
2838
+ build_epilogue (& ctx );
2844
2839
2840
+ /* On pre-ARMv7 append a literal pool of 32-bit imm constants. */
2845
2841
#if __LINUX_ARM_ARCH__ < 7
2846
- tmp_idx = ctx .idx ;
2847
- build_epilogue (& ctx );
2848
- ctx .epilogue_bytes = (ctx .idx - tmp_idx ) * 4 ;
2842
+ ctx .epilogue_bytes = (ctx .idx - ctx .offsets [prog -> len ]) * 4 ;
2849
2843
2850
2844
ctx .idx += ctx .imm_count ;
2851
2845
if (ctx .imm_count ) {
@@ -2855,9 +2849,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
2855
2849
goto out_off ;
2856
2850
}
2857
2851
}
2858
- #else
2859
- /* there's nothing about the epilogue on ARMv7 */
2860
- build_epilogue (& ctx );
2861
2852
#endif
2862
2853
/* Now we can get the actual image size of the JITed arm code.
2863
2854
* Currently, we are not considering the THUMB-2 instructions
@@ -2931,12 +2922,21 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
2931
2922
2932
2923
DEBUG_PASS (3 );
2933
2924
2925
+ if (!prog -> is_func || extra_pass ) {
2926
+ int i ;
2927
+ /* BPF line info expects array of byte-offsets mapping each
2928
+ * xlated insn to the end of its JITed insn (following byte),
2929
+ * so convert to bytes and drop the first array elem mapping
2930
+ * the proglogue.
2931
+ */
2932
+ for (i = 0 ; i <= prog -> len ; i ++ )
2933
+ ctx .offsets [i ] *= 4 ;
2934
+ bpf_prog_fill_jited_linfo (prog , ctx .offsets + 1 );
2934
2935
out_imms :
2935
2936
#if __LINUX_ARM_ARCH__ < 7
2936
- if (ctx .imm_count )
2937
- kfree (ctx .imms );
2937
+ if (ctx .imm_count )
2938
+ kfree (ctx .imms );
2938
2939
#endif
2939
- if (!prog -> is_func || extra_pass ) {
2940
2940
out_off :
2941
2941
kfree (ctx .offsets );
2942
2942
kfree (jit_data );
0 commit comments