📄 file_disasm.c
字号:
/* * vAVRdisasm - AVR program disassembler. * Version 1.0 - January 2007. * Written by Vanya A. Sergeev - <vsergeev@gmail.com> * * Copyright (C) 2007 Vanya A. Sergeev * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * file_disasm.c - Routines to take care of Atmel Generic, Intel HEX, and * Motorola S-Record file disassembly. Interface to avr_disasm.c to and * format_disasm.c to swiftly disassemble and print an assembled instruction. * */#include <stdio.h>#include "libGIS-1.0.0/atmel_generic.h"#include "libGIS-1.0.0/ihex.h"#include "libGIS-1.0.0/srecord.h"#include "avr_disasm.h"#include "format_disasm.h"#include "file_disasm.h"/* Reads a record from an Atmel Generic formatted file, formats the assembled * instruction data into an assembledInsruction structure, then passes the * assembled instruction data to disassembleAndPrint() for disassembly and printing. * Loops until all records have been read and processed. */int disassembleGenericFile(FILE *fileOut, FILE *fileIn, formattingOptions fOptions) { assembledInstruction aInstruction; AtmelGenericRecord arec; int retVal = 0; while (retVal == 0) { retVal = Read_AtmelGenericRecord(&arec, fileIn); if (retVal == ATMEL_GENERIC_ERROR_EOF) break; switch (retVal) { case ATMEL_GENERIC_OK: break; case ATMEL_GENERIC_ERROR_FILE: perror("Error reading Atmel Generic formatted file"); return ERROR_FILE_READING_ERROR; case ATMEL_GENERIC_ERROR_INVALID_RECORD: fprintf(stderr, "Invalid Atmel Generic formatted file!\n"); return ERROR_FILE_READING_ERROR; default: fprintf(stderr, "Encountered an irrecoverable error during reading of Atmel Generic formatted file!\n"); return ERROR_IRRECOVERABLE; } /* Address is multplied by two, because each 16-bit opcode * takes two bytes. */ aInstruction.address = arec.address*2; aInstruction.opcode = arec.data; retVal = disassembleAndPrint(fileOut, aInstruction, fOptions); if (retVal < 0) return retVal; } return 0; }/* Reads a record from an Intel Hex formatted file, formats the assembled * instruction data into an assembledInsruction structure, then passes the * assembled instruction data to disassembleAndPrint() for disassembly and printing. * Loops until all records have been read and processed. */int disassembleIHexFile(FILE *fileOut, FILE *fileIn, formattingOptions fOptions) { assembledInstruction aInstruction; IHexRecord irec; int i; int retVal = 0; while (retVal == 0) { retVal = Read_IHexRecord(&irec, fileIn); if (retVal == IHEX_ERROR_EOF) break; switch (retVal) { case IHEX_OK: break; case IHEX_ERROR_FILE: perror("Error reading Intel HEX formatted file"); return ERROR_FILE_READING_ERROR; case IHEX_ERROR_INVALID_RECORD: fprintf(stderr, "Invalid Intel HEX formatted file!\n"); return ERROR_FILE_READING_ERROR; case IHEX_ERROR_INVALID_ARGUMENTS: default: fprintf(stderr, "Encountered an irrecoverable error during reading of Intel HEX formatted file!\n"); return ERROR_IRRECOVERABLE; } /* Skip the record if it's not a data record */ if (irec.type != IHEX_TYPE_00) continue; aInstruction.address = irec.address; for (i = 0; i < irec.dataLen; i += 2) { /* Make sure there is a data byte after this, * (we need both because each opcode is 16-bits) */ if (i+1 > irec.dataLen) { fprintf(stderr, "Intel HEX formatted file does not hold valid AVR binary!\n"); return ERROR_FILE_READING_ERROR; } /* Assembled AVR program is stored in little-endian, * so the opcode is stored backwords. */ aInstruction.opcode = ((uint16_t)irec.data[i+1] << 8); aInstruction.opcode += ((uint16_t)irec.data[i]); retVal = disassembleAndPrint(fileOut, aInstruction, fOptions); if (retVal < 0) return retVal; /* Increment the address by two for the correct address * location of the next instruction. */ aInstruction.address += 2; } } return 0; }/* Reads a record from an Motorola S-Record formatted file, formats the assembled * instruction data into an assembledInsruction structure, then passes the * assembled instruction data to disassembleAndPrint() for disassembly and printing. * Loops until all records have been read and processed. */int disassembleSRecordFile(FILE *fileOut, FILE *fileIn, formattingOptions fOptions) { assembledInstruction aInstruction; SRecord srec; int i; int retVal = 0; while (retVal == 0) { retVal = Read_SRecord(&srec, fileIn); if (retVal == SRECORD_ERROR_EOF) break; switch (retVal) { case SRECORD_OK: break; case SRECORD_ERROR_FILE: perror("Error reading Motorola S-Record formatted file"); return ERROR_FILE_READING_ERROR; case SRECORD_ERROR_INVALID_RECORD: fprintf(stderr, "Invalid Motorola S-Record formatted file!\n"); return ERROR_FILE_READING_ERROR; case SRECORD_ERROR_INVALID_ARGUMENTS: default: fprintf(stderr, "Encountered an irrecoverable error during reading of Motorola S-Record formatted file!\n"); return ERROR_IRRECOVERABLE; } /* Skip the record if it's not a data record */ if (srec.type != SRECORD_TYPE_S1 || srec.type != SRECORD_TYPE_S2 || srec.type != SRECORD_TYPE_S3) continue; aInstruction.address = srec.address; for (i = 0; i < srec.dataLen; i += 2) { /* Make sure there is a data byte after this, * (we need both because each opcode is 16-bits) */ if (i+1 > srec.dataLen) { fprintf(stderr, "Motorola S-Record formatted file does not hold a valid AVR binary!\n"); return ERROR_FILE_READING_ERROR; } /* Assembled AVR program is stored in little-endian, * so the opcode is stored backwords. */ aInstruction.opcode = ((uint16_t)srec.data[i+1] << 8); aInstruction.opcode += ((uint16_t)srec.data[i]); retVal = disassembleAndPrint(fileOut, aInstruction, fOptions); if (retVal < 0) return retVal; /* Increment the address by two for the correct address * location of the next instruction. */ aInstruction.address += 2; } } return 0;}static int currentAddress = -5;/* Disassemble an assembled instruction, and print its disassembly * to fileOut. Alert user of errors. */int disassembleAndPrint(FILE *fileOut, const assembledInstruction aInstruction, formattingOptions fOptions) { disassembledInstruction dInstruction; int retVal; /* If we are printing address labels (assemble-able code) */ if ((fOptions.options & FORMAT_OPTION_ADDRESS_LABEL) != 0) { /* Increment the current address by two to follow along with the disassembly */ currentAddress += 2; /* If the current address is less than zero (meaning it hasn't been set yet, since * currentAddress is initialized to -5), or the current address isn't consistent with * the address of the next disassembled instruction, we need to mark a new program origin * with the .org directive. */ if (currentAddress < 0 || currentAddress != aInstruction.address) { currentAddress = aInstruction.address; fprintf(fileOut, "\n.org 0x%0*X\n", fOptions.addressFieldWidth, currentAddress/2); } } /* First disassemble the instruction, and check for errors. */ retVal = disassembleInstruction(&dInstruction, aInstruction); switch (retVal) { case 0: break; default: fprintf(stderr, "Encountered an irrecoverable error during disassembly!\n"); return ERROR_IRRECOVERABLE; } /* Next print the disassembled instruction, check for errors. */ retVal = printDisassembledInstruction(fileOut, dInstruction, fOptions); switch (retVal) { case 0: break; case ERROR_FILE_WRITING_ERROR: fprintf(stderr, "Error writing formatted disassembly to file!\n"); return ERROR_FILE_WRITING_ERROR; case ERROR_MEMORY_ALLOCATION_ERROR: fprintf(stderr, "Error allocating sufficient memory for formatted disassembly!\n"); return ERROR_MEMORY_ALLOCATION_ERROR; default: fprintf(stderr, "Encountered an irrecoverable error during disassembly!\n"); return ERROR_IRRECOVERABLE; } return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -