@@ -127,6 +127,18 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
127127 jit -> seen_regs |= (1 << r1 );
128128}
129129
130+ static s32 off_to_pcrel (struct bpf_jit * jit , u32 off )
131+ {
132+ return off - jit -> prg ;
133+ }
134+
135+ static s64 ptr_to_pcrel (struct bpf_jit * jit , const void * ptr )
136+ {
137+ if (jit -> prg_buf )
138+ return (const u8 * )ptr - ((const u8 * )jit -> prg_buf + jit -> prg );
139+ return 0 ;
140+ }
141+
130142#define REG_SET_SEEN (b1 ) \
131143({ \
132144 reg_set_seen(jit, b1); \
@@ -201,7 +213,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
201213
202214#define EMIT4_PCREL_RIC (op , mask , target ) \
203215({ \
204- int __rel = (( target) - jit->prg) / 2; \
216+ int __rel = off_to_pcrel(jit, target) / 2; \
205217 _EMIT4((op) | (mask) << 20 | (__rel & 0xffff)); \
206218})
207219
@@ -239,7 +251,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
239251
240252#define EMIT6_PCREL_RIEB (op1 , op2 , b1 , b2 , mask , target ) \
241253({ \
242- unsigned int rel = (int)((target) - jit->prg ) / 2; \
254+ unsigned int rel = off_to_pcrel( jit, target ) / 2; \
243255 _EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), \
244256 (op2) | (mask) << 12); \
245257 REG_SET_SEEN(b1); \
@@ -248,7 +260,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
248260
249261#define EMIT6_PCREL_RIEC (op1 , op2 , b1 , imm , mask , target ) \
250262({ \
251- unsigned int rel = (int)((target) - jit->prg ) / 2; \
263+ unsigned int rel = off_to_pcrel( jit, target ) / 2; \
252264 _EMIT6((op1) | (reg_high(b1) | (mask)) << 16 | \
253265 (rel & 0xffff), (op2) | ((imm) & 0xff) << 8); \
254266 REG_SET_SEEN(b1); \
@@ -257,29 +269,41 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
257269
258270#define EMIT6_PCREL (op1 , op2 , b1 , b2 , i , off , mask ) \
259271({ \
260- int rel = ( addrs[(i) + (off) + 1] - jit->prg ) / 2; \
272+ int rel = off_to_pcrel(jit, addrs[(i) + (off) + 1]) / 2;\
261273 _EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), (op2) | (mask));\
262274 REG_SET_SEEN(b1); \
263275 REG_SET_SEEN(b2); \
264276})
265277
278+ static void emit6_pcrel_ril (struct bpf_jit * jit , u32 op , s64 pcrel )
279+ {
280+ u32 pc32dbl = (s32 )(pcrel / 2 );
281+
282+ _EMIT6 (op | pc32dbl >> 16 , pc32dbl & 0xffff );
283+ }
284+
285+ static void emit6_pcrel_rilb (struct bpf_jit * jit , u32 op , u8 b , s64 pcrel )
286+ {
287+ emit6_pcrel_ril (jit , op | reg_high (b ) << 16 , pcrel );
288+ REG_SET_SEEN (b );
289+ }
290+
266291#define EMIT6_PCREL_RILB (op , b , target ) \
267- ({ \
268- unsigned int rel = (int)((target) - jit->prg) / 2; \
269- _EMIT6((op) | reg_high(b) << 16 | rel >> 16, rel & 0xffff);\
270- REG_SET_SEEN(b); \
271- })
292+ emit6_pcrel_rilb(jit, op, b, off_to_pcrel(jit, target))
272293
273- #define EMIT6_PCREL_RIL (op , target ) \
274- ({ \
275- unsigned int rel = (int)((target) - jit->prg) / 2; \
276- _EMIT6((op) | rel >> 16, rel & 0xffff); \
277- })
294+ #define EMIT6_PCREL_RILB_PTR (op , b , target_ptr ) \
295+ emit6_pcrel_rilb(jit, op, b, ptr_to_pcrel(jit, target_ptr))
296+
297+ static void emit6_pcrel_rilc (struct bpf_jit * jit , u32 op , u8 mask , s64 pcrel )
298+ {
299+ emit6_pcrel_ril (jit , op | mask << 20 , pcrel );
300+ }
278301
279302#define EMIT6_PCREL_RILC (op , mask , target ) \
280- ({ \
281- EMIT6_PCREL_RIL((op) | (mask) << 20, (target)); \
282- })
303+ emit6_pcrel_rilc(jit, op, mask, off_to_pcrel(jit, target))
304+
305+ #define EMIT6_PCREL_RILC_PTR (op , mask , target_ptr ) \
306+ emit6_pcrel_rilc(jit, op, mask, ptr_to_pcrel(jit, target_ptr))
283307
284308#define _EMIT6_IMM (op , imm ) \
285309({ \
@@ -503,7 +527,7 @@ static void bpf_skip(struct bpf_jit *jit, int size)
503527{
504528 if (size >= 6 && !is_valid_rel (size )) {
505529 /* brcl 0xf,size */
506- EMIT6_PCREL_RIL ( 0xc0f4000000 , size );
530+ EMIT6_PCREL_RILC ( 0xc0040000 , 0xf , size );
507531 size -= 6 ;
508532 } else if (size >= 4 && is_valid_rel (size )) {
509533 /* brc 0xf,size */
0 commit comments