Browse code

zlib/buffer apis.

Török Edvin authored on 2010/03/21 19:56:05
Showing 7 changed files
... ...
@@ -467,37 +467,266 @@ int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t id)
467 467
 {
468 468
 }
469 469
 
470
-int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx)
470
+int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx, uint32_t size)
471 471
 {
472
-    z_stream *s;
473
-    s = cli_realloc(ctx->z_streams, (ctx->z_nstreams+1)*sizeof(*ctx->z_streams));
474
-    if (!s)
472
+    unsigned char *data;
473
+    struct bc_buffer *b;
474
+    unsigned n = ctx->nbuffers + 1;
475
+
476
+    data = cli_malloc(size);
477
+    if (!data)
478
+	return -1;
479
+    b = cli_realloc(ctx->buffers, sizeof(*ctx->buffers)*n);
480
+    if (!b) {
481
+	free(data);
482
+	return -1;
483
+    }
484
+    ctx->buffers = b;
485
+    ctx->nbuffers = n;
486
+    b = &b[n-1];
487
+
488
+    b->data = data;
489
+    b->size = size;
490
+    b->write_cursor = b->read_cursor = 0;
491
+    return n-1;
492
+}
493
+
494
+int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t at)
495
+{
496
+    struct bc_buffer *b;
497
+    unsigned n = ctx->nbuffers + 1;
498
+
499
+    if (at >= ctx->file_size)
500
+	return -1;
501
+
502
+    b = cli_realloc(ctx->buffers, sizeof(*ctx->buffers)*n);
503
+    if (!b) {
504
+	return -1;
505
+    }
506
+    b = &b[n-1];
507
+    ctx->buffers = b;
508
+    ctx->nbuffers = n;
509
+
510
+    /* NULL data means read from file at pos read_cursor */
511
+    b->data = NULL;
512
+    b->size = 0;
513
+    b->read_cursor = at;
514
+    b->write_cursor = 0;
515
+}
516
+
517
+static struct bc_buffer *get_buffer(struct cli_bc_ctx *ctx, int32_t id)
518
+{
519
+    if (!ctx->buffers || id < 0 || id >= ctx->nbuffers)
520
+	return NULL;
521
+    return &ctx->buffers[id];
522
+}
523
+
524
+uint32_t cli_bcapi_buffer_pipe_read_avail(struct cli_bc_ctx *ctx , int32_t id)
525
+{
526
+    struct bc_buffer *b = get_buffer(ctx, id);
527
+    if (!b)
528
+	return 0;
529
+    if (b->data) {
530
+	if (b->write_cursor <= b->read_cursor)
531
+	    return 0;
532
+	return b->write_cursor - b->read_cursor;
533
+    }
534
+    if (!ctx->fmap || ctx->off >= ctx->file_size)
535
+	return 0;
536
+    if (ctx->off + BUFSIZ <= ctx->file_size)
537
+	return BUFSIZ;
538
+    return ctx->file_size - ctx->off;
539
+}
540
+
541
+uint8_t* cli_bcapi_buffer_pipe_read_get(struct cli_bc_ctx *ctx , int32_t id, uint32_t size)
542
+{
543
+    struct bc_buffer *b = get_buffer(ctx, id);
544
+    if (!b || size > cli_bcapi_buffer_pipe_read_avail(ctx, id) || !size)
545
+	return NULL;
546
+    if (b->data)
547
+	return b->data + b->read_cursor;
548
+    return fmap_need_off(ctx->fmap, b->read_cursor, size);
549
+}
550
+
551
+int32_t cli_bcapi_buffer_pipe_read_stopped(struct cli_bc_ctx *ctx , int32_t id, uint32_t amount)
552
+{
553
+    struct bc_buffer *b = get_buffer(ctx, id);
554
+    if (!b)
555
+	return -1;
556
+    if (b->data) {
557
+	if (b->write_cursor <= b->read_cursor)
558
+	    return -1;
559
+	if (b->read_cursor + amount > b->write_cursor)
560
+	    b->read_cursor = b->write_cursor;
561
+	else
562
+	    b->read_cursor += amount;
563
+	if (b->read_cursor >= b->size &&
564
+	    b->write_cursor >= b->size)
565
+	    b->read_cursor = b->write_cursor = 0;
566
+	return 0;
567
+    }
568
+    b->read_cursor += amount;
569
+    return 0;
570
+}
571
+
572
+uint32_t cli_bcapi_buffer_pipe_write_avail(struct cli_bc_ctx *ctx, int32_t id)
573
+{
574
+    struct bc_buffer *b = get_buffer(ctx, id);
575
+    if (!b)
576
+	return 0;
577
+    if (!b->data)
578
+	return 0;
579
+    if (b->write_cursor >= b->size)
580
+	return 0;
581
+    return b->size - b->write_cursor;
582
+}
583
+
584
+uint8_t* cli_bcapi_buffer_pipe_write_get(struct cli_bc_ctx *ctx, int32_t id, uint32_t size)
585
+{
586
+    struct bc_buffer *b = get_buffer(ctx, id);
587
+    if (!b || size > cli_bcapi_buffer_pipe_write_avail(ctx, id) || !size)
588
+	return NULL;
589
+    if (!b->data)
590
+	return NULL;
591
+    return b->data + b->write_cursor;
592
+}
593
+
594
+int32_t cli_bcapi_buffer_pipe_write_stopped(struct cli_bc_ctx *ctx , int32_t id, uint32_t size)
595
+{
596
+    struct bc_buffer *b = get_buffer(ctx, id);
597
+    if (!b || !b->data)
598
+	return -1;
599
+    if (b->write_cursor + size >= b->size)
600
+	b->write_cursor = b->size;
601
+    else
602
+	b->write_cursor += size;
603
+    return 0;
604
+}
605
+
606
+int32_t cli_bcapi_buffer_pipe_done(struct cli_bc_ctx *ctx , int32_t id)
607
+{
608
+    /* TODO */
609
+}
610
+
611
+int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx, int32_t from, int32_t to, int32_t windowBits)
612
+{
613
+    int ret;
614
+    z_stream stream;
615
+    struct bc_inflate *b;
616
+    unsigned n = ctx->ninflates + 1;
617
+    if (!get_buffer(ctx, from) || !get_buffer(ctx, to))
618
+	return -1;
619
+    memset(&stream, 0, sizeof(stream));
620
+    ret = inflateInit2(&stream, windowBits);
621
+    switch (ret) {
622
+	case Z_MEM_ERROR:
623
+	    cli_dbgmsg("bytecode api: inflateInit2: out of memory!\n");
624
+	    return -1;
625
+	case Z_VERSION_ERROR:
626
+	    cli_dbgmsg("bytecode api: inflateinit2: zlib version error!\n");
627
+	    return -1;
628
+	case Z_STREAM_ERROR:
629
+	    cli_dbgmsg("bytecode api: inflateinit2: zlib stream error!\n");
630
+	    return -1;
631
+	case Z_OK:
632
+	    break;
633
+	default:
634
+	    cli_dbgmsg("bytecode api: inflateInit2: unknown error %d\n", ret);
635
+	    return -1;
636
+    }
637
+
638
+    b = cli_realloc(ctx->inflates, sizeof(*ctx->inflates)*n);
639
+    if (!b) {
640
+	inflateEnd(&stream);
475 641
 	return -1;
476
-    ctx->z_streams = s;
477
-    ctx->z_nstreams++;
478
-    s = &s[ctx->z_nstreams-1];
479
-    memset(s, 0, sizeof(*s));
480
-    return inflateInit2(s, MAX_WBITS+16);
642
+    }
643
+    ctx->inflates = b;
644
+    ctx->ninflates = n;
645
+    b = &b[n-1];
646
+
647
+    b->from = from;
648
+    b->to = to;
649
+    b->needSync = 0;
650
+    memcpy(&b->stream, &stream, sizeof(stream));
651
+    return n-1;
481 652
 }
