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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [collect2-aix.c] - Diff between revs 816 and 826

Only display areas with differences | Details | Blame | View Log

Rev 816 Rev 826
/* AIX cross support for collect2.
/* AIX cross support for collect2.
   Copyright (C) 2009 Free Software Foundation, Inc.
   Copyright (C) 2009 Free Software Foundation, Inc.
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify it under
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
Software Foundation; either version 3, or (at your option) any later
version.
version.
 
 
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
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 GCC; see the file COPYING3.  If not see
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "collect2-aix.h"
#include "collect2-aix.h"
 
 
#ifdef CROSS_AIX_SUPPORT
#ifdef CROSS_AIX_SUPPORT
 
 
#include <sys/mman.h>
#include <sys/mman.h>
 
 
/* Read SIZE bytes starting at DATA as a big-endian value.  */
/* Read SIZE bytes starting at DATA as a big-endian value.  */
 
 
static inline bfd_vma
static inline bfd_vma
read_value (char *data, unsigned int size)
read_value (char *data, unsigned int size)
{
{
  bfd_vma value;
  bfd_vma value;
  unsigned int i;
  unsigned int i;
 
 
  value = 0;
  value = 0;
  for (i = 0; i < size; i++)
  for (i = 0; i < size; i++)
    {
    {
      value <<= 8;
      value <<= 8;
      value += (unsigned char) data[i];
      value += (unsigned char) data[i];
    }
    }
  return value;
  return value;
}
}
 
 
/* FIELD is a char array.  Read the contents as a big-endian integer.  */
/* FIELD is a char array.  Read the contents as a big-endian integer.  */
#define READ_FIELD(FIELD) \
#define READ_FIELD(FIELD) \
  read_value (FIELD, sizeof (FIELD))
  read_value (FIELD, sizeof (FIELD))
 
 
/* OBJECT is a char pointer to an in-file object of type struct TYPE.
/* OBJECT is a char pointer to an in-file object of type struct TYPE.
   Return the address of field FIELD.  */
   Return the address of field FIELD.  */
#define OBJECT_FIELD(OBJECT, TYPE, FIELD) \
#define OBJECT_FIELD(OBJECT, TYPE, FIELD) \
  (OBJECT) + offsetof (struct TYPE, FIELD)
  (OBJECT) + offsetof (struct TYPE, FIELD)
 
 
/* Return the size of FIELD, which is a field of struct TYPE.  */
/* Return the size of FIELD, which is a field of struct TYPE.  */
#define FIELD_SIZE(TYPE, FIELD) \
#define FIELD_SIZE(TYPE, FIELD) \
  sizeof (((struct TYPE *) (0))->FIELD)
  sizeof (((struct TYPE *) (0))->FIELD)
 
 
/* OBJECT is a char pointer to an in-file object of type struct TYPE.
/* OBJECT is a char pointer to an in-file object of type struct TYPE.
   Read the value of field FIELD as a big-endian integer.  */
   Read the value of field FIELD as a big-endian integer.  */
#define READ_OBJECT(OBJECT, TYPE, FIELD) \
#define READ_OBJECT(OBJECT, TYPE, FIELD) \
  read_value (OBJECT_FIELD (OBJECT, TYPE, FIELD), FIELD_SIZE (TYPE, FIELD))
  read_value (OBJECT_FIELD (OBJECT, TYPE, FIELD), FIELD_SIZE (TYPE, FIELD))
 
 
/* Copy FIELD from an external structure of type TYPE at address FROM
/* Copy FIELD from an external structure of type TYPE at address FROM
   to an internal structure pointed to by TO.  */
   to an internal structure pointed to by TO.  */
#define COPY_FIELD(TO, FROM, TYPE, FIELD) \
#define COPY_FIELD(TO, FROM, TYPE, FIELD) \
  ((TO)->FIELD = READ_OBJECT (FROM, TYPE, FIELD))
  ((TO)->FIELD = READ_OBJECT (FROM, TYPE, FIELD))
 
 
/* Return true if STRING is less than SIZE bytes long.  EXTRA_TERMINATOR
/* Return true if STRING is less than SIZE bytes long.  EXTRA_TERMINATOR
   is another character (besides '\0') that acts as a terminator,
   is another character (besides '\0') that acts as a terminator,
   or '\0' if none.  */
   or '\0' if none.  */
 
 
static bool
static bool
string_within_bounds_p (const char *string, size_t size, char extra_terminator)
string_within_bounds_p (const char *string, size_t size, char extra_terminator)
{
{
  const char *p;
  const char *p;
 
 
  for (p = string; p < string + size; p++)
  for (p = string; p < string + size; p++)
    if (*p == '\0' || *p == extra_terminator)
    if (*p == '\0' || *p == extra_terminator)
      return true;
      return true;
  return false;
  return false;
}
}
 
 
/* STRING is a pointer to a char array.  Try to read its value as an
/* STRING is a pointer to a char array.  Try to read its value as an
   ASCII-encoded integer.  On success, return true and store the result
   ASCII-encoded integer.  On success, return true and store the result
   in TARGET.  */
   in TARGET.  */
#define PARSE_INTEGER(TARGET, STRING) \
#define PARSE_INTEGER(TARGET, STRING) \
  (string_within_bounds_p (&(STRING)[0], sizeof (STRING), ' ') \
  (string_within_bounds_p (&(STRING)[0], sizeof (STRING), ' ') \
   && ((TARGET) = strtoul (STRING, NULL, 0), true))
   && ((TARGET) = strtoul (STRING, NULL, 0), true))
 
 
/* Check that LDFILE's current object has SIZE bytes starting at OFFSET.  */
/* Check that LDFILE's current object has SIZE bytes starting at OFFSET.  */
 
 
static inline bool
static inline bool
within_object_p (LDFILE *ldfile, size_t offset, size_t size)
within_object_p (LDFILE *ldfile, size_t offset, size_t size)
{
{
  return offset <= ldfile->object_size && offset + size <= ldfile->object_size;
  return offset <= ldfile->object_size && offset + size <= ldfile->object_size;
}
}
 
 
/* Try to read the file header for an XCOFF object at OFFSET bytes into
/* Try to read the file header for an XCOFF object at OFFSET bytes into
   LDFILE.  The object is expected to be OBJECT_SIZE bytes in size.
   LDFILE.  The object is expected to be OBJECT_SIZE bytes in size.
   If the object is a member of an archive, NEXT_MEMBER is the offset
   If the object is a member of an archive, NEXT_MEMBER is the offset
   of the next member, otherwise it is -1.
   of the next member, otherwise it is -1.
 
 
   Return true on success, recording the object information in LDFILE.  */
   Return true on success, recording the object information in LDFILE.  */
 
 
