Commit 8843e857 authored by Martin Hoffmann's avatar Martin Hoffmann

trace analysis: Adding info for accessed OS memory

This includes using nm again, instead of llvm-nm.

Change-Id: Ic8b1b6054427ddaf028ece5e7758309ee0d4b3be
parent 71f04b10
......@@ -82,7 +82,6 @@ file(REMOVE ${GIT_REV_FILE}.tmp) # discard dummy output file
macro(fail_get_variant TNAME TEST)
set(FAIL_VARIANT "${PROJECT_NAME}-${GIT_REV}/")
set(FAIL_BENCHMARK "${TNAME}-${TEST}")
if(CONFIG_ARCH_MPU)
set(FAIL_VARIANT "${FAIL_VARIANT}+mpu")
endif()
......@@ -201,7 +200,7 @@ macro(fail_test TEST TESTELF)
# TODO: make architecture independent
set(BOCHSRC "${PROJECT_BINARY_DIR}/startup_scripts/bochsrc-fail-${TEST}-nogui")
# Tracing
set(TRACEFILE "${FAIL_DIR}/trace.pb")
......@@ -225,10 +224,11 @@ macro(fail_test TEST TESTELF)
COMMAND ${PYTHON} ${STATS_BINARY}
--stats-dict ${STATS_DICT}
--elf ${ELF}
--nm ${CROSS_NM}
COMMAND PYTHONPATH=${PROJECT_SOURCE_DIR} ${STATS_TRACE}
--stats-dict ${STATS_DICT}
--elf ${ELF}
--nm ${CROSS_NM}
--nm ${CROSS_NM}
--trace ${TRACEFILE}
--trace-plugin ${FAIL_TRACE_PLUGIN_PYTHON}
COMMENT "Tracing ${ELF} for ${FAIL_VARIANT}/${BENCHMARK}"
......
......@@ -7,9 +7,30 @@ from gzip import GzipFile
from optparse import OptionParser
from generator.stats_binary import read_symbols, read_regions, Symbol
from generator.statistics import Statistics
from collections import namedtuple
from collections import namedtuple, defaultdict
from random import randint
class MemAccess:
def __init__(self, writeAccess, trace_event):
self.writeAccess = writeAccess
self.address = trace_event.memaddr
self.size = trace_event.width
def __str__(self):
ret = ""
if self.writeAccess:
ret += "W "
else:
ret += "R "
ret += str(self.address) + " - Size: " + str(self.size)
return ret
mem_already_traced = False
memwrites = defaultdict(list)
memreads = defaultdict(list)
def open_trace(filename):
f = open(filename, "rb")
......@@ -19,9 +40,10 @@ def open_trace(filename):
f.seek(0,0)
return f
def read_trace(trace_plugin_filename, trace_filename):
"""Generator that iterates over all events in trace"""
global mem_already_traced
trace_plugin = imp.load_source("trace", trace_plugin_filename)
trace_file = open_trace(trace_filename)
trace_event = trace_plugin.Trace_Event()
......@@ -44,8 +66,16 @@ def read_trace(trace_plugin_filename, trace_filename):
if trace_event.HasField("time_delta"):
acctime += trace_event.time_delta
if trace_event.HasField('memaddr') and not mem_already_traced:
if trace_event.accesstype == trace_plugin.Trace_Event.WRITE:
memwrites[acctime].append(MemAccess(True, trace_event))
if trace_event.accesstype == trace_plugin.Trace_Event.READ:
memreads[acctime].append(MemAccess(False,trace_event))
yield (acctime, trace_event)
trace_file.close()
mem_already_traced = True
class SymbolMap(dict):
......@@ -53,7 +83,7 @@ class SymbolMap(dict):
translation"""
def __init__(self, symbols):
symbols.append(Symbol(addr = 0, size = 1, name = "__OS_syscall_OSEKOS_IncrementCounter",
type = "OBJECT"))
segment = ".text", type = "OBJECT"))
self.symbols = symbols
for symbol in symbols:
if not symbol.size:
......@@ -260,12 +290,31 @@ def main(options, args):
if x.addr]
symbol_map = SymbolMap(symbols)
# Extract OS memory objects
os_memory_symbols = set()
os_memory_size = 0
for symbol in symbols:
if symbol.segment in ('.data', '.bss'):
if not symbol.size:
continue
if not symbol.name.startswith(tuple(["arch::", "os::"])):
continue
os_memory_symbols.add(symbol)
os_memory_size += symbol.size
# fully run over trace once, to get all memory events.
trace_events = read_trace(options.traceplugin, options.trace)
t = list(trace_events)
# Reset trace for region extraction
trace_events = read_trace(options.traceplugin, options.trace)
stats = Statistics.load(options.stats)
for abb in stats.find_all("AtomicBasicBlock").values():
if not 'generated-function' in abb:
continue
abb["activations"] = []
sysgraph = stats.find_all("SystemGraph").values()[0]
IncrementCounter = {"_id": id(main),
"_type": "AtomicBasicBlock",
......@@ -280,7 +329,6 @@ def main(options, args):
delayed_regions = []
regions_count = 0
while region_iterator or len(delayed_regions):
regions_count += 1
if region_iterator:
......@@ -338,6 +386,50 @@ def main(options, args):
if event_type == "__OS_syscall_OSEKOS_IncrementCounter":
IncrementCounter["symbols"] = list(set(IncrementCounter["symbols"]) | set(names))
## Re-Visit all abbs and add memory accesses
# helper to extract accessed symbols within a trace time range
def extract_bytes(sysrange, accesses):
sizes = list() # List: for summing up the accessed memory
addresses = set() # Set: for subsuming actually accessed addresses
# lol: list of memory access lists
lol = [accesses[addr] for addr in sysrange if addr in accesses]
#flatten to a single list
accesses = [ y for x in lol for y in x ]
# Add each single accessed byte address and sizes.
for x in accesses:
if x.address in symbol_map and symbol_map[x.address] in os_memory_symbols:
sizes.append(x.size)
addresses.update(range(x.address, x.address + x.size))
return sizes, addresses
# Overall written/read addresses
total_written_addresses = set()
total_read_addresses = set()
for abb in stats.find_all("AtomicBasicBlock").values():
# Written/read bytes per ABB
written_bytes = list()
read_bytes = list()
if 'activations' in abb:
for acts in abb['activations']:
sysrange = range(acts['start-time'], acts['end-time'])
(ss, addrs) = extract_bytes(sysrange, memwrites)
written_bytes.extend(ss)
total_written_addresses.update(addrs)
(ss, addrs) = extract_bytes(sysrange, memreads)
read_bytes.extend(ss)
total_read_addresses.update(addrs)
abb['written_os_bytes'] = sum(written_bytes)
abb['write_accesses'] = len(written_bytes)
abb['read_os_bytes'] = sum(read_bytes)
abb['read_accesses'] = len(read_bytes)
print "Written addresses: ", len(total_written_addresses)
print "Read addresses: ", len(total_read_addresses)
## done.
print "Processed %d Systemcalls" % regions_count
IncrementCounter["generated-codesize"] = 0
for symbol in IncrementCounter["symbols"]:
......
......@@ -6,7 +6,7 @@ import optparse
import subprocess
from collections import namedtuple
Symbol = namedtuple("Symbol", ["name", "addr", "size", "type"])
Symbol = namedtuple("Symbol", ["name", "addr", "size", "segment", "type"])
def safe_int(i, base=10):
try:
......@@ -45,16 +45,17 @@ def read_regions(objdump, elf_file):
return regions
def read_symbols(elffile, nm = "llvm-nm"):
out = subprocess.check_output([nm, "--print-size", "--format", "sysv", elffile])
def read_symbols(elffile, nm = "nm"):
out = subprocess.check_output([nm, "-t", "dec", "-C", "-S", "-f", "sysv", elffile])
ret = []
for line in out.split("\n"):
if not "|" in line:
continue
line = [x.strip() for x in line.split("|")]
ret.append(Symbol(name = line[0],
addr = safe_int(line[1], 16),
size = safe_int(line[4], 16),
addr = safe_int(line[1]),
size = safe_int(line[4]),
segment = line[6],
type = line[3]
))
return ret
......
......@@ -37,7 +37,7 @@ if(${LLVM_C_COMPILER} STREQUAL "LLVM_C_COMPILER-NOTFOUND")
" Please install one of them !")
endif()
message(STATUS "LLVM compiler: ${LLVM_COMPILER}")
message(STATUS "LLVM compiler: ${LLVM_C_COMPILER}")
if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
......@@ -63,7 +63,7 @@ elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux")
set(CROSS_RANLIB ${LLVM_ROOT}/bin/llvm-ranlib)
set(CROSS_AR ${LLVM_ROOT}/bin/llvm-ar)
find_program(CROSS_OBJDUMP objdump)
find_program(CROSS_NM "${ARCH_PREFIX}nm")
find_program(CROSS_NM "${ARCH_PREFIX}nm" "nm")
else()
message(FATAL "Host system not found :(")
endif()
......
......@@ -49,7 +49,7 @@ set(CMAKE_ASM_FLAGS "-Qunused-arguments" CACHE STRING "ASMFLAGS")
set(CMAKE_ASM-TT_FLAGS "-Qunused-arguments" CACHE STRING "ASMFLAGS")
find_program(CROSS_AR "llvm-ar" HINTS ${LLVM_ROOT}/bin)
find_program(CROSS_NM "llvm-nm" HINTS ${LLVM_ROOT}/bin)
find_program(CROSS_NM "nm")
find_program(CROSS_RANLIB "llvm-ranlib" HINTS ${LLVM_ROOT}/bin)
# Find objdump for pagetable generation
find_program(CROSS_OBJDUMP "llvm-objdump")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment