diff options
author | Alan Modra <amodra@gmail.com> | 2020-06-26 10:52:30 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-06-26 10:58:03 +0930 |
commit | ba9b3ef5ee666467b67780e81f868c432f4fc56d (patch) | |
tree | 7b4799779c2f3f03e1d16f89dfdaf495e05ad146 /bfd/cpu-riscv.c | |
parent | 30610e152009eab265a9fa484f321c5ab4421cdc (diff) | |
download | fsf-binutils-gdb-ba9b3ef5ee666467b67780e81f868c432f4fc56d.zip fsf-binutils-gdb-ba9b3ef5ee666467b67780e81f868c432f4fc56d.tar.gz fsf-binutils-gdb-ba9b3ef5ee666467b67780e81f868c432f4fc56d.tar.bz2 |
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.
Diffstat (limited to 'bfd/cpu-riscv.c')
-rw-r--r-- | bfd/cpu-riscv.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c index 22067ab..2e9e9eb 100644 --- a/bfd/cpu-riscv.c +++ b/bfd/cpu-riscv.c @@ -23,6 +23,86 @@ #include "sysdep.h" #include "bfd.h" #include "libbfd.h" +#include "elfxx-riscv.h" + +/* Record the priv spec version string and the corresponding class. */ + +struct priv_spec_t +{ + const char *name; + enum riscv_priv_spec_class class; +}; + +/* List for all supported privilege versions. */ + +static const struct priv_spec_t priv_specs[] = +{ + {"1.9.1", PRIV_SPEC_CLASS_1P9P1}, + {"1.10", PRIV_SPEC_CLASS_1P10}, + {"1.11", PRIV_SPEC_CLASS_1P11}, + +/* Terminate the list. */ + {NULL, 0} +}; + +/* Get the corresponding CSR version class by giving a privilege + version string. */ + +int +riscv_get_priv_spec_class (const char *s, + enum riscv_priv_spec_class *class) +{ + const struct priv_spec_t *version; + + if (s == NULL) + return 0; + + for (version = &priv_specs[0]; version->name != NULL; ++version) + if (strcmp (version->name, s) == 0) + { + *class = version->class; + return 1; + } + + /* Can not find the supported privilege version. */ + return 0; +} + +/* Get the corresponding CSR version class by giving privilege + version numbers. It is usually used to convert the priv + attribute numbers into the corresponding class. */ + +int +riscv_get_priv_spec_class_from_numbers (unsigned int major, + unsigned int minor, + unsigned int revision, + enum riscv_priv_spec_class *class) +{ + char buf[36]; + + if (major == 0 && minor == 0 && revision == 0) + { + *class = PRIV_SPEC_CLASS_NONE; + return 1; + } + + if (revision != 0) + snprintf (buf, sizeof (buf), "%u.%u.%u", major, minor, revision); + else + snprintf (buf, sizeof (buf), "%u.%u", major, minor); + + return riscv_get_priv_spec_class (buf, class); +} + +/* Get the corresponding privilege version string by giving a CSR + version class. */ + +const char * +riscv_get_priv_spec_name (enum riscv_priv_spec_class class) +{ + /* The first enum is PRIV_SPEC_CLASS_NONE. */ + return priv_specs[class - 1].name; +} /* This routine is provided two arch_infos and returns an arch_info that is compatible with both, or NULL if none exists. */ |