static bool
static bool
read_xcoff_object (LDFILE *ldfile, size_t offset, size_t object_size,
read_xcoff_object (LDFILE *ldfile, size_t offset, size_t object_size,
                   off_t next_member)
                   off_t next_member)
{
{
  struct internal_filehdr *internal;
  struct internal_filehdr *internal;
  char *external;
  char *external;
  void *map;
  void *map;
  size_t page_size;
  size_t page_size;
 
 
  /* First try to map the file into memory.  */
  /* First try to map the file into memory.  */
  page_size = getpagesize ();
  page_size = getpagesize ();
  ldfile->page_offset = offset & (page_size - 1);
  ldfile->page_offset = offset & (page_size - 1);
  map = mmap (NULL, object_size + ldfile->page_offset, PROT_READ,
  map = mmap (NULL, object_size + ldfile->page_offset, PROT_READ,
              MAP_SHARED, ldfile->fd, offset - ldfile->page_offset);
              MAP_SHARED, ldfile->fd, offset - ldfile->page_offset);
  if (map == MAP_FAILED)
  if (map == MAP_FAILED)
    return false;
    return false;
 
 
  /* Record the success.  */
  /* Record the success.  */
  ldfile->object = (char *) map + ldfile->page_offset;
  ldfile->object = (char *) map + ldfile->page_offset;
  ldfile->object_size = object_size;
  ldfile->object_size = object_size;
  ldfile->next_member = next_member;
  ldfile->next_member = next_member;
 
 
  /* Read the magic value to determine the type of file.  */
  /* Read the magic value to determine the type of file.  */
  if (!within_object_p (ldfile, 0, F_MAGIC_SIZE))
  if (!within_object_p (ldfile, 0, F_MAGIC_SIZE))
    return false;
    return false;
 
 
  internal = &ldfile->filehdr;
  internal = &ldfile->filehdr;
  external = ldfile->object;
  external = ldfile->object;
  internal->f_magic = read_value (external, F_MAGIC_SIZE);
  internal->f_magic = read_value (external, F_MAGIC_SIZE);
  if (internal->f_magic == U802TOCMAGIC)
  if (internal->f_magic == U802TOCMAGIC)
    {
    {
      if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_32)))
      if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_32)))
        return false;
        return false;
 
 
      COPY_FIELD (internal, external, external_filehdr_32, f_nscns);
      COPY_FIELD (internal, external, external_filehdr_32, f_nscns);
      COPY_FIELD (internal, external, external_filehdr_32, f_timdat);
      COPY_FIELD (internal, external, external_filehdr_32, f_timdat);
      COPY_FIELD (internal, external, external_filehdr_32, f_symptr);
      COPY_FIELD (internal, external, external_filehdr_32, f_symptr);
      COPY_FIELD (internal, external, external_filehdr_32, f_nsyms);
      COPY_FIELD (internal, external, external_filehdr_32, f_nsyms);
      COPY_FIELD (internal, external, external_filehdr_32, f_opthdr);
      COPY_FIELD (internal, external, external_filehdr_32, f_opthdr);
      COPY_FIELD (internal, external, external_filehdr_32, f_flags);
      COPY_FIELD (internal, external, external_filehdr_32, f_flags);
      return true;
      return true;
    }
    }
  else if (internal->f_magic == U803XTOCMAGIC
  else if (internal->f_magic == U803XTOCMAGIC
           || internal->f_magic == U64_TOCMAGIC)
           || internal->f_magic == U64_TOCMAGIC)
    {
    {
      if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_64)))
      if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_64)))
        return false;
        return false;
 
 
      COPY_FIELD (internal, external, external_filehdr_64, f_nscns);
      COPY_FIELD (internal, external, external_filehdr_64, f_nscns);
      COPY_FIELD (internal, external, external_filehdr_64, f_timdat);
      COPY_FIELD (internal, external, external_filehdr_64, f_timdat);
      COPY_FIELD (internal, external, external_filehdr_64, f_symptr);
      COPY_FIELD (internal, external, external_filehdr_64, f_symptr);
      COPY_FIELD (internal, external, external_filehdr_64, f_nsyms);
      COPY_FIELD (internal, external, external_filehdr_64, f_nsyms);
      COPY_FIELD (internal, external, external_filehdr_64, f_opthdr);
      COPY_FIELD (internal, external, external_filehdr_64, f_opthdr);
      COPY_FIELD (internal, external, external_filehdr_64, f_flags);
      COPY_FIELD (internal, external, external_filehdr_64, f_flags);
      return true;
      return true;
    }
    }
  return false;
  return false;
}
}
 
 
/* Try to read an archive member at OFFSET bytes into LDFILE.
/* Try to read an archive member at OFFSET bytes into LDFILE.
   Return true on success, recording the member and object
   Return true on success, recording the member and object
   information in LDFILE.  */
   information in LDFILE.  */
 
 
