OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [libiberty/] [simple-object.c] - Diff between revs 736 and 783

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 736 Rev 783
/* simple-object.c -- simple routines to read and write object files.
/* simple-object.c -- simple routines to read and write object files.
   Copyright 2010 Free Software Foundation, Inc.
   Copyright 2010 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Google.
   Written by Ian Lance Taylor, Google.
 
 
This program is free software; you can redistribute it and/or modify it
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
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
Free Software Foundation; either version 2, or (at your option) any
later version.
later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, 51 Franklin Street - Fifth Floor,
Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.  */
Boston, MA 02110-1301, USA.  */
 
 
#include "config.h"
#include "config.h"
#include "libiberty.h"
#include "libiberty.h"
#include "simple-object.h"
#include "simple-object.h"
 
 
#include <errno.h>
#include <errno.h>
 
 
#ifdef HAVE_STDLIB_H
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include <stdlib.h>
#endif
#endif
 
 
#ifdef HAVE_STDINT_H
#ifdef HAVE_STDINT_H
#include <stdint.h>
#include <stdint.h>
#endif
#endif
 
 
#ifdef HAVE_STRING_H
#ifdef HAVE_STRING_H
#include <string.h>
#include <string.h>
#endif
#endif
 
 
#ifdef HAVE_INTTYPES_H
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#include <inttypes.h>
#endif
#endif
 
 
#ifndef SEEK_SET
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_SET 0
#endif
#endif
 
 
#include "simple-object-common.h"
#include "simple-object-common.h"
 
 
/* The known object file formats.  */
/* The known object file formats.  */
 
 
static const struct simple_object_functions * const format_functions[] =
static const struct simple_object_functions * const format_functions[] =
{
{
  &simple_object_elf_functions,
  &simple_object_elf_functions,
  &simple_object_mach_o_functions,
  &simple_object_mach_o_functions,
  &simple_object_coff_functions
  &simple_object_coff_functions
};
};
 
 
/* Read data from a file using the simple_object error reporting
/* Read data from a file using the simple_object error reporting
   conventions.  */
   conventions.  */
 
 
int
int
simple_object_internal_read (int descriptor, off_t offset,
simple_object_internal_read (int descriptor, off_t offset,
                             unsigned char *buffer, size_t size,
                             unsigned char *buffer, size_t size,
                             const char **errmsg, int *err)
                             const char **errmsg, int *err)
{
{
  ssize_t got;
  ssize_t got;
 
 
  if (lseek (descriptor, offset, SEEK_SET) < 0)
  if (lseek (descriptor, offset, SEEK_SET) < 0)
    {
    {
      *errmsg = "lseek";
      *errmsg = "lseek";
      *err = errno;
      *err = errno;
      return 0;
      return 0;
    }
    }
 
 
  got = read (descriptor, buffer, size);
  got = read (descriptor, buffer, size);
  if (got < 0)
  if (got < 0)
    {
    {
      *errmsg = "read";
      *errmsg = "read";
      *err = errno;
      *err = errno;
      return 0;
      return 0;
    }
    }
 
 
  if ((size_t) got < size)
  if ((size_t) got < size)
    {
    {
      *errmsg = "file too short";
      *errmsg = "file too short";
      *err = 0;
      *err = 0;
      return 0;
      return 0;
    }
    }
 
 
  return 1;
  return 1;
}
}
 
 
/* Write data to a file using the simple_object error reporting
/* Write data to a file using the simple_object error reporting
   conventions.  */
   conventions.  */
 
 
