Browse Source
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJT6hhYAAoJEJykq7OBq3PIH44IAIC42HoYJFgE1RkLl/77PhpV WNNDJ/SIh/084PS6XKvHja0aUGjmQM/QmlCuV17MLp7ub1XeMDoncP9AnVhiWTyL a3c5TJw8OasBadffSFLXh5ZmW/fgkie+TjXIWud4dB+hZmd28uV46tLLRrJFJA6O uCpAKUUCVyN78LDhsGVUzZAYjXzeFQQ9Eq5z4dysfCO5x4y5rvcTs6MJ6X5vxUBP rF3RTKb5DmcFZvuOYJxVx9WiDOe6RiMS72sitQCszvGspmBtVP0CvJQnHu7nMOVf Ljti0XVui3t3Jto+DJSH4ki0i025MSetgAMhk1bYcVnK4XQ2t03DrQExOM+VjjM= =+ba+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging Tracing pull request * remotes/stefanha/tags/tracing-pull-request: virtio-rng: add some trace events trace: add some tcg tracing support trace: teach lttng backend to use format strings trace: [tcg] Include TCG-tracing header on all targets trace: [tcg] Include event definitions in "trace.h" trace: [tcg] Generate TCG tracing routines trace: [tcg] Include TCG-tracing helpers trace: [tcg] Define TCG tracing helper routine wrappers trace: [tcg] Define TCG tracing helper routines trace: [tcg] Declare TCG tracing helper routines trace: [tcg] Add 'tcg' event property trace: [tcg] Argument type transformation machinery trace: [tcg] Argument type transformation rules trace: [tcg] Add documentation trace: install simpletrace SystemTap tapset simpletrace: add simpletrace.py --no-header option trace: add tracetool simpletrace_stap format trace: extract stap_escape() function for reuse Conflicts: Makefile.objspull/14/head
42 changed files with 808 additions and 28 deletions
@ -0,0 +1,7 @@ |
|||
#ifndef TRACE_TCG_H |
|||
#define TRACE_TCG_H |
|||
|
|||
#include "trace/generated-tcg-tracers.h" |
|||
#include "trace/generated-events.h" |
|||
|
|||
#endif /* TRACE_TCG_H */ |
|||
@ -0,0 +1,71 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only). |
|||
""" |
|||
|
|||
__author__ = "Stefan Hajnoczi <redhat.com>" |
|||
__copyright__ = "Copyright (C) 2014, Red Hat, Inc." |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@redhat.com" |
|||
|
|||
|
|||
from tracetool import out |
|||
from tracetool.backend.dtrace import binary, probeprefix |
|||
from tracetool.backend.simple import is_string |
|||
from tracetool.format.stap import stap_escape |
|||
|
|||
|
|||
def generate(events, backend): |
|||
out('/* This file is autogenerated by tracetool, do not edit. */', |
|||
'') |
|||
|
|||
for event_id, e in enumerate(events): |
|||
if 'disable' in e.properties: |
|||
continue |
|||
|
|||
out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?', |
|||
'{', |
|||
probeprefix=probeprefix(), |
|||
name=e.name) |
|||
|
|||
# Calculate record size |
|||
sizes = ['24'] # sizeof(TraceRecord) |
|||
for type_, name in e.args: |
|||
name = stap_escape(name) |
|||
if is_string(type_): |
|||
out(' try {', |
|||
' arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : "<null>"', |
|||
' } catch {}', |
|||
' arg%(name)s_len = strlen(arg%(name)s_str)', |
|||
name=name) |
|||
sizes.append('4 + arg%s_len' % name) |
|||
else: |
|||
sizes.append('8') |
|||
sizestr = ' + '.join(sizes) |
|||
|
|||
# Generate format string and value pairs for record header and arguments |
|||
fields = [('8b', str(event_id)), |
|||
('8b', 'gettimeofday_ns()'), |
|||
('4b', sizestr), |
|||
('4b', 'pid()')] |
|||
for type_, name in e.args: |
|||
name = stap_escape(name) |
|||
if is_string(type_): |
|||
fields.extend([('4b', 'arg%s_len' % name), |
|||
('.*s', 'arg%s_len, arg%s_str' % (name, name))]) |
|||
else: |
|||
fields.append(('8b', name)) |
|||
|
|||
# Emit the entire record in a single SystemTap printf() |
|||
fmt_str = '%'.join(fmt for fmt, _ in fields) |
|||
arg_str = ', '.join(arg for _, arg in fields) |
|||
out(' printf("%%%(fmt_str)s", %(arg_str)s)', |
|||
fmt_str=fmt_str, arg_str=arg_str) |
|||
|
|||
out('}') |
|||
|
|||
out() |
|||
@ -0,0 +1,57 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
Generate .h file for TCG code generation. |
|||
""" |
|||
|
|||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@linux.vnet.ibm.com" |
|||
|
|||
|
|||
from tracetool import out |
|||
|
|||
|
|||
def generate(events, backend): |
|||
out('/* This file is autogenerated by tracetool, do not edit. */', |
|||
'/* You must include this file after the inclusion of helper.h */', |
|||
'', |
|||
'#ifndef TRACE__GENERATED_TCG_TRACERS_H', |
|||
'#define TRACE__GENERATED_TCG_TRACERS_H', |
|||
'', |
|||
'#include <stdint.h>', |
|||
'', |
|||
'#include "trace.h"', |
|||
'#include "exec/helper-proto.h"', |
|||
'', |
|||
) |
|||
|
|||
for e in events: |
|||
# just keep one of them |
|||
if "tcg-trans" not in e.properties: |
|||
continue |
|||
|
|||
# get the original event definition |
|||
e = e.original.original |
|||
|
|||
out('static inline void %(name_tcg)s(%(args)s)', |
|||
'{', |
|||
name_tcg=e.api(e.QEMU_TRACE_TCG), |
|||
args=e.args) |
|||
|
|||
if "disable" not in e.properties: |
|||
out(' %(name_trans)s(%(argnames_trans)s);', |
|||
' gen_helper_%(name_exec)s(%(argnames_exec)s);', |
|||
name_trans=e.event_trans.api(e.QEMU_TRACE), |
|||
name_exec=e.event_exec.api(e.QEMU_TRACE), |
|||
argnames_trans=", ".join(e.event_trans.args.names()), |
|||
argnames_exec=", ".join(e.event_exec.args.names())) |
|||
|
|||
out('}') |
|||
|
|||
out('', |
|||
'#endif /* TRACE__GENERATED_TCG_TRACERS_H */') |
|||
@ -0,0 +1,50 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
Generate trace/generated-helpers.c. |
|||
""" |
|||
|
|||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@linux.vnet.ibm.com" |
|||
|
|||
|
|||
from tracetool import out |
|||
from tracetool.transform import * |
|||
|
|||
|
|||
def generate(events, backend): |
|||
events = [e for e in events |
|||
if "disable" not in e.properties] |
|||
|
|||
out('/* This file is autogenerated by tracetool, do not edit. */', |
|||
'', |
|||
'#include "qemu-common.h"', |
|||
'#include "trace.h"', |
|||
'#include "exec/helper-proto.h"', |
|||
'', |
|||
) |
|||
|
|||
for e in events: |
|||
if "tcg-exec" not in e.properties: |
|||
continue |
|||
|
|||
# tracetool.generate always transforms types to host |
|||
e_args = e.original.args |
|||
|
|||
values = ["(%s)%s" % (t, n) |
|||
for t, n in e.args.transform(TCG_2_TCG_HELPER_DEF)] |
|||
|
|||
out('void %(name_tcg)s(%(args)s)', |
|||
'{', |
|||
' %(name)s(%(values)s);', |
|||
'}', |
|||
name_tcg="helper_%s_proxy" % e.api(), |
|||
name=e.api(), |
|||
args=e_args.transform(HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF), |
|||
values=", ".join(values), |
|||
) |
|||
@ -0,0 +1,50 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
Generate trace/generated-helpers.h. |
|||
""" |
|||
|
|||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@linux.vnet.ibm.com" |
|||
|
|||
|
|||
from tracetool import out |
|||
from tracetool.transform import * |
|||
|
|||
|
|||
def generate(events, backend): |
|||
events = [e for e in events |
|||
if "disable" not in e.properties] |
|||
|
|||
out('/* This file is autogenerated by tracetool, do not edit. */', |
|||
'', |
|||
) |
|||
|
|||
for e in events: |
|||
if "tcg-exec" not in e.properties: |
|||
continue |
|||
|
|||
# tracetool.generate always transforms types to host |
|||
e_args = e.original.args |
|||
|
|||
# TCG helper proxy declaration |
|||
fmt = "DEF_HELPER_FLAGS_%(argc)d(%(name)s, %(flags)svoid%(types)s)" |
|||
args = e_args.transform(HOST_2_TCG_COMPAT, HOST_2_TCG, |
|||
TCG_2_TCG_HELPER_DECL) |
|||
types = ", ".join(args.types()) |
|||
if types != "": |
|||
types = ", " + types |
|||
|
|||
flags = "TCG_CALL_NO_RWG, " |
|||
|
|||
out(fmt, |
|||
flags=flags, |
|||
argc=len(args), |
|||
name=e.api() + "_proxy", |
|||
types=types, |
|||
) |
|||
@ -0,0 +1,70 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
Generate trace/generated-helpers-wrappers.h. |
|||
""" |
|||
|
|||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@linux.vnet.ibm.com" |
|||
|
|||
|
|||
from tracetool import out |
|||
from tracetool.transform import * |
|||
|
|||
|
|||
def generate(events, backend): |
|||
events = [e for e in events |
|||
if "disable" not in e.properties] |
|||
|
|||
out('/* This file is autogenerated by tracetool, do not edit. */', |
|||
'', |
|||
'#define tcg_temp_new_nop(v) (v)', |
|||
'#define tcg_temp_free_nop(v)', |
|||
'', |
|||
) |
|||
|
|||
for e in events: |
|||
if "tcg-exec" not in e.properties: |
|||
continue |
|||
|
|||
# tracetool.generate always transforms types to host |
|||
e_args = e.original.args |
|||
|
|||
# mixed-type to TCG helper bridge |
|||
args_tcg_compat = e_args.transform(HOST_2_TCG_COMPAT) |
|||
|
|||
code_new = [ |
|||
"%(tcg_type)s __%(name)s = %(tcg_func)s(%(name)s);" % |
|||
{"tcg_type": transform_type(type_, HOST_2_TCG), |
|||
"tcg_func": transform_type(type_, HOST_2_TCG_TMP_NEW), |
|||
"name": name} |
|||
for (type_, name) in args_tcg_compat |
|||
] |
|||
|
|||
code_free = [ |
|||
"%(tcg_func)s(__%(name)s);" % |
|||
{"tcg_func": transform_type(type_, HOST_2_TCG_TMP_FREE), |
|||
"name": name} |
|||
for (type_, name) in args_tcg_compat |
|||
] |
|||
|
|||
gen_name = "gen_helper_" + e.api() |
|||
|
|||
out('static inline void %(name)s(%(args)s)', |
|||
'{', |
|||
' %(code_new)s', |
|||
' %(proxy_name)s(%(tmp_names)s);', |
|||
' %(code_free)s', |
|||
'}', |
|||
name=gen_name, |
|||
args=e_args, |
|||
proxy_name=gen_name + "_proxy", |
|||
code_new="\n ".join(code_new), |
|||
code_free="\n ".join(code_free), |
|||
tmp_names=", ".join(["__%s" % name for _, name in e_args]), |
|||
) |
|||
@ -0,0 +1,166 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
""" |
|||
Type-transformation rules. |
|||
""" |
|||
|
|||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" |
|||
__license__ = "GPL version 2 or (at your option) any later version" |
|||
|
|||
__maintainer__ = "Stefan Hajnoczi" |
|||
__email__ = "stefanha@linux.vnet.ibm.com" |
|||
|
|||
|
|||
def _transform_type(type_, trans): |
|||
if isinstance(trans, str): |
|||
return trans |
|||
elif isinstance(trans, dict): |
|||
if type_ in trans: |
|||
return _transform_type(type_, trans[type_]) |
|||
elif None in trans: |
|||
return _transform_type(type_, trans[None]) |
|||
else: |
|||
return type_ |
|||
elif callable(trans): |
|||
return trans(type_) |
|||
else: |
|||
raise ValueError("Invalid type transformation rule: %s" % trans) |
|||
|
|||
|
|||
def transform_type(type_, *trans): |
|||
"""Return a new type transformed according to the given rules. |
|||
|
|||
Applies each of the transformation rules in trans in order. |
|||
|
|||
If an element of trans is a string, return it. |
|||
|
|||
If an element of trans is a function, call it with type_ as its only |
|||
argument. |
|||
|
|||
If an element of trans is a dict, search type_ in its keys. If type_ is |
|||
a key, use the value as a transformation rule for type_. Otherwise, if |
|||
None is a key use the value as a transformation rule for type_. |
|||
|
|||
Otherwise, return type_. |
|||
|
|||
Parameters |
|||
---------- |
|||
type_ : str |
|||
Type to transform. |
|||
trans : list of function or dict |
|||
Type transformation rules. |
|||
""" |
|||
if len(trans) == 0: |
|||
raise ValueError |
|||
res = type_ |
|||
for t in trans: |
|||
res = _transform_type(res, t) |
|||
return res |
|||
|
|||
|
|||
################################################## |
|||
# tcg -> host |
|||
|
|||
def _tcg_2_host(type_): |
|||
if type_ == "TCGv": |
|||
# force a fixed-size type (target-independent) |
|||
return "uint64_t" |
|||
else: |
|||
return type_ |
|||
|
|||
TCG_2_HOST = { |
|||
"TCGv_i32": "uint32_t", |
|||
"TCGv_i64": "uint64_t", |
|||
"TCGv_ptr": "void *", |
|||
None: _tcg_2_host, |
|||
} |
|||
|
|||
|
|||
################################################## |
|||
# host -> host compatible with tcg sizes |
|||
|
|||
HOST_2_TCG_COMPAT = { |
|||
"uint8_t": "uint32_t", |
|||
} |
|||
|
|||
|
|||
################################################## |
|||
# host/tcg -> tcg |
|||
|
|||
def _host_2_tcg(type_): |
|||
if type_.startswith("TCGv"): |
|||
return type_ |
|||
raise ValueError("Don't know how to translate '%s' into a TCG type\n" % type_) |
|||
|
|||
HOST_2_TCG = { |
|||
"uint32_t": "TCGv_i32", |
|||
"uint64_t": "TCGv_i64", |
|||
"void *" : "TCGv_ptr", |
|||
None: _host_2_tcg, |
|||
} |
|||
|
|||
|
|||
################################################## |
|||
# tcg -> tcg helper definition |
|||
|
|||
def _tcg_2_helper_def(type_): |
|||
if type_ == "TCGv": |
|||
return "target_ulong" |
|||
else: |
|||
return type_ |
|||
|
|||
TCG_2_TCG_HELPER_DEF = { |
|||
"TCGv_i32": "uint32_t", |
|||
"TCGv_i64": "uint64_t", |
|||
"TCGv_ptr": "void *", |
|||
None: _tcg_2_helper_def, |
|||
} |
|||
|
|||
|
|||
################################################## |
|||
# tcg -> tcg helper declaration |
|||
|
|||
def _tcg_2_tcg_helper_decl_error(type_): |
|||
raise ValueError("Don't know how to translate type '%s' into a TCG helper declaration type\n" % type_) |
|||
|
|||
TCG_2_TCG_HELPER_DECL = { |
|||
"TCGv" : "tl", |
|||
"TCGv_ptr": "ptr", |
|||
"TCGv_i32": "i32", |
|||
"TCGv_i64": "i64", |
|||
None: _tcg_2_tcg_helper_decl_error, |
|||
} |
|||
|
|||
|
|||
################################################## |
|||
# host/tcg -> tcg temporal constant allocation |
|||
|
|||
def _host_2_tcg_tmp_new(type_): |
|||
if type_.startswith("TCGv"): |
|||
return "tcg_temp_new_nop" |
|||
raise ValueError("Don't know how to translate type '%s' into a TCG temporal allocation" % type_) |
|||
|
|||
HOST_2_TCG_TMP_NEW = { |
|||
"uint32_t": "tcg_const_i32", |
|||
"uint64_t": "tcg_const_i64", |
|||
"void *" : "tcg_const_ptr", |
|||
None: _host_2_tcg_tmp_new, |
|||
} |
|||
|
|||
|
|||
################################################## |
|||
# host/tcg -> tcg temporal constant deallocation |
|||
|
|||
def _host_2_tcg_tmp_free(type_): |
|||
if type_.startswith("TCGv"): |
|||
return "tcg_temp_free_nop" |
|||
raise ValueError("Don't know how to translate type '%s' into a TCG temporal deallocation" % type_) |
|||
|
|||
HOST_2_TCG_TMP_FREE = { |
|||
"uint32_t": "tcg_temp_free_i32", |
|||
"uint64_t": "tcg_temp_free_i64", |
|||
"void *" : "tcg_temp_free_ptr", |
|||
None: _host_2_tcg_tmp_free, |
|||
} |
|||
Loading…
Reference in new issue