GNU Binutils with patches for OS216
Revisão | ba9b3ef5ee666467b67780e81f868c432f4fc56d (tree) |
---|---|
Hora | 2020-06-26 10:28:03 |
Autor | Alan Modra <amodra@gmai...> |
Commiter | Alan Modra |
RISCV changes broke 32-bit --enable-targets=all
By the look of it, git commit 39ff0b812324 broke 32-bit host
--enable-targets=all binutils builds.
/usr/local/bin/ld: ../opcodes/.libs/libopcodes.a(riscv-dis.o): in function parse_riscv_dis_option':
/home/alan/src/binutils-gdb/opcodes/riscv-dis.c:102: undefined reference to riscv_get_priv_spec_class'
collect2: error: ld returned 1 exit status
Makefile:925: recipe for target 'objdump' failed
The problem is that elfxx-riscv.c is not built for a 32-bit host
without --enable-64-bit-bfd or unless RISCV is given specifically as a
target. No such trimming of 64-bit only targets is done in opcodes.
One solution is to move these support functions to cpu-riscv.c, which
runs into "error: implicit declaration of function ‘xmalloc’". Now,
xmalloc is not supposed to be used in libbfd or libopcodes - it's rude
to crash out of an application that calls libbfd or libopcodes
functions without giving it a chance to deal with out-of-memory
itself. So I removed the xmalloc and instead used a fixed size
buffer. If you are worried about adding 36 bytes for the buffer to
the riscv_get_priv_spec_class_from_numbers stack frame size, then you
have no idea of the likely xmalloc + malloc stack frame size! Trying
to reduce memory usage is commendable, but in this instance
riscv_estimate_digit and malloc for a temp buffer uses a lot more
memory than a fixed max-size buffer.
* elfxx-riscv.c (struct priv_spec_t, priv_specs),
(riscv_get_priv_spec_class, riscv_get_priv_spec_class_from_numbers),
(riscv_get_priv_spec_name): Move to..
* cpu-riscv.c: ..here.
(riscv_get_priv_spec_class_from_numbers): Don't xmalloc temp buffer.
Use %u to print unsigned numbers.
@@ -1,3 +1,12 @@ | ||
1 | +2020-06-26 Alan Modra <amodra@gmail.com> | |
2 | + | |
3 | + * elfxx-riscv.c (struct priv_spec_t, priv_specs), | |
4 | + (riscv_get_priv_spec_class, riscv_get_priv_spec_class_from_numbers), | |
5 | + (riscv_get_priv_spec_name): Move to.. | |
6 | + * cpu-riscv.c: ..here. | |
7 | + (riscv_get_priv_spec_class_from_numbers): Don't xmalloc temp buffer. | |
8 | + Use %u to print unsigned numbers. | |
9 | + | |
1 | 10 | 2020-06-24 Andrew Burgess <andrew.burgess@embecosm.com> |
2 | 11 | |
3 | 12 | * cpu-riscv.c (riscv_scan): Don't allow shorter matches using the |
@@ -23,6 +23,86 @@ | ||
23 | 23 | #include "sysdep.h" |
24 | 24 | #include "bfd.h" |
25 | 25 | #include "libbfd.h" |
26 | +#include "elfxx-riscv.h" | |
27 | + | |
28 | +/* Record the priv spec version string and the corresponding class. */ | |
29 | + | |
30 | +struct priv_spec_t | |
31 | +{ | |
32 | + const char *name; | |
33 | + enum riscv_priv_spec_class class; | |
34 | +}; | |
35 | + | |
36 | +/* List for all supported privilege versions. */ | |
37 | + | |
38 | +static const struct priv_spec_t priv_specs[] = | |
39 | +{ | |
40 | + {"1.9.1", PRIV_SPEC_CLASS_1P9P1}, | |
41 | + {"1.10", PRIV_SPEC_CLASS_1P10}, | |
42 | + {"1.11", PRIV_SPEC_CLASS_1P11}, | |
43 | + | |
44 | +/* Terminate the list. */ | |
45 | + {NULL, 0} | |
46 | +}; | |
47 | + | |
48 | +/* Get the corresponding CSR version class by giving a privilege | |
49 | + version string. */ | |
50 | + | |
51 | +int | |
52 | +riscv_get_priv_spec_class (const char *s, | |
53 | + enum riscv_priv_spec_class *class) | |
54 | +{ | |
55 | + const struct priv_spec_t *version; | |
56 | + | |
57 | + if (s == NULL) | |
58 | + return 0; | |
59 | + | |
60 | + for (version = &priv_specs[0]; version->name != NULL; ++version) | |
61 | + if (strcmp (version->name, s) == 0) | |
62 | + { | |
63 | + *class = version->class; | |
64 | + return 1; | |
65 | + } | |
66 | + | |
67 | + /* Can not find the supported privilege version. */ | |
68 | + return 0; | |
69 | +} | |
70 | + | |
71 | +/* Get the corresponding CSR version class by giving privilege | |
72 | + version numbers. It is usually used to convert the priv | |
73 | + attribute numbers into the corresponding class. */ | |
74 | + | |
75 | +int | |
76 | +riscv_get_priv_spec_class_from_numbers (unsigned int major, | |
77 | + unsigned int minor, | |
78 | + unsigned int revision, | |
79 | + enum riscv_priv_spec_class *class) | |
80 | +{ | |
81 | + char buf[36]; | |
82 | + | |
83 | + if (major == 0 && minor == 0 && revision == 0) | |
84 | + { | |
85 | + *class = PRIV_SPEC_CLASS_NONE; | |
86 | + return 1; | |
87 | + } | |
88 | + | |
89 | + if (revision != 0) | |
90 | + snprintf (buf, sizeof (buf), "%u.%u.%u", major, minor, revision); | |
91 | + else | |
92 | + snprintf (buf, sizeof (buf), "%u.%u", major, minor); | |
93 | + | |
94 | + return riscv_get_priv_spec_class (buf, class); | |
95 | +} | |
96 | + | |
97 | +/* Get the corresponding privilege version string by giving a CSR | |
98 | + version class. */ | |
99 | + | |
100 | +const char * | |
101 | +riscv_get_priv_spec_name (enum riscv_priv_spec_class class) | |
102 | +{ | |
103 | + /* The first enum is PRIV_SPEC_CLASS_NONE. */ | |
104 | + return priv_specs[class - 1].name; | |
105 | +} | |
26 | 106 | |
27 | 107 | /* This routine is provided two arch_infos and returns an arch_info |
28 | 108 | that is compatible with both, or NULL if none exists. */ |
@@ -1749,98 +1749,3 @@ riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset) | ||
1749 | 1749 | |
1750 | 1750 | return attr_str; |
1751 | 1751 | } |
1752 | - | |
1753 | -/* Record the priv spec version string and the corresponding class. */ | |
1754 | - | |
1755 | -struct priv_spec_t | |
1756 | -{ | |
1757 | - const char *name; | |
1758 | - enum riscv_priv_spec_class class; | |
1759 | -}; | |
1760 | - | |
1761 | -/* List for all supported privilege versions. */ | |
1762 | - | |
1763 | -static const struct priv_spec_t priv_specs[] = | |
1764 | -{ | |
1765 | - {"1.9.1", PRIV_SPEC_CLASS_1P9P1}, | |
1766 | - {"1.10", PRIV_SPEC_CLASS_1P10}, | |
1767 | - {"1.11", PRIV_SPEC_CLASS_1P11}, | |
1768 | - | |
1769 | -/* Terminate the list. */ | |
1770 | - {NULL, 0} | |
1771 | -}; | |
1772 | - | |
1773 | -/* Get the corresponding CSR version class by giving a privilege | |
1774 | - version string. */ | |
1775 | - | |
1776 | -int | |
1777 | -riscv_get_priv_spec_class (const char *s, | |
1778 | - enum riscv_priv_spec_class *class) | |
1779 | -{ | |
1780 | - const struct priv_spec_t *version; | |
1781 | - | |
1782 | - if (s == NULL) | |
1783 | - return 0; | |
1784 | - | |
1785 | - for (version = &priv_specs[0]; version->name != NULL; ++version) | |
1786 | - if (strcmp (version->name, s) == 0) | |
1787 | - { | |
1788 | - *class = version->class; | |
1789 | - return 1; | |
1790 | - } | |
1791 | - | |
1792 | - /* Can not find the supported privilege version. */ | |
1793 | - return 0; | |
1794 | -} | |
1795 | - | |
1796 | -/* Get the corresponding CSR version class by giving privilege | |
1797 | - version numbers. It is usually used to convert the priv | |
1798 | - attribute numbers into the corresponding class. */ | |
1799 | - | |
1800 | -int | |
1801 | -riscv_get_priv_spec_class_from_numbers (unsigned int major, | |
1802 | - unsigned int minor, | |
1803 | - unsigned int revision, | |
1804 | - enum riscv_priv_spec_class *class) | |
1805 | -{ | |
1806 | - size_t buf_size; | |
1807 | - char *buf; | |
1808 | - int result = 1; | |
1809 | - | |
1810 | - if (major == 0 && minor == 0 && revision == 0) | |
1811 | - { | |
1812 | - *class = PRIV_SPEC_CLASS_NONE; | |
1813 | - return result; | |
1814 | - } | |
1815 | - | |
1816 | - buf_size = riscv_estimate_digit (major) | |
1817 | - + 1 /* '.' */ | |
1818 | - + riscv_estimate_digit (minor) | |
1819 | - + 1; /* string terminator */ | |
1820 | - if (revision != 0) | |
1821 | - { | |
1822 | - buf_size += 1 /* '.' */ | |
1823 | - + riscv_estimate_digit (revision); | |
1824 | - buf = xmalloc (buf_size); | |
1825 | - snprintf (buf, buf_size, "%d.%d.%d", major, minor, revision); | |
1826 | - } | |
1827 | - else | |
1828 | - { | |
1829 | - buf = xmalloc (buf_size); | |
1830 | - snprintf (buf, buf_size, "%d.%d", major, minor); | |
1831 | - } | |
1832 | - | |
1833 | - result = riscv_get_priv_spec_class (buf, class); | |
1834 | - free (buf); | |
1835 | - return result; | |
1836 | -} | |
1837 | - | |
1838 | -/* Get the corresponding privilege version string by giving a CSR | |
1839 | - version class. */ | |
1840 | - | |
1841 | -const char * | |
1842 | -riscv_get_priv_spec_name (enum riscv_priv_spec_class class) | |
1843 | -{ | |
1844 | - /* The first enum is PRIV_SPEC_CLASS_NONE. */ | |
1845 | - return priv_specs[class - 1].name; | |
1846 | -} |