int
int
simple_object_internal_write (int descriptor, off_t offset,
simple_object_internal_write (int descriptor, off_t offset,
                              const unsigned char *buffer, size_t size,
                              const unsigned char *buffer, size_t size,
                              const char **errmsg, int *err)
                              const char **errmsg, int *err)
{
{
  ssize_t wrote;
  ssize_t wrote;
 
 
  if (lseek (descriptor, offset, SEEK_SET) < 0)
  if (lseek (descriptor, offset, SEEK_SET) < 0)
    {
    {
      *errmsg = "lseek";
      *errmsg = "lseek";
      *err = errno;
      *err = errno;
      return 0;
      return 0;
    }
    }
 
 
  wrote = write (descriptor, buffer, size);
  wrote = write (descriptor, buffer, size);
  if (wrote < 0)
  if (wrote < 0)
    {
    {
      *errmsg = "write";
      *errmsg = "write";
      *err = errno;
      *err = errno;
      return 0;
      return 0;
    }
    }
 
 
  if ((size_t) wrote < size)
  if ((size_t) wrote < size)
    {
    {
      *errmsg = "short write";
      *errmsg = "short write";
      *err = 0;
      *err = 0;
      return 0;
      return 0;
    }
    }
 
 
  return 1;
  return 1;
}
}
 
 
/* Open for read.  */
/* Open for read.  */
 
 
simple_object_read *
simple_object_read *
simple_object_start_read (int descriptor, off_t offset,
simple_object_start_read (int descriptor, off_t offset,
                          const char *segment_name, const char **errmsg,
                          const char *segment_name, const char **errmsg,
                          int *err)
                          int *err)
{
{
  unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
  unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
  size_t len, i;
  size_t len, i;
 
 
  if (!simple_object_internal_read (descriptor, offset, header,
  if (!simple_object_internal_read (descriptor, offset, header,
                                    SIMPLE_OBJECT_MATCH_HEADER_LEN,
                                    SIMPLE_OBJECT_MATCH_HEADER_LEN,
                                    errmsg, err))
                                    errmsg, err))
    return NULL;
    return NULL;
 
 
  len = sizeof (format_functions) / sizeof (format_functions[0]);
  len = sizeof (format_functions) / sizeof (format_functions[0]);
  for (i = 0; i < len; ++i)
  for (i = 0; i < len; ++i)
    {
    {
      void *data;
      void *data;
 
 
      data = format_functions[i]->match (header, descriptor, offset,
      data = format_functions[i]->match (header, descriptor, offset,
                                         segment_name, errmsg, err);
                                         segment_name, errmsg, err);
      if (data != NULL)
      if (data != NULL)
        {
        {
          simple_object_read *ret;
          simple_object_read *ret;
 
 
          ret = XNEW (simple_object_read);
          ret = XNEW (simple_object_read);
          ret->descriptor = descriptor;
          ret->descriptor = descriptor;
          ret->offset = offset;
          ret->offset = offset;
          ret->functions = format_functions[i];
          ret->functions = format_functions[i];
          ret->data = data;
          ret->data = data;
          return ret;
          return ret;
        }
        }
    }
    }
 
 
  *errmsg = "file not recognized";
  *errmsg = "file not recognized";
  *err = 0;
  *err = 0;
  return NULL;
  return NULL;
}
}
 
 
/* Find all sections.  */
/* Find all sections.  */
 
 
const char *
const char *
simple_object_find_sections (simple_object_read *sobj,
simple_object_find_sections (simple_object_read *sobj,
                             int (*pfn) (void *, const char *, off_t, off_t),
                             int (*pfn) (void *, const char *, off_t, off_t),
                             void *data,
                             void *data,
                             int *err)
                             int *err)
{
{
  return sobj->functions->find_sections (sobj, pfn, data, err);
  return sobj->functions->find_sections (sobj, pfn, data, err);
}
}
 
 
/* Internal data passed to find_one_section.  */
/* Internal data passed to find_one_section.  */
 
 
struct find_one_section_data
struct find_one_section_data
{
{
  /* The section we are looking for.  */
  /* The section we are looking for.  */
  const char *name;
  const char *name;
  /* Where to store the section offset.  */
  /* Where to store the section offset.  */
  off_t *offset;
  off_t *offset;
  /* Where to store the section length.  */
  /* Where to store the section length.  */
  off_t *length;
  off_t *length;
  /* Set if the name is found.  */
  /* Set if the name is found.  */
  int found;
  int found;
};
};
 
 
/* Internal function passed to find_sections.  */
/* Internal function passed to find_sections.  */
 
 
static int
static int
find_one_section (void *data, const char *name, off_t offset, off_t length)
find_one_section (void *data, const char *name, off_t offset, off_t length)
{
{
  struct find_one_section_data *fosd = (struct find_one_section_data *) data;
  struct find_one_section_data *fosd = (struct find_one_section_data *) data;
 
 
  if (strcmp (name, fosd->name) != 0)
  if (strcmp (name, fosd->name) != 0)
    return 1;
    return 1;
 
 
  *fosd->offset = offset;
  *fosd->offset = offset;
  *fosd->length = length;
  *fosd->length = length;
  fosd->found = 1;
  fosd->found = 1;
 
 
  /* Stop iteration.  */
  /* Stop iteration.  */
  return 0;
  return 0;
}
}
 
 
/* Find a section.  */
/* Find a section.  */
 
 
int
int
simple_object_find_section (simple_object_read *sobj, const char *name,
simple_object_find_section (simple_object_read *sobj, const char *name,
                            off_t *offset, off_t *length,
                            off_t *offset, off_t *length,
                            const char **errmsg, int *err)
                            const char **errmsg, int *err)
{
{
  struct find_one_section_data fosd;
  struct find_one_section_data fosd;
 
 
  fosd.name = name;
  fosd.name = name;
  fosd.offset = offset;
  fosd.offset = offset;
  fosd.length = length;
  fosd.length = length;
  fosd.found = 0;
  fosd.found = 0;
 
 
  *errmsg = simple_object_find_sections (sobj, find_one_section,
  *errmsg = simple_object_find_sections (sobj, find_one_section,
                                         (void *) &fosd, err);
                                         (void *) &fosd, err);
  if (*errmsg != NULL)
  if (*errmsg != NULL)
    return 0;
    return 0;
  if (!fosd.found)
  if (!fosd.found)
    return 0;
    return 0;
  return 1;
  return 1;
}
}
 
 
/* Fetch attributes.  */
/* Fetch attributes.  */
 
 
simple_object_attributes *
simple_object_attributes *
simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
                                int *err)
                                int *err)
{
{
  void *data;
  void *data;
  simple_object_attributes *ret;
  simple_object_attributes *ret;
 
 
  data = sobj->functions->fetch_attributes (sobj, errmsg, err);
  data = sobj->functions->fetch_attributes (sobj, errmsg, err);
  if (data == NULL)
  if (data == NULL)
    return NULL;
    return NULL;
  ret = XNEW (simple_object_attributes);
  ret = XNEW (simple_object_attributes);
  ret->functions = sobj->functions;
  ret->functions = sobj->functions;
  ret->data = data;
  ret->data = data;
  return ret;
  return ret;
}
}
 
 
/* Release an simple_object_read.  */
/* Release an simple_object_read.  */
 
 
void
void
simple_object_release_read (simple_object_read *sobj)
simple_object_release_read (simple_object_read *sobj)
{
{
  sobj->functions->release_read (sobj->data);
  sobj->functions->release_read (sobj->data);
  XDELETE (sobj);
  XDELETE (sobj);
}
}
 
 
/* Merge attributes.  */
/* Merge attributes.  */
 
 
const char *
const char *
simple_object_attributes_merge (simple_object_attributes *to,
simple_object_attributes_merge (simple_object_attributes *to,
                                simple_object_attributes *from,
                                simple_object_attributes *from,
                                int *err)
                                int *err)
{
{
  if (to->functions != from->functions)
  if (to->functions != from->functions)
    {
    {
      *err = 0;
      *err = 0;
      return "different object file format";
      return "different object file format";
    }
    }
  return to->functions->attributes_merge (to->data, from->data, err);
  return to->functions->attributes_merge (to->data, from->data, err);
}
}
 
 
/* Release an attributes structure.  */
/* Release an attributes structure.  */
 
 
void
void
simple_object_release_attributes (simple_object_attributes *attrs)
simple_object_release_attributes (simple_object_attributes *attrs)
{
{
  attrs->functions->release_attributes (attrs->data);
  attrs->functions->release_attributes (attrs->data);
  XDELETE (attrs);
  XDELETE (attrs);
}
}
 
 
/* Start creating an object file.  */
/* Start creating an object file.  */
 
 
simple_object_write *
simple_object_write *
simple_object_start_write (simple_object_attributes *attrs,
simple_object_start_write (simple_object_attributes *attrs,
                           const char *segment_name, const char **errmsg,
                           const char *segment_name, const char **errmsg,
                           int *err)
                           int *err)
{
{
  void *data;
  void *data;
  simple_object_write *ret;
  simple_object_write *ret;
 
 
  data = attrs->functions->start_write (attrs->data, errmsg, err);
  data = attrs->functions->start_write (attrs->data, errmsg, err);
  if (data == NULL)
  if (data == NULL)
    return NULL;
    return NULL;
  ret = XNEW (simple_object_write);
  ret = XNEW (simple_object_write);
  ret->functions = attrs->functions;
  ret->functions = attrs->functions;
  ret->segment_name = xstrdup (segment_name);
  ret->segment_name = xstrdup (segment_name);
  ret->sections = NULL;
  ret->sections = NULL;
  ret->last_section = NULL;
  ret->last_section = NULL;
  ret->data = data;
  ret->data = data;
  return ret;
  return ret;
}
}
 
 
/* Start creating a section.  */
/* Start creating a section.  */
 
 
simple_object_write_section *
simple_object_write_section *
simple_object_write_create_section (simple_object_write *sobj, const char *name,
simple_object_write_create_section (simple_object_write *sobj, const char *name,
                                    unsigned int align,
                                    unsigned int align,
                                    const char **errmsg ATTRIBUTE_UNUSED,
                                    const char **errmsg ATTRIBUTE_UNUSED,
                                    int *err ATTRIBUTE_UNUSED)
                                    int *err ATTRIBUTE_UNUSED)
{
{
  simple_object_write_section *ret;
  simple_object_write_section *ret;
 
 
  ret = XNEW (simple_object_write_section);
  ret = XNEW (simple_object_write_section);
  ret->next = NULL;
  ret->next = NULL;
  ret->name = xstrdup (name);
  ret->name = xstrdup (name);
  ret->align = align;
  ret->align = align;
  ret->buffers = NULL;
  ret->buffers = NULL;
  ret->last_buffer = NULL;
  ret->last_buffer = NULL;
 
 
  if (sobj->last_section == NULL)
  if (sobj->last_section == NULL)
    {
    {
      sobj->sections = ret;
      sobj->sections = ret;
      sobj->last_section = ret;
      sobj->last_section = ret;
    }
    }
  else
  else
    {
    {
      sobj->last_section->next = ret;
      sobj->last_section->next = ret;
      sobj->last_section = ret;
      sobj->last_section = ret;
    }
    }
 
 
  return ret;
  return ret;
}
}
 
 
/* Add data to a section.  */
/* Add data to a section.  */
 
 
const char *
const char *
simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
                              simple_object_write_section *section,
                              simple_object_write_section *section,
                              const void *buffer,
                              const void *buffer,
                              size_t size, int copy,
                              size_t size, int copy,
                              int *err ATTRIBUTE_UNUSED)
                              int *err ATTRIBUTE_UNUSED)
{
{
  struct simple_object_write_section_buffer *wsb;
  struct simple_object_write_section_buffer *wsb;
 
 
  wsb = XNEW (struct simple_object_write_section_buffer);
  wsb = XNEW (struct simple_object_write_section_buffer);
  wsb->next = NULL;
  wsb->next = NULL;
  wsb->size = size;
  wsb->size = size;
 
 
  if (!copy)
  if (!copy)
    {
    {
      wsb->buffer = buffer;
      wsb->buffer = buffer;
      wsb->free_buffer = NULL;
      wsb->free_buffer = NULL;
    }
    }
  else
  else
    {
    {
      wsb->free_buffer = (void *) XNEWVEC (char, size);
      wsb->free_buffer = (void *) XNEWVEC (char, size);
      memcpy (wsb->free_buffer, buffer, size);
      memcpy (wsb->free_buffer, buffer, size);
      wsb->buffer = wsb->free_buffer;
      wsb->buffer = wsb->free_buffer;
    }
    }
 
 
  if (section->last_buffer == NULL)
  if (section->last_buffer == NULL)
    {
    {
      section->buffers = wsb;
      section->buffers = wsb;
      section->last_buffer = wsb;
      section->last_buffer = wsb;
    }
    }
  else
  else
    {
    {
      section->last_buffer->next = wsb;
      section->last_buffer->next = wsb;
      section->last_buffer = wsb;
      section->last_buffer = wsb;
    }
    }
 
 
  return NULL;
  return NULL;
}
}
 
 
/* Write the complete object file.  */
/* Write the complete object file.  */
 
 
const char *
const char *
simple_object_write_to_file (simple_object_write *sobj, int descriptor,
simple_object_write_to_file (simple_object_write *sobj, int descriptor,
                             int *err)
                             int *err)
{
{
  return sobj->functions->write_to_file (sobj, descriptor, err);
  return sobj->functions->write_to_file (sobj, descriptor, err);
}
}
 
 
/* Release an simple_object_write.  */
/* Release an simple_object_write.  */
 
 
void
void
simple_object_release_write (simple_object_write *sobj)
simple_object_release_write (simple_object_write *sobj)
{
{
  simple_object_write_section *section;
  simple_object_write_section *section;
 
 
  free (sobj->segment_name);
  free (sobj->segment_name);
 
 
  section = sobj->sections;
  section = sobj->sections;
  while (section != NULL)
  while (section != NULL)
    {
    {
      struct simple_object_write_section_buffer *buffer;
      struct simple_object_write_section_buffer *buffer;
      simple_object_write_section *next_section;
      simple_object_write_section *next_section;
 
 
      buffer = section->buffers;
      buffer = section->buffers;
      while (buffer != NULL)
      while (buffer != NULL)
        {
        {
          struct simple_object_write_section_buffer *next_buffer;
          struct simple_object_write_section_buffer *next_buffer;
 
 
          if (buffer->free_buffer != NULL)
          if (buffer->free_buffer != NULL)
            XDELETEVEC (buffer->free_buffer);
            XDELETEVEC (buffer->free_buffer);
          next_buffer = buffer->next;
          next_buffer = buffer->next;
          XDELETE (buffer);
          XDELETE (buffer);
          buffer = next_buffer;
          buffer = next_buffer;
        }
        }
 
 
      next_section = section->next;
      next_section = section->next;
      free (section->name);
      free (section->name);
      XDELETE (section);
      XDELETE (section);
      section = next_section;
      section = next_section;
    }
    }
 
 
  sobj->functions->release_write (sobj->data);
  sobj->functions->release_write (sobj->data);
  XDELETE (sobj);
  XDELETE (sobj);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.