mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Added pcodetest source code to SleighDevTools module. Corrected
certification issues.
This commit is contained in:
parent
5b65962e04
commit
fca9e847c7
55 changed files with 12576 additions and 5 deletions
291
Ghidra/Extensions/SleighDevTools/pcodetest/build.py
Normal file
291
Ghidra/Extensions/SleighDevTools/pcodetest/build.py
Normal file
|
@ -0,0 +1,291 @@
|
|||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import pwd
|
||||
import grp
|
||||
import re
|
||||
|
||||
class BuildUtil(object):
|
||||
|
||||
def __init__(self):
|
||||
self.log = False
|
||||
self.name = False
|
||||
self.num_errors = 0
|
||||
self.num_warnings = 0
|
||||
|
||||
def run(self, cmd, stdout=False, stderr=False, verbose=True):
|
||||
if isinstance(cmd, basestring):
|
||||
if stdout and stderr:
|
||||
cmd += ' 1>%s 2>%s' % (stdout, stderr)
|
||||
elif stdout and not stderr:
|
||||
cmd += ' 1>%s 2>&1' % (stdout)
|
||||
elif not stdout and stderr:
|
||||
cmd += ' 2>%s' % (stderr)
|
||||
if verbose: self.log_info(cmd)
|
||||
os.system(cmd)
|
||||
else:
|
||||
str = ' '.join(cmd);
|
||||
if stdout:
|
||||
f = file(stdout, 'w+')
|
||||
str += ' 1>%s 2>&1' % (stdout)
|
||||
else:
|
||||
f = subprocess.PIPE
|
||||
if verbose: self.log_info(str)
|
||||
try:
|
||||
sp = subprocess.Popen(cmd, stdout=f, stderr=subprocess.PIPE)
|
||||
except OSError as e:
|
||||
self.log_err(cmd)
|
||||
self.log_err(e)
|
||||
return 0,e.message#raise
|
||||
if stdout: f.close()
|
||||
out, err = sp.communicate()
|
||||
# print 'run returned %d bytes stdout and %d bytes stderr' % (len(out) if out else 0, len(err) if err else 0)
|
||||
return out, err
|
||||
|
||||
def isdir(self, dname):
|
||||
return os.path.isdir(dname)
|
||||
|
||||
def getcwd(self):
|
||||
return os.getcwd()
|
||||
|
||||
def basename(self, fname):
|
||||
return os.path.basename(fname)
|
||||
|
||||
def dirname(self, fname):
|
||||
return os.path.dirname(fname)
|
||||
|
||||
def getmtime(self, fname):
|
||||
return os.path.getmtime(fname)
|
||||
|
||||
def isfile(self, fname):
|
||||
return os.path.isfile(fname)
|
||||
|
||||
def getenv(self, var, dflt):
|
||||
return os.getenv(var, dflt)
|
||||
|
||||
def pw_name(self, fname):
|
||||
return pwd.getpwuid(os.stat(fname).st_uid).pw_name
|
||||
|
||||
def gr_name(self, fname):
|
||||
return grp.getgrgid(os.stat(fname).st_gid).gr_name
|
||||
|
||||
def isatty(self):
|
||||
return os.isatty(sys.stdin.fileno())
|
||||
|
||||
def is_readable_file(self, fname):
|
||||
if not self.isfile(fname):
|
||||
self.log_warn('%s does not exist' % fname)
|
||||
return False
|
||||
if os.stat(fname).st_size == 0:
|
||||
self.log_warn('%s is empty' % fname)
|
||||
return False
|
||||
if os.access(fname, os.R_OK) == 0:
|
||||
self.log_warn('%s is not readable' % fname)
|
||||
return False
|
||||
return True
|
||||
|
||||
def is_executable_file(self, fname):
|
||||
if not self.is_readable_file(fname): return False
|
||||
if os.access(fname, os.X_OK) == 0:
|
||||
self.log_warn('%s is not executable' % fname)
|
||||
return False
|
||||
return True
|
||||
|
||||
# export a file to a directory
|
||||
def export_file(self, fname, dname,):
|
||||
try:
|
||||
if not os.path.isdir(dname):
|
||||
self.makedirs(dname)
|
||||
if os.path.isfile(fname):
|
||||
self.copy(fname, dname, verbose=True)
|
||||
elif os.path.isdir(fname):
|
||||
self.copy(fname, dname, dir=True, verbose=True)
|
||||
except IOError as e:
|
||||
self.log_err('Error occurred exporting %s to %s' % (fname, dname))
|
||||
self.log_err("Unexpected error: %s" % str(e))
|
||||
|
||||
def rmtree(self, dir, verbose=True):
|
||||
if verbose: self.log_info('rm -r %s' % dir)
|
||||
shutil.rmtree(dir)
|
||||
|
||||
def makedirs(self, dir, verbose=True):
|
||||
if verbose: self.log_info('mkdir -p %s' % dir)
|
||||
try: os.makedirs(dir)
|
||||
except: pass
|
||||
|
||||
# copy a file to a directory
|
||||
def copy(self, fname, dname, verbose=True, dir=False):
|
||||
if not dir:
|
||||
if verbose: self.log_info('cp -av %s %s' % (fname, dname))
|
||||
shutil.copy(fname, dname)
|
||||
else:
|
||||
if verbose: self.log_info('cp -avr %s %s' % (fname, dname))
|
||||
if os.path.exists(dname):
|
||||
shutil.rmtree(dname)
|
||||
shutil.copytree(fname, dname)
|
||||
|
||||
def chdir(self, dir, verbose=True):
|
||||
if verbose: self.log_info('cd %s' % dir)
|
||||
os.chdir(dir)
|
||||
|
||||
def remove(self, fname, verbose=True):
|
||||
if verbose: self.log_info('rm -f %s' % fname)
|
||||
try: os.remove(fname)
|
||||
except: pass
|
||||
|
||||
def environment(self, var, val, verbose=True):
|
||||
if verbose: self.log_info('%s=%s' % (var, val))
|
||||
os.environ[var] = val
|
||||
|
||||
def unlink(self, targ, verbose=True):
|
||||
if verbose: self.log_info('unlink %s' % targ)
|
||||
os.unlink(targ)
|
||||
|
||||
def symlink(self, src, targ, verbose=True):
|
||||
if verbose: self.log_info('ln -s %s %s' % (src, targ))
|
||||
if os.path.islink(targ):
|
||||
os.unlink(targ)
|
||||
os.symlink(src, targ)
|
||||
|
||||
def build_dir(self, root, kind, what):
|
||||
return root + "/" + re.sub(r'[^a-zA-Z0-9_-]+', '_', 'build-%s-%s' % (kind, what))
|
||||
|
||||
def log_prefix(self, kind, what):
|
||||
return kind.upper() + ' ' + what
|
||||
|
||||
def open_log(self, root, kind, what, chdir=False):
|
||||
build_dir = self.build_dir(root, kind, what)
|
||||
|
||||
# Get the name of the log file
|
||||
logFile = '%s/log.txt' % build_dir
|
||||
|
||||
self.log_info('%s LOGFILE %s' % (self.log_prefix(kind, what), logFile))
|
||||
|
||||
try: self.rmtree(build_dir, verbose=False)
|
||||
except: pass
|
||||
self.makedirs(build_dir, verbose=False)
|
||||
self.log_open(logFile)
|
||||
if chdir: self.chdir(build_dir)
|
||||
|
||||
def log_open(self, name):
|
||||
if self.log: self.log_close()
|
||||
self.log = open(name, 'w')
|
||||
self.name = name
|
||||
|
||||
def log_close(self):
|
||||
if self.log:
|
||||
if self.num_errors > 0:
|
||||
print '# ERROR: There were errors, see %s' % self.name
|
||||
elif self.num_warnings > 0:
|
||||
print '# WARNING: There were warnings, see %s' % self.name
|
||||
self.log.close()
|
||||
self.log = False
|
||||
self.name = False
|
||||
self.num_errors = 0
|
||||
self.num_warnings = 0
|
||||
|
||||
def log_pr(self, what):
|
||||
if self.log:
|
||||
self.log.write(what + '\n')
|
||||
self.log.flush()
|
||||
else:
|
||||
print what
|
||||
sys.stdout.flush()
|
||||
|
||||
def log_err(self, what):
|
||||
self.log_pr('# ERROR: ' + what)
|
||||
self.num_errors += 1
|
||||
|
||||
def log_warn(self, what):
|
||||
self.log_pr('# WARNING: ' + what)
|
||||
self.num_warnings += 1
|
||||
|
||||
def log_info(self, what):
|
||||
self.log_pr('# INFO: ' + what)
|
||||
|
||||
# create a file with size, type, and symbol info
|
||||
# the function is here because it is useful and has no dependencies
|
||||
|
||||
def mkinfo(self, fname):
|
||||
ifdefs = { 'i8':'HAS_LONGLONG', 'u8':'HAS_LONGLONG', 'f4':'HAS_FLOAT', 'f8':'HAS_DOUBLE' }
|
||||
|
||||
sizes = [
|
||||
'char', 'signed char', 'unsigned char',
|
||||
'short', 'signed short', 'unsigned short',
|
||||
'int', 'signed int', 'unsigned int',
|
||||
'long', 'signed long', 'unsigned long',
|
||||
'long long', 'signed long long', 'unsigned long long',
|
||||
'float', 'double', 'float', 'long double',
|
||||
'i1', 'i2', 'i4', 'u1', 'u2', 'u4', 'i8', 'u8', 'f4', 'f8']
|
||||
|
||||
syms = [
|
||||
'__AVR32__', '__AVR_ARCH__', 'dsPIC30', '__GNUC__', '__has_feature', 'INT4_IS_LONG',
|
||||
'__INT64_TYPE__', '__INT8_TYPE__', '__llvm__', '_M_ARM_FP', '__MSP430__', '_MSV_VER',
|
||||
'__SDCC', '__SIZEOF_DOUBLE__', '__SIZEOF_FLOAT__', '__SIZEOF_SIZE_T__', '__TI_COMPILER_VERSION__',
|
||||
'__INT8_TYPE__', '__INT16_TYPE__', '__INT32_TYPE__', '__INT64_TYPE__', '__UINT8_TYPE__',
|
||||
'__UINT16_TYPE__', '__UINT32_TYPE__', '__UINT64_TYPE__', 'HAS_FLOAT', 'HAS_DOUBLE',
|
||||
'HAS_LONGLONG', 'HAS_FLOAT_OVERRIDE', 'HAS_DOUBLE_OVERRIDE', 'HAS_LONGLONG_OVERRIDE']
|
||||
|
||||
typedefs = { 'i1':1, 'i2':2, 'i4':4, 'u1':1, 'u2':2, 'u4':4, 'i8':8, 'u8':8, 'f4':4, 'f8':8 }
|
||||
|
||||
f = open(fname, 'w')
|
||||
|
||||
f.write('#include "types.h"\n\n')
|
||||
|
||||
i = 0
|
||||
for s in sizes:
|
||||
i += 1
|
||||
d = 'INFO sizeof(%s) = ' % s
|
||||
x = list(d)
|
||||
x = "', '".join(x)
|
||||
x = "'%s', '0'+sizeof(%s), '\\n'" % (x, s)
|
||||
l = 'char size_info_%d[] = {%s};\n' % (i, x)
|
||||
if s in ifdefs: f.write('#ifdef %s\n' % ifdefs[s])
|
||||
f.write(l)
|
||||
if s in ifdefs: f.write('#endif\n')
|
||||
|
||||
for s in typedefs:
|
||||
if s in ifdefs: f.write('#ifdef %s\n' % ifdefs[s])
|
||||
f.write('_Static_assert(sizeof(%s) == %d, "INFO %s should have size %d, is not correct\\n");\n' % (s, typedefs[s], s, typedefs[s]))
|
||||
if s in ifdefs: f.write('#endif\n')
|
||||
|
||||
for s in syms:
|
||||
i += 1
|
||||
f.write('#ifdef %s\n' % s)
|
||||
f.write('char sym_info_%d[] = "INFO %s is defined\\n\";\n' % (i, s))
|
||||
f.write('#else\n')
|
||||
f.write('char sym_info_%d[] = "INFO %s is not defined\\n\";\n' % (i, s))
|
||||
f.write('#endif\n')
|
||||
|
||||
f.close()
|
||||
|
||||
class Config(object):
|
||||
|
||||
def __init__(self, *obj):
|
||||
for o in obj:
|
||||
if isinstance(o, dict): self.__dict__.update(o)
|
||||
else: self.__dict__.update(o.__dict__)
|
||||
|
||||
def format(self, val):
|
||||
if isinstance(val, basestring) and '%' in val:
|
||||
return val % self.__dict__
|
||||
elif isinstance(val, dict):
|
||||
return dict(map(lambda (k,v): (k,self.format(v)), val.iteritems()))
|
||||
else: return val
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return ''
|
||||
|
||||
def expand(self):
|
||||
for k,v in self.__dict__.iteritems():
|
||||
self.__dict__[k] = self.format(v)
|
||||
|
||||
def dump(self):
|
||||
ret = ''
|
||||
for k,v in sorted(self.__dict__.iteritems()):
|
||||
if isinstance(v, basestring): vv = "'" + v + "'"
|
||||
else: vv = str(v)
|
||||
ret += ' '.ljust(10) + k.ljust(20) + vv + '\n'
|
||||
return ret
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue