Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
ihex.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libiberty.h"
#include "safe-ctype.h"

Go to the source code of this file.

Classes

struct  ihex_data_list
struct  ihex_data_struct

Defines

#define CHUNK   16
#define NIBBLE(x)   (hex_value (x))
#define HEX2(buffer)   ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))
#define HEX4(buffer)   ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))
#define ISHEX(x)   (hex_p (x))
#define TOHEX(buf, v)   ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])
#define ihex_close_and_cleanup   _bfd_generic_close_and_cleanup
#define ihex_bfd_free_cached_info   _bfd_generic_bfd_free_cached_info
#define ihex_new_section_hook   _bfd_generic_new_section_hook
#define ihex_get_section_contents_in_window   _bfd_generic_get_section_contents_in_window
#define ihex_get_symtab_upper_bound   bfd_0l
#define ihex_canonicalize_symtab   ((long (*) (bfd *, asymbol **)) bfd_0l)
#define ihex_make_empty_symbol   _bfd_generic_make_empty_symbol
#define ihex_print_symbol   _bfd_nosymbols_print_symbol
#define ihex_get_symbol_info   _bfd_nosymbols_get_symbol_info
#define ihex_bfd_is_target_special_symbol   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
#define ihex_bfd_is_local_label_name   _bfd_nosymbols_bfd_is_local_label_name
#define ihex_get_lineno   _bfd_nosymbols_get_lineno
#define ihex_find_nearest_line   _bfd_nosymbols_find_nearest_line
#define ihex_find_inliner_info   _bfd_nosymbols_find_inliner_info
#define ihex_bfd_make_debug_symbol   _bfd_nosymbols_bfd_make_debug_symbol
#define ihex_read_minisymbols   _bfd_nosymbols_read_minisymbols
#define ihex_minisymbol_to_symbol   _bfd_nosymbols_minisymbol_to_symbol
#define ihex_bfd_get_relocated_section_contents   bfd_generic_get_relocated_section_contents
#define ihex_bfd_relax_section   bfd_generic_relax_section
#define ihex_bfd_gc_sections   bfd_generic_gc_sections
#define ihex_bfd_merge_sections   bfd_generic_merge_sections
#define ihex_bfd_is_group_section   bfd_generic_is_group_section
#define ihex_bfd_discard_group   bfd_generic_discard_group
#define ihex_section_already_linked   _bfd_generic_section_already_linked
#define ihex_bfd_link_hash_table_create   _bfd_generic_link_hash_table_create
#define ihex_bfd_link_hash_table_free   _bfd_generic_link_hash_table_free
#define ihex_bfd_link_add_symbols   _bfd_generic_link_add_symbols
#define ihex_bfd_link_just_syms   _bfd_generic_link_just_syms
#define ihex_bfd_final_link   _bfd_generic_final_link
#define ihex_bfd_link_split_section   _bfd_generic_link_split_section

Functions

static void ihex_init (void)
static bfd_boolean ihex_mkobject (bfd *abfd)
static INLINE int ihex_get_byte (bfd *abfd, bfd_boolean *errorptr)
static void ihex_bad_byte (bfd *abfd, unsigned int lineno, int c, bfd_boolean error)
static bfd_boolean ihex_scan (bfd *abfd)
static const bfd_targetihex_object_p (bfd *abfd)
static bfd_boolean ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
static bfd_boolean ihex_get_section_contents (bfd *abfd, asection *section, void *location, file_ptr offset, bfd_size_type count)
static bfd_boolean ihex_set_section_contents (bfd *abfd, asection *section, const void *location, file_ptr offset, bfd_size_type count)
static bfd_boolean ihex_write_record (bfd *abfd, size_t count, unsigned int addr, unsigned int type, bfd_byte *data)
static bfd_boolean ihex_write_object_contents (bfd *abfd)
static bfd_boolean ihex_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach)
static int ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED)

Variables

const bfd_target ihex_vec

Class Documentation

struct ihex_data_list

Definition at line 141 of file ihex.c.

Collaboration diagram for ihex_data_list:
Class Members
bfd_byte * data
struct ihex_data_list * next
bfd_size_type size
bfd_vma where
struct ihex_data_struct

