# ***************************************************************************** # * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. # * All rights reserved. This program and the accompanying materials # * are made available under the terms of the Eclipse Public License v1.0 # * which accompanies this distribution, and is available at # * http://www.eclipse.org/legal/epl-v10.html # * # * Contributors: # * Wind River Systems - initial API and implementation # ***************************************************************************** """ Line numbers service associates locations in the source files with the corresponding machine instruction addresses in the executable object. """ from .. import services NAME = "LineNumbers" class CodeArea(object): """ A CodeArea represents a continues area in source text mapped to continues range of code addresses. Line and columns are counted starting from 1. File name can be a relative path, in this case the client should use the CodeArea directory name as origin for the path. File and directory names are valid on a host where code was compiled. It is client responsibility to map names to local host file system. """ def __init__(self, directory, fileName, start_line, start_column, end_line, end_column, start_address, end_address, isa, is_statement, basic_block, prologue_end, epilogue_begin): self.directory = directory self.file = fileName self.start_line = start_line self.start_column = start_column self.end_line = end_line self.end_column = end_column self.start_address = start_address self.end_address = end_address self.isa = isa self.is_statement = is_statement self.basic_block = basic_block self.prologue_end = prologue_end self.epilogue_begin = epilogue_begin def __eq__(self, o): if self is o: return True if not isinstance(o, CodeArea): return False if self.start_line != o.start_line: return False if self.start_column != o.start_column: return False if self.end_line != o.end_line: return False if self.end_column != o.end_column: return False if self.isa != o.isa: return False if self.is_statement != o.is_statement: return False if self.basic_block != o.basic_block: return False if self.prologue_end != o.prologue_end: return False if self.epilogue_begin != o.epilogue_begin: return False if self.start_address != o.start_address: return False if self.end_address != o.end_address: return False if self.file != o.file: return False if self.directory != o.directory: return False return True def __hash__(self): h = 0 if self.file: h += hash(self.file) return h + self.start_line + self.start_column + self.end_line + \ self.end_column def __str__(self): import cStringIO bf = cStringIO.StringIO() bf.write('[') if self.directory: bf.write(self.directory) bf.write(':') if self.file: bf.write(self.file) bf.write(':') bf.write(str(self.start_line)) if self.start_column: bf.write('.') bf.write(str(self.start_column)) bf.write("..") bf.write(str(self.end_line)) if self.end_column: bf.write('.') bf.write(str(self.end_column)) bf.write(" -> ") if self.start_address: bf.write("0x") bf.write(hex(self.start_address)) else: bf.write('0') bf.write("..") if self.end_address: bf.write("0x") bf.write(hex(self.end_address)) else: bf.write('0') if self.isa: bf.write(",isa ") bf.write(str(self.isa)) if self.is_statement: bf.write(",statement") if self.basic_block: bf.write(",basic block") if self.prologue_end: bf.write(",prologue end") if self.epilogue_begin: bf.write(",epilogue begin") bf.write(']') return bf.getvalue() class LineNumbersService(services.Service): def getName(self): return NAME def mapToSource(self, context_id, start_address, end_address, done): raise NotImplementedError("Abstract method") def mapToMemory(self, context_id, fileName, line, column, done): raise NotImplementedError("Abstract method") class DoneMapToSource(object): def doneMapToSource(self, token, error, areas): pass class DoneMapToMemory(object): def doneMapToMemory(self, token, error, areas): pass