aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2023-04-20 14:15:47 +0800
committerKito Cheng <kito.cheng@sifive.com>2023-04-24 16:05:21 +0800
commitd58e67689d89a635f7dc3bebbcf757e3fca7825e (patch)
tree3c441575eba1e224be16394190f2d4e1aa5e6078 /scripts
parent016637ce7094975e390039dc007613e89fc79871 (diff)
downloadriscv-gnu-toolchain-d58e67689d89a635f7dc3bebbcf757e3fca7825e.zip
riscv-gnu-toolchain-d58e67689d89a635f7dc3bebbcf757e3fca7825e.tar.gz
riscv-gnu-toolchain-d58e67689d89a635f7dc3bebbcf757e3fca7825e.tar.bz2
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.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/march-to-cpu-opt45
-rwxr-xr-xscripts/wrapper/qemu/riscv64-unknown-linux-gnu-run2
2 files changed, 45 insertions, 2 deletions
diff --git a/scripts/march-to-cpu-opt b/scripts/march-to-cpu-opt
index f85bd26..cec7d41 100755
--- a/scripts/march-to-cpu-opt
+++ b/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__':
diff --git a/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run b/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run
index 078360e..f0943f4 100755
--- a/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run
+++ b/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} "$@"