482 653
 
483
-int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t id,
484
-				  uint8_t* in, uint32_t in_size,
485
-				  uint8_t* out, uint32_t out_size)
654
+static struct bc_inflate *get_inflate(struct cli_bc_ctx *ctx, int32_t id)
486 655
 {
487
-    if (id >= ctx->z_nstreams)
656
+    if (id < 0 || id >= ctx->ninflates || !ctx->inflates)
657
+	return NULL;
658
+    return &ctx->inflates[id];
659
+}
660
+
661
+int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t id)
662
+{
663
+    int ret;
664
+    unsigned avail_in_orig, avail_out_orig;
665
+    struct bc_inflate *b = get_inflate(ctx, id);
666
+    if (!b)
667
+	return -1;
668
+
669
+    b->stream.avail_in = avail_in_orig =
670
+	cli_bcapi_buffer_pipe_read_avail(ctx, b->from);
671
+
672
+    b->stream.next_in = cli_bcapi_buffer_pipe_read_get(ctx, b->from,
673
+						       b->stream.avail_in);
674
+
675
+    b->stream.avail_out = avail_out_orig =
676
+	cli_bcapi_buffer_pipe_write_avail(ctx, b->to);
677
+
678
+    b->stream.next_out = cli_bcapi_buffer_pipe_write_get(ctx, b->to,
679
+							 b->stream.avail_out);
680
+
681
+    if (!b->stream.avail_in || !b->stream.avail_out)
488 682
 	return -1;
489
-    z_stream *s = &ctx->z_streams[id];
490
-    s->next_in = in;
491
-    s->avail_in = in_size;
492
-    s->next_out = out;
493
-    s->avail_out = out_size;
494
-    return inflate(s, 0);
683
+    /* try hard to extract data, skipping over corrupted data */
684
+    do {
685
+	if (!b->needSync) {
686
+	    ret = inflate(&b->stream, Z_NO_FLUSH);
687
+	    if (ret == Z_DATA_ERROR) {
688
+		cli_dbgmsg("bytecode api: inflate at %u: %s\n", b->stream.total_in,
689
+			   b->stream.msg);
690
+		b->needSync = 1;
691
+	    }
692
+	}
693
+	if (b->needSync) {
694
+	    ret = inflateSync(&b->stream);
695
+	    if (ret == Z_OK) {
696
+		b->needSync = 0;
697
+		continue;
698
+	    }
699
+	}
700
+	break;
701
+    } while (1);
702
+    cli_bcapi_buffer_pipe_read_stopped(ctx, b->from, avail_in_orig - b->stream.avail_in);
703
+    cli_bcapi_buffer_pipe_write_stopped(ctx, b->to, avail_out_orig - b->stream.avail_out);
704
+
705
+    if (ret == Z_MEM_ERROR) {
706
+	cli_dbgmsg("bytecode api: out of memory!\n");
707
+	cli_bcapi_inflate_done(ctx, id);
708
+	return ret;
709
+    }
710
+    if (ret == Z_STREAM_END) {
711
+	cli_bcapi_inflate_done(ctx, id);
712
+    }
713
+    if (ret == Z_BUF_ERROR) {
714
+	cli_dbgmsg("bytecode api: buffer error!\n");
715
+    }
716
+
717
+    return ret;
495 718
 }
