import gdb
import re
pp = None # pyparsing
import mcgdb
from mcgdb.toolbox.target import my_archi
from mcgdb.model.gpu import representation, capture
from .. import user
from .. import representation as ocl_representation
name_resolver = []
[docs]def get_ocl_create_read_write_buffer(line):
try:
return re.match(r"call ocl_create_read_write_buffer\((.*)\)", line).group(1).split(',')[-1].strip()
except:
return None
name_resolver.append([get_ocl_create_read_write_buffer, 2])
[docs]def get_ocl_create_read_buffer(line):
try:
return re.match(r"call ocl_create_read_buffer\((.*)\)", line).group(1).split(',')[-1].strip()
except:
return None
name_resolver.append([get_ocl_create_read_buffer, 2])
[docs]def get_ocl_pin_write_buffer_async(line):
try:
lparen = pp.Literal("(").suppress()
rparen = pp.Literal(")").suppress()
init = pp.Literal("call").suppress()
identifier = pp.Word(pp.alphas, pp.alphapp.nums + "%" + "_"+"+"+"-"+"*")
integer = pp.Word(pp.nums)
functor = identifier
plus = pp.Literal( "+" )
minus = pp.Literal( "-" )
mult = pp.Literal( "*" )
div = pp.Literal( "/" )
lpar = pp.Literal( "(" )
rpar = pp.Literal( ")" )
addop = plus | minus
multop = mult | div
expop = pp.Literal( "^" )
assign = pp.Literal( "=" )
expr = pp.Forward()
atom = (integer | identifier | (lpar + expr + rpar))
factor = pp.Forward()
factor << atom + pp.ZeroOrMore( ( expop + factor ) )
term = factor + pp.ZeroOrMore( ( multop + factor ) )
expr << term + pp.ZeroOrMore( ( addop + term ) )
expr.setParseAction(lambda s, loc, toks : "".join(toks))
# allow expression to be used recursively
expression = pp.Forward()
args = pp.delimitedList(pp.Group(expression) | identifier | expr)
expression << functor + lparen + args + rparen
a_line = init + expression
the_line = a_line.parseString(line)
if the_line[0] in ("ocl_pin_write_buffer_async", "ocl_pin_read_buffer_async"):
last = the_line[-1]
if last.__class__ == pp.ParseResults:
last = "%s(%s)" % (last[0], ", ".join(last[0:]))
return last
else:
return None
except:
return None
name_resolver.append([get_ocl_pin_write_buffer_async, 2])
[docs]def get_new_buffer_name_line():
for a_try, a_depth in name_resolver:
current = gdb.newest_frame()
for i in range(a_depth):
current = current.older()
if current is None:
return None, None
sal = current.find_sal()
line_no = sal.line
line = ""
while sal.line - line_no < 5:
new_line = gdb.execute("list %s:%d,%d" % (sal.symtab.filename, line_no, line_no), to_string=True)
new_line = new_line[:-1] # remove newline char
if new_line[-1] == "&":
new_line = new_line[:-1]
line = re.match(r"\d+\s+(.*)", new_line).group(1) + line
if re.match(r"\d+\s+call", new_line):
break
line_no -= 1
a_name = a_try(line)
if a_name:
return a_name, "%s (%s:%d)" % (line, sal.symtab.filename, line_no)
else:
return None, None
[docs]class clCreateBufferBP(capture.OpenCLFunctionBreakpoint):
func_type = mcgdb.capture.FunctionTypes.define_func
def __init__(self):
capture.OpenCLFunctionBreakpoint.__init__(self, "clCreateBuffer")
[docs] def prepare_before (self):
data = {}
data["mode"] = my_archi.nth_arg(2, my_archi.INT)
## STRANGE, this is supposed to be 5 ... (it's 6 sometimes)
data["retcode_p"] = my_archi.nth_arg(5, my_archi.INT_P)
data["name"], data["line"] = get_new_buffer_name_line()
return (False, True, data)
[docs] def prepare_after(self, data):
try:
if int(data["retcode_p"].dereference()) != ocl_representation.CL_SUCCESS:
print ("%s failed: returned %d" % (self.location, int(data["retcode_p"].dereference())) )
return
except MemoryError as e:
print ("clCreateBufferBP failed: ", e)
print ("(maybe try to switch retcode_p arg btw 5 and 6)")
data["ret"] = my_archi.return_value(my_archi.VOID_P)
data["stack"] = gdb.execute("where", to_string=True)
if data["line"] is None:
try:
lineno = gdb.newest_frame().find_sal().line
data["line"] = gdb.execute("l *$pc,%d" % lineno, to_string=True)
data["line"] = data["line"].partition("\t")[-1].strip()
except e:
data["line"] = str(e)
mode_idx = int(data["mode"])
representation.Buffer(data["ret"], (mode_idx, ocl_representation.MODE[mode_idx]), data["stack"], data["line"], data["name"])
[docs]def activate():
global pp
import pyparsing as pp # https://pyparsing.wikispaces.com/
clCreateBufferBP()