Definition at line 151 of file ihex.c.

Collaboration diagram for ihex_data_struct:
Class Members
struct ihex_data_list * head
struct ihex_data_list * tail

Define Documentation

#define CHUNK   16

Definition at line 129 of file ihex.c.

#define HEX2 (   buffer)    ((NIBBLE ((buffer)[0]) << 4) + NIBBLE ((buffer)[1]))

Definition at line 134 of file ihex.c.

#define HEX4 (   buffer)    ((HEX2 (buffer) << 8) + HEX2 ((buffer) + 2))

Definition at line 135 of file ihex.c.

Definition at line 932 of file ihex.c.

Definition at line 938 of file ihex.c.

Definition at line 911 of file ihex.c.

Definition at line 929 of file ihex.c.

Definition at line 927 of file ihex.c.

Definition at line 931 of file ihex.c.

Definition at line 920 of file ihex.c.

Definition at line 919 of file ihex.c.

Definition at line 936 of file ihex.c.

Definition at line 934 of file ihex.c.

Definition at line 935 of file ihex.c.

Definition at line 937 of file ihex.c.

Definition at line 939 of file ihex.c.

Definition at line 924 of file ihex.c.

Definition at line 930 of file ihex.c.

Definition at line 928 of file ihex.c.

#define ihex_canonicalize_symtab   ((long (*) (bfd *, asymbol **)) bfd_0l)

Definition at line 915 of file ihex.c.

Definition at line 910 of file ihex.c.

Definition at line 923 of file ihex.c.

Definition at line 922 of file ihex.c.

Definition at line 921 of file ihex.c.

Definition at line 913 of file ihex.c.

Definition at line 918 of file ihex.c.

Definition at line 914 of file ihex.c.

Definition at line 916 of file ihex.c.

Definition at line 926 of file ihex.c.

Definition at line 912 of file ihex.c.

Definition at line 917 of file ihex.c.

Definition at line 925 of file ihex.c.

Definition at line 933 of file ihex.c.

#define ISHEX (   x)    (hex_p (x))

Definition at line 136 of file ihex.c.

#define NIBBLE (   x)    (hex_value (x))

Definition at line 133 of file ihex.c.

#define TOHEX (   buf,
  v 
)    ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])

Function Documentation

static void ihex_bad_byte ( bfd abfd,
unsigned int  lineno,
int  c,
bfd_boolean  error 
) [static]

Definition at line 209 of file ihex.c.