496 719
 
497 720
 int32_t cli_bcapi_inflate_done(struct cli_bc_ctx *ctx , int32_t id)
498 721
 {
499
-    if (id >= ctx->z_nstreams)
722
+    int ret;
723
+    struct bc_inflate *b = get_inflate(ctx, id);
724
+    if (!b || b->from == -1 || b->to == -1)
500 725
 	return -1;
501
-    z_stream *s = &ctx->z_streams[id];
502
-    return inflateEnd(s);
726
+    ret = inflateEnd(&b->stream);
727
+    if (ret == Z_STREAM_ERROR)
728
+	cli_dbgmsg("bytecode api: inflateEnd: %s\n", b->stream.msg);
729
+    b->from = b->to = -1;
730
+    return ret;
503 731
 }
732
+
... ...
@@ -230,9 +230,18 @@ int32_t hashset_remove(int32_t hs, uint32_t key);
230 230
 int32_t hashset_contains(int32_t hs, uint32_t key);
231 231
 int32_t hashset_done(int32_t id);
232 232
 
233
-int32_t inflate_init(void);
234
-int32_t inflate_process(int32_t id, uint8_t *input, uint32_t input_size,
235
-                        uint8_t *output, uint32_t output_size);
233
+int32_t  buffer_pipe_new(uint32_t size);
234
+int32_t  buffer_pipe_new_fromfile(uint32_t pos);
235
+uint32_t buffer_pipe_read_avail(int32_t id);
236
+uint8_t *buffer_pipe_read_get(int32_t id, uint32_t amount);
237
+int32_t  buffer_pipe_read_stopped(int32_t id, uint32_t amount);
238
+uint32_t buffer_pipe_write_avail(int32_t id);
239
+uint8_t *buffer_pipe_write_get(int32_t id, uint32_t size);
240
+int32_t  buffer_pipe_write_stopped(int32_t id, uint32_t amount);
241
+int32_t  buffer_pipe_done(int32_t id);
242
+
243
+int32_t inflate_init(int32_t from_buffer, int32_t to_buffer, int32_t windowBits);
244
+int32_t inflate_process(int32_t id);
236 245
 int32_t inflate_done(int32_t id);
