diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gdb/astest.c | 103 | ||||
-rw-r--r-- | tools/img2srec.c | 413 |
2 files changed, 516 insertions, 0 deletions
diff --git a/tools/gdb/astest.c b/tools/gdb/astest.c new file mode 100644 index 0000000000..8c8ed2819a --- /dev/null +++ b/tools/gdb/astest.c @@ -0,0 +1,103 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <bfd.h> +#include "error.h" + +int verbose = 0; + +void +process_section(bfd *abfd, asection *sect, PTR obj) +{ + printf("Section '%s':\n", sect->name); + + printf("\tindex=%d, flags=%x\n", sect->index, sect->flags); + +#if 0 + printf("\tuser_set_vma=%u, reloc_done=%u, linker_mark=%u, gc_mark=%u\n", + (unsigned long)sect->user_set_vma, (unsigned long)sect->reloc_done, + (unsigned long)sect->linker_mark, (unsigned long)sect->gc_mark); +#else + printf("\tuser_set_vma=%u, reloc_done=%u\n", + (unsigned int)sect->user_set_vma, (unsigned int)sect->reloc_done); +#endif + + printf("\tvma=%08lx, lma=%08lx\n", + (unsigned long)sect->vma, (unsigned long)sect->lma); + + printf("\tcooked_size=%ld, raw_size=%ld, output_offset=%ld\n", + (long)sect->_cooked_size, (long)sect->_raw_size, + (long)sect->output_offset); + + printf("\talignment_power=%d, reloc_count=%d, filepos=%ld\n", + sect->alignment_power, sect->reloc_count, sect->filepos); + + printf("\trel_filepos=%ld, line_filepos=%ld, lineno_count=%d\n", + sect->rel_filepos, sect->line_filepos, sect->lineno_count); + + printf("\tmoving_line_filepos=%ld, target_index=%d\n", + sect->moving_line_filepos, sect->target_index); +} + +int +main(int ac, char **av) +{ + int c, ifd; + char *ifn; + bfd *bfdp; + + if ((pname = strrchr(av[0], '/')) == NULL) + pname = av[0]; + else + pname++; + + while ((c = getopt(ac, av, "v")) != EOF) + switch (c) { + + case 'v': + verbose = 1; + break; + + default: + usage: + fprintf(stderr, "Usage: %s [-v] imagefile\n", pname); + exit(1); + } + if (optind != ac - 1) + goto usage; + + ifn = av[optind]; + + if (verbose) + fprintf(stderr, "Opening file...\n"); + + if ((ifd = open(ifn, O_RDONLY)) < 0) + Perror("can't open image file '%s'", ifn); + + if ((bfdp = bfd_fdopenr(ifn, "elf32-powerpc", ifd)) == NULL) { + bfd_perror(ifn); + close(ifd); + Error("bfd_fdopenr of file '%s' failed", ifn); + } + bfdp->cacheable = true; + + if (!bfd_check_format(bfdp, bfd_object) || + (bfd_get_file_flags(bfdp) & EXEC_P) == 0) { + bfd_close(bfdp); + Error("file '%s' is not an executable object file (%s,0x%x)", ifn, + bfd_format_string(bfd_get_format(bfdp)), bfd_get_file_flags(bfdp)); + } + + printf("file '%s' is type '%s'...\n", ifn, bfd_get_target(bfdp)); + + bfd_map_over_sections(bfdp, process_section, NULL);; + + bfd_close(bfdp); + + if (verbose) + fprintf(stderr, "Done.\n"); + + return (0); +} diff --git a/tools/img2srec.c b/tools/img2srec.c new file mode 100644 index 0000000000..330ae02ecf --- /dev/null +++ b/tools/img2srec.c @@ -0,0 +1,413 @@ +/************************************************************************* +| COPYRIGHT (c) 2000 BY ABATRON AG +|************************************************************************* +| +| PROJECT NAME: Linux Image to S-record Conversion Utility +| FILENAME : img2srec.c +| +| COMPILER : GCC +| +| TARGET OS : LINUX / UNIX +| TARGET HW : - +| +| PROGRAMMER : Abatron / RD +| CREATION : 07.07.00 +| +|************************************************************************* +| +| DESCRIPTION : +| +| Utility to convert a Linux Boot Image to S-record: +| ================================================== +| +| This command line utility can be used to convert a Linux boot image +| (zimage.initrd) to S-Record format used for flash programming. +| This conversion takes care of the special sections "IMAGE" and INITRD". +| +| img2srec [-o offset] image > image.srec +| +| +| Build the utility: +| ================== +| +| To build the utility use GCC as follows: +| +| gcc img2srec.c -o img2srec +| +| +|************************************************************************* +| +| +| UPDATES : +| +| DATE NAME CHANGES +| ----------------------------------------------------------- +| Latest update +| +| 07.07.00 aba Initial release +| +|*************************************************************************/ + +/************************************************************************* +| INCLUDES +|*************************************************************************/ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <elf.h> +#include <unistd.h> +#include <errno.h> + +extern int errno; + +/************************************************************************* +| DEFINES +|*************************************************************************/ + +#define FALSE 0 +#define TRUE 1 + +/************************************************************************* +| MACROS +|*************************************************************************/ + +/************************************************************************* +| TYPEDEFS +|*************************************************************************/ + +typedef uint8_t CHAR; +typedef uint8_t BYTE; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef int BOOL; + +/************************************************************************* +| LOCALS +|*************************************************************************/ + +/************************************************************************* +| PROTOTYPES +|*************************************************************************/ + +static char *ExtractHex(DWORD *value, char *getPtr); +static char *ExtractDecimal(DWORD *value, char *getPtr); +static void ExtractNumber(DWORD *value, char *getPtr); +static BYTE *ExtractWord(WORD *value, BYTE *buffer); +static BYTE *ExtractLong(DWORD *value, BYTE *buffer); +static BYTE *ExtractBlock(WORD count, BYTE *data, BYTE *buffer); +static char *WriteHex(char *pa, BYTE value, WORD *pCheckSum); +static char *BuildSRecord(char *pa, WORD sType, DWORD addr, + const BYTE *data, int nCount); +static void ConvertELF(char *fileName, DWORD loadOffset); +int main(int argc, char *argv[]); + +/************************************************************************* +| FUNCTIONS +|*************************************************************************/ + +static char* ExtractHex (DWORD* value, char* getPtr) +{ + DWORD num; + DWORD digit; + BYTE c; + + while (*getPtr == ' ') getPtr++; + num = 0; + for (;;) { + c = *getPtr; + if ((c >= '0') && (c <= '9')) digit = (DWORD)(c - '0'); + else if ((c >= 'A') && (c <= 'F')) digit = (DWORD)(c - 'A' + 10); + else if ((c >= 'a') && (c <= 'f')) digit = (DWORD)(c - 'a' + 10); + else break; + num <<= 4; + num += digit; + getPtr++; + } /* for */ + *value = num; + return getPtr; +} /* ExtractHex */ + +static char* ExtractDecimal (DWORD* value, char* getPtr) +{ + DWORD num; + DWORD digit; + BYTE c; + + while (*getPtr == ' ') getPtr++; + num = 0; + for (;;) { + c = *getPtr; + if ((c >= '0') && (c <= '9')) digit = (DWORD)(c - '0'); + else break; + num *= 10; + num += digit; + getPtr++; + } /* for */ + *value = num; + return getPtr; +} /* ExtractDecimal */ + + +static void ExtractNumber (DWORD* value, char* getPtr) +{ + BOOL neg = FALSE;; + + while (*getPtr == ' ') getPtr++; + if (*getPtr == '-') { + neg = TRUE; + getPtr++; + } /* if */ + if ((*getPtr == '0') && ((*(getPtr+1) == 'x') || (*(getPtr+1) == 'X'))) { + getPtr +=2; + (void)ExtractHex(value, getPtr); + } /* if */ + else { + (void)ExtractDecimal(value, getPtr); + } /* else */ + if (neg) *value = -(*value); +} /* ExtractNumber */ + + +static BYTE* ExtractWord(WORD* value, BYTE* buffer) +{ + WORD x; + x = (WORD)*buffer++; + x = (x<<8) + (WORD)*buffer++; + *value = x; + return buffer; +} /* ExtractWord */ + + +static BYTE* ExtractLong(DWORD* value, BYTE* buffer) +{ + DWORD x; + x = (DWORD)*buffer++; + x = (x<<8) + (DWORD)*buffer++; + x = (x<<8) + (DWORD)*buffer++; + x = (x<<8) + (DWORD)*buffer++; + *value = x; + return buffer; +} /* ExtractLong */ + + +static BYTE* ExtractBlock(WORD count, BYTE* data, BYTE* buffer) +{ + while (count--) *data++ = *buffer++; + return buffer; +} /* ExtractBlock */ + + +static char* WriteHex(char* pa, BYTE value, WORD* pCheckSum) +{ + WORD temp; + + static char ByteToHex[] = "0123456789ABCDEF"; + + *pCheckSum += value; + temp = value / 16; + *pa++ = ByteToHex[temp]; + temp = value % 16; + *pa++ = ByteToHex[temp]; + return pa; +} + + +static char* BuildSRecord(char* pa, WORD sType, DWORD addr, + const BYTE* data, int nCount) +{ + WORD addrLen; + WORD sRLen; + WORD checkSum; + WORD i; + + switch (sType) { + case 0: + case 1: + case 9: + addrLen = 2; + break; + case 2: + case 8: + addrLen = 3; + break; + case 3: + case 7: + addrLen = 4; + break; + default: + return pa; + } /* switch */ + + *pa++ = 'S'; + *pa++ = (char)(sType + '0'); + sRLen = addrLen + nCount + 1; + checkSum = 0; + pa = WriteHex(pa, (BYTE)sRLen, &checkSum); + + /* Write address field */ + for (i = 1; i <= addrLen; i++) { + pa = WriteHex(pa, (BYTE)(addr >> (8 * (addrLen - i))), &checkSum); + } /* for */ + + /* Write code/data fields */ + for (i = 0; i < nCount; i++) { + pa = WriteHex(pa, *data++, &checkSum); + } /* for */ + + /* Write checksum field */ + checkSum = ~checkSum; + pa = WriteHex(pa, (BYTE)checkSum, &checkSum); + *pa++ = '\0'; + return pa; +} + + +static void ConvertELF(char* fileName, DWORD loadOffset) +{ + FILE* file; + int i; + int rxCount; + BYTE rxBlock[1024]; + DWORD loadSize; + DWORD firstAddr; + DWORD loadAddr; + DWORD loadDiff = 0; + Elf32_Ehdr elfHeader; + Elf32_Shdr sectHeader[32]; + BYTE* getPtr; + char srecLine[128]; + char *hdr_name; + + + /* open file */ + if ((file = fopen(fileName,"rb")) == NULL) { + fprintf (stderr, "Can't open %s: %s\n", fileName, strerror(errno)); + return; + } /* if */ + + /* read ELF header */ + rxCount = fread(rxBlock, 1, sizeof elfHeader, file); + getPtr = ExtractBlock(sizeof elfHeader.e_ident, elfHeader.e_ident, rxBlock); + getPtr = ExtractWord(&elfHeader.e_type, getPtr); + getPtr = ExtractWord(&elfHeader.e_machine, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_version, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_entry, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_phoff, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_shoff, getPtr); + getPtr = ExtractLong((DWORD *)&elfHeader.e_flags, getPtr); + getPtr = ExtractWord(&elfHeader.e_ehsize, getPtr); + getPtr = ExtractWord(&elfHeader.e_phentsize, getPtr); + getPtr = ExtractWord(&elfHeader.e_phnum, getPtr); + getPtr = ExtractWord(&elfHeader.e_shentsize, getPtr); + getPtr = ExtractWord(&elfHeader.e_shnum, getPtr); + getPtr = ExtractWord(&elfHeader.e_shstrndx, getPtr); + if ( (rxCount != sizeof elfHeader) + || (elfHeader.e_ident[0] != ELFMAG0) + || (elfHeader.e_ident[1] != ELFMAG1) + || (elfHeader.e_ident[2] != ELFMAG2) + || (elfHeader.e_ident[3] != ELFMAG3) + || (elfHeader.e_type != ET_EXEC) + ) { + fclose(file); + fprintf (stderr, "*** illegal file format\n"); + return; + } /* if */ + + /* read all section headers */ + fseek(file, elfHeader.e_shoff, SEEK_SET); + for (i = 0; i < elfHeader.e_shnum; i++) { + rxCount = fread(rxBlock, 1, sizeof sectHeader[0], file); + getPtr = ExtractLong((DWORD *)§Header[i].sh_name, rxBlock); + getPtr = ExtractLong((DWORD *)§Header[i].sh_type, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_flags, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_addr, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_offset, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_size, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_link, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_info, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_addralign, getPtr); + getPtr = ExtractLong((DWORD *)§Header[i].sh_entsize, getPtr); + if (rxCount != sizeof sectHeader[0]) { + fclose(file); + fprintf (stderr, "*** illegal file format\n"); + return; + } /* if */ + } /* for */ + + if ((hdr_name = strrchr(fileName, '/')) == NULL) { + hdr_name = fileName; + } else { + ++hdr_name; + } + /* write start record */ + (void)BuildSRecord(srecLine, 0, 0, (BYTE *)hdr_name, strlen(hdr_name)); + printf("%s\r\n",srecLine); + + /* write data records */ + firstAddr = ~0; + loadAddr = 0; + for (i = 0; i < elfHeader.e_shnum; i++) { + if ( (sectHeader[i].sh_type == SHT_PROGBITS) + && (sectHeader[i].sh_size != 0) + ) { + loadSize = sectHeader[i].sh_size; + if (sectHeader[i].sh_flags != 0) { + loadAddr = sectHeader[i].sh_addr; + loadDiff = loadAddr - sectHeader[i].sh_offset; + } /* if */ + else { + loadAddr = sectHeader[i].sh_offset + loadDiff; + } /* else */ + + if (loadAddr < firstAddr) + firstAddr = loadAddr; + + /* build s-records */ + loadSize = sectHeader[i].sh_size; + fseek(file, sectHeader[i].sh_offset, SEEK_SET); + while (loadSize) { + rxCount = fread(rxBlock, 1, (loadSize > 32) ? 32 : loadSize, file); + if (rxCount < 0) { + fclose(file); + fprintf (stderr, "*** illegal file format\n"); + return; + } /* if */ + (void)BuildSRecord(srecLine, 3, loadAddr + loadOffset, rxBlock, rxCount); + loadSize -= rxCount; + loadAddr += rxCount; + printf("%s\r\n",srecLine); + } /* while */ + } /* if */ + } /* for */ + + /* add end record */ + (void)BuildSRecord(srecLine, 7, firstAddr + loadOffset, 0, 0); + printf("%s\r\n",srecLine); + fclose(file); +} /* ConvertELF */ + + +/************************************************************************* +| MAIN +|*************************************************************************/ + +int main( int argc, char *argv[ ]) +{ + DWORD offset; + + if (argc == 2) { + ConvertELF(argv[1], 0); + } /* if */ + else if ((argc == 4) && (strcmp(argv[1], "-o") == 0)) { + ExtractNumber(&offset, argv[2]); + ConvertELF(argv[3], offset); + } /* if */ + else { + fprintf (stderr, "Usage: img2srec [-o offset] <image>\n"); + } /* if */ + + return 0; +} /* main */ |