Browse Source

Set qemu cpu option from ELF attribute

This could help multi-lib testing, but the price is slightly increase
the testing time since it will need to extract ELF attribute from binary
before running qemu.

But I think the cost is acceptable compare to make build system more
complicate, and actually we already use this approach in our internal stuffs
for years.
pull/1233/head
Kito Cheng 3 years ago
parent
commit
d58e67689d
  1. 5
      Makefile.in
  2. 45
      scripts/march-to-cpu-opt
  3. 2
      scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run

5
Makefile.in

@ -175,9 +175,8 @@ report-gdb: report-gdb-@default_target@
.PHONY: build-sim
ifeq ($(SIM),qemu)
QEMU_CPU=$(shell $(srcdir)/scripts/march-to-cpu-opt $(WITH_ARCH))
SIM_PATH:=$(srcdir)/scripts/wrapper/qemu
SIM_PREPARE:=PATH="$(SIM_PATH):$(INSTALL_DIR)/bin:$(PATH)" RISC_V_SYSROOT="$(SYSROOT)" QEMU_CPU="$(QEMU_CPU)"
SIM_PATH:=$(srcdir)/scripts/wrapper/qemu:$(srcdir)/scripts
SIM_PREPARE:=PATH="$(SIM_PATH):$(INSTALL_DIR)/bin:$(PATH)" RISC_V_SYSROOT="$(SYSROOT)"
SIM_STAMP:= stamps/build-qemu
else
ifeq ($(SIM),spike)

45
scripts/march-to-cpu-opt

@ -3,6 +3,9 @@
import argparse
import sys
import unittest
import elftools.elf.elffile
import elftools.elf.enums
import elftools.elf.sections
EXT_OPTS = {
"zba": "zba=true",
@ -26,6 +29,7 @@ def parse_opt(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-march', '--with-arch', type=str, dest='march')
parser.add_argument('-selftest', action='store_true')
parser.add_argument('--get-riscv-tag', type=str)
opt = parser.parse_args()
return opt
@ -156,12 +160,51 @@ class TestArchStringParse(unittest.TestCase):
def selftest():
unittest.main(argv=sys.argv[1:])
def read_arch_attr (path):
try:
elffile = elftools.elf.elffile.ELFFile(open(path, 'rb'))
except elftools.common.exceptions.ELFError:
raise Exception("%s is not ELF file!" % path)
attr_sec = elffile.get_section_by_name(".riscv.attributes")
if attr_sec:
# pyelftools has support RISC-V attribute but not contain in any
# release yet, so use ARMAttributesSection for now...
xattr_section = \
elftools.elf.sections.ARMAttributesSection (
attr_sec.header,
attr_sec.name,
elffile)
for subsec in xattr_section.subsections:
for subsubsec in subsec.subsubsections:
for attr in subsubsec.iter_attributes():
val = attr.value
if (not isinstance(val, str)):
continue
pos32 = val.find("rv32")
pos64 = val.find("rv64")
# MAGIC WORKAROUND
# Some version of pyelftools has issue for parsing
# Tag number = 5, it will wrongly parse it become
# Tag number = 4 + 0x10 + 0x5
if (pos32 == 2) or (pos64 == 2):
val = val[2:]
# End of MAGIC WORKAROUND
if (pos32 != -1 or pos64 != -1):
return val
raise Exception("Not found ELF attribute in %s?" % path)
def main(argv):
opt = parse_opt(argv)
if opt.selftest:
selftest()
return 0
cpu_opt = conver_arch_to_qemu_cpu_opt(opt.march)
if (opt.with_elf):
march = read_arch_attr (opt.with_elf)
else:
march = opt.march
cpu_opt = conver_arch_to_qemu_cpu_opt(march)
print (cpu_opt)
if __name__ == '__main__':

2
scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run

@ -12,4 +12,4 @@ done
xlen="$(readelf -h $1 | grep 'Class' | cut -d: -f 2 | xargs echo | sed 's/^ELF//')"
QEMU_CPU=${QEMU_CPU} qemu-riscv$xlen -r 5.10 "${qemu_args[@]}" -L ${RISC_V_SYSROOT} "$@"
QEMU_CPU="$(march-to-cpu-opt --get-riscv-tag $1)" qemu-riscv$xlen -r 5.10 "${qemu_args[@]}" -L ${RISC_V_SYSROOT} "$@"

Loading…
Cancel
Save