237 246
 
238 247
 #endif
... ...
@@ -61,8 +61,17 @@ int32_t cli_bcapi_hashset_add(struct cli_bc_ctx *ctx , int32_t, uint32_t);
61 61
 int32_t cli_bcapi_hashset_remove(struct cli_bc_ctx *ctx , int32_t, uint32_t);
62 62
 int32_t cli_bcapi_hashset_contains(struct cli_bc_ctx *ctx , int32_t, uint32_t);
63 63
 int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t);
64
-int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx );
65
-int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t, uint8_t*, uint32_t, uint8_t*, uint32_t);
64
+int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx , uint32_t);
65
+int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t);
66
+uint32_t cli_bcapi_buffer_pipe_read_avail(struct cli_bc_ctx *ctx , int32_t);
67
+uint8_t* cli_bcapi_buffer_pipe_read_get(struct cli_bc_ctx *ctx , int32_t, uint32_t);
68
+int32_t cli_bcapi_buffer_pipe_read_stopped(struct cli_bc_ctx *ctx , int32_t, uint32_t);
69
+uint32_t cli_bcapi_buffer_pipe_write_avail(struct cli_bc_ctx *ctx , int32_t);
70
+uint8_t* cli_bcapi_buffer_pipe_write_get(struct cli_bc_ctx *ctx , int32_t, uint32_t);
71
+int32_t cli_bcapi_buffer_pipe_write_stopped(struct cli_bc_ctx *ctx , int32_t, uint32_t);
72
+int32_t cli_bcapi_buffer_pipe_done(struct cli_bc_ctx *ctx , int32_t);
73
+int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx , int32_t, int32_t, int32_t);
74
+int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t);
66 75
 int32_t cli_bcapi_inflate_done(struct cli_bc_ctx *ctx , int32_t);
67 76
 