static bool
static bool
read_archive_member (LDFILE *ldfile, size_t offset)
read_archive_member (LDFILE *ldfile, size_t offset)
{
{
  struct external_big_ar_member member;
  struct external_big_ar_member member;
  size_t namlen;
  size_t namlen;
  size_t size;
  size_t size;
  off_t next_member;
  off_t next_member;
 
 
  if (lseek (ldfile->fd, offset, SEEK_SET) >= 0
  if (lseek (ldfile->fd, offset, SEEK_SET) >= 0
      && read (ldfile->fd, &member, sizeof (member)) == sizeof (member)
      && read (ldfile->fd, &member, sizeof (member)) == sizeof (member)
      && PARSE_INTEGER (namlen, member.ar_namlen)
      && PARSE_INTEGER (namlen, member.ar_namlen)
      /* Stop once we reach the member table entry, which has a name
      /* Stop once we reach the member table entry, which has a name
         of length 0.  */
         of length 0.  */
      && namlen > 0
      && namlen > 0
      && PARSE_INTEGER (size, member.ar_size)
      && PARSE_INTEGER (size, member.ar_size)
      && PARSE_INTEGER (next_member, member.ar_nextoff))
      && PARSE_INTEGER (next_member, member.ar_nextoff))
    {
    {
      /* The archive is followed by an even-padded name, then by
      /* The archive is followed by an even-padded name, then by
         a magic string of length SXCOFFARFMAG.  The object itself
         a magic string of length SXCOFFARFMAG.  The object itself
         starts after that. */
         starts after that. */
      offset += sizeof (member) + namlen + SXCOFFARFMAG;
      offset += sizeof (member) + namlen + SXCOFFARFMAG;
      offset += offset & 1;
      offset += offset & 1;
      return read_xcoff_object (ldfile, offset, size, next_member);
      return read_xcoff_object (ldfile, offset, size, next_member);
    }
    }
  return false;
  return false;
}
}
 
 
/* Try to treat LDFILE as a non-empty big archive.  Return true
/* Try to treat LDFILE as a non-empty big archive.  Return true
   on success, storing the member and object information for
   on success, storing the member and object information for
   the first member in LDFILE.  */
   the first member in LDFILE.  */
 
 
static bool
static bool
read_big_archive (LDFILE *ldfile)
read_big_archive (LDFILE *ldfile)
{
{
  struct external_big_ar_filehdr filehdr;
  struct external_big_ar_filehdr filehdr;
  size_t offset;
  size_t offset;
 
 
  return (lseek (ldfile->fd, 0L, SEEK_SET) == 0
  return (lseek (ldfile->fd, 0L, SEEK_SET) == 0
          && read (ldfile->fd, &filehdr, sizeof (filehdr)) == sizeof (filehdr)
          && read (ldfile->fd, &filehdr, sizeof (filehdr)) == sizeof (filehdr)
          && memcmp (filehdr.fl_magic, FL_MAGIC_BIG_AR, FL_MAGIC_SIZE) == 0
          && memcmp (filehdr.fl_magic, FL_MAGIC_BIG_AR, FL_MAGIC_SIZE) == 0
          && PARSE_INTEGER (offset, filehdr.fl_firstmemoff)
          && PARSE_INTEGER (offset, filehdr.fl_firstmemoff)
          && read_archive_member (ldfile, offset));
          && read_archive_member (ldfile, offset));
}
}
 
 
/* LDFILE is a zero-initialized structure.  Try to open FILENAME,
/* LDFILE is a zero-initialized structure.  Try to open FILENAME,
   returning true on success.  */
   returning true on success.  */
 
 
static bool
static bool
open_file (LDFILE *ldfile, const char *filename)
open_file (LDFILE *ldfile, const char *filename)
{
{
  struct stat st;
  struct stat st;
 
 
  ldfile->fd = open (filename, O_RDONLY);
  ldfile->fd = open (filename, O_RDONLY);
  if (ldfile->fd < 0)
  if (ldfile->fd < 0)
    return false;
    return false;
 
 
  if (read_big_archive (ldfile))
  if (read_big_archive (ldfile))
    return true;
    return true;
 
 
  if (fstat (ldfile->fd, &st) < 0)
  if (fstat (ldfile->fd, &st) < 0)
    return false;
    return false;
 
 
  return read_xcoff_object (ldfile, 0, st.st_size, -1);
  return read_xcoff_object (ldfile, 0, st.st_size, -1);
}
}
 
 
/* Release the memory associated with the current object, if one has
/* Release the memory associated with the current object, if one has
   been mapped.  */
   been mapped.  */
 
 
