Extracting Equivalent Hex Values from a COFF File
Total Page:16
File Type:pdf, Size:1020Kb
Application Report SPRA573 Extracting Equivalent Hex Values From a COFF File Arun Chhabra and Ramesh Iyer Digital Signal Processing Solutions Abstract During compilation and linking of code, the assembler and linker create object and output files respectively. These files are in the common object file format (COFF). The initialized sections (.text, .data and .sect) are placed in the processor memory when the program is loaded. The uninitialized sections (.bss and .usect) do not have any actual contents, but instead they reserve space in memory. At runtime the program uses this reserved space to create and store variables. The COFF-to-hex extraction utility extracts the equivalent hex values of the COFF executable file. Contents Extracting Data from a COFF File....................................................................................................2 Digital Signal Processing Solutions July 1999 Application Report SPRA573 Extracting Data from a COFF File The appended COFF-to-hex extraction utility converts a COFF file (versions 1 and 2) to an equivalent data dump in hex format. The utility shown here is intended to parse a 16-bit COFF format executable file and print out the extracted hex code. The code is designed to run on a PC platform running Windows 95TM. To better understand invoking of this utility, consider the following example consisting of the sample assembly file: Example 1. Sample Assembly File ************************* Example file: SAMPLE.asm ************************* .def main .mmregs .text main: STM 2h, 002ch LD #0h, A LD #1h, A loop: ADD #2h, A SUB #1h, A NOP LD #10h, B SUB A, B BC loop, BNEQ .end ************************* End of sample.asm ************************* ******************************************* * FILENAME: VECTORS.ASM for kernal.asm * * AUTHOR: ARUN CHHABRA * * DATE: 10/15/97 * ******************************************* .ref start .ref main Extracting Equivalent Hex Values From a COFF File 2 Application Report SPRA573 .sect ".vectors" .mmregs B start NOP NOP Assemble and link this file with the appropriate vectors and linker command file. The coff utility will be applied on the generated "sample.out" file. On the DOS command line, type in the following: "coff_both -out sample.out" The generated output containing the extracted hex code will be entitled "sample.out.c" and its contents will appear as shown in Example 2. Extracting Equivalent Hex Values From a COFF File 3 Application Report SPRA573 Example 2. Generated Output Containing Extracted Hex Code **************************** Contents of sample.out.c **************************** Section = .text src_addr = 0x0 length = 0xD (13) dest_addr = 0x80 space = 0 0x772C, 0x0002, 0xE800, 0xE801, 0xF000, 0x0002, 0xF010, 0x0001, 0xF495, 0xE910, 0xF520, 0xF84C, 0x0084, checksum = 0x6751 Section = .vectors src_addr = 0x0 length = 0x4 (4) dest_addr = 0xFF80 space = 0 0xF073, 0x0080, 0xF495, 0xF495, checksum = 0xF0F3 ************************* End of sample.out.c ************************* Extracting Equivalent Hex Values From a COFF File 4 Application Report SPRA573 ************************************************************************* SOURCE CODE BEGINS HERE ************************************************************************* // FILENAME: Coff_both.c // DESCRIPTION: Convert a COFF file (versions 1 and 2) to an equivalent // data dump in hex format // ARGUMENTS: // a) Input: TI executable .out file (e.g. “foo.out”) // b) Output: “foo.out.c” *************************************************************************** #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include "coff.h" #include <errno.h> int out = 0; *************************************************************************** SOURCE CODE – function swapushort() BEGINS HERE *************************************************************************** // FUNCTION NAME: swapushort() // DESCRIPTION: Obtains hex values of data in a byte-wise manner // ARGUMENTS: // a) Input: ushort data // b) Output: tmp *************************************************************************** ushort swapushort (ushort data) { ushort tmp; tmp = (data & 0x00FF); tmp|= (data & 0xFF00); return tmp; } *************************************************************************** SOURCE CODE – function xor() BEGINS HERE *************************************************************************** // FUNCTION NAME: xor() // DESCRIPTION: Print checksum output in specified format // ARGUMENTS: // a) Input: ushort a, ushort b // b) Output: (~(a|b)^(~a|~b)) // i.e. [a <XOR> b] *************************************************************************** ushort xor (ushort a, ushort b) Extracting Equivalent Hex Values From a COFF File 5 Application Report SPRA573 { return (~(a|b)^(~a|~b)); } *************************************************************************** SOURCE CODE – function Download() BEGINS HERE *************************************************************************** // FUNCTION NAME: Download() // DESCRIPTION: Format output appearance and call two other routines that // output result and perform checksum. The file pointer "fp" // corresponds to the target output file. The file pointer is // passed as a parameter from the main() routine (passed as // file pointer “ofp”) to Download() (referred to here as // “fp”). // ARGUMENTS: // a) Input: uint src_addr, uint length // uint dest_addr, int space, struct buffer buf // STEPS: // The following steps outline the procedure for Download(): // i) Call swapushort() // ii)Call xor() *************************************************************************** void DownLoad (uint src_addr, uint length, uint dest_addr, int space, struct buffer buf, FILE *fp) { int i; int wrap = 0; ushort checksum = 0; if (out) { fprintf(fp, "src_addr = 0x%X \n", src_addr); fprintf(fp, "length = 0x%X (%d) \n", length, length); fprintf(fp, "dest_addr = 0x%X\n", dest_addr); fprintf(fp, "space = %d\n", space); fprintf(fp, " \n"); for (i = 0; i < length; i++) { if (4 <= wrap) { wrap = 0; fprintf(fp, "\n "); } fprintf(fp, "0x%04X, ", swapushort(buf.data[i])); checksum = xor(checksum, swapushort(buf.data[i])); /* prints the output in the specified format and performs the checksum */ wrap++; } fprintf(fp, "\n\n"); fprintf(fp, "checksum = 0x%4X\n\n", checksum); Extracting Equivalent Hex Values From a COFF File 6 Application Report SPRA573 } return; } *************************************************************************** SOURCE CODE – Main() routine BEGINS HERE *************************************************************************** // FUNCTION NAME: Main() // ARGUMENTS: // a) Input: int argc, char *argv[] // b) Output: entryaddr // STEPS: // The following steps outline the procedure for Main(): // i) Read command line arguments // ii) Enter appropriate ‘if’ loop depending on COFF format // specified // iii) Get COFF file header // iv) Get COFF section header // v) Print content of each section by calling Download() *************************************************************************** int main (int argc, char *argv[]) { char *targetfile; char sectionname[9] = ""; long entryaddr = 0; long tempentry; FILE* infile; long sectlen = 0; long remaining = 0; double headersize; unsigned char *file2struct_ptr; struct fheader fileheader; struct sheader1 sectheader1; struct sheader2 sectheader2; struct buffer inbuff; long currentloc = 0; int i, value; char ofname[256], line[2]; FILE *ofp; if (argc > 2) { /* Check if number of items (entries) on the command line */ /* are greater than 2 */ if (0 == strcmp(argv[1], "-out")) /* if the second entry on the command line is "-out" */ { out = 1; /* variable out = true */ targetfile = argv[2]; /* 'targetfile' points to the third entry on command line, which */ /* is the input to the "coff_new" routine; in this case, it is */ Extracting Equivalent Hex Values From a COFF File 7 Application Report SPRA573 /* the executable generated by TI tools as a .out file */ } else { printf("usage: coff [-out] <coff_image>\n"); exit(1); /* if "-out" condition not satisfied, then print error in usage message */ } } else if (argc > 1) /* if number of entries on command line are greater */ /* than 1 */ { targetfile = argv[1]; /* make 'targetfile' point to the second entry on command line */ } else { printf("usage: coff [-out] <coff_image>\n"); /* else print error in usage message * / exit(1); } if (out) /* if second entry on command line = "-out" */ { sprintf(ofname, "%s.c", targetfile); /* prints out the filename pointed to by targetfile into a */ /* string "ofname" */ if (NULL == (ofp = fopen(ofname, "w"))) /* file pointer "ofp" is assigned a pointer to the file "ofname". */ /* If "ofname" doesn't exist then, print error message below */ { printf("cannot open file %s. errno = %d\n", ofname, errno); return; } } printf("Which type of COFF output file format are you using?\n"); printf("\tEnter '2' if using COFF2, enter '1' if using COFF1...followed by 'Enter'\n\n"); fgets(line, sizeof(line), stdin); sscanf(line, "%d", &value); /***** FOR COFF1 FORMAT *****/ if (value==1) { /* Get File header */ file2struct_ptr = (unsigned char *)&fileheader; /* assigns the address of 'fileheader' to file2struct_ptr ; 'fileheader' */ /* is a structure of type 'struct fheader' */ headersize = sizeof(fileheader); /* headersize is assigned the size of structure 'fileheader' */ Extracting Equivalent Hex Values From a COFF File 8 Application Report SPRA573 if ((infile = fopen(targetfile, "rb")) == NULL) { /* if 'targetfile' does not exist then, print error