68 77
 const struct cli_apiglobal cli_globals[] = {
... ...
@@ -87,21 +96,22 @@ static uint16_t cli_tmp5[]={32, 16, 16, 32, 32, 32, 16, 16};
87 87
 static uint16_t cli_tmp6[]={32};
88 88
 static uint16_t cli_tmp7[]={32};
89 89
 static uint16_t cli_tmp8[]={32, 32};
90
-static uint16_t cli_tmp9[]={32, 32, 65, 32, 65, 32};
91
-static uint16_t cli_tmp10[]={32};
92
-static uint16_t cli_tmp11[]={32, 32, 32};
93
-static uint16_t cli_tmp12[]={32, 65, 32, 32, 32, 32};
94
-static uint16_t cli_tmp13[]={32, 83, 32};
95
-static uint16_t cli_tmp14[]={84};
96
-static uint16_t cli_tmp15[]={32, 32, 32, 32, 32, 32, 32, 32, 32};
97
-static uint16_t cli_tmp16[]={65, 32};
98
-static uint16_t cli_tmp17[]={32, 65, 32};
99
-static uint16_t cli_tmp18[]={32, 88, 32};
100
-static uint16_t cli_tmp19[]={89};
101
-static uint16_t cli_tmp20[]={16, 8, 8, 8, 91, 90};
102
-static uint16_t cli_tmp21[]={8};
103
-static uint16_t cli_tmp22[]={92};
104
-static uint16_t cli_tmp23[]={8};
90
+static uint16_t cli_tmp9[]={32, 32, 32, 32};
91
+static uint16_t cli_tmp10[]={32, 32, 32};
92
+static uint16_t cli_tmp11[]={65, 32, 32};
93
+static uint16_t cli_tmp12[]={32};
94
+static uint16_t cli_tmp13[]={32, 65, 32, 32, 32, 32};
95
+static uint16_t cli_tmp14[]={32, 84, 32};
96
+static uint16_t cli_tmp15[]={85};
97
+static uint16_t cli_tmp16[]={32, 32, 32, 32, 32, 32, 32, 32, 32};
98
+static uint16_t cli_tmp17[]={65, 32};
99
+static uint16_t cli_tmp18[]={32, 65, 32};
100
+static uint16_t cli_tmp19[]={32, 89, 32};
101
+static uint16_t cli_tmp20[]={90};
102
+static uint16_t cli_tmp21[]={16, 8, 8, 8, 92, 91};
103
+static uint16_t cli_tmp22[]={8};
104
+static uint16_t cli_tmp23[]={93};
105
+static uint16_t cli_tmp24[]={8};
105 106
 
106 107
 const struct cli_bc_type cli_apicall_types[]={
107 108
 	{DStructType, cli_tmp0, 11, 0, 0},
... ...
@@ -113,57 +123,67 @@ const struct cli_bc_type cli_apicall_types[]={
113 113
 	{DArrayType, cli_tmp6, 1, 0, 0},
114 114
 	{DArrayType, cli_tmp7, 64, 0, 0},
115 115
 	{DFunctionType, cli_tmp8, 2, 0, 0},
116
-	{DFunctionType, cli_tmp9, 6, 0, 0},
117
-	{DFunctionType, cli_tmp10, 1, 0, 0},
116
+	{DFunctionType, cli_tmp9, 4, 0, 0},
117
+	{DFunctionType, cli_tmp10, 3, 0, 0},
118 118
 	{DFunctionType, cli_tmp11, 3, 0, 0},
119
-	{DFunctionType, cli_tmp12, 6, 0, 0},
120
-	{DFunctionType, cli_tmp13, 3, 0, 0},
121
-	{DPointerType, cli_tmp14, 1, 0, 0},
122
-	{DStructType, cli_tmp15, 9, 0, 0},
123
-	{DFunctionType, cli_tmp16, 2, 0, 0},
124
-	{DFunctionType, cli_tmp17, 3, 0, 0},
119
+	{DFunctionType, cli_tmp12, 1, 0, 0},
120
+	{DFunctionType, cli_tmp13, 6, 0, 0},
121
+	{DFunctionType, cli_tmp14, 3, 0, 0},
122
+	{DPointerType, cli_tmp15, 1, 0, 0},
123
+	{DStructType, cli_tmp16, 9, 0, 0},
124
+	{DFunctionType, cli_tmp17, 2, 0, 0},
125 125
 	{DFunctionType, cli_tmp18, 3, 0, 0},
126
-	{DPointerType, cli_tmp19, 1, 0, 0},
127
-	{DStructType, cli_tmp20, 6, 0, 0},
128
-	{DArrayType, cli_tmp21, 29, 0, 0},
129
-	{DArrayType, cli_tmp22, 3, 0, 0},
130
-	{DArrayType, cli_tmp23, 10, 0, 0}
126
+	{DFunctionType, cli_tmp19, 3, 0, 0},
127
+	{DPointerType, cli_tmp20, 1, 0, 0},
128
+	{DStructType, cli_tmp21, 6, 0, 0},
129
+	{DArrayType, cli_tmp22, 29, 0, 0},
130
+	{DArrayType, cli_tmp23, 3, 0, 0},
131
+	{DArrayType, cli_tmp24, 10, 0, 0}
131 132
 };
132 133
 
133 134
 const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
134 135
 const struct cli_apicall cli_apicalls[]={
135 136
 /* Bytecode APIcalls BEGIN */
136
-	{"test1", 11, 0, 0},
137
-	{"read", 17, 0, 1},
138
-	{"write", 17, 1, 1},
139
-	{"seek", 11, 1, 0},
140
-	{"setvirusname", 17, 2, 1},
141
-	{"debug_print_str", 17, 3, 1},
137
+	{"test1", 10, 0, 0},
138
+	{"read", 18, 0, 1},
139
+	{"write", 18, 1, 1},
140
+	{"seek", 10, 1, 0},
141
+	{"setvirusname", 18, 2, 1},
142
+	{"debug_print_str", 18, 3, 1},
142 143
 	{"debug_print_uint", 8, 0, 2},
143
-	{"disasm_x86", 18, 4, 1},
144
-	{"trace_directory", 17, 5, 1},
145
-	{"trace_scope", 17, 6, 1},
146
-	{"trace_source", 17, 7, 1},
147
-	{"trace_op", 17, 8, 1},
148
-	{"trace_value", 17, 9, 1},
149
-	{"trace_ptr", 17, 10, 1},
144
+	{"disasm_x86", 19, 4, 1},
145
+	{"trace_directory", 18, 5, 1},
146
+	{"trace_scope", 18, 6, 1},
147
+	{"trace_source", 18, 7, 1},
148
+	{"trace_op", 18, 8, 1},
149
+	{"trace_value", 18, 9, 1},
150
+	{"trace_ptr", 18, 10, 1},
150 151
 	{"pe_rawaddr", 8, 1, 2},
151
-	{"file_find", 17, 11, 1},
152
+	{"file_find", 18, 11, 1},
152 153
 	{"file_byteat", 8, 2, 2},
153
-	{"malloc", 16, 0, 3},
154
+	{"malloc", 17, 0, 3},
154 155
 	{"test2", 8, 3, 2},
155
-	{"get_pe_section", 13, 12, 1},
156
-	{"fill_buffer", 12, 0, 4},
156
+	{"get_pe_section", 14, 12, 1},
157
+	{"fill_buffer", 13, 0, 4},
157 158
 	{"extract_new", 8, 4, 2},
158 159
 	{"read_number", 8, 5, 2},
159
-	{"hashset_new", 10, 0, 5},
160
-	{"hashset_add", 11, 2, 0},
161
-	{"hashset_remove", 11, 3, 0},
162
-	{"hashset_contains", 11, 4, 0},
160
+	{"hashset_new", 12, 0, 5},
161
+	{"hashset_add", 10, 2, 0},
162
+	{"hashset_remove", 10, 3, 0},
163
+	{"hashset_contains", 10, 4, 0},
163 164
 	{"hashset_done", 8, 6, 2},
164
-	{"inflate_init", 10, 1, 5},
165
-	{"inflate_process", 9, 0, 6},
166
-	{"inflate_done", 8, 7, 2}
165
+	{"buffer_pipe_new", 8, 7, 2},
166
+	{"buffer_pipe_new_fromfile", 8, 8, 2},
167
+	{"buffer_pipe_read_avail", 8, 9, 2},
168
+	{"buffer_pipe_read_get", 11, 0, 6},
169
+	{"buffer_pipe_read_stopped", 10, 5, 0},
170
+	{"buffer_pipe_write_avail", 8, 10, 2},
171
+	{"buffer_pipe_write_get", 11, 1, 6},
172
+	{"buffer_pipe_write_stopped", 10, 6, 0},
173
+	{"buffer_pipe_done", 8, 11, 2},
174
+	{"inflate_init", 9, 0, 7},
175
+	{"inflate_process", 8, 12, 2},
176
+	{"inflate_done", 8, 13, 2}
167 177
 /* Bytecode APIcalls END */
168 178
 };
169 179
 const cli_apicall_int2 cli_apicalls0[] = {
... ...
@@ -171,7 +191,9 @@ const cli_apicall_int2 cli_apicalls0[] = {
171 171
 	(cli_apicall_int2)cli_bcapi_seek,
172 172
 	(cli_apicall_int2)cli_bcapi_hashset_add,
173 173
 	(cli_apicall_int2)cli_bcapi_hashset_remove,
174
-	(cli_apicall_int2)cli_bcapi_hashset_contains
174
+	(cli_apicall_int2)cli_bcapi_hashset_contains,
175
+	(cli_apicall_int2)cli_bcapi_buffer_pipe_read_stopped,
176
+	(cli_apicall_int2)cli_bcapi_buffer_pipe_write_stopped
175 177
 };
176 178
 const cli_apicall_pointer cli_apicalls1[] = {
177 179
 	(cli_apicall_pointer)cli_bcapi_read,
... ...
@@ -196,6 +218,12 @@ const cli_apicall_int1 cli_apicalls2[] = {
196 196
 	(cli_apicall_int1)cli_bcapi_extract_new,
197 197
 	(cli_apicall_int1)cli_bcapi_read_number,
198 198
 	(cli_apicall_int1)cli_bcapi_hashset_done,
199
+	(cli_apicall_int1)cli_bcapi_buffer_pipe_new,
200
+	(cli_apicall_int1)cli_bcapi_buffer_pipe_new_fromfile,
201
+	(cli_apicall_int1)cli_bcapi_buffer_pipe_read_avail,
202
+	(cli_apicall_int1)cli_bcapi_buffer_pipe_write_avail,
203
+	(cli_apicall_int1)cli_bcapi_buffer_pipe_done,
204
+	(cli_apicall_int1)cli_bcapi_inflate_process,
199 205
 	(cli_apicall_int1)cli_bcapi_inflate_done
200 206
 };
201 207
 const cli_apicall_malloclike cli_apicalls3[] = {
... ...
@@ -205,10 +233,13 @@ const cli_apicall_ptrbuffdata cli_apicalls4[] = {
205 205
 	(cli_apicall_ptrbuffdata)cli_bcapi_fill_buffer
206 206
 };
207 207
 const cli_apicall_allocobj cli_apicalls5[] = {
208
-	(cli_apicall_allocobj)cli_bcapi_hashset_new,
209
-	(cli_apicall_allocobj)cli_bcapi_inflate_init
208
+	(cli_apicall_allocobj)cli_bcapi_hashset_new
210 209
 };
211
-const cli_apicall_bufops cli_apicalls6[] = {
212
-	(cli_apicall_bufops)cli_bcapi_inflate_process
210
+const cli_apicall_bufget cli_apicalls6[] = {
211
+	(cli_apicall_bufget)cli_bcapi_buffer_pipe_read_get,
212
+	(cli_apicall_bufget)cli_bcapi_buffer_pipe_write_get
213
+};
214
+const cli_apicall_int3 cli_apicalls7[] = {
215
+	(cli_apicall_int3)cli_bcapi_inflate_init
213 216
 };
214 217
 const unsigned cli_apicall_maxapi = sizeof(cli_apicalls)/sizeof(cli_apicalls[0]);
... ...
@@ -58,8 +58,17 @@ int32_t cli_bcapi_hashset_add(struct cli_bc_ctx *ctx , int32_t, uint32_t);
58 58
 int32_t cli_bcapi_hashset_remove(struct cli_bc_ctx *ctx , int32_t, uint32_t);
59 59
 int32_t cli_bcapi_hashset_contains(struct cli_bc_ctx *ctx , int32_t, uint32_t);
60 60
 int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t);
61
-int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx );
62
-int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t, uint8_t*, uint32_t, uint8_t*, uint32_t);
61
+int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx , uint32_t);
62
+int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t);
63
+uint32_t cli_bcapi_buffer_pipe_read_avail(struct cli_bc_ctx *ctx , int32_t);
64
+uint8_t* cli_bcapi_buffer_pipe_read_get(struct cli_bc_ctx *ctx , int32_t, uint32_t);
65
+int32_t cli_bcapi_buffer_pipe_read_stopped(struct cli_bc_ctx *ctx , int32_t, uint32_t);
66
+uint32_t cli_bcapi_buffer_pipe_write_avail(struct cli_bc_ctx *ctx , int32_t);
67
+uint8_t* cli_bcapi_buffer_pipe_write_get(struct cli_bc_ctx *ctx , int32_t, uint32_t);
68
+int32_t cli_bcapi_buffer_pipe_write_stopped(struct cli_bc_ctx *ctx , int32_t, uint32_t);
69
+int32_t cli_bcapi_buffer_pipe_done(struct cli_bc_ctx *ctx , int32_t);
70
+int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx , int32_t, int32_t, int32_t);
71
+int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t);
63 72
 int32_t cli_bcapi_inflate_done(struct cli_bc_ctx *ctx , int32_t);
