diff options
| -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 000000000..8c8ed2819 --- /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 000000000..330ae02ec --- /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 */ |