|
|
@@ -1,5 +1,4 @@
|
|
1
|
1
|
#include <assert.h>
|
|
2
|
|
-#include <errno.h>
|
|
3
|
2
|
#include <inttypes.h>
|
|
4
|
3
|
#include <stdio.h>
|
|
5
|
4
|
#include <string.h>
|
|
|
@@ -508,9 +507,6 @@ struct ir *ir_new(void)
|
|
508
|
507
|
return ir;
|
|
509
|
508
|
}
|
|
510
|
509
|
|
|
511
|
|
-
|
|
512
|
|
-/* ir->bpf generation */
|
|
513
|
|
-
|
|
514
|
510
|
static void ir_bpf_vreg_replace(struct ir *ir, struct vinsn *last, int reg)
|
|
515
|
511
|
{
|
|
516
|
512
|
struct vinsn *vi;
|
|
|
@@ -529,7 +525,7 @@ static void ir_bpf_vreg_replace(struct ir *ir, struct vinsn *last, int reg)
|
|
529
|
525
|
}
|
|
530
|
526
|
|
|
531
|
527
|
|
|
532
|
|
-static int ir_bpf_registerize_one(struct ir *ir, struct vinsn *last)
|
|
|
528
|
+int ir_bpf_registerize_one(struct ir *ir, struct vinsn *last)
|
|
533
|
529
|
{
|
|
534
|
530
|
struct vinsn *vi;
|
|
535
|
531
|
uint16_t clean = 0x3ff;
|
|
|
@@ -542,8 +538,7 @@ static int ir_bpf_registerize_one(struct ir *ir, struct vinsn *last)
|
|
542
|
538
|
clean &= ~(1 << vi->insn.src);
|
|
543
|
539
|
if (!(vi->insn.dst & vreg_base))
|
|
544
|
540
|
clean &= ~(1 << vi->insn.dst);
|
|
545
|
|
- if ((BPF_CLASS(vi->insn.bpf.code) == BPF_JMP)
|
|
546
|
|
- && (BPF_OP(vi->insn.bpf.code) == BPF_CALL))
|
|
|
541
|
+ if (vi->insn.bpf.code == (BPF_JMP | BPF_CALL))
|
|
547
|
542
|
clean &= ~BPF_REG_CALLER_SAVE;
|
|
548
|
543
|
}
|
|
549
|
544
|
|
|
|
@@ -560,7 +555,7 @@ static int ir_bpf_registerize_one(struct ir *ir, struct vinsn *last)
|
|
560
|
555
|
return -1;
|
|
561
|
556
|
}
|
|
562
|
557
|
|
|
563
|
|
-static int ir_bpf_registerize(struct ir *ir)
|
|
|
558
|
+int ir_bpf_registerize(struct ir *ir)
|
|
564
|
559
|
{
|
|
565
|
560
|
struct vinsn *vi;
|
|
566
|
561
|
int err = 0;
|
|
|
@@ -581,50 +576,6 @@ static int ir_bpf_registerize(struct ir *ir)
|
|
581
|
576
|
return err;
|
|
582
|
577
|
}
|
|
583
|
578
|
|
|
584
|
|
-static int ir_bpf_jmp_resolve_one(struct ir *ir, struct vinsn *jmp)
|
|
585
|
|
-{
|
|
586
|
|
- struct vinsn *vi;
|
|
587
|
|
- int off = 0;
|
|
588
|
|
-
|
|
589
|
|
- for (vi = jmp + 1; vi < &ir->vi[ir->len - 1]; vi++) {
|
|
590
|
|
- switch (vi->vitype) {
|
|
591
|
|
- case VI_INSN:
|
|
592
|
|
- off++;
|
|
593
|
|
- break;
|
|
594
|
|
- case VI_LABEL:
|
|
595
|
|
- if (vi->label != jmp->insn.bpf.off)
|
|
596
|
|
- break;
|
|
597
|
|
-
|
|
598
|
|
- jmp->insn.bpf.off = off;
|
|
599
|
|
- return 0;
|
|
600
|
|
- default:
|
|
601
|
|
- break;
|
|
602
|
|
- }
|
|
603
|
|
- }
|
|
604
|
|
-
|
|
605
|
|
- return -ENOENT;
|
|
606
|
|
-}
|
|
607
|
|
-
|
|
608
|
|
-static int ir_bpf_jmp_resolve(struct ir *ir)
|
|
609
|
|
-{
|
|
610
|
|
- struct vinsn *vi;
|
|
611
|
|
- int err;
|
|
612
|
|
-
|
|
613
|
|
- for (vi = ir->vi; vi < &ir->vi[ir->len - 1]; vi++) {
|
|
614
|
|
- if (vi->vitype != VI_INSN)
|
|
615
|
|
- continue;
|
|
616
|
|
-
|
|
617
|
|
- if ((BPF_CLASS(vi->insn.bpf.code) == BPF_JMP)
|
|
618
|
|
- && (vi->insn.bpf.off < 0)) {
|
|
619
|
|
- err = ir_bpf_jmp_resolve_one(ir, vi);
|
|
620
|
|
- if (err)
|
|
621
|
|
- return err;
|
|
622
|
|
- }
|
|
623
|
|
- }
|
|
624
|
|
-
|
|
625
|
|
- return 0;
|
|
626
|
|
-}
|
|
627
|
|
-
|
|
628
|
579
|
int ir_bpf_generate(struct ir *ir)
|
|
629
|
580
|
{
|
|
630
|
581
|
int err;
|
|
|
@@ -633,13 +584,5 @@ int ir_bpf_generate(struct ir *ir)
|
|
633
|
584
|
if (err)
|
|
634
|
585
|
return err;
|
|
635
|
586
|
|
|
636
|
|
- /* no instructions will be added/removed to the program after
|
|
637
|
|
- * this point, thus it is now safe to convert labeled jumps to
|
|
638
|
|
- * fixed offsets. */
|
|
639
|
|
-
|
|
640
|
|
- err = ir_bpf_jmp_resolve(ir);
|
|
641
|
|
- if (err)
|
|
642
|
|
- return err;
|
|
643
|
|
-
|
|
644
|
587
|
return 0;
|
|
645
|
588
|
}
|