64 73
 
65 74
 #endif
... ...
@@ -116,6 +116,21 @@ enum trace_level {
116 116
     trace_op,
117 117
     trace_val
118 118
 };
119
+
120
+struct bc_buffer {
121
+    unsigned char *data;
122
+    unsigned size;
123
+    unsigned write_cursor;
124
+    unsigned read_cursor;
125
+};
126
+
127
+struct bc_inflate {
128
+    z_stream stream;
129
+    int32_t from;
130
+    int32_t to;
131
+    int8_t  needSync;
132
+};
133
+
119 134
 struct cli_bc_ctx {
120 135
     /* id and params of toplevel function called */
121 136
     const struct cli_bc *bc;
... ...
@@ -152,8 +167,10 @@ struct cli_bc_ctx {
152 152
     mpool_t *mpool;
153 153
     uint32_t numGlobals;
154 154
     uint8_t* globals;
155
-    z_stream* z_streams;
156
-    unsigned z_nstreams;
155
+    struct bc_inflate* inflates;
156
+    unsigned ninflates;
157
+    struct bc_buffer *buffers;
158
+    unsigned nbuffers;
157 159
 };
158 160
 struct cli_all_bc;
159 161
 int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct cli_bc_func *func, const struct cli_bc_inst *inst);
... ...
@@ -1408,6 +1408,9 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
1408 1408
 		case 6:
