33import argparse
44import sys
55import unittest
6+ import elftools .elf .elffile
7+ import elftools .elf .enums
8+ import elftools .elf .sections
69
710EXT_OPTS = {
811 "zba" : "zba=true" ,
@@ -26,6 +29,8 @@ def parse_opt(argv):
2629 parser = argparse .ArgumentParser ()
2730 parser .add_argument ('-march' , '--with-arch' , type = str , dest = 'march' )
2831 parser .add_argument ('-selftest' , action = 'store_true' )
32+ parser .add_argument ('--get-riscv-tag' , type = str )
33+ parser .add_argument ('--get-elf-class' , type = str )
2934 opt = parser .parse_args ()
3035 return opt
3136
@@ -156,12 +161,63 @@ class TestArchStringParse(unittest.TestCase):
156161def selftest ():
157162 unittest .main (argv = sys .argv [1 :])
158163
164+ def open_elf (path ):
165+ try :
166+ elffile = elftools .elf .elffile .ELFFile (open (path , 'rb' ))
167+ except elftools .common .exceptions .ELFError :
168+ raise Exception ("%s is not ELF file!" % path )
169+ return elffile
170+
171+ def read_elf_class (path ):
172+ elffile = open_elf (path )
173+ return elffile .elfclass
174+
175+ def read_arch_attr (path ):
176+ elffile = open_elf (path )
177+
178+ attr_sec = elffile .get_section_by_name (".riscv.attributes" )
179+ if attr_sec :
180+ # pyelftools has support RISC-V attribute but not contain in any
181+ # release yet, so use ARMAttributesSection for now...
182+ xattr_section = \
183+ elftools .elf .sections .ARMAttributesSection (
184+ attr_sec .header ,
185+ attr_sec .name ,
186+ elffile )
187+ for subsec in xattr_section .subsections :
188+ for subsubsec in subsec .subsubsections :
189+ for attr in subsubsec .iter_attributes ():
190+ val = attr .value
191+ if (not isinstance (val , str )):
192+ continue
193+ pos32 = val .find ("rv32" )
194+ pos64 = val .find ("rv64" )
195+ # MAGIC WORKAROUND
196+ # Some version of pyelftools has issue for parsing
197+ # Tag number = 5, it will wrongly parse it become
198+ # Tag number = 4 + 0x10 + 0x5
199+ if (pos32 == 2 ) or (pos64 == 2 ):
200+ val = val [2 :]
201+ # End of MAGIC WORKAROUND
202+
203+ if (pos32 != - 1 or pos64 != - 1 ):
204+ return val
205+ raise Exception ("Not found ELF attribute in %s?" % path )
206+
159207def main (argv ):
160208 opt = parse_opt (argv )
161209 if opt .selftest :
162210 selftest ()
163211 return 0
164- cpu_opt = conver_arch_to_qemu_cpu_opt (opt .march )
212+ if (opt .get_elf_class ):
213+ elf_class = read_elf_class (opt .get_elf_class )
214+ print (elf_class )
215+ return
216+ if (opt .get_riscv_tag ):
217+ march = read_arch_attr (opt .get_riscv_tag )
218+ else :
219+ march = opt .march
220+ cpu_opt = conver_arch_to_qemu_cpu_opt (march )
165221 print (cpu_opt )
166222
167223if __name__ == '__main__' :
0 commit comments