summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-03 12:41:42 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-03 12:41:42 +0300
commit7790c66bf2e26a4f34f2b42766d92e6c61f3930d (patch)
treeabb337e47be4fbaac5a533dc936019223c9f01a3
parentace54abd2ddae8facfce059d9442866517fc4b58 (diff)
downloadmailutils-7790c66bf2e26a4f34f2b42766d92e6c61f3930d.tar.gz
mailutils-7790c66bf2e26a4f34f2b42766d92e6c61f3930d.tar.bz2
fmtcheck: use symbolic label names by default
Actual program counters may differ between different architecture, so avoid using them in the testsuite. * mh/fmtcheck.c: New option -pc requires printing program counters. Unless this option is used, -disass prints only labels where needed. * mh/mh.h (mh_format_dump_disass): Change signature. * mh/mh_format.c (mh_format_dump_disass): Take additional flag indicating whether to print program counters. Compute and print program labels, unless this flag is non-zero. * mh/tests/fmtcomp.at: Don't expect program counters in disassembled code.
-rw-r--r--mh/fmtcheck.c12
-rw-r--r--mh/mh.h2
-rw-r--r--mh/mh_format.c167
-rw-r--r--mh/tests/fmtcomp.at228
4 files changed, 286 insertions, 123 deletions
diff --git a/mh/fmtcheck.c b/mh/fmtcheck.c
index 8c8509744..b0d7d37e2 100644
--- a/mh/fmtcheck.c
+++ b/mh/fmtcheck.c
@@ -31,6 +31,7 @@ static int debug_option;
31static char *input_file; 31static char *input_file;
32static size_t width; 32static size_t width;
33static size_t msgno; 33static size_t msgno;
34static int pc_option;
34 35
35void 36void
36opt_formfile (struct mu_parseopt *po, struct mu_option *opt, char const *arg) 37opt_formfile (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
@@ -58,12 +59,15 @@ static struct mu_option options[] = {
58 { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT, 59 { "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT,
59 N_("use this format string"), 60 N_("use this format string"),
60 mu_c_string, NULL, opt_format }, 61 mu_c_string, NULL, opt_format },
61 { "dump", 0, NULL, MU_OPTION_HIDDEN, 62 { "dump", 0, NULL, MU_OPTION_DEFAULT,
62 N_("dump the listing of compiled format code"), 63 N_("dump the listing of compiled format code"),
63 mu_c_bool, &dump_option }, 64 mu_c_bool, &dump_option },
64 { "disassemble", 0, NULL, MU_OPTION_HIDDEN, 65 { "disassemble", 0, NULL, MU_OPTION_DEFAULT,
65 N_("dump disassembled format code"), 66 N_("dump disassembled format code"),
66 mu_c_bool, &disass_option }, 67 mu_c_bool, &disass_option },
68 { "pc", 0, NULL, MU_OPTION_DEFAULT,
69 N_("print program counter along with disassembled code (implies --disassemble)"),
70 mu_c_bool, &pc_option },
67 { "debug", 0, NULL, MU_OPTION_DEFAULT, 71 { "debug", 0, NULL, MU_OPTION_DEFAULT,
68 N_("enable parser debugging output"), 72 N_("enable parser debugging output"),
69 mu_c_bool, &debug_option }, 73 mu_c_bool, &debug_option },
@@ -94,6 +98,8 @@ int
94main (int argc, char **argv) 98main (int argc, char **argv)
95{ 99{
96 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL); 100 mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
101 if (pc_option)
102 disass_option = 1;
97 switch (argc) 103 switch (argc)
98 { 104 {
99 case 0: 105 case 0:
@@ -123,7 +129,7 @@ main (int argc, char **argv)
123 if (dump_option) 129 if (dump_option)
124 mh_format_dump_code (format); 130 mh_format_dump_code (format);
125 if (disass_option) 131 if (disass_option)
126 mh_format_dump_disass (format); 132 mh_format_dump_disass (format, pc_option);
127 133
128 if (input_file) 134 if (input_file)
129 run (); 135 run ();
diff --git a/mh/mh.h b/mh/mh.h
index 312f9b0bc..c1d8ee85a 100644
--- a/mh/mh.h
+++ b/mh/mh.h
@@ -182,7 +182,7 @@ void mh_fvm_run (mh_fvm_t fvm, mu_message_t msg, size_t msgno);
182int mh_format_str (mh_format_t fmt, char *str, size_t width, char **pret); 182int mh_format_str (mh_format_t fmt, char *str, size_t width, char **pret);
183 183
184void mh_format_dump_code (mh_format_t fmt); 184void mh_format_dump_code (mh_format_t fmt);
185void mh_format_dump_disass (mh_format_t fmt); 185void mh_format_dump_disass (mh_format_t fmt, int addr);
186 186
187#define MH_FMT_PARSE_DEFAULT 0 187#define MH_FMT_PARSE_DEFAULT 0
188#define MH_FMT_PARSE_TREE 0x01 188#define MH_FMT_PARSE_TREE 0x01
diff --git a/mh/mh_format.c b/mh/mh_format.c
index 86eeb4ff3..0f1d4b728 100644
--- a/mh/mh_format.c
+++ b/mh/mh_format.c
@@ -1896,8 +1896,128 @@ _get_builtin_name (mh_builtin_fp ptr)
1896 return NULL; 1896 return NULL;
1897} 1897}
1898 1898
1899/* Label array is used when disassembling the code, in order to create.
1900 meaningful label names. The array elements starting from index 1 keep
1901 the code addesses to which branch instructions point, in ascending order.
1902 Element 0 keeps the number of addresses stored. Thus, the label
1903 array LAB with contents { 3, 2, 5, 7 } declares three labels: "L1" on
1904 address 2, "L2", on address 5, and "L3" on address 7.
1905*/
1906
1907/* Find in LAB the index of the label corresponding to the given PC. Return
1908 0 if no label found. */
1909size_t
1910find_label (size_t *lab, size_t pc)
1911{
1912 if (lab)
1913 {
1914 size_t i;
1915 for (i = 1; i <= lab[0]; i++)
1916 {
1917 if (lab[i] == pc)
1918 return i;
1919 }
1920 }
1921 return 0;
1922}
1923
1924static int
1925comp_pc (const void *a, const void *b)
1926{
1927 size_t pca = *(size_t*)a;
1928 size_t pcb = *(size_t*)b;
1929 if (pca < pcb)
1930 return -1;
1931 else if (pca > pcb)
1932 return 1;
1933 return 0;
1934}
1935
1936/* Extract a label array from a compiled format FMT. */
1937static size_t *
1938extract_labels (mh_format_t fmt)
1939{
1940 size_t *lab;
1941 size_t pc;
1942 long n;
1943
1944 lab = mu_calloc (fmt->progcnt, sizeof (lab[0]));
1945 lab[0] = 0;
1946 for (pc = 1; pc < fmt->progcnt; )
1947 {
1948 mh_opcode_t opcode = MHI_OPCODE (fmt->prog[pc++]);
1949 if (opcode == mhop_stop)
1950 break;
1951 switch (opcode)
1952 {
1953 case mhop_branch:
1954 case mhop_brzn:
1955 case mhop_brzs:
1956 n = MHI_NUM (fmt->prog[pc++]);
1957 if (!find_label (lab, pc + n - 1))
1958 lab[++lab[0]] = pc + n - 1;
1959 break;
1960
1961 case mhop_setn:
1962 pc += 2;
1963 break;
1964
1965 case mhop_sets:
1966 case mhop_ldcomp:
1967 pc += 2 + MHI_NUM (fmt->prog[pc + 1]);
1968 break;
1969
1970 case mhop_movn:
1971 case mhop_movs:
1972 pc += 2;
1973 break;
1974
1975 case mhop_ldbody:
1976 case mhop_call:
1977 case mhop_fmtspec:
1978 pc++;
1979 break;
1980
1981 case mhop_printlit:
1982 pc += 1 + MHI_NUM (fmt->prog[pc]);
1983 break;
1984
1985 case mhop_atoi:
1986 case mhop_itoa:
1987 case mhop_printn:
1988 case mhop_prints:
1989 break;
1990
1991 default:
1992 abort ();
1993 }
1994 }
1995 if (lab[0] > 0)
1996 qsort (lab + 1, lab[0], sizeof lab[0], comp_pc);
1997 return lab;
1998}
1999
2000/* Print to *PBUF (of size *PSZ) the label corresponding to the address PC.
2001 If there's no label having this address (in particular, if LAB==NULL),
2002 format the address itself to *PBUF.
2003 Reallocate *PBUF, updating *PSZ, if necessary.
2004*/
1899void 2005void
1900mh_format_dump_disass (mh_format_t fmt) 2006format_label (size_t *lab, size_t pc, char **pbuf, size_t *psz)
2007{
2008 size_t ln = find_label (lab, pc);
2009 if (ln)
2010 mu_asnprintf (pbuf, psz, "L%ld", (long) ln);
2011 else
2012 mu_asnprintf (pbuf, psz, "%ld", (long) pc);
2013}
2014
2015/* Dump disassembled code of FMT to stdout. If ADDR is 0, print label names
2016 where necessary, otherwise, prefix each line of output with its program
2017 counter in decimal.
2018*/
2019void
2020mh_format_dump_disass (mh_format_t fmt, int addr)
1901{ 2021{
1902 mh_instr_t *prog = fmt->prog; 2022 mh_instr_t *prog = fmt->prog;
1903 size_t pc = 1; 2023 size_t pc = 1;
@@ -1908,14 +2028,46 @@ mh_format_dump_disass (mh_format_t fmt)
1908 [R_ACC] = "acc" 2028 [R_ACC] = "acc"
1909 }; 2029 };
1910 static char c_trans[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"; 2030 static char c_trans[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
2031 size_t *lab;
2032 size_t lc;
2033 char *lbuf = NULL;
2034 size_t lsz = 0;
1911 2035
1912 if (!prog) 2036 if (!prog)
1913 return; 2037 return;
2038
2039 if (!addr)
2040 lab = extract_labels (fmt);
2041 else
2042 lab = NULL;
2043 lc = lab ? 1 : 0;
2044
1914 while (!stop) 2045 while (!stop)
1915 { 2046 {
1916 mh_opcode_t opcode; 2047 mh_opcode_t opcode;
1917 2048
1918 printf ("% 4.4ld: ", (long) pc);