1409 1409
 		    dest = (void*)(intptr_t)cli_apicalls6[api->idx];
1410 1410
 		    break;
1411
+		case 7:
1412
+		    dest = (void*)(intptr_t)cli_apicalls7[api->idx];
1413
+		    break;
1411 1414
 		default:
1412 1415
 		    llvm_unreachable("invalid api type");
1413 1416
 	    }
... ...
@@ -47,7 +47,8 @@ typedef uint32_t (*cli_apicall_int1)(struct cli_bc_ctx *, uint32_t);
47 47
 typedef void* (*cli_apicall_malloclike)(struct cli_bc_ctx *, uint32_t);
48 48
 typedef void* (*cli_apicall_ptrbuffdata)(struct cli_bc_ctx *, void*, uint32_t, uint32_t, uint32_t, uint32_t);
49 49
 typedef int32_t (*cli_apicall_allocobj)(struct cli_bc_ctx *);
50
-typedef int32_t (*cli_apicall_bufops)(struct cli_bc_ctx *, int32_t, void*, uint32_t, void*, uint32_t);
50
+typedef void* (*cli_apicall_bufget)(struct cli_bc_ctx *, int32_t, uint32_t);
51
+typedef int32_t (*cli_apicall_int3)(struct cli_bc_ctx *, int32_t, int32_t, int32_t);
51 52
 
52 53
 struct cli_apicall {
53 54
     const char *name;
... ...
@@ -78,7 +79,8 @@ extern const cli_apicall_int1 cli_apicalls2[];
78 78
 extern const cli_apicall_malloclike cli_apicalls3[];
79 79
 extern const cli_apicall_ptrbuffdata cli_apicalls4[];
80 80
 extern const cli_apicall_allocobj cli_apicalls5[];
81
-extern const cli_apicall_bufops cli_apicalls6[];
81
+extern const cli_apicall_bufget cli_apicalls6[];
82
+extern const cli_apicall_int3 cli_apicalls7[];
82 83
 extern const unsigned cli_apicall_maxapi;
83 84
 extern const unsigned cli_apicall_maxglobal;
84 85