{
  if (c == EOF)
    {
      if (! error)
       bfd_set_error (bfd_error_file_truncated);
    }
  else
    {
      char buf[10];

      if (! ISPRINT (c))
       sprintf (buf, "\\%03o", (unsigned int) c);
      else
       {
         buf[0] = c;
         buf[1] = '\0';
       }
      (*_bfd_error_handler)
       (_("%B:%d: unexpected character `%s' in Intel Hex file"),
        abfd, lineno, buf);
      bfd_set_error (bfd_error_bad_value);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static INLINE int ihex_get_byte ( bfd abfd,
bfd_boolean errorptr 
) [static]

Definition at line 192 of file ihex.c.

{
  bfd_byte c;

  if (bfd_bread (&c, (bfd_size_type) 1, abfd) != 1)
    {
      if (bfd_get_error () != bfd_error_file_truncated)
       *errorptr = TRUE;
      return EOF;
    }

  return (int) (c & 0xff);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean ihex_get_section_contents ( bfd abfd,
asection section,
void *  location,
file_ptr  offset,
bfd_size_type  count 
) [static]

Definition at line 630 of file ihex.c.

{
  if (section->used_by_bfd == NULL)
    {
      section->used_by_bfd = bfd_alloc (abfd, section->size);
      if (section->used_by_bfd == NULL)
       return FALSE;
      if (! ihex_read_section (abfd, section, section->used_by_bfd))
       return FALSE;
    }

  memcpy (location, (bfd_byte *) section->used_by_bfd + offset,
         (size_t) count);

  return TRUE;
}

Here is the call graph for this function:

static void ihex_init ( void  ) [static]

Definition at line 160 of file ihex.c.

{
  static bfd_boolean inited;

  if (! inited)
    {
      inited = TRUE;
      hex_init ();
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean ihex_mkobject ( bfd abfd) [static]

Definition at line 174 of file ihex.c.

{
  struct ihex_data_struct *tdata;

  tdata = bfd_alloc (abfd, sizeof (* tdata));
  if (tdata == NULL)
    return FALSE;

  abfd->tdata.ihex_data = tdata;
  tdata->head = NULL;
  tdata->tail = NULL;
  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const bfd_target* ihex_object_p ( bfd abfd) [static]

Definition at line 483 of file ihex.c.

{
  void * tdata_save;
  bfd_byte b[9];
  unsigned int i;
  unsigned int type;

  ihex_init ();

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    return NULL;
  if (bfd_bread (b, (bfd_size_type) 9, abfd) != 9)
    {
      if (bfd_get_error () == bfd_error_file_truncated)
       bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  if (b[0] != ':')
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  for (i = 1; i < 9; i++)
    {
      if (! ISHEX (b[i]))
       {
         bfd_set_error (bfd_error_wrong_format);
         return NULL;
       }
    }

  type = HEX2 (b + 7);
  if (type > 5)
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  /* OK, it looks like it really is an Intel Hex file.  */
  tdata_save = abfd->tdata.any;
  if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
    {
      if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
       bfd_release (abfd, abfd->tdata.any);
      abfd->tdata.any = tdata_save;
      return NULL;
    }

  return abfd->xvec;
}

Here is the call graph for this function:

static bfd_boolean ihex_read_section ( bfd abfd,
asection section,
bfd_byte contents 
) [static]

Definition at line 539 of file ihex.c.

{
  int c;
  bfd_byte *p;
  bfd_byte *buf = NULL;
  size_t bufsize;
  bfd_boolean error;

  if (bfd_seek (abfd, section->filepos, SEEK_SET) != 0)
    goto error_return;

  p = contents;
  bufsize = 0;
  error = FALSE;
  while ((c = ihex_get_byte (abfd, &error)) != EOF)
    {
      char hdr[8];
      unsigned int len;
      unsigned int type;
      unsigned int i;

      if (c == '\r' || c == '\n')
       continue;

      /* This is called after ihex_scan has succeeded, so we ought to
         know the exact format.  */
      BFD_ASSERT (c == ':');

      if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
       goto error_return;

      len = HEX2 (hdr);
      type = HEX2 (hdr + 6);

      /* We should only see type 0 records here.  */
      if (type != 0)
       {
         (*_bfd_error_handler)
           (_("%B: internal error in ihex_read_section"), abfd);
         bfd_set_error (bfd_error_bad_value);
         goto error_return;
       }

      if (len * 2 > bufsize)
       {
         buf = bfd_realloc (buf, (bfd_size_type) len * 2);
         if (buf == NULL)
           goto error_return;
         bufsize = len * 2;
       }

      if (bfd_bread (buf, (bfd_size_type) len * 2, abfd) != len * 2)
       goto error_return;

      for (i = 0; i < len; i++)
       *p++ = HEX2 (buf + 2 * i);
      if ((bfd_size_type) (p - contents) >= section->size)
       {
         /* We've read everything in the section.  */
         if (buf != NULL)
           free (buf);
         return TRUE;
       }

      /* Skip the checksum.  */
      if (bfd_bread (buf, (bfd_size_type) 2, abfd) != 2)
       goto error_return;
    }

  if ((bfd_size_type) (p - contents) < section->size)
    {
      (*_bfd_error_handler)
       (_("%B: bad section length in ihex_read_section"), abfd);
      bfd_set_error (bfd_error_bad_value);
      goto error_return;
    }

  if (buf != NULL)
    free (buf);

  return TRUE;

 error_return:
  if (buf != NULL)
    free (buf);
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean ihex_scan ( bfd abfd) [static]

Definition at line 238 of file ihex.c.

{
  bfd_vma segbase;
  bfd_vma extbase;
  asection *sec;
  unsigned int lineno;
  bfd_boolean error;
  bfd_byte *buf = NULL;
  size_t bufsize;
  int c;

  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto error_return;

  abfd->start_address = 0;

  segbase = 0;
  extbase = 0;
  sec = NULL;
  lineno = 1;
  error = FALSE;
  bufsize = 0;

  while ((c = ihex_get_byte (abfd, &error)) != EOF)
    {
      if (c == '\r')
       continue;
      else if (c == '\n')
       {
         ++lineno;
         continue;
       }
      else if (c != ':')
       {
         ihex_bad_byte (abfd, lineno, c, error);
         goto error_return;
       }
      else
       {
         file_ptr pos;
         char hdr[8];
         unsigned int i;
         unsigned int len;
         bfd_vma addr;
         unsigned int type;
         unsigned int chars;
         unsigned int chksum;

         /* This is a data record.  */
         pos = bfd_tell (abfd) - 1;

         /* Read the header bytes.  */
         if (bfd_bread (hdr, (bfd_size_type) 8, abfd) != 8)
           goto error_return;

         for (i = 0; i < 8; i++)
           {
             if (! ISHEX (hdr[i]))
              {
                ihex_bad_byte (abfd, lineno, hdr[i], error);
                goto error_return;
              }
           }

         len = HEX2 (hdr);
         addr = HEX4 (hdr + 2);
         type = HEX2 (hdr + 6);

         /* Read the data bytes.  */
         chars = len * 2 + 2;
         if (chars >= bufsize)
           {
             buf = bfd_realloc (buf, (bfd_size_type) chars);
             if (buf == NULL)
              goto error_return;
             bufsize = chars;
           }

         if (bfd_bread (buf, (bfd_size_type) chars, abfd) != chars)
           goto error_return;

         for (i = 0; i < chars; i++)
           {
             if (! ISHEX (buf[i]))
              {
                ihex_bad_byte (abfd, lineno, hdr[i], error);
                goto error_return;
              }
           }

         /* Check the checksum.  */
         chksum = len + addr + (addr >> 8) + type;
         for (i = 0; i < len; i++)
           chksum += HEX2 (buf + 2 * i);
         if (((- chksum) & 0xff) != (unsigned int) HEX2 (buf + 2 * i))
           {
             (*_bfd_error_handler)
              (_("%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
               abfd, lineno,
               (- chksum) & 0xff, (unsigned int) HEX2 (buf + 2 * i));
             bfd_set_error (bfd_error_bad_value);
             goto error_return;
           }

         switch (type)
           {
           case 0:
             /* This is a data record.  */
             if (sec != NULL
                && sec->vma + sec->size == extbase + segbase + addr)
              {
                /* This data goes at the end of the section we are
                     currently building.  */
                sec->size += len;
              }
             else if (len > 0)
              {
                char secbuf[20];
                char *secname;
                bfd_size_type amt;
                flagword flags;

                sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
                amt = strlen (secbuf) + 1;
                secname = bfd_alloc (abfd, amt);
                if (secname == NULL)
                  goto error_return;
                strcpy (secname, secbuf);
                flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
                sec = bfd_make_section_with_flags (abfd, secname, flags);
                if (sec == NULL)
                  goto error_return;
                sec->vma = extbase + segbase + addr;
                sec->lma = extbase + segbase + addr;
                sec->size = len;
                sec->filepos = pos;
              }
             break;

           case 1:
             /* An end record.  */
             if (abfd->start_address == 0)
              abfd->start_address = addr;
             if (buf != NULL)
              free (buf);
             return TRUE;

           case 2:
             /* An extended address record.  */
             if (len != 2)
              {
                (*_bfd_error_handler)
                  (_("%B:%u: bad extended address record length in Intel Hex file"),
                   abfd, lineno);
                bfd_set_error (bfd_error_bad_value);
                goto error_return;
              }

             segbase = HEX4 (buf) << 4;

             sec = NULL;

             break;

           case 3:
             /* An extended start address record.  */
             if (len != 4)
              {
                (*_bfd_error_handler)
                  (_("%B:%u: bad extended start address length in Intel Hex file"),
                   abfd, lineno);
                bfd_set_error (bfd_error_bad_value);
                goto error_return;
              }

             abfd->start_address += (HEX4 (buf) << 4) + HEX4 (buf + 4);

             sec = NULL;

             break;

           case 4:
             /* An extended linear address record.  */
             if (len != 2)
              {
                (*_bfd_error_handler)
                  (_("%B:%u: bad extended linear address record length in Intel Hex file"),
                   abfd, lineno);
                bfd_set_error (bfd_error_bad_value);
                goto error_return;
              }

             extbase = HEX4 (buf) << 16;

             sec = NULL;

             break;

           case 5:
             /* An extended linear start address record.  */
             if (len != 2 && len != 4)
              {
                (*_bfd_error_handler)
                  (_("%B:%u: bad extended linear start address length in Intel Hex file"),
                   abfd, lineno);
                bfd_set_error (bfd_error_bad_value);
                goto error_return;
              }

             if (len == 2)
              abfd->start_address += HEX4 (buf) << 16;
             else
              abfd->start_address = (HEX4 (buf) << 16) + HEX4 (buf + 4);

             sec = NULL;

             break;

           default:
             (*_bfd_error_handler)
              (_("%B:%u: unrecognized ihex type %u in Intel Hex file"),
               abfd, lineno, type);
             bfd_set_error (bfd_error_bad_value);
             goto error_return;
           }
       }
    }

  if (error)
    goto error_return;

  if (buf != NULL)
    free (buf);

  return TRUE;

 error_return:
  if (buf != NULL)
    free (buf);
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean ihex_set_arch_mach ( bfd abfd,
enum bfd_architecture  arch,
unsigned long  mach 
) [static]

Definition at line 887 of file ihex.c.

{
  if (! bfd_default_set_arch_mach (abfd, arch, mach))
    {
      if (arch != bfd_arch_unknown)
       return FALSE;
    }
  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean ihex_set_section_contents ( bfd abfd,
asection section,
const void *  location,
file_ptr  offset,
bfd_size_type  count 
) [static]

Definition at line 654 of file ihex.c.

{
  struct ihex_data_list *n;
  bfd_byte *data;
  struct ihex_data_struct *tdata;

  if (count == 0
      || (section->flags & SEC_ALLOC) == 0
      || (section->flags & SEC_LOAD) == 0)
    return TRUE;

  n = bfd_alloc (abfd, sizeof (* n));
  if (n == NULL)
    return FALSE;

  data = bfd_alloc (abfd, count);
  if (data == NULL)
    return FALSE;
  memcpy (data, location, (size_t) count);

  n->data = data;
  n->where = section->lma + offset;
  n->size = count;

  /* Sort the records by address.  Optimize for the common case of
     adding a record to the end of the list.  */
  tdata = abfd->tdata.ihex_data;
  if (tdata->tail != NULL
      && n->where >= tdata->tail->where)
    {
      tdata->tail->next = n;
      n->next = NULL;
      tdata->tail = n;
    }
  else
    {
      struct ihex_data_list **pp;

      for (pp = &tdata->head;
          *pp != NULL && (*pp)->where < n->where;
          pp = &(*pp)->next)
       ;
      n->next = *pp;
      *pp = n;
      if (n->next == NULL)
       tdata->tail = n;
    }

  return TRUE;
}

Here is the call graph for this function:

static int ihex_sizeof_headers ( bfd *abfd  ATTRIBUTE_UNUSED,
struct bfd_link_info *info  ATTRIBUTE_UNUSED 
) [static]

Definition at line 902 of file ihex.c.

{
  return 0;
}
static bfd_boolean ihex_write_object_contents ( bfd abfd) [static]

Definition at line 756 of file ihex.c.

{
  bfd_vma segbase;
  bfd_vma extbase;
  struct ihex_data_list *l;

  segbase = 0;
  extbase = 0;
  for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next)
    {
      bfd_vma where;
      bfd_byte *p;
      bfd_size_type count;

      where = l->where;
      p = l->data;
      count = l->size;

      while (count > 0)
       {
         size_t now;
         unsigned int rec_addr;

         now = count;
         if (count > CHUNK)
           now = CHUNK;

         if (where > segbase + extbase + 0xffff)
           {
             bfd_byte addr[2];

             /* We need a new base address.  */
             if (where <= 0xfffff)
              {
                /* The addresses should be sorted.  */
                BFD_ASSERT (extbase == 0);

                segbase = where & 0xf0000;
                addr[0] = (bfd_byte)(segbase >> 12) & 0xff;
                addr[1] = (bfd_byte)(segbase >> 4) & 0xff;
                if (! ihex_write_record (abfd, 2, 0, 2, addr))
                  return FALSE;
              }
             else
              {
                /* The extended address record and the extended
                     linear address record are combined, at least by
                     some readers.  We need an extended linear address
                     record here, so if we've already written out an
                     extended address record, zero it out to avoid
                     confusion.  */
                if (segbase != 0)
                  {
                    addr[0] = 0;
                    addr[1] = 0;
                    if (! ihex_write_record (abfd, 2, 0, 2, addr))
                     return FALSE;
                    segbase = 0;
                  }

                extbase = where & 0xffff0000;
                if (where > extbase + 0xffff)
                  {
                    char buf[20];

                    sprintf_vma (buf, where);
                    (*_bfd_error_handler)
                     (_("%s: address 0x%s out of range for Intel Hex file"),
                      bfd_get_filename (abfd), buf);
                    bfd_set_error (bfd_error_bad_value);
                    return FALSE;
                  }
                addr[0] = (bfd_byte)(extbase >> 24) & 0xff;
                addr[1] = (bfd_byte)(extbase >> 16) & 0xff;
                if (! ihex_write_record (abfd, 2, 0, 4, addr))
                  return FALSE;
              }
           }

         rec_addr = where - (extbase + segbase);

          /* Output records shouldn't cross 64K boundaries.  */
          if (rec_addr + now > 0xffff)
            now = 0x10000 - rec_addr;

         if (! ihex_write_record (abfd, now, rec_addr, 0, p))
           return FALSE;

         where += now;
         p += now;
         count -= now;
       }
    }

  if (abfd->start_address != 0)
    {
      bfd_vma start;
      bfd_byte startbuf[4];

      start = abfd->start_address;

      if (start <= 0xfffff)
       {
         startbuf[0] = (bfd_byte)((start & 0xf0000) >> 12) & 0xff;
         startbuf[1] = 0;
         startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
         startbuf[3] = (bfd_byte)start & 0xff;
         if (! ihex_write_record (abfd, 4, 0, 3, startbuf))
           return FALSE;
       }
      else
       {
         startbuf[0] = (bfd_byte)(start >> 24) & 0xff;
         startbuf[1] = (bfd_byte)(start >> 16) & 0xff;
         startbuf[2] = (bfd_byte)(start >> 8) & 0xff;
         startbuf[3] = (bfd_byte)start & 0xff;
         if (! ihex_write_record (abfd, 4, 0, 5, startbuf))
           return FALSE;
       }
    }

  if (! ihex_write_record (abfd, 0, 0, 1, NULL))
    return FALSE;

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean ihex_write_record ( bfd abfd,
size_t  count,
unsigned int  addr,
unsigned int  type,
bfd_byte data 
) [static]

Definition at line 712 of file ihex.c.

{
  static const char digs[] = "0123456789ABCDEF";
  char buf[9 + CHUNK * 2 + 4];
  char *p;
  unsigned int chksum;
  unsigned int i;
  size_t total;

#define TOHEX(buf, v) \
  ((buf)[0] = digs[((v) >> 4) & 0xf], (buf)[1] = digs[(v) & 0xf])

  buf[0] = ':';
  TOHEX (buf + 1, count);
  TOHEX (buf + 3, (addr >> 8) & 0xff);
  TOHEX (buf + 5, addr & 0xff);
  TOHEX (buf + 7, type);

  chksum = count + addr + (addr >> 8) + type;

  for (i = 0, p = buf + 9; i < count; i++, p += 2, data++)
    {
      TOHEX (p, *data);
      chksum += *data;
    }

  TOHEX (p, (- chksum) & 0xff);
  p[2] = '\r';
  p[3] = '\n';

  total = 9 + count * 2 + 4;
  if (bfd_bwrite (buf, (bfd_size_type) total, abfd) != total)
    return FALSE;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 943 of file ihex.c.