1 /*
2 * Copyright (c) 2001-2012 Tony Bybell.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <config.h>
24 #include "lxt_write.h"
25
26 /*
27 * in-place sort to keep chained facs from migrating...
28 */
wave_mergesort(struct lt_symbol ** a,struct lt_symbol ** b,int lo,int hi)29 static void wave_mergesort(struct lt_symbol **a, struct lt_symbol **b, int lo, int hi)
30 {
31 int i, j, k;
32
33 if (lo<hi)
34 {
35 int mid=(lo+hi)/2;
36
37 wave_mergesort(a, b, lo, mid);
38 wave_mergesort(a, b, mid+1, hi);
39
40 i=0; j=lo;
41 while (j<=mid)
42 {
43 b[i++]=a[j++];
44 }
45
46 i=0; k=lo;
47 while ((k<j)&&(j<=hi))
48 {
49 if (strcmp(b[i]->name, a[j]->name) <= 0)
50 {
51 a[k++]=b[i++];
52 }
53 else
54 {
55 a[k++]=a[j++];
56 }
57 }
58
59 while (k<j)
60 {
61 a[k++]=b[i++];
62 }
63 }
64 }
65
wave_msort(struct lt_symbol ** a,int num)66 static void wave_msort(struct lt_symbol **a, int num)
67 {
68 struct lt_symbol **b = malloc(((num/2)+1) * sizeof(struct lt_symbol *));
69
70 wave_mergesort(a, b, 0, num-1);
71
72 free(b);
73 }
74
75 /************************ splay ************************/
76
77 static int dslxt_success;
78
dslxt_splay(char * i,dslxt_Tree * t)79 static dslxt_Tree * dslxt_splay (char *i, dslxt_Tree * t) {
80 /* Simple top down splay, not requiring i to be in the tree t. */
81 /* What it does is described above. */
82 dslxt_Tree N, *l, *r, *y;
83 int dir;
84
85 dslxt_success = 0;
86
87 if (t == NULL) return t;
88 N.left = N.right = NULL;
89 l = r = &N;
90
91 for (;;) {
92 dir = strcmp(i, t->item);
93 if (dir < 0) {
94 if (t->left == NULL) break;
95 if (strcmp(i, t->left->item)<0) {
96 y = t->left; /* rotate right */
97 t->left = y->right;
98 y->right = t;
99 t = y;
100 if (t->left == NULL) break;
101 }
102 r->left = t; /* link right */
103 r = t;
104 t = t->left;
105 } else if (dir > 0) {
106 if (t->right == NULL) break;
107 if (strcmp(i, t->right->item)>0) {
108 y = t->right; /* rotate left */
109 t->right = y->left;
110 y->left = t;
111 t = y;
112 if (t->right == NULL) break;
113 }
114 l->right = t; /* link left */
115 l = t;
116 t = t->right;
117 } else {
118 dslxt_success=1;
119 break;
120 }
121 }
122 l->right = t->left; /* assemble */
123 r->left = t->right;
124 t->left = N.right;
125 t->right = N.left;
126 return t;
127 }
128
129
dslxt_insert(char * i,dslxt_Tree * t,unsigned int val)130 static dslxt_Tree * dslxt_insert(char *i, dslxt_Tree * t, unsigned int val) {
131 /* Insert i into the tree t, unless it's already there. */
132 /* Return a pointer to the resulting tree. */
133 dslxt_Tree * n;
134 int dir;
135
136 n = (dslxt_Tree *) calloc (1, sizeof (dslxt_Tree));
137 if (n == NULL) {
138 fprintf(stderr, "dslxt_insert: ran out of memory, exiting.\n");
139 exit(255);
140 }
141 n->item = i;
142 n->val = val;
143 if (t == NULL) {
144 n->left = n->right = NULL;
145 return n;
146 }
147 t = dslxt_splay(i,t);
148 dir = strcmp(i,t->item);
149 if (dir<0) {
150 n->left = t->left;
151 n->right = t;
152 t->left = NULL;
153 return n;
154 } else if (dir>0) {
155 n->right = t->right;
156 n->left = t;
157 t->right = NULL;
158 return n;
159 } else { /* We get here if it's already in the tree */
160 /* Don't add it again */
161 free(n);
162 return t;
163 }
164 }
165
166 #if 0
167 /* unused for now but delete is here for completeness */
168 static dslxt_Tree * dslxt_delete(char *i, dslxt_Tree * t) {
169 /* Deletes i from the tree if it's there. */
170 /* Return a pointer to the resulting tree. */
171 dslxt_Tree * x;
172 if (t==NULL) return NULL;
173 t = dslxt_splay(i,t);
174 if (!strcmp(i, t->item)) { /* found it */
175 if (t->left == NULL) {
176 x = t->right;
177 } else {
178 x = dslxt_splay(i, t->left);
179 x->right = t->right;
180 }
181 free(t);
182 return x;
183 }
184 return t; /* It wasn't there */
185 }
186 #endif
187
188 /************************ splay ************************/
189
190 /*
191 * functions which emit various big endian
192 * data to a file
193 */
lt_emit_u8(struct lt_trace * lt,int value)194 static int lt_emit_u8(struct lt_trace *lt, int value)
195 {
196 unsigned char buf[1];
197 int nmemb;
198
199 buf[0] = value & 0xff;
200 nmemb=fwrite(buf, sizeof(char), 1, lt->handle);
201 lt->position+=nmemb;
202 return(nmemb);
203 }
204
205
lt_emit_u16(struct lt_trace * lt,int value)206 static int lt_emit_u16(struct lt_trace *lt, int value)
207 {
208 unsigned char buf[2];
209 int nmemb;
210
211 buf[0] = (value>>8) & 0xff;
212 buf[1] = value & 0xff;
213 nmemb = fwrite(buf, sizeof(char), 2, lt->handle);
214 lt->position+=nmemb;
215 return(nmemb);
216 }
217
218
lt_emit_u24(struct lt_trace * lt,int value)219 static int lt_emit_u24(struct lt_trace *lt, int value)
220 {
221 unsigned char buf[3];
222 int nmemb;
223
224 buf[0] = (value>>16) & 0xff;
225 buf[1] = (value>>8) & 0xff;
226 buf[2] = value & 0xff;
227 nmemb=fwrite(buf, sizeof(char), 3, lt->handle);
228 lt->position+=nmemb;
229 return(nmemb);
230 }
231
232
lt_emit_u32(struct lt_trace * lt,int value)233 static int lt_emit_u32(struct lt_trace *lt, int value)
234 {
235 unsigned char buf[4];
236 int nmemb;
237
238 buf[0] = (value>>24) & 0xff;
239 buf[1] = (value>>16) & 0xff;
240 buf[2] = (value>>8) & 0xff;
241 buf[3] = value & 0xff;
242 nmemb=fwrite(buf, sizeof(char), 4, lt->handle);
243 lt->position+=nmemb;
244 return(nmemb);
245 }
246
247
lt_emit_u64(struct lt_trace * lt,int valueh,int valuel)248 static int lt_emit_u64(struct lt_trace *lt, int valueh, int valuel)
249 {
250 int rc;
251
252 if((rc=lt_emit_u32(lt, valueh)))
253 {
254 rc=lt_emit_u32(lt, valuel);
255 }
256
257 return(rc);
258 }
259
260
lt_emit_double(struct lt_trace * lt,double value)261 static int lt_emit_double(struct lt_trace *lt, double value)
262 {
263 int nmemb;
264
265 nmemb=fwrite(&value, sizeof(char), sizeof(double)/sizeof(char), lt->handle);
266 lt->position+=nmemb;
267 return(nmemb);
268 }
269
270
lt_emit_string(struct lt_trace * lt,char * value)271 static int lt_emit_string(struct lt_trace *lt, char *value)
272 {
273 int rc=1;
274 do
275 {
276 rc&=lt_emit_u8(lt, *value);
277 } while(*(value++));
278 return(rc);
279 }
280
281
282 /*
283 * gzfunctions which emit various big endian
284 * data to a file. (lt->position needs to be
285 * fixed up on gzclose so the tables don't
286 * get out of sync!)
287 */
lt_emit_u8z(struct lt_trace * lt,int value)288 static int lt_emit_u8z(struct lt_trace *lt, int value)
289 {
290 unsigned char buf[1];
291 int nmemb;
292
293 buf[0] = value & 0xff;
294 nmemb=gzwrite(lt->zhandle, buf, 1);
295 lt->zpackcount++;
296 lt->position++;
297 return(nmemb);
298 }
299
300
lt_emit_u16z(struct lt_trace * lt,int value)301 static int lt_emit_u16z(struct lt_trace *lt, int value)
302 {
303 unsigned char buf[2];
304 int nmemb;
305
306 buf[0] = (value>>8) & 0xff;
307 buf[1] = value & 0xff;
308 nmemb = gzwrite(lt->zhandle, buf, 2);
309 lt->zpackcount+=2;
310 lt->position+=2;
311 return(nmemb);
312 }
313
314
lt_emit_u24z(struct lt_trace * lt,int value)315 static int lt_emit_u24z(struct lt_trace *lt, int value)
316 {
317 unsigned char buf[3];
318 int nmemb;
319
320 buf[0] = (value>>16) & 0xff;
321 buf[1] = (value>>8) & 0xff;
322 buf[2] = value & 0xff;
323 nmemb=gzwrite(lt->zhandle, buf, 3);
324 lt->zpackcount+=3;
325 lt->position+=3;
326 return(nmemb);
327 }
328
329
lt_emit_u32z(struct lt_trace * lt,int value)330 static int lt_emit_u32z(struct lt_trace *lt, int value)
331 {
332 unsigned char buf[4];
333 int nmemb;
334
335 buf[0] = (value>>24) & 0xff;
336 buf[1] = (value>>16) & 0xff;
337 buf[2] = (value>>8) & 0xff;
338 buf[3] = value & 0xff;
339 nmemb=gzwrite(lt->zhandle, buf, 4);
340
341 lt->zpackcount+=4;
342 lt->position+=4;
343 return(nmemb);
344 }
345
346
lt_emit_u64z(struct lt_trace * lt,int valueh,int valuel)347 static int lt_emit_u64z(struct lt_trace *lt, int valueh, int valuel)
348 {
349 int rc;
350
351 if((rc=lt_emit_u32z(lt, valueh)))
352 {
353 rc=lt_emit_u32z(lt, valuel);
354 }
355
356 return(rc);
357 }
358
359
lt_emit_doublez(struct lt_trace * lt,double value)360 static int lt_emit_doublez(struct lt_trace *lt, double value)
361 {
362 int nmemb;
363
364 nmemb=gzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char));
365 lt->zpackcount+=(sizeof(double)/sizeof(char));
366 lt->position+=(sizeof(double)/sizeof(char));;
367 return(nmemb);
368 }
369
370
lt_emit_stringz(struct lt_trace * lt,char * value)371 static int lt_emit_stringz(struct lt_trace *lt, char *value)
372 {
373 int rc=1;
374 do
375 {
376 rc&=lt_emit_u8z(lt, *value);
377 } while(*(value++));
378 return(rc);
379 }
380
381 /*
382 * bz2functions which emit various big endian
383 * data to a file. (lt->position needs to be
384 * fixed up on BZ2_bzclose so the tables don't
385 * get out of sync!)
386 */
lt_emit_u8bz(struct lt_trace * lt,int value)387 static int lt_emit_u8bz(struct lt_trace *lt, int value)
388 {
389 unsigned char buf[1];
390 int nmemb;
391
392 buf[0] = value & 0xff;
393 nmemb=BZ2_bzwrite(lt->zhandle, buf, 1);
394 lt->zpackcount++;
395 lt->position++;
396 return(nmemb);
397 }
398
399
lt_emit_u16bz(struct lt_trace * lt,int value)400 static int lt_emit_u16bz(struct lt_trace *lt, int value)
401 {
402 unsigned char buf[2];
403 int nmemb;
404
405 buf[0] = (value>>8) & 0xff;
406 buf[1] = value & 0xff;
407 nmemb = BZ2_bzwrite(lt->zhandle, buf, 2);
408 lt->zpackcount+=2;
409 lt->position+=2;
410 return(nmemb);
411 }
412
413
lt_emit_u24bz(struct lt_trace * lt,int value)414 static int lt_emit_u24bz(struct lt_trace *lt, int value)
415 {
416 unsigned char buf[3];
417 int nmemb;
418
419 buf[0] = (value>>16) & 0xff;
420 buf[1] = (value>>8) & 0xff;
421 buf[2] = value & 0xff;
422 nmemb=BZ2_bzwrite(lt->zhandle, buf, 3);
423 lt->zpackcount+=3;
424 lt->position+=3;
425 return(nmemb);
426 }
427
428
lt_emit_u32bz(struct lt_trace * lt,int value)429 static int lt_emit_u32bz(struct lt_trace *lt, int value)
430 {
431 unsigned char buf[4];
432 int nmemb;
433
434 buf[0] = (value>>24) & 0xff;
435 buf[1] = (value>>16) & 0xff;
436 buf[2] = (value>>8) & 0xff;
437 buf[3] = value & 0xff;
438 nmemb=BZ2_bzwrite(lt->zhandle, buf, 4);
439
440 lt->zpackcount+=4;
441 lt->position+=4;
442 return(nmemb);
443 }
444
445
lt_emit_u64bz(struct lt_trace * lt,int valueh,int valuel)446 static int lt_emit_u64bz(struct lt_trace *lt, int valueh, int valuel)
447 {
448 int rc;
449
450 if((rc=lt_emit_u32bz(lt, valueh)))
451 {
452 rc=lt_emit_u32bz(lt, valuel);
453 }
454
455 return(rc);
456 }
457
458
lt_emit_doublebz(struct lt_trace * lt,double value)459 static int lt_emit_doublebz(struct lt_trace *lt, double value)
460 {
461 int nmemb;
462
463 nmemb=BZ2_bzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char));
464 lt->zpackcount+=(sizeof(double)/sizeof(char));
465 lt->position+=(sizeof(double)/sizeof(char));;
466 return(nmemb);
467 }
468
469
lt_emit_stringbz(struct lt_trace * lt,char * value)470 static int lt_emit_stringbz(struct lt_trace *lt, char *value)
471 {
472 int rc=1;
473 do
474 {
475 rc&=lt_emit_u8bz(lt, *value);
476 } while(*(value++));
477 return(rc);
478 }
479
480
481 /*
482 * switch between compression modes above
483 */
lt_set_zmode(struct lt_trace * lt,int mode)484 static void lt_set_zmode(struct lt_trace *lt, int mode)
485 {
486 switch(mode)
487 {
488 case LT_ZMODE_NONE:
489 lt->lt_emit_u8 = lt_emit_u8;
490 lt->lt_emit_u16 = lt_emit_u16;
491 lt->lt_emit_u24 = lt_emit_u24;
492 lt->lt_emit_u32 = lt_emit_u32;
493 lt->lt_emit_u64 = lt_emit_u64;
494 lt->lt_emit_double = lt_emit_double;
495 lt->lt_emit_string = lt_emit_string;
496 break;
497
498 case LT_ZMODE_GZIP:
499 lt->lt_emit_u8 = lt_emit_u8z;
500 lt->lt_emit_u16 = lt_emit_u16z;
501 lt->lt_emit_u24 = lt_emit_u24z;
502 lt->lt_emit_u32 = lt_emit_u32z;
503 lt->lt_emit_u64 = lt_emit_u64z;
504 lt->lt_emit_double = lt_emit_doublez;
505 lt->lt_emit_string = lt_emit_stringz;
506 break;
507
508 case LT_ZMODE_BZIP2:
509 lt->lt_emit_u8 = lt_emit_u8bz;
510 lt->lt_emit_u16 = lt_emit_u16bz;
511 lt->lt_emit_u24 = lt_emit_u24bz;
512 lt->lt_emit_u32 = lt_emit_u32bz;
513 lt->lt_emit_u64 = lt_emit_u64bz;
514 lt->lt_emit_double = lt_emit_doublebz;
515 lt->lt_emit_string = lt_emit_stringbz;
516 break;
517 }
518 }
519
520
521 /*
522 * hash/symtable manipulation
523 */
lt_hash(const char * s)524 static int lt_hash(const char *s)
525 {
526 const char *p;
527 char ch;
528 unsigned int h=0, h2=0, pos=0, g;
529 for(p=s;*p;p++)
530 {
531 ch=*p;
532 h2<<=3;
533 h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */
534
535 h=(h<<4)+ch;
536 if((g=h&0xf0000000))
537 {
538 h=h^(g>>24);
539 h=h^g;
540 }
541 }
542
543 h^=h2; /* combine the two hashes */
544 return(h%LT_SYMPRIME);
545 }
546
547
lt_symadd(struct lt_trace * lt,const char * name,int hv)548 static struct lt_symbol *lt_symadd(struct lt_trace *lt, const char *name, int hv)
549 {
550 struct lt_symbol *s;
551
552 s=(struct lt_symbol *)calloc(1,sizeof(struct lt_symbol));
553 strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name);
554 s->next=lt->sym[hv];
555 lt->sym[hv]=s;
556 return(s);
557 }
558
559
lt_symfind(struct lt_trace * lt,const char * s)560 static struct lt_symbol *lt_symfind(struct lt_trace *lt, const char *s)
561 {
562 int hv;
563 struct lt_symbol *temp;
564
565 hv=lt_hash(s);
566 if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */
567
568 while(temp)
569 {
570 if(!strcmp(temp->name,s))
571 {
572 return(temp); /* in table already */
573 }
574 if(!temp->next) break;
575 temp=temp->next;
576 }
577
578 return(NULL); /* not found, add here if you want to add*/
579 }
580
581
582 /*
583 * compress facs to a prefix count + string + 0x00
584 */
lt_compress_fac(struct lt_trace * lt,char * str)585 static void lt_compress_fac(struct lt_trace *lt, char *str)
586 {
587 int i;
588 int len = strlen(str);
589 int minlen = (len<lt->compress_fac_len) ? len : lt->compress_fac_len;
590
591 if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */
592
593 if(lt->compress_fac_str)
594 {
595 for(i=0;i<minlen;i++)
596 {
597 if(lt->compress_fac_str[i]!=str[i]) break;
598 }
599 lt_emit_u16z(lt, i);
600 lt_emit_stringz(lt, str+i);
601 free(lt->compress_fac_str);
602 }
603 else
604 {
605 lt_emit_u16z(lt, 0);
606 lt_emit_stringz(lt, str);
607 }
608
609 lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1);
610 strcpy(lt->compress_fac_str, str);
611 }
612
613
strip_brack(struct lt_symbol * s)614 static void strip_brack(struct lt_symbol *s)
615 {
616 char *lastch = s->name+s->namlen - 1;
617 if(*lastch!=']') return;
618 if(s->namlen<3) return;
619 lastch--;
620 while(lastch!=s->name)
621 {
622 if(*lastch=='.')
623 {
624 return; /* MTI SV [0.3] notation for implicit vars */
625 }
626
627 if(*lastch=='[')
628 {
629 *lastch=0x00;
630 return;
631 }
632 lastch--;
633 }
634 return;
635 }
636
637
lt_emitfacs(struct lt_trace * lt)638 static void lt_emitfacs(struct lt_trace *lt)
639 {
640 int i;
641
642 if((lt)&&(lt->numfacs))
643 {
644 struct lt_symbol *s = lt->symchain;
645 char is_interlaced_trace = (lt->sorted_facs==NULL);
646
647 if(!lt->sorted_facs)
648 {
649 if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *))))
650 {
651 if(lt->do_strip_brackets)
652 for(i=0;i<lt->numfacs;i++)
653 {
654 lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */
655 strip_brack(s);
656 s=s->symchain;
657 }
658 else
659 for(i=0;i<lt->numfacs;i++)
660 {
661 lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing*/
662 s=s->symchain;
663 }
664 wave_msort(lt->sorted_facs, lt->numfacs);
665
666 for(i=0;i<lt->numfacs;i++)
667 {
668 lt->sorted_facs[i]->facnum = i;
669 }
670 }
671 }
672
673 if(lt->sorted_facs)
674 {
675 lt->facname_offset=lt->position;
676
677 lt_emit_u32(lt, lt->numfacs); /* uncompressed */
678 lt_emit_u32(lt, lt->numfacbytes); /* uncompressed */
679 fflush(lt->handle);
680 lt->zfacname_size = lt->position;
681 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
682
683 lt->zpackcount = 0;
684 for(i=0;i<lt->numfacs;i++)
685 {
686 lt_compress_fac(lt, lt->sorted_facs[i]->name);
687 }
688 free(lt->compress_fac_str); lt->compress_fac_str=NULL;
689 lt->compress_fac_len=0;
690 lt->zfacname_predec_size = lt->zpackcount;
691
692 gzclose(lt->zhandle);
693 fseeko(lt->handle, 0L, SEEK_END);
694 lt->position=ftello(lt->handle);
695 lt->zfacname_size = lt->position - lt->zfacname_size;
696
697 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
698
699 lt->facgeometry_offset = lt->position;
700 for(i=0;i<lt->numfacs;i++)
701 {
702 if((lt->sorted_facs[i]->flags<_SYM_F_ALIAS)==0)
703 {
704 lt_emit_u32z(lt, lt->sorted_facs[i]->rows);
705 lt_emit_u32z(lt, lt->sorted_facs[i]->msb);
706 lt_emit_u32z(lt, lt->sorted_facs[i]->lsb);
707 lt_emit_u32z(lt, lt->sorted_facs[i]->flags);
708 }
709 else
710 {
711 lt_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum);
712 lt_emit_u32z(lt, lt->sorted_facs[i]->msb);
713 lt_emit_u32z(lt, lt->sorted_facs[i]->lsb);
714 lt_emit_u32z(lt, LT_SYM_F_ALIAS);
715 }
716 }
717
718 gzclose(lt->zhandle);
719 fseeko(lt->handle, 0L, SEEK_END);
720 lt->position=ftello(lt->handle);
721 lt->zfacgeometry_size = lt->position - lt->facgeometry_offset;
722
723 if(is_interlaced_trace)
724 {
725 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
726
727 lt->sync_table_offset = lt->position;
728 for(i=0;i<lt->numfacs;i++)
729 {
730 lt_emit_u32z(lt, lt->sorted_facs[i]->last_change);
731 }
732
733 gzclose(lt->zhandle); lt->zhandle = NULL;
734 fseeko(lt->handle, 0L, SEEK_END);
735 lt->position=ftello(lt->handle);
736 lt->zsync_table_size = lt->position - lt->sync_table_offset;
737 }
738 }
739 }
740 }
741
742
743 /*
744 * initialize the trace and get back an lt context
745 */
lt_init(const char * name)746 struct lt_trace *lt_init(const char *name)
747 {
748 struct lt_trace *lt=(struct lt_trace *)calloc(1, sizeof(struct lt_trace));
749
750 if(!(lt->handle=fopen(name, "wb")))
751 {
752 free(lt);
753 lt=NULL;
754 }
755 else
756 {
757 lt_emit_u16(lt, LT_HDRID);
758 lt_emit_u16(lt, LT_VERSION);
759 lt->change_field_offset = lt->position;
760 lt->initial_value = -1; /* if a user sets this it will have a different POSITIVE val */
761 lt->timescale = -256; /* will be in range of -128<=x<=127 if set */
762
763 lt_set_zmode(lt, LT_ZMODE_NONE);
764
765 lt->mintime=ULLDescriptor(1);
766 lt->maxtime=ULLDescriptor(0);
767 }
768
769 return(lt);
770 }
771
772 /*
773 * clock flushing..
774 */
lt_flushclock(struct lt_trace * lt,struct lt_symbol * s)775 static void lt_flushclock(struct lt_trace *lt, struct lt_symbol *s)
776 {
777 unsigned int last_change_delta = lt->position - s->last_change - 2;
778 unsigned int start_position = lt->position;
779 int tag;
780 int numbytes, numbytes_trans;
781 int numtrans = s->clk_numtrans - LT_CLKPACK - 1;
782
783 if(numtrans<0)
784 {
785 /* it never got around to caching */
786 fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans);
787 return;
788 }
789
790 if(numtrans >= 256*65536)
791 {
792 numbytes_trans = 3;
793 }
794 else
795 if(numtrans >= 65536)
796 {
797 numbytes_trans = 2;
798 }
799 else
800 if(numtrans >= 256)
801 {
802 numbytes_trans = 1;
803 }
804 else
805 {
806 numbytes_trans = 0;
807 }
808
809 if(!lt->numfacs_bytes)
810 {
811 if(last_change_delta >= 256*65536)
812 {
813 numbytes = 3;
814 }
815 else
816 if(last_change_delta >= 65536)
817 {
818 numbytes = 2;
819 }
820 else
821 if(last_change_delta >= 256)
822 {
823 numbytes = 1;
824 }
825 else
826 {
827 numbytes = 0;
828 }
829
830 tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */
831
832 lt->lt_emit_u8(lt, tag);
833 switch(numbytes&3)
834 {
835 case 0: lt->lt_emit_u8(lt, last_change_delta); break;
836 case 1: lt->lt_emit_u16(lt, last_change_delta); break;
837 case 2: lt->lt_emit_u24(lt, last_change_delta); break;
838 case 3: lt->lt_emit_u32(lt, last_change_delta); break;
839 }
840 }
841 else
842 {
843 tag = 0xC + numbytes_trans; /* yields C..F */
844
845 switch(lt->numfacs_bytes)
846 {
847 case 1: lt->lt_emit_u8(lt, s->facnum); break;
848 case 2: lt->lt_emit_u16(lt, s->facnum); break;
849 case 3: lt->lt_emit_u24(lt, s->facnum); break;
850 case 4: lt->lt_emit_u32(lt, s->facnum); break;
851 }
852 lt->lt_emit_u8(lt, tag);
853 }
854
855 s->last_change = start_position;
856
857 /* s->clk_prevval CAN BE INFERRED! */
858 /* s->clk_prevtrans CAN BE INFERRED! */
859 /* s->clk_delta CAN BE INFERRED! */
860
861 switch(numbytes_trans&3)
862 {
863 case 0: lt->lt_emit_u8(lt, numtrans); break;
864 case 1: lt->lt_emit_u16(lt, numtrans); break;
865 case 2: lt->lt_emit_u24(lt, numtrans); break;
866 case 3: lt->lt_emit_u32(lt, numtrans); break;
867 }
868
869 /* printf("Clock finish for '%s' at %lld ending with '%c' for %d repeats over a switch delta of %d\n",
870 s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK, s->clk_delta); */
871 s->clk_prevtrans = ULLDescriptor(~0);
872 s->clk_numtrans = 0;
873 }
874
lt_flushclock_m(struct lt_trace * lt,struct lt_symbol * s)875 static void lt_flushclock_m(struct lt_trace *lt, struct lt_symbol *s)
876 {
877 unsigned int last_change_delta = lt->position - s->last_change - 2;
878 unsigned int start_position = lt->position;
879 int tag;
880 int numbytes, numbytes_trans;
881 int numtrans = s->clk_numtrans - LT_CLKPACK_M - 1;
882
883 if(numtrans<0)
884 {
885 /* it never got around to caching */
886 fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans);
887 return;
888 }
889
890 if(numtrans >= 256*65536)
891 {
892 numbytes_trans = 3;
893 }
894 else
895 if(numtrans >= 65536)
896 {
897 numbytes_trans = 2;
898 }
899 else
900 if(numtrans >= 256)
901 {
902 numbytes_trans = 1;
903 }
904 else
905 {
906 numbytes_trans = 0;
907 }
908
909 if(!lt->numfacs_bytes)
910 {
911 if(last_change_delta >= 256*65536)
912 {
913 numbytes = 3;
914 }
915 else
916 if(last_change_delta >= 65536)
917 {
918 numbytes = 2;
919 }
920 else
921 if(last_change_delta >= 256)
922 {
923 numbytes = 1;
924 }
925 else
926 {
927 numbytes = 0;
928 }
929
930 tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */
931
932 lt->lt_emit_u8(lt, tag);
933 switch(numbytes&3)
934 {
935 case 0: lt->lt_emit_u8(lt, last_change_delta); break;
936 case 1: lt->lt_emit_u16(lt, last_change_delta); break;
937 case 2: lt->lt_emit_u24(lt, last_change_delta); break;
938 case 3: lt->lt_emit_u32(lt, last_change_delta); break;
939 }
940 }
941 else
942 {
943 tag = 0xC + numbytes_trans; /* yields C..F */
944
945 switch(lt->numfacs_bytes)
946 {
947 case 1: lt->lt_emit_u8(lt, s->facnum); break;
948 case 2: lt->lt_emit_u16(lt, s->facnum); break;
949 case 3: lt->lt_emit_u24(lt, s->facnum); break;
950 case 4: lt->lt_emit_u32(lt, s->facnum); break;
951 }
952 lt->lt_emit_u8(lt, tag);
953 }
954
955
956 s->last_change = start_position;
957
958 /* s->clk_prevval CAN BE INFERRED! */
959 /* s->clk_prevtrans CAN BE INFERRED! */
960 /* s->clk_delta CAN BE INFERRED! */
961
962 switch(numbytes_trans&3)
963 {
964 case 0: lt->lt_emit_u8(lt, numtrans); break;
965 case 1: lt->lt_emit_u16(lt, numtrans); break;
966 case 2: lt->lt_emit_u24(lt, numtrans); break;
967 case 3: lt->lt_emit_u32(lt, numtrans); break;
968 }
969
970 /* printf("Clock finish for '%s' at %lld ending with '%08x' for %d repeats over a switch delta of %lld\n",
971 s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK_M, s->clk_delta); */
972 s->clk_prevtrans = ULLDescriptor(~0);
973 s->clk_numtrans = 0;
974 }
975
976
977 /*
978 * recurse through dictionary
979 */
lt_recurse_dictionary(struct lt_trace * lt,dslxt_Tree * ds)980 static void lt_recurse_dictionary(struct lt_trace *lt, dslxt_Tree *ds)
981 {
982 if(ds->left) lt_recurse_dictionary(lt, ds->left);
983 lt->sorted_dict[ds->val] = ds;
984 if(ds->right) lt_recurse_dictionary(lt, ds->right);
985 }
986
lt_recurse_dictionary_free(struct lt_trace * lt,dslxt_Tree * ds)987 static void lt_recurse_dictionary_free(struct lt_trace *lt, dslxt_Tree *ds)
988 {
989 dslxt_Tree *lft = ds->left;
990 dslxt_Tree *rgh = ds->right;
991
992 if(lft) lt_recurse_dictionary_free(lt, lft);
993 free(ds->item); free(ds);
994 if(rgh) lt_recurse_dictionary_free(lt, rgh);
995 }
996
lt_dictval_compare(const void * v1,const void * v2)997 static int lt_dictval_compare(const void *v1, const void *v2)
998 {
999 const dslxt_Tree *s1 = *(const dslxt_Tree * const *)v1;
1000 const dslxt_Tree *s2 = *(const dslxt_Tree * const *)v2;
1001
1002 if(s1->val > s2->val) return(1); else return(-1); /* they're *never* equal */
1003 }
1004
lt_finalize_dictionary(struct lt_trace * lt)1005 static void lt_finalize_dictionary(struct lt_trace *lt)
1006 {
1007 unsigned int i;
1008
1009 lt->sorted_dict = calloc(lt->num_dict_entries, sizeof(dslxt_Tree *));
1010
1011 lt->dictionary_offset=lt->position;
1012
1013 lt_emit_u32(lt, lt->num_dict_entries); /* uncompressed */
1014 lt_emit_u32(lt, lt->dict_string_mem_required - lt->num_dict_entries); /* uncompressed : minus because leading '1' is implied so its stripped */
1015 lt_emit_u32(lt, lt->dict16_offset); /* uncompressed */
1016 lt_emit_u32(lt, lt->dict24_offset); /* uncompressed */
1017 lt_emit_u32(lt, lt->dict32_offset); /* uncompressed */
1018 lt_emit_u32(lt, lt->mindictwidth); /* uncompressed */
1019 fflush(lt->handle);
1020
1021 #if 0
1022 fprintf(stderr, "*** dictionary_offset = %08x\n", lt->dictionary_offset);
1023 fprintf(stderr, "*** num_dict_entries = %d\n", lt->num_dict_entries);
1024 #endif
1025
1026 lt->zdictionary_size = lt->position;
1027 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
1028
1029 lt_recurse_dictionary(lt, lt->dict);
1030 qsort((void *)lt->sorted_dict, lt->num_dict_entries, sizeof(struct dsTree **), lt_dictval_compare);
1031
1032 for(i=0;i<lt->num_dict_entries;i++)
1033 {
1034 dslxt_Tree *ds = lt->sorted_dict[i];
1035 /* fprintf(stderr, "%8d) '%s'\n", ds->val, ds->item); */
1036 lt_emit_stringz(lt, ds->item+1);
1037 }
1038
1039 gzclose(lt->zhandle);
1040 fseeko(lt->handle, 0L, SEEK_END);
1041 lt->position=ftello(lt->handle);
1042 lt->zdictionary_size = lt->position - lt->zdictionary_size;
1043
1044 free(lt->sorted_dict); lt->sorted_dict = NULL;
1045
1046 lt_recurse_dictionary_free(lt, lt->dict);
1047 lt->dict = NULL;
1048 }
1049
1050
1051 /*
1052 * close out the trace and fixate it
1053 */
lt_close(struct lt_trace * lt)1054 void lt_close(struct lt_trace *lt)
1055 {
1056 lxttime_t lasttime=ULLDescriptor(0);
1057 int lastposition=0;
1058 char is64=0;
1059
1060 if(lt)
1061 {
1062 struct lt_symbol *s = lt->symchain;
1063
1064 if(lt->clock_compress)
1065 while(s)
1066 {
1067 if(s->clk_prevtrans!=ULLDescriptor(~0))
1068 {
1069 int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len;
1070 if(len>1)
1071 {
1072 if(s->clk_numtrans > LT_CLKPACK_M) lt_flushclock_m(lt, s);
1073 }
1074 else
1075 {
1076 if(s->clk_numtrans > LT_CLKPACK) lt_flushclock(lt, s);
1077 }
1078 }
1079
1080 s=s->symchain;
1081 }
1082
1083 lt_set_dumpon(lt); /* in case it was turned off */
1084
1085 if(lt->zmode!=LT_ZMODE_NONE)
1086 {
1087 lt->chg_table_size = lt->position - lt->change_field_offset;
1088
1089 switch(lt->zmode)
1090 {
1091 case LT_ZMODE_GZIP: gzclose(lt->zhandle); break;
1092 case LT_ZMODE_BZIP2: BZ2_bzclose(lt->zhandle); break;
1093 }
1094 lt->zhandle = NULL;
1095 fseeko(lt->handle, 0L, SEEK_END);
1096 lt->position=ftello(lt->handle);
1097
1098 lt_set_zmode(lt, LT_ZMODE_NONE);
1099 lt->zchg_table_size = lt->position - lt->change_field_offset;
1100 }
1101
1102 lt_emitfacs(lt);
1103 if(lt->dict) lt_finalize_dictionary(lt);
1104
1105 free(lt->timebuff);
1106 lt->timebuff=NULL;
1107
1108 if(lt->timehead)
1109 {
1110 struct lt_timetrail *t=lt->timehead;
1111 struct lt_timetrail *t2;
1112
1113 lt->time_table_offset = lt->position;
1114
1115 lt_emit_u32(lt, lt->timechangecount); /* this is uncompressed! */
1116
1117 fflush(lt->handle);
1118 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
1119 lt->ztime_table_size = lt->position;
1120
1121 is64=(lt->maxtime > ULLDescriptor(0xFFFFFFFF));
1122
1123 if(is64)
1124 {
1125 lt_emit_u64z(lt, (int)((lt->mintime)>>32), (int)lt->mintime);
1126 lt_emit_u64z(lt, (int)((lt->maxtime)>>32), (int)lt->maxtime);
1127 }
1128 else
1129 {
1130 lt_emit_u32z(lt, (int)lt->mintime);
1131 lt_emit_u32z(lt, (int)lt->maxtime);
1132 }
1133
1134 while(t)
1135 {
1136 lt_emit_u32z(lt, t->position - lastposition); lastposition = t->position;
1137 t=t->next;
1138 }
1139
1140 t=lt->timehead;
1141 if(is64)
1142 {
1143 while(t)
1144 {
1145 lxttime_t delta = t->timeval - lasttime;
1146 lt_emit_u64z(lt, (int)(delta>>32), (int)delta); lasttime = t->timeval;
1147
1148 t2=t->next;
1149 free(t);
1150 t=t2;
1151 }
1152 }
1153 else
1154 {
1155 while(t)
1156 {
1157 lt_emit_u32z(lt, (int)(t->timeval - lasttime)); lasttime = t->timeval;
1158
1159 t2=t->next;
1160 free(t);
1161 t=t2;
1162 }
1163
1164 lt->timehead = lt->timecurr = NULL;
1165 }
1166
1167 gzclose(lt->zhandle); lt->zhandle = NULL;
1168 fseeko(lt->handle, 0L, SEEK_END);
1169 lt->position=ftello(lt->handle);
1170 lt->ztime_table_size = lt->position - lt->ztime_table_size;
1171 }
1172
1173 if(lt->initial_value>=0)
1174 {
1175 lt->initial_value_offset = lt->position;
1176 lt_emit_u8(lt, lt->initial_value);
1177 }
1178
1179 if((lt->timescale>-129)&&(lt->timescale<128))
1180 {
1181 lt->timescale_offset = lt->position;
1182 lt_emit_u8(lt, lt->timescale);
1183 }
1184
1185 if(lt->double_used)
1186 {
1187 lt->double_test_offset = lt->position;
1188 lt_emit_double(lt, 3.14159);
1189 }
1190
1191 if(lt->dumpoffcount)
1192 {
1193 struct lt_timetrail *ltt = lt->dumpoffhead;
1194 struct lt_timetrail *ltt2;
1195
1196 lt->exclude_offset = lt->position;
1197 lt_emit_u32(lt, lt->dumpoffcount);
1198
1199 while(ltt)
1200 {
1201 lt_emit_u64(lt, (int)((ltt->timeval)>>32), (int)ltt->timeval);
1202 ltt2 = ltt;
1203 ltt=ltt->next;
1204 free(ltt2);
1205 }
1206
1207 lt->dumpoffhead = lt->dumpoffcurr = NULL;
1208 lt->dumpoffcount = 0;
1209 }
1210
1211 if(lt->timezero)
1212 {
1213 lt->timezero_offset = lt->position;
1214 lt_emit_u64(lt, (int)((lt->timezero)>>32), (int)lt->timezero);
1215 }
1216
1217 /* prefix */
1218 lt_emit_u8(lt, LT_SECTION_END);
1219
1220 /* Version 1 */
1221 if(lt->change_field_offset) { lt_emit_u32(lt, lt->change_field_offset); lt_emit_u8(lt, LT_SECTION_CHG); lt->change_field_offset = 0; }
1222 if(lt->sync_table_offset) { lt_emit_u32(lt, lt->sync_table_offset); lt_emit_u8(lt, LT_SECTION_SYNC_TABLE); lt->sync_table_offset = 0; }
1223 if(lt->facname_offset) { lt_emit_u32(lt, lt->facname_offset); lt_emit_u8(lt, LT_SECTION_FACNAME); lt->facname_offset = 0; }
1224 if(lt->facgeometry_offset) { lt_emit_u32(lt, lt->facgeometry_offset); lt_emit_u8(lt, LT_SECTION_FACNAME_GEOMETRY); lt->facgeometry_offset = 0; }
1225 if(lt->timescale_offset) { lt_emit_u32(lt, lt->timescale_offset); lt_emit_u8(lt, LT_SECTION_TIMESCALE); lt->timescale_offset = 0; }
1226 if(lt->time_table_offset) { lt_emit_u32(lt, lt->time_table_offset); lt_emit_u8(lt, is64 ? LT_SECTION_TIME_TABLE64 : LT_SECTION_TIME_TABLE); lt->time_table_offset = 0; }
1227 if(lt->initial_value_offset) { lt_emit_u32(lt, lt->initial_value_offset); lt_emit_u8(lt, LT_SECTION_INITIAL_VALUE); lt->initial_value_offset = 0; }
1228 if(lt->double_test_offset) { lt_emit_u32(lt, lt->double_test_offset); lt_emit_u8(lt, LT_SECTION_DOUBLE_TEST); lt->double_test_offset = 0; }
1229
1230 /* Version 2 adds */
1231 if(lt->zfacname_predec_size) { lt_emit_u32(lt, lt->zfacname_predec_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_PREDEC_SIZE); lt->zfacname_predec_size = 0; }
1232 if(lt->zfacname_size) { lt_emit_u32(lt, lt->zfacname_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_SIZE); lt->zfacname_size = 0; }
1233 if(lt->zfacgeometry_size) { lt_emit_u32(lt, lt->zfacgeometry_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_GEOMETRY_SIZE); lt->zfacgeometry_size = 0; }
1234 if(lt->zsync_table_size) { lt_emit_u32(lt, lt->zsync_table_size); lt_emit_u8(lt, LT_SECTION_ZSYNC_SIZE); lt->zsync_table_size = 0; }
1235 if(lt->ztime_table_size) { lt_emit_u32(lt, lt->ztime_table_size); lt_emit_u8(lt, LT_SECTION_ZTIME_TABLE_SIZE); lt->ztime_table_size = 0; }
1236 if(lt->chg_table_size) { lt_emit_u32(lt, lt->chg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_PREDEC_SIZE); lt->chg_table_size = 0; }
1237 if(lt->zchg_table_size) { lt_emit_u32(lt, lt->zchg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_SIZE); lt->zchg_table_size = 0; }
1238
1239 /* Version 4 adds */
1240 if(lt->dictionary_offset) { lt_emit_u32(lt, lt->dictionary_offset); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY); lt->dictionary_offset = 0; }
1241 if(lt->zdictionary_size) { lt_emit_u32(lt, lt->zdictionary_size); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY_SIZE); lt->zdictionary_size = 0; }
1242
1243 /* Version 5 adds */
1244 if(lt->exclude_offset) { lt_emit_u32(lt, lt->exclude_offset); lt_emit_u8(lt, LT_SECTION_EXCLUDE_TABLE); lt->exclude_offset = 0; }
1245
1246 /* Version 6 adds */
1247 if(lt->timezero_offset) { lt_emit_u32(lt, lt->timezero_offset); lt_emit_u8(lt, LT_SECTION_TIMEZERO); lt->timezero_offset = 0; }
1248
1249 /* suffix */
1250 lt_emit_u8(lt, LT_TRLID);
1251
1252 if(lt->symchain)
1253 {
1254 struct lt_symbol *sc = lt->symchain;
1255 struct lt_symbol *s2;
1256
1257 while(sc)
1258 {
1259 free(sc->name);
1260 s2=sc->symchain;
1261 free(sc);
1262 sc=s2;
1263 }
1264 }
1265
1266 free(lt->sorted_facs);
1267 fclose(lt->handle);
1268 free(lt);
1269 }
1270
1271 }
1272
1273
1274 /*
1275 * maint function for finding a symbol if it exists
1276 */
lt_symbol_find(struct lt_trace * lt,const char * name)1277 struct lt_symbol *lt_symbol_find(struct lt_trace *lt, const char *name)
1278 {
1279 struct lt_symbol *s=NULL;
1280
1281 if((lt)&&(name)) s=lt_symfind(lt, name);
1282 return(s);
1283 }
1284
1285
1286 /*
1287 * add a trace (if it doesn't exist already)
1288 */
lt_symbol_add(struct lt_trace * lt,const char * name,unsigned int rows,int msb,int lsb,int flags)1289 struct lt_symbol *lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags)
1290 {
1291 struct lt_symbol *s;
1292 int len;
1293 int flagcnt;
1294
1295 if((!lt)||(lt->sorted_facs)) return(NULL);
1296
1297 flagcnt = ((flags<_SYM_F_INTEGER)!=0) + ((flags<_SYM_F_DOUBLE)!=0) + ((flags<_SYM_F_STRING)!=0);
1298
1299 if((flagcnt>1)||(!lt)||(!name)||(lt_symfind(lt, name))) return (NULL);
1300
1301 if(flags<_SYM_F_DOUBLE) lt->double_used = 1;
1302
1303 s=lt_symadd(lt, name, lt_hash(name));
1304 s->rows = rows;
1305 s->flags = flags&(~LT_SYM_F_ALIAS); /* aliasing makes no sense here.. */
1306
1307 if(!flagcnt)
1308 {
1309 s->msb = msb;
1310 s->lsb = lsb;
1311 s->len = (msb<lsb) ? (lsb-msb+1) : (msb-lsb+1);
1312
1313 if((s->len==1)&&(s->rows==0)) s->clk_prevtrans = ULLDescriptor(~0);
1314 }
1315
1316 s->symchain = lt->symchain;
1317 lt->symchain = s;
1318
1319 lt->numfacs++;
1320
1321 if((len=strlen(name)) > lt->longestname) lt->longestname = len;
1322 lt->numfacbytes += (len+1);
1323
1324 return(s);
1325 }
1326
1327 /*
1328 * add an alias trace (if it doesn't exist already and orig is found)
1329 */
lt_symbol_alias(struct lt_trace * lt,const char * existing_name,const char * alias,int msb,int lsb)1330 struct lt_symbol *lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb)
1331 {
1332 struct lt_symbol *s, *sa;
1333 int len;
1334 int bitlen;
1335 int flagcnt;
1336
1337 if((!lt)||(!existing_name)||(!alias)||(!(s=lt_symfind(lt, existing_name)))||(lt_symfind(lt, alias))) return (NULL);
1338
1339 if(lt->sorted_facs) return(NULL);
1340
1341 while(s->aliased_to) /* find root alias */
1342 {
1343 s=s->aliased_to;
1344 }
1345
1346 flagcnt = ((s->flags<_SYM_F_INTEGER)!=0) + ((s->flags<_SYM_F_DOUBLE)!=0) + ((s->flags<_SYM_F_STRING)!=0);
1347 bitlen = (msb<lsb) ? (lsb-msb+1) : (msb-lsb+1);
1348 if((!flagcnt)&&(bitlen!=s->len)) return(NULL);
1349
1350 sa=lt_symadd(lt, alias, lt_hash(alias));
1351 sa->flags = LT_SYM_F_ALIAS; /* only point this can get set */
1352 sa->aliased_to = s;
1353
1354 if(!flagcnt)
1355 {
1356 sa->msb = msb;
1357 sa->lsb = lsb;
1358 sa->len = bitlen;
1359 }
1360
1361 sa->symchain = lt->symchain;
1362 lt->symchain = sa;
1363 lt->numfacs++;
1364 if((len=strlen(alias)) > lt->longestname) lt->longestname = len;
1365 lt->numfacbytes += (len+1);
1366
1367 return(sa);
1368 }
1369
1370
1371 /*
1372 * set current time
1373 */
lt_inc_time_by_delta(struct lt_trace * lt,unsigned int timeval)1374 int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval)
1375 {
1376 return(lt_set_time64(lt, lt->maxtime + (lxttime_t)timeval));
1377 }
1378
lt_set_time(struct lt_trace * lt,unsigned int timeval)1379 int lt_set_time(struct lt_trace *lt, unsigned int timeval)
1380 {
1381 return(lt_set_time64(lt, (lxttime_t)timeval));
1382 }
1383
lt_inc_time_by_delta64(struct lt_trace * lt,lxttime_t timeval)1384 int lt_inc_time_by_delta64(struct lt_trace *lt, lxttime_t timeval)
1385 {
1386 return(lt_set_time64(lt, lt->maxtime + timeval));
1387 }
1388
lt_set_time64(struct lt_trace * lt,lxttime_t timeval)1389 int lt_set_time64(struct lt_trace *lt, lxttime_t timeval)
1390 {
1391 int rc=0;
1392
1393 if(lt)
1394 {
1395 struct lt_timetrail *trl=(struct lt_timetrail *)calloc(1, sizeof(struct lt_timetrail));
1396 if(trl)
1397 {
1398 trl->timeval = timeval;
1399 trl->position = lt->position;
1400
1401 if((lt->timecurr)||(lt->timebuff))
1402 {
1403 if(((timeval>lt->mintime)&&(timeval>lt->maxtime))||((lt->mintime==ULLDescriptor(1))&&(lt->maxtime==ULLDescriptor(0))))
1404 {
1405 lt->maxtime = timeval;
1406 }
1407 else
1408 {
1409 free(trl);
1410 goto bail;
1411 }
1412 }
1413 else
1414 {
1415 lt->mintime = lt->maxtime = timeval;
1416 }
1417
1418 free(lt->timebuff);
1419 lt->timebuff = trl;
1420 lt->timeval = timeval;
1421 rc=1;
1422 }
1423 }
1424
1425 bail:
1426 return(rc);
1427 }
1428
1429
1430 /*
1431 * sets trace timescale as 10**x seconds
1432 */
lt_set_timescale(struct lt_trace * lt,int timescale)1433 void lt_set_timescale(struct lt_trace *lt, int timescale)
1434 {
1435 if(lt)
1436 {
1437 lt->timescale = timescale;
1438 }
1439 }
1440
1441
1442 /*
1443 * sets clock compression heuristic
1444 */
lt_set_clock_compress(struct lt_trace * lt)1445 void lt_set_clock_compress(struct lt_trace *lt)
1446 {
1447 if(lt)
1448 {
1449 lt->clock_compress = 1;
1450 }
1451 }
1452
1453
1454 /*
1455 * sets change dump compression
1456 */
lt_set_chg_compress(struct lt_trace * lt)1457 void lt_set_chg_compress(struct lt_trace *lt)
1458 {
1459 if(lt)
1460 {
1461 if((lt->zmode==LT_ZMODE_NONE)&&(!lt->emitted))
1462 {
1463 lt_set_zmode(lt, lt->zmode = LT_ZMODE_GZIP);
1464 fflush(lt->handle);
1465 lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
1466 }
1467 }
1468 }
1469
1470
1471 /*
1472 * sets change dictionary compression
1473 */
lt_set_dict_compress(struct lt_trace * lt,unsigned int minwidth)1474 void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth)
1475 {
1476 if((lt)&&(!lt->emitted))
1477 {
1478 lt->dictmode = 1;
1479
1480 if(minwidth>1)
1481 {
1482 lt->mindictwidth = minwidth;
1483 }
1484 }
1485 }
1486
1487 /*
1488 * sets change interlace
1489 */
lt_set_no_interlace(struct lt_trace * lt)1490 void lt_set_no_interlace(struct lt_trace *lt)
1491 {
1492 if((lt)&&(!lt->emitted)&&(!lt->sorted_facs))
1493 {
1494 if(lt->zmode==LT_ZMODE_NONE) /* this mode implies BZIP2 compression! */
1495 {
1496 lt_set_zmode(lt, lt->zmode = LT_ZMODE_BZIP2);
1497 fflush(lt->handle);
1498 lt->zhandle = BZ2_bzdopen(dup(fileno(lt->handle)), "wb9");
1499 }
1500
1501 if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *))))
1502 {
1503 struct lt_symbol *s = lt->symchain;
1504 int i;
1505
1506 if(lt->do_strip_brackets)
1507 for(i=0;i<lt->numfacs;i++)
1508 {
1509 lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */
1510 strip_brack(s);
1511 s=s->symchain;
1512 }
1513 else
1514 for(i=0;i<lt->numfacs;i++)
1515 {
1516 lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */
1517 s=s->symchain;
1518 }
1519 wave_msort(lt->sorted_facs, lt->numfacs);
1520
1521 for(i=0;i<lt->numfacs;i++)
1522 {
1523 lt->sorted_facs[i]->facnum = i;
1524 }
1525
1526 if(lt->numfacs >= 256*65536)
1527 {
1528 lt->numfacs_bytes = 4;
1529 }
1530 else
1531 if(lt->numfacs >= 65536)
1532 {
1533 lt->numfacs_bytes = 3;
1534 }
1535 else
1536 if(lt->numfacs >= 256)
1537 {
1538 lt->numfacs_bytes = 2;
1539 }
1540 else
1541 {
1542 lt->numfacs_bytes = 1;
1543 }
1544 }
1545 }
1546 }
1547
1548
1549 /*
1550 * sets trace initial value
1551 */
lt_set_initial_value(struct lt_trace * lt,char value)1552 void lt_set_initial_value(struct lt_trace *lt, char value)
1553 {
1554 if(lt)
1555 {
1556 int tag;
1557 switch(value)
1558 {
1559 case '0': tag = 0; break;
1560 case '1': tag = 1; break;
1561 case 'Z':
1562 case 'z': tag = 2; break;
1563 case 'X':
1564 case 'x': tag = 3; break;
1565 case 'H':
1566 case 'h': tag = 4; break;
1567 case 'U':
1568 case 'u': tag = 5; break;
1569 case 'W':
1570 case 'w': tag = 6; break;
1571 case 'L':
1572 case 'l': tag = 0x7; break;
1573 case '-': tag = 0x8; break;
1574 default: tag = -1; break;
1575 }
1576 lt->initial_value = tag;
1577 }
1578 }
1579
1580
1581 /*
1582 * Sets bracket stripping (useful for VCD conversions of
1583 * bitblasted nets)
1584 */
lt_symbol_bracket_stripping(struct lt_trace * lt,int doit)1585 void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit)
1586 {
1587 if(lt)
1588 {
1589 lt->do_strip_brackets = (doit!=0);
1590 }
1591 }
1592
1593
1594 /*
1595 * emission for trace values..
1596 */
1597 static int lt_optimask[]=
1598 {
1599 0x00000000,
1600
1601 0x00000001,
1602 0x00000003,
1603 0x00000007,
1604 0x0000000f,
1605
1606 0x0000001f,
1607 0x0000003f,
1608 0x0000007f,
1609 0x000000ff,
1610
1611 0x000001ff,
1612 0x000003ff,
1613 0x000007ff,
1614 0x00000fff,
1615
1616 0x00001fff,
1617 0x00003fff,
1618 0x00007fff,
1619 0x0000ffff,
1620
1621 0x0001ffff,
1622 0x0003ffff,
1623 0x0007ffff,
1624 0x000fffff,
1625
1626 0x001fffff,
1627 0x003fffff,
1628 0x007fffff,
1629 0x00ffffff,
1630
1631 0x01ffffff,
1632 0x03ffffff,
1633 0x07ffffff,
1634 0x0fffffff,
1635
1636 0x1fffffff,
1637 0x3fffffff,
1638 0x7fffffff,
1639 0xffffffff
1640 };
1641
1642
lt_expand_integer_to_bits(int len,int value)1643 static char *lt_expand_integer_to_bits(int len, int value)
1644 {
1645 static char s[33];
1646 char *p = s;
1647 int i;
1648
1649 len--;
1650
1651 for(i=0;i<=len;i++)
1652 {
1653 *(p++) = '0' | ((value & (1<<(len-i)))!=0);
1654 }
1655 *p = 0;
1656
1657 return(s);
1658 }
1659
1660
lt_emit_value_int(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,int value)1661 int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value)
1662 {
1663 int rc=0;
1664
1665 if((!lt)||(!s)) return(rc);
1666
1667 if(!lt->emitted) lt->emitted = 1;
1668
1669 while(s->aliased_to) /* find root alias if exists */
1670 {
1671 s=s->aliased_to;
1672 }
1673
1674 if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING)))
1675 {
1676 int numbytes; /* number of bytes to store value minus one */
1677 unsigned int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len;
1678 unsigned int last_change_delta;
1679
1680 if((lt->clock_compress)&&(s->rows==0))
1681 {
1682 if((len>1)&&(len<=32))
1683 {
1684 int ivalue = value;
1685 int delta1, delta2;
1686 s->clk_mask <<= 1;
1687 s->clk_mask |= 1;
1688
1689 if( ((s->clk_mask&0x1f)==0x1f) &&
1690 ( (delta1=(ivalue - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) &&
1691 ( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) &&
1692 ( (delta1==delta2) || ((!delta1)&&(!delta2)) )
1693 )
1694 {
1695 if(s->clk_prevtrans==ULLDescriptor(~0))
1696 {
1697 s->clk_prevtrans = lt->timeval;
1698 s->clk_numtrans = 0;
1699 }
1700 else
1701 if(s->clk_numtrans == 0)
1702 {
1703 s->clk_delta = lt->timeval - s->clk_prevtrans;
1704 s->clk_prevtrans = lt->timeval;
1705 s->clk_numtrans++;
1706 }
1707 else
1708 {
1709 if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
1710 {
1711 s->clk_numtrans++;
1712 s->clk_prevtrans = lt->timeval;
1713 if(s->clk_numtrans > LT_CLKPACK_M)
1714 {
1715 s->clk_prevval4 = s->clk_prevval3;
1716 s->clk_prevval3 = s->clk_prevval2;
1717 s->clk_prevval2 = s->clk_prevval1;
1718 s->clk_prevval1 = s->clk_prevval;
1719 s->clk_prevval = ivalue;
1720
1721 /* printf("Clock value '%08x' for '%s' at %lld (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */
1722 return(1);
1723 }
1724 }
1725 else
1726 {
1727 if(s->clk_numtrans > LT_CLKPACK_M)
1728 {
1729 lt_flushclock_m(lt, s);
1730 /* flush clock then continue below! */
1731 }
1732 else
1733 {
1734 s->clk_prevtrans=ULLDescriptor(~0);
1735 }
1736 }
1737 }
1738
1739 }
1740 else
1741 {
1742 if(s->clk_numtrans > LT_CLKPACK_M)
1743 {
1744 lt_flushclock_m(lt, s);
1745 /* flush clock then continue below! */
1746 }
1747 else
1748 {
1749 s->clk_prevtrans=ULLDescriptor(~0);
1750 }
1751 }
1752
1753 s->clk_prevval4 = s->clk_prevval3;
1754 s->clk_prevval3 = s->clk_prevval2;
1755 s->clk_prevval2 = s->clk_prevval1;
1756 s->clk_prevval1 = s->clk_prevval;
1757 s->clk_prevval = ivalue;
1758 }
1759 else
1760 if(len==1) /* possible clock handling */
1761 {
1762 int ivalue = value&1;
1763
1764 if(((s->clk_prevval == '1') && (ivalue==0)) || ((s->clk_prevval == '0') && (ivalue==1)))
1765 {
1766 if(s->clk_prevtrans==ULLDescriptor(~0))
1767 {
1768 s->clk_prevtrans = lt->timeval;
1769 s->clk_numtrans = 0;
1770 }
1771 else
1772 if(s->clk_numtrans == 0)
1773 {
1774 s->clk_delta = lt->timeval - s->clk_prevtrans;
1775 s->clk_prevtrans = lt->timeval;
1776 s->clk_numtrans++;
1777 }
1778 else
1779 {
1780 if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
1781 {
1782 s->clk_numtrans++;
1783 s->clk_prevtrans = lt->timeval;
1784 if(s->clk_numtrans > LT_CLKPACK)
1785 {
1786 s->clk_prevval = ivalue + '0';
1787
1788 /* printf("Clock value '%d' for '%s' at %d (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */
1789 return(1);
1790 }
1791 }
1792 else
1793 {
1794 if(s->clk_numtrans > LT_CLKPACK)
1795 {
1796 lt_flushclock(lt, s);
1797 /* flush clock then continue below! */
1798 }
1799 else
1800 {
1801 s->clk_prevtrans=ULLDescriptor(~0);
1802 }
1803 }
1804 }
1805
1806 }
1807 else
1808 {
1809 if(s->clk_numtrans > LT_CLKPACK)
1810 {
1811 lt_flushclock(lt, s);
1812 /* flush clock then continue below! */
1813 }
1814 else
1815 {
1816 s->clk_prevtrans=ULLDescriptor(~0);
1817 }
1818 }
1819
1820 s->clk_prevval = ivalue + '0';
1821 }
1822 }
1823
1824 /* normal trace handling */
1825
1826 last_change_delta = lt->position - s->last_change - 2;
1827
1828 if(last_change_delta >= 256*65536)
1829 {
1830 numbytes = 3;
1831 }
1832 else
1833 if(last_change_delta >= 65536)
1834 {
1835 numbytes = 2;
1836 }
1837 else
1838 if(last_change_delta >= 256)
1839 {
1840 numbytes = 1;
1841 }
1842 else
1843 {
1844 numbytes = 0;
1845 }
1846
1847 if(len<=32)
1848 {
1849 int start_position = lt->position;
1850 int tag;
1851 int optimized0 = ((value<_optimask[len])==0);
1852 int optimized1 = ((value<_optimask[len])==lt_optimask[len]);
1853 int optimized = optimized0|optimized1;
1854
1855 if(!lt->numfacs_bytes)
1856 {
1857 if(optimized)
1858 {
1859 tag = (numbytes<<4) | (3+optimized1); /* for x3 and x4 cases */
1860 }
1861 else
1862 {
1863 tag = (numbytes<<4);
1864 }
1865
1866 lt->lt_emit_u8(lt, tag);
1867 switch(numbytes&3)
1868 {
1869 case 0: lt->lt_emit_u8(lt, last_change_delta); break;
1870 case 1: lt->lt_emit_u16(lt, last_change_delta); break;
1871 case 2: lt->lt_emit_u24(lt, last_change_delta); break;
1872 case 3: lt->lt_emit_u32(lt, last_change_delta); break;
1873 }
1874 }
1875 else
1876 {
1877 switch(lt->numfacs_bytes)
1878 {
1879 case 1: lt->lt_emit_u8(lt, s->facnum); break;
1880 case 2: lt->lt_emit_u16(lt, s->facnum); break;
1881 case 3: lt->lt_emit_u24(lt, s->facnum); break;
1882 case 4: lt->lt_emit_u32(lt, s->facnum); break;
1883 }
1884 lt->lt_emit_u8(lt, optimized ? (3+optimized1) : 0);
1885 }
1886
1887 s->last_change = start_position;
1888
1889 if(s->rows>0)
1890 {
1891 if(s->rows >= 256*65536)
1892 {
1893 numbytes = 3;
1894 }
1895 else
1896 if(s->rows >= 65536)
1897 {
1898 numbytes = 2;
1899 }
1900 else
1901 if(s->rows >= 256)
1902 {
1903 numbytes = 1;
1904 }
1905 else
1906 {
1907 numbytes = 0;
1908 }
1909
1910 switch(numbytes&3)
1911 {
1912 case 0: lt->lt_emit_u8(lt, row); break;
1913 case 1: lt->lt_emit_u16(lt, row); break;
1914 case 2: lt->lt_emit_u24(lt, row); break;
1915 case 3: lt->lt_emit_u32(lt, row); break;
1916 }
1917 }
1918
1919 if(!optimized)
1920 {
1921 if((lt->dictmode)&&(len>lt->mindictwidth))
1922 {
1923 char *vpnt_orig = lt_expand_integer_to_bits(len, value);
1924 char *vpnt = vpnt_orig;
1925
1926 while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++;
1927
1928 lt->dict = dslxt_splay (vpnt, lt->dict);
1929 if(!dslxt_success)
1930 {
1931 unsigned int vlen = strlen(vpnt)+1;
1932 char *vcopy = (char *)malloc(vlen);
1933
1934 strcpy(vcopy, vpnt);
1935 lt->dict_string_mem_required += vlen;
1936 lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries);
1937
1938 if(!lt->dict16_offset)
1939 {
1940 if(lt->num_dict_entries==256) lt->dict16_offset = lt->position;
1941 }
1942 else
1943 if(!lt->dict24_offset)
1944 {
1945 if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position;
1946 }
1947 else
1948 if(!lt->dict32_offset)
1949 {
1950 if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position;
1951 }
1952
1953 lt->num_dict_entries++;
1954 }
1955
1956 if(lt->dict24_offset)
1957 {
1958 if(lt->dict32_offset)
1959 {
1960 lt->lt_emit_u32(lt, lt->dict->val);
1961 }
1962 else
1963 {
1964 lt->lt_emit_u24(lt, lt->dict->val);
1965 }
1966 }
1967 else
1968 {
1969 if(lt->dict16_offset)
1970 {
1971 lt->lt_emit_u16(lt, lt->dict->val);
1972 }
1973 else
1974 {
1975 lt->lt_emit_u8(lt, lt->dict->val);
1976 }
1977 }
1978 }
1979 else
1980 if(len<9)
1981 {
1982 value <<= (8-len);
1983 rc=lt->lt_emit_u8(lt, value);
1984 }
1985 else
1986 if(len<17)
1987 {
1988 value <<= (16-len);
1989 rc=lt->lt_emit_u16(lt, value);
1990 }
1991 else
1992 if(len<25)
1993 {
1994 value <<= (24-len);
1995 rc=lt->lt_emit_u24(lt, value);
1996 }
1997 else
1998 {
1999 value <<= (32-len);
2000 rc=lt->lt_emit_u32(lt, value);
2001 }
2002 }
2003 }
2004
2005 if(lt->timebuff)
2006 {
2007 lt->timechangecount++;
2008 if(lt->timecurr)
2009 {
2010 lt->timecurr->next = lt->timebuff;
2011 lt->timecurr = lt->timebuff;
2012 }
2013 else
2014 {
2015 lt->timehead = lt->timecurr = lt->timebuff;
2016 }
2017
2018 lt->timebuff=NULL;
2019 }
2020 }
2021
2022 return(rc);
2023 }
2024
2025
lt_emit_value_double(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,double value)2026 int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value)
2027 {
2028 int rc=0;
2029 int start_position;
2030 int tag;
2031
2032 if((!lt)||(!s)) return(rc);
2033
2034 if(!lt->emitted) lt->emitted = 1;
2035
2036 while(s->aliased_to) /* find root alias if exists */
2037 {
2038 s=s->aliased_to;
2039 }
2040
2041 if((s->flags)<_SYM_F_DOUBLE)
2042 {
2043 int numbytes; /* number of bytes to store value minus one */
2044 unsigned int last_change_delta = lt->position - s->last_change - 2;
2045
2046 if(!lt->numfacs_bytes)
2047 {
2048 if(last_change_delta >= 256*65536)
2049 {
2050 numbytes = 3;
2051 }
2052 else
2053 if(last_change_delta >= 65536)
2054 {
2055 numbytes = 2;
2056 }
2057 else
2058 if(last_change_delta >= 256)
2059 {
2060 numbytes = 1;
2061 }
2062 else
2063 {
2064 numbytes = 0;
2065 }
2066
2067 start_position = lt->position;
2068 s->last_change = start_position;
2069
2070 tag = (numbytes<<4);
2071 lt->lt_emit_u8(lt, tag);
2072 switch(numbytes&3)
2073 {
2074 case 0: lt->lt_emit_u8(lt, last_change_delta); break;
2075 case 1: lt->lt_emit_u16(lt, last_change_delta); break;
2076 case 2: lt->lt_emit_u24(lt, last_change_delta); break;
2077 case 3: lt->lt_emit_u32(lt, last_change_delta); break;
2078 }
2079 }
2080 else
2081 {
2082 switch(lt->numfacs_bytes)
2083 {
2084 case 1: lt->lt_emit_u8(lt, s->facnum); break;
2085 case 2: lt->lt_emit_u16(lt, s->facnum); break;
2086 case 3: lt->lt_emit_u24(lt, s->facnum); break;
2087 case 4: lt->lt_emit_u32(lt, s->facnum); break;
2088 }
2089 }
2090
2091 if(s->rows>0)
2092 {
2093 if(s->rows >= 256*65536)
2094 {
2095 numbytes = 3;
2096 }
2097 else
2098 if(s->rows >= 65536)
2099 {
2100 numbytes = 2;
2101 }
2102 else
2103 if(s->rows >= 256)
2104 {
2105 numbytes = 1;
2106 }
2107 else
2108 {
2109 numbytes = 0;
2110 }
2111
2112 switch(numbytes&3)
2113 {
2114 case 0: lt->lt_emit_u8(lt, row); break;
2115 case 1: lt->lt_emit_u16(lt, row); break;
2116 case 2: lt->lt_emit_u24(lt, row); break;
2117 case 3: lt->lt_emit_u32(lt, row); break;
2118 }
2119 }
2120
2121 rc=lt->lt_emit_double(lt, value);
2122
2123 if(lt->timebuff)
2124 {
2125 lt->timechangecount++;
2126 if(lt->timecurr)
2127 {
2128 lt->timecurr->next = lt->timebuff;
2129 lt->timecurr = lt->timebuff;
2130 }
2131 else
2132 {
2133 lt->timehead = lt->timecurr = lt->timebuff;
2134 }
2135
2136 lt->timebuff=NULL;
2137 }
2138 }
2139
2140 return(rc);
2141 }
2142
2143
lt_emit_value_string(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,char * value)2144 int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value)
2145 {
2146 int rc=0;
2147 int start_position;
2148 int tag;
2149
2150 if((!lt)||(!s)||(!value)) return(rc);
2151
2152 if(!lt->emitted) lt->emitted = 1;
2153
2154 while(s->aliased_to) /* find root alias if exists */
2155 {
2156 s=s->aliased_to;
2157 }
2158
2159 if((s->flags)<_SYM_F_STRING)
2160 {
2161 int numbytes; /* number of bytes to store value minus one */
2162 unsigned int last_change_delta = lt->position - s->last_change - 2;
2163
2164 if(!lt->numfacs_bytes)
2165 {
2166 if(last_change_delta >= 256*65536)
2167 {
2168 numbytes = 3;
2169 }
2170 else
2171 if(last_change_delta >= 65536)
2172 {
2173 numbytes = 2;
2174 }
2175 else
2176 if(last_change_delta >= 256)
2177 {
2178 numbytes = 1;
2179 }
2180 else
2181 {
2182 numbytes = 0;
2183 }
2184
2185 start_position = lt->position;
2186 s->last_change = start_position;
2187
2188 tag = (numbytes<<4);
2189 lt->lt_emit_u8(lt, tag);
2190 switch(numbytes&3)
2191 {
2192 case 0: lt->lt_emit_u8(lt, last_change_delta); break;
2193 case 1: lt->lt_emit_u16(lt, last_change_delta); break;
2194 case 2: lt->lt_emit_u24(lt, last_change_delta); break;
2195 case 3: lt->lt_emit_u32(lt, last_change_delta); break;
2196 }
2197 }
2198 else
2199 {
2200 switch(lt->numfacs_bytes)
2201 {
2202 case 1: lt->lt_emit_u8(lt, s->facnum); break;
2203 case 2: lt->lt_emit_u16(lt, s->facnum); break;
2204 case 3: lt->lt_emit_u24(lt, s->facnum); break;
2205 case 4: lt->lt_emit_u32(lt, s->facnum); break;
2206 }
2207 }
2208
2209 if(s->rows>0)
2210 {
2211 if(s->rows >= 256*65536)
2212 {
2213 numbytes = 3;
2214 }
2215 else
2216 if(s->rows >= 65536)
2217 {
2218 numbytes = 2;
2219 }
2220 else
2221 if(s->rows >= 256)
2222 {
2223 numbytes = 1;
2224 }
2225 else
2226 {
2227 numbytes = 0;
2228 }
2229
2230 switch(numbytes&3)
2231 {
2232 case 0: lt->lt_emit_u8(lt, row); break;
2233 case 1: lt->lt_emit_u16(lt, row); break;
2234 case 2: lt->lt_emit_u24(lt, row); break;
2235 case 3: lt->lt_emit_u32(lt, row); break;
2236 }
2237 }
2238
2239 rc=lt->lt_emit_string(lt, value);
2240
2241 if(lt->timebuff)
2242 {
2243 lt->timechangecount++;
2244 if(lt->timecurr)
2245 {
2246 lt->timecurr->next = lt->timebuff;
2247 lt->timecurr = lt->timebuff;
2248 }
2249 else
2250 {
2251 lt->timehead = lt->timecurr = lt->timebuff;
2252 }
2253
2254 lt->timebuff=NULL;
2255 }
2256 }
2257
2258 return(rc);
2259 }
2260
2261
lt_emit_value_bit_string(struct lt_trace * lt,struct lt_symbol * s,unsigned int row,char * value)2262 int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value)
2263 {
2264 int rc=0;
2265 int start_position;
2266 int tag, tagadd;
2267
2268 if((!lt)||(!s)||(!value)||(!*value)) return(rc);
2269
2270 if(!lt->emitted) lt->emitted = 1;
2271
2272 while(s->aliased_to) /* find root alias if exists */
2273 {
2274 s=s->aliased_to;
2275 }
2276
2277 if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING)))
2278 {
2279 int numbytes; /* number of bytes to store value minus one */
2280 char *pnt;
2281 int mvl=0;
2282 char ch;
2283 char prevch;
2284 unsigned int last_change_delta;
2285
2286 unsigned int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len;
2287
2288 if((lt->clock_compress)&&(s->rows==0))
2289 {
2290 if((len>1)&&(len<=32))
2291 {
2292 int legal = 0;
2293 int ivalue = 0;
2294 unsigned int i;
2295 char *pntv = value;
2296 int delta1, delta2;
2297
2298 for(i=0;i<len;i++)
2299 {
2300 if((*pntv!='0')&&(*pntv!='1'))
2301 {
2302 if((!*pntv)&&(i>0))
2303 {
2304 pntv--;
2305 }
2306 else
2307 {
2308 legal = 0;
2309 break;
2310 }
2311 }
2312
2313 ivalue = (((unsigned int)ivalue) << 1);
2314 ivalue |= (*pntv & 1);
2315 legal = 1;
2316 pntv++;
2317 }
2318 s->clk_mask <<= 1;
2319 s->clk_mask |= legal;
2320
2321 if( ((s->clk_mask&0x1f)==0x1f) &&
2322 ( (delta1=(ivalue - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) &&
2323 ( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) &&
2324 ( (delta1==delta2) || ((!delta1)&&(!delta2)) )
2325 )
2326 {
2327 if(s->clk_prevtrans==ULLDescriptor(~0))
2328 {
2329 s->clk_prevtrans = lt->timeval;
2330 s->clk_numtrans = 0;
2331 }
2332 else
2333 if(s->clk_numtrans == 0)
2334 {
2335 s->clk_delta = lt->timeval - s->clk_prevtrans;
2336 s->clk_prevtrans = lt->timeval;
2337 s->clk_numtrans++;
2338 }
2339 else
2340 {
2341 if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
2342 {
2343 s->clk_numtrans++;
2344 s->clk_prevtrans = lt->timeval;
2345 if(s->clk_numtrans > LT_CLKPACK_M)
2346 {
2347 s->clk_prevval4 = s->clk_prevval3;
2348 s->clk_prevval3 = s->clk_prevval2;
2349 s->clk_prevval2 = s->clk_prevval1;
2350 s->clk_prevval1 = s->clk_prevval;
2351 s->clk_prevval = ivalue;
2352
2353 /* printf("Clock value '%08x' for '%s' [len=%d] at %lld (#%d)\n",
2354 ivalue, s->name, len, lt->timeval, s->clk_numtrans); */
2355 return(1);
2356 }
2357 }
2358 else
2359 {
2360 if(s->clk_numtrans > LT_CLKPACK_M)
2361 {
2362 lt_flushclock_m(lt, s);
2363 /* flush clock then continue below! */
2364 }
2365 else
2366 {
2367 s->clk_prevtrans=ULLDescriptor(~0);
2368 }
2369 }
2370 }
2371
2372 }
2373 else
2374 {
2375 if(s->clk_numtrans > LT_CLKPACK_M)
2376 {
2377 lt_flushclock_m(lt, s);
2378 /* flush clock then continue below! */
2379 }
2380 else
2381 {
2382 s->clk_prevtrans=ULLDescriptor(~0);
2383 }
2384 }
2385
2386 s->clk_prevval4 = s->clk_prevval3;
2387 s->clk_prevval3 = s->clk_prevval2;
2388 s->clk_prevval2 = s->clk_prevval1;
2389 s->clk_prevval1 = s->clk_prevval;
2390 s->clk_prevval = ivalue;
2391 }
2392 else
2393 if(len==1) /* possible clock handling */
2394 {
2395 if(((s->clk_prevval == '1') && (value[0]=='0')) || ((s->clk_prevval == '0') && (value[0]=='1')))
2396 {
2397 if(s->clk_prevtrans==ULLDescriptor(~0))
2398 {
2399 s->clk_prevtrans = lt->timeval;
2400 s->clk_numtrans = 0;
2401 }
2402 else
2403 if(s->clk_numtrans == 0)
2404 {
2405 s->clk_delta = lt->timeval - s->clk_prevtrans;
2406 s->clk_prevtrans = lt->timeval;
2407 s->clk_numtrans++;
2408 }
2409 else
2410 {
2411 if(s->clk_delta == (lt->timeval - s->clk_prevtrans))
2412 {
2413 s->clk_numtrans++;
2414 s->clk_prevtrans = lt->timeval;
2415 if(s->clk_numtrans > LT_CLKPACK)
2416 {
2417 s->clk_prevval = value[0];
2418
2419 /* printf("Clock value '%c' for '%s' at %lld (#%d)\n", value[0], s->name, lt->timeval, s->clk_numtrans); */
2420 return(1);
2421 }
2422 }
2423 else
2424 {
2425 if(s->clk_numtrans > LT_CLKPACK)
2426 {
2427 lt_flushclock(lt, s);
2428 /* flush clock then continue below! */
2429 }
2430 else
2431 {
2432 s->clk_prevtrans=ULLDescriptor(~0);
2433 }
2434 }
2435 }
2436
2437 }
2438 else
2439 {
2440 if(s->clk_numtrans > LT_CLKPACK)
2441 {
2442 lt_flushclock(lt, s);
2443 /* flush clock then continue below! */
2444 }
2445 else
2446 {
2447 s->clk_prevtrans=ULLDescriptor(~0);
2448 }
2449 }
2450
2451 s->clk_prevval = value[0];
2452 }
2453 }
2454
2455 /* normal trace handling */
2456
2457 last_change_delta = lt->position - s->last_change - 2;
2458
2459 if(last_change_delta >= 256*65536)
2460 {
2461 numbytes = 3;
2462 }
2463 else
2464 if(last_change_delta >= 65536)
2465 {
2466 numbytes = 2;
2467 }
2468 else
2469 if(last_change_delta >= 256)
2470 {
2471 numbytes = 1;
2472 }
2473 else
2474 {
2475 numbytes = 0;
2476 }
2477
2478 pnt = value;
2479 prevch = *pnt;
2480 while((ch=*(pnt++)))
2481 {
2482 switch(ch)
2483 {
2484 case '0':
2485 case '1': mvl|=LT_MVL_2; break;
2486 case 'Z':
2487 case 'z':
2488 case 'X':
2489 case 'x': mvl|=LT_MVL_4; break;
2490 default: mvl|=LT_MVL_9; break;
2491 }
2492
2493 if(prevch!=ch) prevch = 0;
2494 }
2495
2496 switch(prevch)
2497 {
2498 case 0x00: tagadd = 0; break;
2499 case '0': tagadd = 3; break;
2500 case '1': tagadd = 4; break;
2501 case 'Z':
2502 case 'z': tagadd = 5; break;
2503 case 'X':
2504 case 'x': tagadd = 6; break;
2505 case 'H':
2506 case 'h': tagadd = 7; break;
2507 case 'U':
2508 case 'u': tagadd = 8; break;
2509 case 'W':
2510 case 'w': tagadd = 9; break;
2511 case 'L':
2512 case 'l': tagadd = 0xa; break;
2513 default: tagadd = 0xb; break;
2514 }
2515
2516 if(mvl)
2517 {
2518 start_position = lt->position;
2519
2520 if(!lt->numfacs_bytes)
2521 {
2522 if(tagadd)
2523 {
2524 tag = (numbytes<<4) + tagadd;
2525 }
2526 else
2527 {
2528 tag = (numbytes<<4) + ((mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0));
2529 }
2530 lt->lt_emit_u8(lt, tag);
2531 switch(numbytes&3)
2532 {
2533 case 0: lt->lt_emit_u8(lt, last_change_delta); break;
2534 case 1: lt->lt_emit_u16(lt, last_change_delta); break;
2535 case 2: lt->lt_emit_u24(lt, last_change_delta); break;
2536 case 3: lt->lt_emit_u32(lt, last_change_delta); break;
2537 }
2538 }
2539 else
2540 {
2541 switch(lt->numfacs_bytes)
2542 {
2543 case 1: lt->lt_emit_u8(lt, s->facnum); break;
2544 case 2: lt->lt_emit_u16(lt, s->facnum); break;
2545 case 3: lt->lt_emit_u24(lt, s->facnum); break;
2546 case 4: lt->lt_emit_u32(lt, s->facnum); break;
2547 }
2548 if(tagadd)
2549 {
2550 lt->lt_emit_u8(lt, tagadd);
2551 }
2552 else
2553 {
2554 lt->lt_emit_u8(lt, (mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0) );
2555 }
2556 }
2557
2558 s->last_change = start_position;
2559
2560 if(s->rows>0)
2561 {
2562 if(s->rows >= 256*65536)
2563 {
2564 numbytes = 3;
2565 }
2566 else
2567 if(s->rows >= 65536)
2568 {
2569 numbytes = 2;
2570 }
2571 else
2572 if(s->rows >= 256)
2573 {
2574 numbytes = 1;
2575 }
2576 else
2577 {
2578 numbytes = 0;
2579 }
2580
2581 switch(numbytes&3)
2582 {
2583 case 0: lt->lt_emit_u8(lt, row); break;
2584 case 1: lt->lt_emit_u16(lt, row); break;
2585 case 2: lt->lt_emit_u24(lt, row); break;
2586 case 3: lt->lt_emit_u32(lt, row); break;
2587 }
2588 }
2589
2590 if(!tagadd)
2591 {
2592 unsigned int len2 = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len;
2593 if((mvl & (LT_MVL_2|LT_MVL_4|LT_MVL_9)) == LT_MVL_2)
2594 {
2595 unsigned int i;
2596 int bitpos = 7;
2597 int outval = 0;
2598 int thisval= 0;
2599
2600 pnt = value;
2601
2602 if((lt->dictmode)&&(len2>lt->mindictwidth))
2603 {
2604 char *vpnt = value;
2605 while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++;
2606
2607 lt->dict = dslxt_splay (vpnt, lt->dict);
2608 if(!dslxt_success)
2609 {
2610 unsigned int vlen = strlen(vpnt)+1;
2611 char *vcopy = (char *)malloc(vlen);
2612
2613 strcpy(vcopy, vpnt);
2614 lt->dict_string_mem_required += vlen;
2615 lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries);
2616
2617 if(!lt->dict16_offset)
2618 {
2619 if(lt->num_dict_entries==256) lt->dict16_offset = lt->position;
2620 }
2621 else
2622 if(!lt->dict24_offset)
2623 {
2624 if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position;
2625 }
2626 else
2627 if(!lt->dict32_offset)
2628 {
2629 if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position;
2630 }
2631
2632 lt->num_dict_entries++;
2633 }
2634
2635 if(lt->dict24_offset)
2636 {
2637 if(lt->dict32_offset)
2638 {
2639 lt->lt_emit_u32(lt, lt->dict->val);
2640 }
2641 else
2642 {
2643 lt->lt_emit_u24(lt, lt->dict->val);
2644 }
2645 }
2646 else
2647 {
2648 if(lt->dict16_offset)
2649 {
2650 lt->lt_emit_u16(lt, lt->dict->val);
2651 }
2652 else
2653 {
2654 lt->lt_emit_u8(lt, lt->dict->val);
2655 }
2656 }
2657 }
2658 else
2659 for(i=0;i<len2;i++)
2660 {
2661 if(*pnt)
2662 {
2663 thisval = (*pnt=='1');
2664 pnt++;
2665 }
2666 outval |= (thisval<<bitpos);
2667 bitpos--;
2668 if((bitpos==-1)||(i==len2-1))
2669 {
2670 lt->lt_emit_u8(lt, outval);
2671 outval = 0;
2672 bitpos = 7;
2673 }
2674 }
2675 }
2676 else
2677 if((mvl & (LT_MVL_4|LT_MVL_9)) == LT_MVL_4)
2678 {
2679 unsigned int i;
2680 int bitpos = 6;
2681 int outval = 0;
2682 int thisval= 0;
2683
2684 pnt = value;
2685
2686 for(i=0;i<len2;i++)
2687 {
2688 if(*pnt)
2689 {
2690 switch(*pnt)
2691 {
2692 case '0': thisval = 0; break;
2693 case '1': thisval = 1; break;
2694 case 'X':
2695 case 'x': thisval = 3; break;
2696 default: thisval = 2; break;
2697 }
2698 pnt++;
2699 }
2700 outval |= (thisval<<bitpos);
2701 bitpos-=2;
2702 if((bitpos==-2)||(i==len2-1))
2703 {
2704 lt->lt_emit_u8(lt, outval);
2705 outval = 0;
2706 bitpos = 6;
2707 }
2708 }
2709 }
2710 else
2711 /* if(mvl & LT_MVL_9) */
2712 {
2713 unsigned int i;
2714 int bitpos = 4;
2715 int outval = 0;
2716 int thisval= 0;
2717
2718 pnt = value;
2719
2720 for(i=0;i<len2;i++)
2721 {
2722 if(*pnt)
2723 {
2724 switch(*pnt)
2725 {
2726 case '0': thisval = 0; break;
2727 case '1': thisval = 1; break;
2728 case 'Z':
2729 case 'z': thisval = 2; break;
2730 case 'X':
2731 case 'x': thisval = 3; break;
2732 case 'H':
2733 case 'h': thisval = 4; break;
2734 case 'U':
2735 case 'u': thisval = 5; break;
2736 case 'W':
2737 case 'w': thisval = 6; break;
2738 case 'L':
2739 case 'l': thisval = 7; break;
2740 default: thisval = 8; break;
2741 }
2742 pnt++;
2743 }
2744 outval |= (thisval<<bitpos);
2745 bitpos-=4;
2746 if((bitpos==-4)||(i==len2-1))
2747 {
2748 lt->lt_emit_u8(lt, outval);
2749 outval = 0;
2750 bitpos = 4;
2751 }
2752 }
2753 }
2754 }
2755
2756 rc=1;
2757 }
2758
2759 if(lt->timebuff)
2760 {
2761 lt->timechangecount++;
2762 if(lt->timecurr)
2763 {
2764 lt->timecurr->next = lt->timebuff;
2765 lt->timecurr = lt->timebuff;
2766 }
2767 else
2768 {
2769 lt->timehead = lt->timecurr = lt->timebuff;
2770 }
2771
2772 lt->timebuff=NULL;
2773 }
2774 }
2775
2776 return(rc);
2777 }
2778
2779
2780 /*
2781 * blackout functions
2782 */
lt_set_dumpoff(struct lt_trace * lt)2783 void lt_set_dumpoff(struct lt_trace *lt)
2784 {
2785 if((lt)&&(!lt->dumpoff_active))
2786 {
2787 struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail));
2788
2789 ltt->timeval = lt->timeval;
2790 if(lt->dumpoffhead)
2791 {
2792 lt->dumpoffcurr->next = ltt;
2793 lt->dumpoffcurr = ltt;
2794 }
2795 else
2796 {
2797 lt->dumpoffhead = lt->dumpoffcurr = ltt;
2798 }
2799
2800 lt->dumpoff_active = 1;
2801 lt->dumpoffcount++;
2802 }
2803 }
2804
lt_set_dumpon(struct lt_trace * lt)2805 void lt_set_dumpon(struct lt_trace *lt)
2806 {
2807 if((lt)&&(lt->dumpoff_active))
2808 {
2809 struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail));
2810
2811 ltt->timeval = lt->timeval;
2812
2813 lt->dumpoffcurr->next = ltt;
2814 lt->dumpoffcurr = ltt;
2815
2816 lt->dumpoff_active = 0;
2817 }
2818 }
2819
lt_set_timezero(struct lt_trace * lt,lxtotime_t timeval)2820 void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval)
2821 {
2822 if(lt)
2823 {
2824 lt->timezero = timeval;
2825 }
2826 }
2827
2828