def isDirective(self, chip, itemList): trace.debug(1, "PROGRAM isDirective") trace.debug(2, "mnemonic: " + str(itemList[0].upper())) found = False for section in chip.getSectionSet(): mnemonic = section.getName() if itemList[0].upper() == section.getName(): self.setReadingData(section.isData()) found = True break if not found: return None instLine = InstructionLine() instLine.type = instLine.Directive instLine.mnemonic = mnemonic fct = section.getFct() if fct: # it means that an operand is expected if len(itemList) <= 1: instLine.errorList.append(mnemonic + ": operand missing") else: addressStr = itemList[1] instLine.operand = addressStr instLine.address = fct(addressStr) else: if len(itemList) > 1: instLine.errorList.append(mnemonic + ": no operand expected") return instLine
def isDirective(self, chip, itemList): trace.debug(1, "PROGRAM isDirective") trace.debug(2, "mnemonic: " + str(itemList[0].upper())) found = False for section in chip.getSectionSet(): mnemonic = section.getName() if itemList[0].upper() == section.getName(): self.setReadingData(section.isData()) found= True break if not found: return None instLine = InstructionLine() instLine.type = instLine.Directive; instLine.mnemonic = mnemonic fct = section.getFct() if fct: # it means that an operand is expected if len(itemList) <= 1: instLine.errorList.append(mnemonic + ": operand missing") else: addressStr = itemList[1] instLine.operand = addressStr instLine.address = fct(addressStr) else: if len(itemList) > 1: instLine.errorList.append(mnemonic + ": no operand expected") return instLine
def isCode(self, chip, itemList): trace.debug(1, "PROGRAM isCode") # look for at least an instruction with the same opcode # line can be # <LABEL> OPCODE <OPERAND> # so opcode can be in position 0 or 1 maxi = len(itemList) if maxi > 2: maxi = 2 foundMnemonic = False for i in range(maxi): for chipInst in chip.getInstructionSet(): mnemo = chipInst.getMnemonic() if itemList[i].upper() == mnemo.upper(): foundMnemonic = True index = i break if foundMnemonic: break if not foundMnemonic: return None instLine = InstructionLine() instLine.type = instLine.Code instLine.mnemonic = itemList[index].upper() instLine.size = chip.getInstructionSize() instLine.withLabel = False if index > 0: instLine.withLabel = True instLine.label = itemList[0] # flag indicating if zero page is an address or a displacement is present # moreover, when looking for operand type, consider label as a zeroPage instead of absolute instLine.isOffset = chipInst.isOffset() instLine.operand = "" instLine.operandList = [] if index < (len(itemList) - 1): if (chip.getOperandSeparator()): # multiple operands per instruction # TODO: split operand list and decode each operand instLine.errorList.append( "Multiple operand not implemented: contact program author") return None else: instLine.operand = itemList[index + 1] operand = self.decodeOperand(chip, instLine, instLine.operand) if (not operand): # inst contains error report return instLine instLine.operandList.append(operand) #if not self.findOpcode(chip, inst): # return None self.findOpcode(chip, instLine) return instLine
def setAddrCode(self, chip, instLine): trace.debug(1, "PROGRAM setAddrCode") instLine.address = self.loadAddress self.loadAddress += instLine.size if instLine.withLabel: self.labelDict[instLine.label] = instLine.address for operand in instLine.operandList: self.loadAddress += operand.size
def isCode(self, chip, itemList): trace.debug(1, "PROGRAM isCode") # look for at least an instruction with the same opcode # line can be # <LABEL> OPCODE <OPERAND> # so opcode can be in position 0 or 1 maxi = len(itemList) if maxi > 2: maxi = 2 foundMnemonic = False for i in range(maxi): for chipInst in chip.getInstructionSet(): mnemo = chipInst.getMnemonic() if itemList[i].upper() == mnemo.upper(): foundMnemonic = True index = i break if foundMnemonic: break if not foundMnemonic: return None instLine = InstructionLine() instLine.type = instLine.Code instLine.mnemonic = itemList[index].upper() instLine.size = chip.getInstructionSize() instLine.withLabel = False if index > 0: instLine.withLabel = True instLine.label = itemList[0] # flag indicating if zero page is an address or a displacement is present # moreover, when looking for operand type, consider label as a zeroPage instead of absolute instLine.isOffset = chipInst.isOffset() instLine.operand = "" instLine.operandList = [] if index < (len(itemList) - 1): if (chip.getOperandSeparator()): # multiple operands per instruction # TODO: split operand list and decode each operand instLine.errorList.append("Multiple operand not implemented: contact program author") return None else: instLine.operand = itemList[index + 1] operand = self.decodeOperand(chip, instLine, instLine.operand) if (not operand): # inst contains error report return instLine instLine.operandList.append(operand) #if not self.findOpcode(chip, inst): # return None self.findOpcode(chip, instLine) return instLine
def isData(self, chip, itemList): trace.debug(1, "PROGRAM isData") # # look for at least one keyword # line can be # <LABEL> keyword value # or # <LABEL> address value # if dataWithAddress is True # found = False maxi = len(itemList) if maxi > 2: maxi = 2 for i in range(maxi): for data in chip.getDataSet(): string = itemList[i].upper() mnemonic = data.getMnemonic() if re.match("^" + mnemonic + "$", string): #if itemList[i].upper() == mnemonic.upper(): found = True index = i break if found: break if not found: return None instLine = InstructionLine() instLine.type = instLine.Data if (chip.isDataWithAddress()): instLine.address = chip.decodeAddr(string) if index < (len(itemList) - 1): fct = data.getFct() instLine.value = fct(itemList[index + 1]) else: instLine.value = 0 # no mnemonic to indicate data size: use default word size instLine.size = chip.getWordSize() if index == 1: # there is a label before instLine.withLabel = True instLine.label = itemList[0] else: instLine.mnemonic = string instLine.withLabel = False if index > 0: instLine.withLabel = True instLine.label = itemList[0] instLine.operand = itemList[index + 1] fct = data.getFct() instLine.value = fct(instLine.operand) instLine.size = data.getSize() return instLine
def setAddrData(self, chip, instLine): trace.debug(1, "PROGRAM setAddrData") if (instLine.address < 0): instLine.address = self.loadAddress self.loadAddress += instLine.size else: # address specified at data definition self.loadAddress = instLine.address + instLine.size if instLine.withLabel: self.labelDict[instLine.label] = instLine.address
def isLabel(self, chip, itemList): trace.debug(1, "PROGRAM isLabel") if len(itemList) == 1: p = re.match("^(" + chip.getLabelPattern() + ")\:$", itemList[0]) if p: label = p.group(1) instLine = InstructionLine() instLine.type = instLine.Label instLine.label = label instLine.size = 0 return instLine return None
def analyzeFile(self, filename, chip): trace.debug(1, "PROGRAM analyzeFile") f = open(filename, "r") lineNb = 0 for line in f: lineNb += 1 # remove comments and ignore empty lines line = line.split(chip.getComment(), 1)[0] # split using spaces/tabs as separators itemList = line.split() if len(itemList) == 0: continue trace.debug(2, line) # 1st step: analyze line to determine its type # and store various item error = False msg = "" instLine = None try: instLine = self.isDirective(chip, itemList) if not instLine: instLine = self.isCode(chip, itemList) if not instLine: instLine = self.isData(chip, itemList) if not instLine: instLine = self.isLabel(chip, itemList) except Error as e: error = True msg = str(e) if not instLine or error: instLine = InstructionLine() if error: instLine.errorList.append(msg) else: instLine.errorList.append("Invalid mnemonic " + itemList[0]) instLine.line = line instLine.lineNb = lineNb self.instructionList.append(instLine)
def load(self, fileName, board): trace.debug(1, "PROGRAM load") chip = board.chip self.instructionList = [] self.errorList = [] self.labelDict = {} self.analyzeFile(fileName, chip) self.setAddr(board) self.resolveLabel(board) # collect all error messages for instLine in self.instructionList: for error in instLine.errorList: msg = "Line " + str(instLine.lineNb) + ": " + error self.errorList.append(msg) if len(self.errorList) > 0: raise ProgramError(Error.error, self.errorList) return False return self.loadCode(board)
def load(self, fileName, board): trace.debug(1, "PROGRAM load") chip = board.chip self.instructionList = [] self.errorList = [] self.labelDict = {} self.analyzeFile(fileName, chip) self.setAddr(board) self.resolveLabel(board) # collect all error messages for instLine in self.instructionList: for error in instLine.errorList: msg = "Line " + str(instLine.lineNb) + ": "+ error self.errorList.append(msg) if len(self.errorList) > 0: raise ProgramError(Error.error, self.errorList) return False return self.loadCode(board)
def loadCode(self, board): trace.debug(1, "PROGRAM loadCode") memory = board.memory codeAddress = -1 for instLine in self.instructionList: if instLine.type == instLine.Data: memory.set(instLine.address, instLine.size, instLine.value) elif instLine.type == instLine.Code: address = instLine.address if (codeAddress == -1): codeAddress = address memory.set(address, instLine.size, instLine.opcode) address += instLine.size for operand in instLine.operandList: memory.set(address, operand.size, operand.value) address += operand.size if (codeAddress == -1): raise ProgramError(Error.error, ["No instruction"]) return False self.setCodeBase(codeAddress) return True
def decodeOperand(self, chip, instLine, operandStr): trace.debug(1, "PROGRAM decodeOperand") for addressing in chip.getAddressingSet(): trace.debug(4, "addressing " + str(addressing)) trace.debug(4, "check against: " + addressing.getPattern()) pattern = re.compile("^" + addressing.getPattern() + "$") match = pattern.match(operandStr) if (match): trace.debug(4, "--> matching: " + addressing.getPattern()) # as pattern could contain several groups (to match label and real value) # we need to extract the one that matched string = None trace.debug(4, "Groups: " + str(match.groups())) for g in match.groups(): if (g): string = g break string = str(string) # if label, store it trace.debug(4, "Operand string: " + string) operand = Operand() operand.text = operandStr operand.addressing = addressing # if the operand can be either a value or a label (several group), check if it is a label # if there is one group, it can be a register name operand.isLabel = False if len(match.groups()) > 1: trace.debug(4, "labelPattern: " + chip.getLabelPattern()) pattern = re.compile("^" + chip.getLabelPattern() + "$") match = pattern.match(string) if (match): # special case for instruction performing relative branch # LABEL, used to reference address, could need to be converted with an offset # computed addressing mode could need to change accordingly trace.debug(4, "---> LABEL") operand.isLabel = True operand.size = chip.getAddressSize() operand.label = string if (instLine.isOffset): operand.addressing = chip.translateIntoOffset(operand.addressing) operand.size = operand.addressing.getSize() if not operand.isLabel: trace.debug(4, "---> NOT A LABEL") # decode value depending on operand type fct = addressing.getProcessing() operand.value = fct(string) operand.size = addressing.getSize() return operand error = operandStr + ": operand type not recognized" instLine.errorList.append(error) return None
def test__trace(): trace.error("Here is the Error Information!!") trace.warning("Here is the Warning Information") trace.info("Here is the Trace Information") trace.debug("Here is the Debug Information")
def setAddrDirective(self, chip, instLine): trace.debug(1, "PROGRAM setAddrDirective") self.loadAddress = instLine.address
def findOpcode(self, chip, instLine): trace.debug(1, "PROGRAM findOpCode") trace.debug(2, "mnemonic: " + instLine.mnemonic) for chipInst in chip.getInstructionSet(): trace.debug(3, "comparing with " + chipInst.getMnemonic()) if instLine.mnemonic == chipInst.getMnemonic(): found = True addressingList = chipInst.getAddressing() trace.debug( 4, "nb of operands " + str(len(instLine.operandList)) + " compared with " + str(len(addressingList))) if len(instLine.operandList) == len(addressingList): trace.debug(4, "--> compare operand") for i in range(len(instLine.operandList)): trace.debug( 4, " compare " + str(instLine.operandList[i].addressing) + " and " + str(addressingList[i])) if instLine.operandList[ i].addressing != addressingList[i]: #trace.debug(4, "---> AT LEAST ONE DOESN'T MACH: NOT FOUND") found = False break if found: #print "---> FOUND" instLine.opcode = chipInst.getOpcode() return True else: # number of operands doesn't match found = False if not found: error = instLine.mnemonic + ": operand type does not match" instLine.errorList.append(error) return False return True
def thisIsFunctionA(): debug()
def __init__(self): debug()
def __init__(self, fileName): home = os.path.expanduser("~") self.configFileName = os.path.join(home, fileName) trace.debug(1, "Using configuration file " + self.configFileName) self.config = ConfigParser.ConfigParser() self.config.read(self.configFileName)
def getSectionSet(self): trace.debug(4, "PROCESSOR getSectionSet") return self.__sectionSet
def Aha(self): debug()
def findOpcode(self, chip, instLine): trace.debug(1, "PROGRAM findOpCode") trace.debug(2, "mnemonic: " + instLine.mnemonic) for chipInst in chip.getInstructionSet(): trace.debug(3, "comparing with " + chipInst.getMnemonic()) if instLine.mnemonic == chipInst.getMnemonic(): found = True addressingList = chipInst.getAddressing() trace.debug(4, "nb of operands " + str(len(instLine.operandList)) + " compared with " + str(len(addressingList))) if len(instLine.operandList) == len(addressingList): trace.debug(4, "--> compare operand") for i in range(len(instLine.operandList)): trace.debug(4, " compare " + str(instLine.operandList[i].addressing) + " and " + str(addressingList[i])) if instLine.operandList[i].addressing != addressingList[i]: #trace.debug(4, "---> AT LEAST ONE DOESN'T MACH: NOT FOUND") found = False break if found: #print "---> FOUND" instLine.opcode = chipInst.getOpcode() return True else: # number of operands doesn't match found = False if not found: error = instLine.mnemonic + ": operand type does not match" instLine.errorList.append(error) return False return True
def Ahb(self): debug()
def decodeOperand(self, chip, instLine, operandStr): trace.debug(1, "PROGRAM decodeOperand") for addressing in chip.getAddressingSet(): trace.debug(4, "addressing " + str(addressing)) trace.debug(4, "check against: " + addressing.getPattern()) pattern = re.compile("^" + addressing.getPattern() + "$") match = pattern.match(operandStr) if (match): trace.debug(4, "--> matching: " + addressing.getPattern()) # as pattern could contain several groups (to match label and real value) # we need to extract the one that matched string = None trace.debug(4, "Groups: " + str(match.groups())) for g in match.groups(): if (g): string = g break string = str(string) # if label, store it trace.debug(4, "Operand string: " + string) operand = Operand() operand.text = operandStr operand.addressing = addressing # if the operand can be either a value or a label (several group), check if it is a label # if there is one group, it can be a register name operand.isLabel = False if len(match.groups()) > 1: trace.debug(4, "labelPattern: " + chip.getLabelPattern()) pattern = re.compile("^" + chip.getLabelPattern() + "$") match = pattern.match(string) if (match): # special case for instruction performing relative branch # LABEL, used to reference address, could need to be converted with an offset # computed addressing mode could need to change accordingly trace.debug(4, "---> LABEL") operand.isLabel = True operand.size = chip.getAddressSize() operand.label = string if (instLine.isOffset): operand.addressing = chip.translateIntoOffset( operand.addressing) operand.size = operand.addressing.getSize() if not operand.isLabel: trace.debug(4, "---> NOT A LABEL") # decode value depending on operand type fct = addressing.getProcessing() operand.value = fct(string) operand.size = addressing.getSize() return operand error = operandStr + ": operand type not recognized" instLine.errorList.append(error) return None
def getInstructionSet(self): trace.debug(4, "PROCESSOR getInstructionSet") l = [] for inst in self.__instructionSet: l.append(inst) return l