@@ -127,6 +127,18 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
127
127
jit -> seen_regs |= (1 << r1 );
128
128
}
129
129
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
+
130
142
#define REG_SET_SEEN (b1 ) \
131
143
({ \
132
144
reg_set_seen(jit, b1); \
@@ -201,7 +213,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
201
213
202
214
#define EMIT4_PCREL_RIC (op , mask , target ) \
203
215
({ \
204
- int __rel = (( target) - jit->prg) / 2; \
216
+ int __rel = off_to_pcrel(jit, target) / 2; \
205
217
_EMIT4((op) | (mask) << 20 | (__rel & 0xffff)); \
206
218
})
207
219
@@ -239,7 +251,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
239
251
240
252
#define EMIT6_PCREL_RIEB (op1 , op2 , b1 , b2 , mask , target ) \
241
253
({ \
242
- unsigned int rel = (int)((target) - jit->prg ) / 2; \
254
+ unsigned int rel = off_to_pcrel( jit, target ) / 2; \
243
255
_EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), \
244
256
(op2) | (mask) << 12); \
245
257
REG_SET_SEEN(b1); \
@@ -248,7 +260,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
248
260
249
261
#define EMIT6_PCREL_RIEC (op1 , op2 , b1 , imm , mask , target ) \
250
262
({ \
251
- unsigned int rel = (int)((target) - jit->prg ) / 2; \
263
+ unsigned int rel = off_to_pcrel( jit, target ) / 2; \
252
264
_EMIT6((op1) | (reg_high(b1) | (mask)) << 16 | \
253
265
(rel & 0xffff), (op2) | ((imm) & 0xff) << 8); \
254
266
REG_SET_SEEN(b1); \
@@ -257,29 +269,41 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
257
269
258
270
#define EMIT6_PCREL (op1 , op2 , b1 , b2 , i , off , mask ) \
259
271
({ \
260
- int rel = ( addrs[(i) + (off) + 1] - jit->prg ) / 2; \
272
+ int rel = off_to_pcrel(jit, addrs[(i) + (off) + 1]) / 2;\
261
273
_EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), (op2) | (mask));\
262
274
REG_SET_SEEN(b1); \
263
275
REG_SET_SEEN(b2); \
264
276
})
265
277
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
+
266
291
#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))
272
293
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
+ }
278
301
279
302
#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))
283
307
284
308
#define _EMIT6_IMM (op , imm ) \
285
309
({ \
@@ -503,7 +527,7 @@ static void bpf_skip(struct bpf_jit *jit, int size)
503
527
{
504
528
if (size >= 6 && !is_valid_rel (size )) {
505
529
/* brcl 0xf,size */
506
- EMIT6_PCREL_RIL ( 0xc0f4000000 , size );
530
+ EMIT6_PCREL_RILC ( 0xc0040000 , 0xf , size );
507
531
size -= 6 ;
508
532
} else if (size >= 4 && is_valid_rel (size )) {
509
533
/* brc 0xf,size */
0 commit comments