43
43
#define LITT_UNCOMPRESSED_SIZE_OFFSET 8
44
44
#define LITT_HEADER_SIZE 12
45
45
46
- // TODO Constants similar to these are defined in opcodesswitch.h and should
47
- // be refactored so they can be used here, as well.
48
- #define TAG_COMPACT_INT 0x01
49
- #define TAG_COMPACT_ATOM 0x02
50
- #define TAG_EXTENDED_INT 0x09
51
- #define TAG_EXTENDED_ATOM 0x0A
52
-
53
46
#define CHECK_FREE_SPACE (space , error ) \
54
47
if ((size_t) ((pos + space) - data) > len) { \
55
48
fprintf(stderr, error); \
@@ -449,22 +442,39 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
449
442
}
450
443
uint8_t tag = * pos ;
451
444
switch (tag & 0x0F ) {
452
- case TAG_COMPACT_INT : {
445
+ case COMPACT_INTEGER : {
453
446
++ i ;
454
447
++ pos ;
455
448
break ;
456
449
}
457
- case TAG_EXTENDED_INT : {
450
+ case COMPACT_LARGE_INTEGER : {
458
451
++ pos ;
452
+ switch (tag & COMPACT_LARGE_IMM_MASK ) {
453
+ case COMPACT_11BITS_VALUE : {
454
+ ++ pos ;
455
+ break ;
456
+ }
457
+ case COMPACT_NBITS_VALUE : {
458
+ int sz = (tag >> 5 ) + 2 ;
459
+ if (UNLIKELY (sz > 4 )) {
460
+ fprintf (stderr , "Invalid line_ref: expected extended int with sz <= 4 (line number <= 2^31)" );
461
+ return false;
462
+ }
463
+ pos += sz ;
464
+ break ;
465
+ }
466
+ default :
467
+ fprintf (stderr , "Invalid line_ref: expected extended int -- tag = %u" , (unsigned int ) tag );
468
+ return false;
469
+ }
459
470
if ((size_t ) (pos - * data ) > len ) {
460
471
fprintf (stderr , "Invalid line_ref: expected extended int.\n" );
461
472
return false;
462
473
}
463
474
++ i ;
464
- ++ pos ;
465
475
break ;
466
476
}
467
- case TAG_COMPACT_ATOM : {
477
+ case COMPACT_ATOM : {
468
478
uint16_t location_ix = ((tag & 0xF0 ) >> 4 );
469
479
if (location_ix > mod -> locations_count ) {
470
480
fprintf (stderr , "Invalid line_ref: location_ix = %d is greater than locations_count = %d.\n" , (int ) location_ix , (int ) mod -> locations_count );
@@ -473,11 +483,16 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
473
483
++ pos ;
474
484
break ;
475
485
}
476
- case TAG_EXTENDED_ATOM : {
486
+ case COMPACT_LARGE_ATOM : {
487
+ // We don't support more than 11bits (2048) locations.
488
+ if (UNLIKELY ((tag & COMPACT_LARGE_IMM_MASK ) != COMPACT_11BITS_VALUE )) {
489
+ fprintf (stderr , "Invalid line_ref: location_ix is larger than 2048.\n" );
490
+ return false;
491
+ }
477
492
uint16_t high_order_3_bits = (tag & 0xE0 );
478
493
++ pos ;
479
494
if ((size_t ) (pos - * data ) > len ) {
480
- fprintf (stderr , "Invalid line_ref: expected extended int .\n" );
495
+ fprintf (stderr , "Invalid line_ref: expected extended atom .\n" );
481
496
return false;
482
497
}
483
498
uint8_t next_byte = * pos ;
@@ -490,7 +505,6 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
490
505
break ;
491
506
}
492
507
default :
493
- // TODO handle integer compact encodings > 2048
494
508
fprintf (stderr , "Unsupported line_ref tag: %u\n" , tag );
495
509
return false;
496
510
}
@@ -520,7 +534,7 @@ static bool module_check_locations(Module *mod, const uint8_t *data, size_t len)
520
534
return true;
521
535
}
522
536
523
- static bool module_get_line_ref (Module * mod , uint16_t line_ref , uint16_t * out_line , uint16_t * out_location )
537
+ static bool module_get_line_ref (Module * mod , uint16_t line_ref , uint32_t * out_line , uint16_t * out_location )
524
538
{
525
539
// First is undefined
526
540
if (line_ref == 0 ) {
@@ -535,9 +549,9 @@ static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint16_t *out_li
535
549
while (i <= mod -> line_refs_count ) {
536
550
uint8_t tag = * pos ;
537
551
switch (tag & 0x0F ) {
538
- case TAG_COMPACT_INT : {
552
+ case COMPACT_INTEGER : {
539
553
if (i == line_ref ) {
540
- uint16_t line_idx = ((tag & 0xF0 ) >> 4 );
554
+ uint32_t line_idx = ((tag & 0xF0 ) >> 4 );
541
555
* out_line = line_idx ;
542
556
* out_location = location_ix ;
543
557
return true;
@@ -546,32 +560,49 @@ static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint16_t *out_li
546
560
++ pos ;
547
561
break ;
548
562
}
549
- case TAG_EXTENDED_INT : {
563
+ case COMPACT_LARGE_INTEGER : {
564
+ uint32_t line_idx ;
565
+ switch (tag & COMPACT_LARGE_IMM_MASK ) {
566
+ case COMPACT_11BITS_VALUE : {
567
+ uint16_t high_order_3_bits = (tag & 0xE0 );
568
+ line_idx = ((high_order_3_bits << 3 ) | pos [1 ]);
569
+ pos += 2 ;
570
+ break ;
571
+ }
572
+ case COMPACT_NBITS_VALUE : {
573
+ pos ++ ;
574
+ int sz = (tag >> 5 ) + 2 ;
575
+ line_idx = 0 ;
576
+ for (int i = 0 ; i < sz ; i ++ ) {
577
+ line_idx = line_idx * 256 + pos [i ];
578
+ }
579
+ pos += sz ;
580
+ break ;
581
+ }
582
+ default :
583
+ UNREACHABLE ();
584
+ }
550
585
if (i == line_ref ) {
551
- uint16_t high_order_3_bits = (tag & 0xE0 );
552
- uint16_t line_idx = ((high_order_3_bits << 3 ) | pos [1 ]);
553
586
* out_line = line_idx ;
554
587
* out_location = location_ix ;
555
588
return true;
556
589
}
557
- pos += 2 ;
558
590
++ i ;
559
591
break ;
560
592
}
561
- case TAG_COMPACT_ATOM : {
593
+ case COMPACT_ATOM : {
562
594
location_ix = ((tag & 0xF0 ) >> 4 );
563
595
++ pos ;
564
596
break ;
565
597
}
566
- case TAG_EXTENDED_ATOM : {
598
+ case COMPACT_LARGE_ATOM : {
567
599
uint16_t high_order_3_bits = (tag & 0xE0 );
568
600
location_ix = ((high_order_3_bits << 3 ) | pos [1 ]);
569
601
pos += 2 ;
570
602
break ;
571
603
}
572
604
default :
573
- // TODO handle integer compact encodings > 2048
574
- return false;
605
+ UNREACHABLE ();
575
606
}
576
607
}
577
608
@@ -680,7 +711,7 @@ void module_insert_line_ref_offset(Module *mod, int line_ref, int offset)
680
711
list_append (& mod -> line_ref_offsets , & ref_offset -> head );
681
712
}
682
713
683
- static bool module_find_line_ref (Module * mod , uint16_t line_ref , uint16_t * line , size_t * filename_len , const uint8_t * * filename )
714
+ static bool module_find_line_ref (Module * mod , uint16_t line_ref , uint32_t * line , size_t * filename_len , const uint8_t * * filename )
684
715
{
685
716
uint16_t location_ix ;
686
717
if (UNLIKELY (!module_get_line_ref (mod , line_ref , line , & location_ix ))) {
@@ -689,7 +720,7 @@ static bool module_find_line_ref(Module *mod, uint16_t line_ref, uint16_t *line,
689
720
return module_get_location (mod , location_ix , filename_len , filename );
690
721
}
691
722
692
- bool module_find_line (Module * mod , unsigned int offset , uint16_t * line , size_t * filename_len , const uint8_t * * filename )
723
+ bool module_find_line (Module * mod , unsigned int offset , uint32_t * line , size_t * filename_len , const uint8_t * * filename )
693
724
{
694
725
int i = 0 ;
695
726
struct LineRefOffset * head = GET_LIST_ENTRY (& mod -> line_ref_offsets , struct LineRefOffset , head );
0 commit comments