@@ -602,7 +602,7 @@ static int load_raw(struct pt_image_section_cache *iscache,
602
602
return 0 ;
603
603
}
604
604
605
- static xed_machine_mode_enum_t translate_mode (enum pt_exec_mode mode )
605
+ static xed_machine_mode_enum_t to_xed_mode (enum pt_exec_mode mode )
606
606
{
607
607
switch (mode ) {
608
608
case ptem_unknown :
@@ -621,6 +621,25 @@ static xed_machine_mode_enum_t translate_mode(enum pt_exec_mode mode)
621
621
return XED_MACHINE_MODE_INVALID ;
622
622
}
623
623
624
+ static xed_address_width_enum_t to_xed_addr_width (enum pt_exec_mode mode )
625
+ {
626
+ switch (mode ) {
627
+ case ptem_unknown :
628
+ return XED_ADDRESS_WIDTH_INVALID ;
629
+
630
+ case ptem_16bit :
631
+ return XED_ADDRESS_WIDTH_16b ;
632
+
633
+ case ptem_32bit :
634
+ return XED_ADDRESS_WIDTH_32b ;
635
+
636
+ case ptem_64bit :
637
+ return XED_ADDRESS_WIDTH_64b ;
638
+ }
639
+
640
+ return XED_ADDRESS_WIDTH_INVALID ;
641
+ }
642
+
624
643
static const char * visualize_iclass (enum pt_insn_class iclass )
625
644
{
626
645
switch (iclass ) {
@@ -808,18 +827,27 @@ static void check_insn_iclass(const xed_decoded_inst_t *inst,
808
827
visualize_iclass (insn -> iclass ), xed_iclass_enum_t2str (iclass ));
809
828
}
810
829
811
- static void check_insn_decode (xed_decoded_inst_t * inst ,
812
- const struct pt_insn * insn , uint64_t offset )
830
+ static void check_insn (const struct pt_insn * insn , uint64_t offset )
813
831
{
832
+ xed_address_width_enum_t addr_width ;
833
+ xed_machine_mode_enum_t mode ;
834
+ xed_decoded_inst_t inst ;
814
835
xed_error_enum_t errcode ;
836
+ xed_state_t xed ;
815
837
816
- if (!inst || ! insn ) {
838
+ if (!insn ) {
817
839
printf ("[internal error]\n" );
818
840
return ;
819
841
}
820
842
821
- xed_decoded_inst_set_mode (inst , translate_mode (insn -> mode ),
822
- XED_ADDRESS_WIDTH_INVALID );
843
+ if (insn -> isid <= 0 )
844
+ printf ("[%" PRIx64 ", %" PRIx64 ": check error: "
845
+ "bad isid]\n" , offset , insn -> ip );
846
+
847
+ addr_width = to_xed_addr_width (insn -> mode );
848
+ mode = to_xed_mode (insn -> mode );
849
+ xed_state_init2 (& xed , mode , addr_width );
850
+ xed_decoded_inst_zero_set_mode (& inst , & xed );
823
851
824
852
/* Decode the instruction (again).
825
853
*
@@ -830,43 +858,19 @@ static void check_insn_decode(xed_decoded_inst_t *inst,
830
858
* while not printing instructions since the latter is too expensive for
831
859
* regular use with long traces.
832
860
*/
833
- errcode = xed_decode (inst , insn -> raw , insn -> size );
861
+ errcode = xed_decode (& inst , insn -> raw , insn -> size );
834
862
if (errcode != XED_ERROR_NONE ) {
835
863
printf ("[%" PRIx64 ", %" PRIx64 ": xed error: (%u) %s]\n" ,
836
864
offset , insn -> ip , errcode ,
837
865
xed_error_enum_t2str (errcode ));
838
866
return ;
839
867
}
840
868
841
- if (!xed_decoded_inst_valid (inst )) {
869
+ if (!xed_decoded_inst_valid (& inst )) {
842
870
printf ("[%" PRIx64 ", %" PRIx64 ": xed error: "
843
871
"invalid instruction]\n" , offset , insn -> ip );
844
872
return ;
845
873
}
846
- }
847
-
848
- static void check_insn (const struct pt_insn * insn , uint64_t offset )
849
- {
850
- xed_decoded_inst_t inst ;
851
-
852
- if (!insn ) {
853
- printf ("[internal error]\n" );
854
- return ;
855
- }
856
-
857
- if (insn -> isid <= 0 )
858
- printf ("[%" PRIx64 ", %" PRIx64 ": check error: "
859
- "bad isid]\n" , offset , insn -> ip );
860
-
861
- xed_decoded_inst_zero (& inst );
862
- check_insn_decode (& inst , insn , offset );
863
-
864
- /* We need a valid instruction in order to do further checks.
865
- *
866
- * Invalid instructions have already been diagnosed.
867
- */
868
- if (!xed_decoded_inst_valid (& inst ))
869
- return ;
870
874
871
875
check_insn_iclass (& inst , insn , offset );
872
876
}
@@ -953,13 +957,15 @@ static void print_insn(const struct pt_insn *insn,
953
957
printf ("%016" PRIx64 , insn -> ip );
954
958
955
959
if (!options -> dont_print_insn ) {
960
+ xed_address_width_enum_t addr_width ;
956
961
xed_machine_mode_enum_t mode ;
957
962
xed_decoded_inst_t inst ;
958
963
xed_error_enum_t errcode ;
959
964
xed_state_t xed ;
960
965
961
- mode = translate_mode (insn -> mode );
962
- xed_state_init2 (& xed , mode , XED_ADDRESS_WIDTH_INVALID );
966
+ addr_width = to_xed_addr_width (insn -> mode );
967
+ mode = to_xed_mode (insn -> mode );
968
+ xed_state_init2 (& xed , mode , addr_width );
963
969
xed_decoded_inst_zero_set_mode (& inst , & xed );
964
970
965
971
errcode = xed_decode (& inst , insn -> raw , insn -> size );
@@ -1388,8 +1394,11 @@ static void diagnose_insn(struct ptxed_decoder *decoder,
1388
1394
const char * errtype , int errcode ,
1389
1395
const struct pt_insn * insn )
1390
1396
{
1397
+ xed_address_width_enum_t addr_width ;
1398
+ xed_machine_mode_enum_t mode ;
1391
1399
xed_decoded_inst_t inst ;
1392
1400
xed_error_enum_t xederr ;
1401
+ xed_state_t xed ;
1393
1402
uint64_t ip ;
1394
1403
1395
1404
if (!decoder || !insn ) {
@@ -1424,10 +1433,10 @@ static void diagnose_insn(struct ptxed_decoder *decoder,
1424
1433
if (insn .iclass == ptic_error )
1425
1434
break ;
1426
1435
#endif
1427
- xed_decoded_inst_zero ( & inst );
1428
- xed_decoded_inst_set_mode ( & inst ,
1429
- translate_mode ( insn -> mode ),
1430
- XED_ADDRESS_WIDTH_INVALID );
1436
+ addr_width = to_xed_addr_width ( insn -> mode );
1437
+ mode = to_xed_mode ( insn -> mode );
1438
+ xed_state_init2 ( & xed , mode , addr_width );
1439
+ xed_decoded_inst_zero_set_mode ( & inst , & xed );
1431
1440
1432
1441
xederr = xed_decode (& inst , insn -> raw , insn -> size );
1433
1442
if (xederr == XED_ERROR_NONE )
@@ -1664,8 +1673,11 @@ static void diagnose_block(struct ptxed_decoder *decoder,
1664
1673
const struct pt_block * block )
1665
1674
{
1666
1675
struct pt_insn insn ;
1676
+ xed_address_width_enum_t addr_width ;
1677
+ xed_machine_mode_enum_t mode ;
1667
1678
xed_decoded_inst_t inst ;
1668
1679
xed_error_enum_t xederr ;
1680
+ xed_state_t xed ;
1669
1681
uint64_t ip ;
1670
1682
int err ;
1671
1683
@@ -1702,10 +1714,10 @@ static void diagnose_block(struct ptxed_decoder *decoder,
1702
1714
if (err < 0 )
1703
1715
break ;
1704
1716
1705
- xed_decoded_inst_zero ( & inst );
1706
- xed_decoded_inst_set_mode ( & inst ,
1707
- translate_mode ( insn . mode ),
1708
- XED_ADDRESS_WIDTH_INVALID );
1717
+ addr_width = to_xed_addr_width ( block -> mode );
1718
+ mode = to_xed_mode ( block -> mode );
1719
+ xed_state_init2 ( & xed , mode , addr_width );
1720
+ xed_decoded_inst_zero_set_mode ( & inst , & xed );
1709
1721
1710
1722
xederr = xed_decode (& inst , insn .raw , insn .size );
1711
1723
if (xederr == XED_ERROR_NONE )
@@ -1724,6 +1736,7 @@ static void print_block(struct ptxed_decoder *decoder,
1724
1736
const struct ptxed_stats * stats ,
1725
1737
uint64_t offset , uint64_t time )
1726
1738
{
1739
+ xed_address_width_enum_t addr_width ;
1727
1740
xed_machine_mode_enum_t mode ;
1728
1741
xed_state_t xed ;
1729
1742
uint64_t ip ;
@@ -1741,8 +1754,9 @@ static void print_block(struct ptxed_decoder *decoder,
1741
1754
printf ("]\n" );
1742
1755
}
1743
1756
1744
- mode = translate_mode (block -> mode );
1745
- xed_state_init2 (& xed , mode , XED_ADDRESS_WIDTH_INVALID );
1757
+ addr_width = to_xed_addr_width (block -> mode );
1758
+ mode = to_xed_mode (block -> mode );
1759
+ xed_state_init2 (& xed , mode , addr_width );
1746
1760
1747
1761
/* There's nothing to do for empty blocks. */
1748
1762
ninsn = block -> ninsn ;
@@ -1811,7 +1825,11 @@ static void check_block(const struct pt_block *block,
1811
1825
uint64_t offset )
1812
1826
{
1813
1827
struct pt_insn insn ;
1828
+ xed_address_width_enum_t addr_width ;
1829
+ xed_machine_mode_enum_t mode ;
1814
1830
xed_decoded_inst_t inst ;
1831
+ xed_error_enum_t xederr ;
1832
+ xed_state_t xed ;
1815
1833
uint64_t ip ;
1816
1834
uint16_t ninsn ;
1817
1835
int errcode ;
@@ -1830,6 +1848,10 @@ static void check_block(const struct pt_block *block,
1830
1848
printf ("[%" PRIx64 ", %" PRIx64 ": check error: "
1831
1849
"bad isid]\n" , offset , block -> ip );
1832
1850
1851
+ addr_width = to_xed_addr_width (block -> mode );
1852
+ mode = to_xed_mode (block -> mode );
1853
+ xed_state_init2 (& xed , mode , addr_width );
1854
+
1833
1855
ip = block -> ip ;
1834
1856
do {
1835
1857
errcode = block_fetch_insn (& insn , block , ip , iscache );
@@ -1839,15 +1861,31 @@ static void check_block(const struct pt_block *block,
1839
1861
return ;
1840
1862
}
1841
1863
1842
- xed_decoded_inst_zero (& inst );
1843
- check_insn_decode (& inst , & insn , offset );
1864
+ xed_decoded_inst_zero_set_mode (& inst , & xed );
1844
1865
1845
- /* We need a valid instruction in order to do further checks .
1866
+ /* Decode the instruction (again) .
1846
1867
*
1847
- * Invalid instructions have already been diagnosed.
1868
+ * We may have decoded the instruction already for printing.
1869
+ * In this case, we will decode it twice.
1870
+ *
1871
+ * The more common use-case, however, is to check the
1872
+ * instruction class while not printing instructions since the
1873
+ * latter is too expensive for regular use with long traces.
1848
1874
*/
1849
- if (!xed_decoded_inst_valid (& inst ))
1875
+ xederr = xed_decode (& inst , insn .raw , insn .size );
1876
+ if (xederr != XED_ERROR_NONE ) {
1877
+ printf ("[%" PRIx64 ", %" PRIx64
1878
+ ": xed error: (%u) %s]\n" ,
1879
+ offset , insn .ip , xederr ,
1880
+ xed_error_enum_t2str (xederr ));
1850
1881
return ;
1882
+ }
1883
+
1884
+ if (!xed_decoded_inst_valid (& inst )) {
1885
+ printf ("[%" PRIx64 ", %" PRIx64 ": xed error: "
1886
+ "invalid instruction]\n" , offset , insn .ip );
1887
+ return ;
1888
+ }
1851
1889
1852
1890
errcode = xed_next_ip (& ip , & inst , ip );
1853
1891
if (errcode < 0 ) {
0 commit comments