static void
static void
free_object (LDFILE *ldfile)
free_object (LDFILE *ldfile)
{
{
  if (ldfile->object)
  if (ldfile->object)
    munmap (ldfile->object - ldfile->page_offset,
    munmap (ldfile->object - ldfile->page_offset,
            ldfile->object_size + ldfile->page_offset);
            ldfile->object_size + ldfile->page_offset);
}
}
 
 
/* Free LDFILE and all resources associated with it.  */
/* Free LDFILE and all resources associated with it.  */
 
 
static void
static void
free_ldfile (LDFILE *ldfile)
free_ldfile (LDFILE *ldfile)
{
{
  if (ldfile->fd >= 0)
  if (ldfile->fd >= 0)
    close (ldfile->fd);
    close (ldfile->fd);
  XDELETE (ldfile);
  XDELETE (ldfile);
}
}
 
 
/* Implement the API-defined ldopen function.  */
/* Implement the API-defined ldopen function.  */
 
 
LDFILE *
LDFILE *
ldopen (char *filename, LDFILE *ldfile)
ldopen (char *filename, LDFILE *ldfile)
{
{
  if (ldfile == NULL)
  if (ldfile == NULL)
    {
    {
      ldfile = XCNEW (LDFILE);
      ldfile = XCNEW (LDFILE);
      if (!open_file (ldfile, filename))
      if (!open_file (ldfile, filename))
        {
        {
          free_object (ldfile);
          free_object (ldfile);
          free_ldfile (ldfile);
          free_ldfile (ldfile);
          return NULL;
          return NULL;
        }
        }
    }
    }
  return ldfile;
  return ldfile;
}
}
 
 
/* Implement the API-defined ldtbread function.  */
/* Implement the API-defined ldtbread function.  */
 
 
int
int
ldtbread (LDFILE *ldfile, long index, SYMENT *internal)
ldtbread (LDFILE *ldfile, long index, SYMENT *internal)
{
{
  size_t offset, name_length;
  size_t offset, name_length;
  char *external;
  char *external;
 
 
  /* Make sure that the symbol index is valid.  */
  /* Make sure that the symbol index is valid.  */
  if (index < 0 || index >= HEADER (ldfile).f_nsyms)
  if (index < 0 || index >= HEADER (ldfile).f_nsyms)
    return FAILURE;
    return FAILURE;
 
 
  /* Work out the offset of the symbol table entry.  */
  /* Work out the offset of the symbol table entry.  */
  offset = HEADER (ldfile).f_symptr + index * sizeof (struct external_syment);
  offset = HEADER (ldfile).f_symptr + index * sizeof (struct external_syment);
  if (!within_object_p (ldfile, offset, sizeof (struct external_syment)))
  if (!within_object_p (ldfile, offset, sizeof (struct external_syment)))
    return FAILURE;
    return FAILURE;
 
 
  /* Read all the fields.  The format differs between 32-bit and
  /* Read all the fields.  The format differs between 32-bit and
     64-bit files.  */
     64-bit files.  */
  external = ldfile->object + offset;
  external = ldfile->object + offset;
  if (HEADER (ldfile).f_magic == U802TOCMAGIC)
  if (HEADER (ldfile).f_magic == U802TOCMAGIC)
    {
    {
      /* Copy the n_zeroes/n_offset interpretation.  */
      /* Copy the n_zeroes/n_offset interpretation.  */
      internal->n_zeroes = READ_OBJECT (external, external_syment,
      internal->n_zeroes = READ_OBJECT (external, external_syment,
                                        u.xcoff32.u.u.n_zeroes);
                                        u.xcoff32.u.u.n_zeroes);
      internal->n_offset = READ_OBJECT (external, external_syment,
      internal->n_offset = READ_OBJECT (external, external_syment,
                                        u.xcoff32.u.u.n_offset);
                                        u.xcoff32.u.u.n_offset);
 
 
      /* Copy the n_name interpretation.  The internal version has room
      /* Copy the n_name interpretation.  The internal version has room
         for a null terminator.  */
         for a null terminator.  */
      name_length = FIELD_SIZE (external_syment, u.xcoff32.u.n_name);
      name_length = FIELD_SIZE (external_syment, u.xcoff32.u.n_name);
      memcpy (internal->n_name,
      memcpy (internal->n_name,
              external + offsetof (struct external_syment, u.xcoff32.u.n_name),
              external + offsetof (struct external_syment, u.xcoff32.u.n_name),
              name_length);
              name_length);
      internal->n_name[name_length] = 0;
      internal->n_name[name_length] = 0;
 
 
      internal->n_value = READ_OBJECT (external, external_syment,
      internal->n_value = READ_OBJECT (external, external_syment,
                                       u.xcoff32.n_value);
                                       u.xcoff32.n_value);
    }
    }
  else
  else
    {
    {
      internal->n_zeroes = 0;
      internal->n_zeroes = 0;
      internal->n_offset = READ_OBJECT (external, external_syment,
      internal->n_offset = READ_OBJECT (external, external_syment,
                                        u.xcoff64.n_offset);
                                        u.xcoff64.n_offset);
      internal->n_value = READ_OBJECT (external, external_syment,
      internal->n_value = READ_OBJECT (external, external_syment,
                                       u.xcoff64.n_value);
                                       u.xcoff64.n_value);
    }
    }
  COPY_FIELD (internal, external, external_syment, n_scnum);
  COPY_FIELD (internal, external, external_syment, n_scnum);
  COPY_FIELD (internal, external, external_syment, n_type);
  COPY_FIELD (internal, external, external_syment, n_type);
  COPY_FIELD (internal, external, external_syment, n_sclass);
  COPY_FIELD (internal, external, external_syment, n_sclass);
  COPY_FIELD (internal, external, external_syment, n_numaux);
  COPY_FIELD (internal, external, external_syment, n_numaux);
  return SUCCESS;
  return SUCCESS;
}
}
 
 
/* Implement the API-defined ldgetname function.  */
/* Implement the API-defined ldgetname function.  */
 
 
char *
char *
ldgetname (LDFILE *ldfile, SYMENT *symbol)
ldgetname (LDFILE *ldfile, SYMENT *symbol)
{
{
  char *name;
  char *name;
  size_t offset;
  size_t offset;
 
 
  /* If the zeroes field is nonzero, the name is in the symbol table
  /* If the zeroes field is nonzero, the name is in the symbol table
     entry itself.  */
     entry itself.  */
  if (symbol->n_zeroes != 0)
  if (symbol->n_zeroes != 0)
    return symbol->n_name;
    return symbol->n_name;
 
 
  /* Otherwise, the symbol table entry contains an offset into the
  /* Otherwise, the symbol table entry contains an offset into the
     string table, which starts after the end of the symbol table.  */
     string table, which starts after the end of the symbol table.  */
  offset = (HEADER (ldfile).f_symptr
  offset = (HEADER (ldfile).f_symptr
            + HEADER (ldfile).f_nsyms * sizeof (struct external_syment)
            + HEADER (ldfile).f_nsyms * sizeof (struct external_syment)
            + symbol->n_offset);
            + symbol->n_offset);
  if (offset >= ldfile->object_size)
  if (offset >= ldfile->object_size)
    return NULL;
    return NULL;
 
 
  /* Make sure that the name is entirely contained within the object.  */
  /* Make sure that the name is entirely contained within the object.  */
  name = ldfile->object + offset;
  name = ldfile->object + offset;
  if (!string_within_bounds_p (name, ldfile->object_size - offset, '\0'))
  if (!string_within_bounds_p (name, ldfile->object_size - offset, '\0'))
    return NULL;
    return NULL;
 
 
  return name;
  return name;
}
}
 
 
/* Implement the API-defined ldclose function.  */
/* Implement the API-defined ldclose function.  */
 
 
int
int
ldclose (LDFILE *ldfile)
ldclose (LDFILE *ldfile)
{
{
  free_object (ldfile);
  free_object (ldfile);
  if (ldfile->next_member >= 0
  if (ldfile->next_member >= 0
      && read_archive_member (ldfile, ldfile->next_member))
      && read_archive_member (ldfile, ldfile->next_member))
    return FAILURE;
    return FAILURE;
 
 
  free_ldfile (ldfile);
  free_ldfile (ldfile);
  return SUCCESS;
  return SUCCESS;
}
}
 
 
#endif
#endif
 
 

powered by: WebSVN 2.1.0

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