Makefile.in (COLLECT2_OBJS): Add collect2-aix.o.
gcc/ * Makefile.in (COLLECT2_OBJS): Add collect2-aix.o. (collect2.o): Depend on collect2-aix.h. (collect2-aix.o): New rule. * collect2-aix.h: New file. * collect2-aix.c: Likewise. * collect2.c: Include collect2-aix.h. Don't undefine OBJECT_FORMAT_COFF if CROSS_AIX_SUPPORT is defined. Guard native includes with #ifndef CROSS_DIRECTORY_STRUCTURE. Use TARGET_AIX_VERSION instead of _AIX51. * config/rs6000/aix43.h (TARGET_AIX_VERSION): Define. * config/rs6000/aix51.h (TARGET_AIX_VERSION): Likewise. * config/rs6000/aix52.h (TARGET_AIX_VERSION): Likewise. * config/rs6000/aix53.h (TARGET_AIX_VERSION): Likewise. * config/rs6000/aix61.h (TARGET_AIX_VERSION): Likewise. From-SVN: r148096
This commit is contained in:
parent
51136ae818
commit
dfb636dcd0
@ -1,3 +1,20 @@
|
||||
2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* Makefile.in (COLLECT2_OBJS): Add collect2-aix.o.
|
||||
(collect2.o): Depend on collect2-aix.h.
|
||||
(collect2-aix.o): New rule.
|
||||
* collect2-aix.h: New file.
|
||||
* collect2-aix.c: Likewise.
|
||||
* collect2.c: Include collect2-aix.h. Don't undefine
|
||||
OBJECT_FORMAT_COFF if CROSS_AIX_SUPPORT is defined.
|
||||
Guard native includes with #ifndef CROSS_DIRECTORY_STRUCTURE.
|
||||
Use TARGET_AIX_VERSION instead of _AIX51.
|
||||
* config/rs6000/aix43.h (TARGET_AIX_VERSION): Define.
|
||||
* config/rs6000/aix51.h (TARGET_AIX_VERSION): Likewise.
|
||||
* config/rs6000/aix52.h (TARGET_AIX_VERSION): Likewise.
|
||||
* config/rs6000/aix53.h (TARGET_AIX_VERSION): Likewise.
|
||||
* config/rs6000/aix61.h (TARGET_AIX_VERSION): Likewise.
|
||||
|
||||
2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||
|
||||
* collect2.c (ignore_library): Avoid premature post-increment
|
||||
|
@ -1897,7 +1897,7 @@ ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(EBITMAP_H) $(RTL_H) $(FLAGS_H) $(OBSTACK_H)
|
||||
sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
|
||||
|
||||
COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
|
||||
COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o intl.o version.o
|
||||
COLLECT2_LIBS = @COLLECT2_LIBS@
|
||||
collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
|
||||
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
|
||||
@ -1906,10 +1906,13 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
|
||||
mv -f T$@ $@
|
||||
|
||||
collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
|
||||
$(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h
|
||||
$(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h
|
||||
$(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
|
||||
-DTARGET_MACHINE=\"$(target_noncanonical)\" \
|
||||
-c $(srcdir)/collect2.c $(OUTPUT_OPTION)
|
||||
-c $(srcdir)/collect2.c $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
|
||||
|
||||
collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
collect2-aix.h
|
||||
|
||||
tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(OBSTACK_H) collect2.h intl.h
|
||||
|
371
gcc/collect2-aix.c
Normal file
371
gcc/collect2-aix.c
Normal file
@ -0,0 +1,371 @@
|
||||
/* AIX cross support for collect2.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "collect2-aix.h"
|
||||
|
||||
#ifdef CROSS_AIX_SUPPORT
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* Read SIZE bytes starting at DATA as a big-endian value. */
|
||||
|
||||
static inline bfd_vma
|
||||
read_value (char *data, unsigned int size)
|
||||
{
|
||||
bfd_vma value;
|
||||
unsigned int i;
|
||||
|
||||
value = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
value <<= 8;
|
||||
value += (unsigned char) data[i];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* FIELD is a char array. Read the contents as a big-endian integer. */
|
||||
#define READ_FIELD(FIELD) \
|
||||
read_value (FIELD, sizeof (FIELD))
|
||||
|
||||
/* OBJECT is a char pointer to an in-file object of type struct TYPE.
|
||||
Return the address of field FIELD. */
|
||||
#define OBJECT_FIELD(OBJECT, TYPE, FIELD) \
|
||||
(OBJECT) + offsetof (struct TYPE, FIELD)
|
||||
|
||||
/* Return the size of FIELD, which is a field of struct TYPE. */
|
||||
#define FIELD_SIZE(TYPE, FIELD) \
|
||||
sizeof (((struct TYPE *) (0))->FIELD)
|
||||
|
||||
/* 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. */
|
||||
#define READ_OBJECT(OBJECT, 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
|
||||
to an internal structure pointed to by TO. */
|
||||
#define COPY_FIELD(TO, FROM, TYPE, FIELD) \
|
||||
((TO)->FIELD = READ_OBJECT (FROM, TYPE, FIELD))
|
||||
|
||||
/* Return true if STRING is less than SIZE bytes long. EXTRA_TERMINATOR
|
||||
is another character (besides '\0') that acts as a terminator,
|
||||
or '\0' if none. */
|
||||
|
||||
static bool
|
||||
string_within_bounds_p (const char *string, size_t size, char extra_terminator)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = string; p < string + size; p++)
|
||||
if (*p == '\0' || *p == extra_terminator)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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
|
||||
in TARGET. */
|
||||
#define PARSE_INTEGER(TARGET, STRING) \
|
||||
(string_within_bounds_p (&(STRING)[0], sizeof (STRING), ' ') \
|
||||
&& ((TARGET) = strtoul (STRING, NULL, 0), true))
|
||||
|
||||
/* Check that LDFILE's current object has SIZE bytes starting at OFFSET. */
|
||||
|
||||
static inline bool
|
||||
within_object_p (LDFILE *ldfile, size_t offset, size_t 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
|
||||
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
|
||||
of the next member, otherwise it is -1.
|
||||
|
||||
Return true on success, recording the object information in LDFILE. */
|
||||
|
||||
static bool
|
||||
read_xcoff_object (LDFILE *ldfile, size_t offset, size_t object_size,
|
||||
off_t next_member)
|
||||
{
|
||||
struct internal_filehdr *internal;
|
||||
char *external;
|
||||
void *map;
|
||||
size_t page_size;
|
||||
|
||||
/* First try to map the file into memory. */
|
||||
page_size = getpagesize ();
|
||||
ldfile->page_offset = offset & (page_size - 1);
|
||||
map = mmap (NULL, object_size + ldfile->page_offset, PROT_READ,
|
||||
MAP_SHARED, ldfile->fd, offset - ldfile->page_offset);
|
||||
if (map == MAP_FAILED)
|
||||
return false;
|
||||
|
||||
/* Record the success. */
|
||||
ldfile->object = (char *) map + ldfile->page_offset;
|
||||
ldfile->object_size = object_size;
|
||||
ldfile->next_member = next_member;
|
||||
|
||||
/* Read the magic value to determine the type of file. */
|
||||
if (!within_object_p (ldfile, 0, F_MAGIC_SIZE))
|
||||
return false;
|
||||
|
||||
internal = &ldfile->filehdr;
|
||||
external = ldfile->object;
|
||||
internal->f_magic = read_value (external, F_MAGIC_SIZE);
|
||||
if (internal->f_magic == U802TOCMAGIC)
|
||||
{
|
||||
if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_32)))
|
||||
return false;
|
||||
|
||||
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_symptr);
|
||||
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_flags);
|
||||
return true;
|
||||
}
|
||||
else if (internal->f_magic == U803XTOCMAGIC
|
||||
|| internal->f_magic == U64_TOCMAGIC)
|
||||
{
|
||||
if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_64)))
|
||||
return false;
|
||||
|
||||
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_symptr);
|
||||
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_flags);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Try to read an archive member at OFFSET bytes into LDFILE.
|
||||
Return true on success, recording the member and object
|
||||
information in LDFILE. */
|
||||
|
||||
static bool
|
||||
read_archive_member (LDFILE *ldfile, size_t offset)
|
||||
{
|
||||
struct external_big_ar_member member;
|
||||
size_t namlen;
|
||||
size_t size;
|
||||
off_t next_member;
|
||||
|
||||
if (lseek (ldfile->fd, offset, SEEK_SET) >= 0
|
||||
&& read (ldfile->fd, &member, sizeof (member)) == sizeof (member)
|
||||
&& PARSE_INTEGER (namlen, member.ar_namlen)
|
||||
/* Stop once we reach the member table entry, which has a name
|
||||
of length 0. */
|
||||
&& namlen > 0
|
||||
&& PARSE_INTEGER (size, member.ar_size)
|
||||
&& PARSE_INTEGER (next_member, member.ar_nextoff))
|
||||
{
|
||||
/* The archive is followed by an even-padded name, then by
|
||||
a magic string of length SXCOFFARFMAG. The object itself
|
||||
starts after that. */
|
||||
offset += sizeof (member) + namlen + SXCOFFARFMAG;
|
||||
offset += offset & 1;
|
||||
return read_xcoff_object (ldfile, offset, size, next_member);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Try to treat LDFILE as a non-empty big archive. Return true
|
||||
on success, storing the member and object information for
|
||||
the first member in LDFILE. */
|
||||
|
||||
static bool
|
||||
read_big_archive (LDFILE *ldfile)
|
||||
{
|
||||
struct external_big_ar_filehdr filehdr;
|
||||
size_t offset;
|
||||
|
||||
return (lseek (ldfile->fd, 0L, SEEK_SET) == 0
|
||||
&& read (ldfile->fd, &filehdr, sizeof (filehdr)) == sizeof (filehdr)
|
||||
&& memcmp (filehdr.fl_magic, FL_MAGIC_BIG_AR, FL_MAGIC_SIZE) == 0
|
||||
&& PARSE_INTEGER (offset, filehdr.fl_firstmemoff)
|
||||
&& read_archive_member (ldfile, offset));
|
||||
}
|
||||
|
||||
/* LDFILE is a zero-initialized structure. Try to open FILENAME,
|
||||
returning true on success. */
|
||||
|
||||
static bool
|
||||
open_file (LDFILE *ldfile, const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
ldfile->fd = open (filename, O_RDONLY);
|
||||
if (ldfile->fd < 0)
|
||||
return false;
|
||||
|
||||
if (read_big_archive (ldfile))
|
||||
return true;
|
||||
|
||||
if (fstat (ldfile->fd, &st) < 0)
|
||||
return false;
|
||||
|
||||
return read_xcoff_object (ldfile, 0, st.st_size, -1);
|
||||
}
|
||||
|
||||
/* Release the memory associated with the current object, if one has
|
||||
been mapped. */
|
||||
|
||||
static void
|
||||
free_object (LDFILE *ldfile)
|
||||
{
|
||||
if (ldfile->object)
|
||||
munmap (ldfile->object - ldfile->page_offset,
|
||||
ldfile->object_size + ldfile->page_offset);
|
||||
}
|
||||
|
||||
/* Free LDFILE and all resources associated with it. */
|
||||
|
||||
static void
|
||||
free_ldfile (LDFILE *ldfile)
|
||||
{
|
||||
if (ldfile->fd >= 0)
|
||||
close (ldfile->fd);
|
||||
XDELETE (ldfile);
|
||||
}
|
||||
|
||||
/* Implement the API-defined ldopen function. */
|
||||
|
||||
LDFILE *
|
||||
ldopen (char *filename, LDFILE *ldfile)
|
||||
{
|
||||
if (ldfile == NULL)
|
||||
{
|
||||
ldfile = XCNEW (LDFILE);
|
||||
if (!open_file (ldfile, filename))
|
||||
{
|
||||
free_object (ldfile);
|
||||
free_ldfile (ldfile);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ldfile;
|
||||
}
|
||||
|
||||
/* Implement the API-defined ldtbread function. */
|
||||
|
||||
int
|
||||
ldtbread (LDFILE *ldfile, long index, SYMENT *internal)
|
||||
{
|
||||
size_t offset, name_length;
|
||||
char *external;
|
||||
|
||||
/* Make sure that the symbol index is valid. */
|
||||
if (index < 0 || index >= HEADER (ldfile).f_nsyms)
|
||||
return FAILURE;
|
||||
|
||||
/* Work out the offset of the symbol table entry. */
|
||||
offset = HEADER (ldfile).f_symptr + index * sizeof (struct external_syment);
|
||||
if (!within_object_p (ldfile, offset, sizeof (struct external_syment)))
|
||||
return FAILURE;
|
||||
|
||||
/* Read all the fields. The format differs between 32-bit and
|
||||
64-bit files. */
|
||||
external = ldfile->object + offset;
|
||||
if (HEADER (ldfile).f_magic == U802TOCMAGIC)
|
||||
{
|
||||
/* Copy the n_zeroes/n_offset interpretation. */
|
||||
internal->n_zeroes = READ_OBJECT (external, external_syment,
|
||||
u.xcoff32.u.u.n_zeroes);
|
||||
internal->n_offset = READ_OBJECT (external, external_syment,
|
||||
u.xcoff32.u.u.n_offset);
|
||||
|
||||
/* Copy the n_name interpretation. The internal version has room
|
||||
for a null terminator. */
|
||||
name_length = FIELD_SIZE (external_syment, u.xcoff32.u.n_name);
|
||||
memcpy (internal->n_name,
|
||||
external + offsetof (struct external_syment, u.xcoff32.u.n_name),
|
||||
name_length);
|
||||
internal->n_name[name_length] = 0;
|
||||
|
||||
internal->n_value = READ_OBJECT (external, external_syment,
|
||||
u.xcoff32.n_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal->n_zeroes = 0;
|
||||
internal->n_offset = READ_OBJECT (external, external_syment,
|
||||
u.xcoff64.n_offset);
|
||||
internal->n_value = READ_OBJECT (external, external_syment,
|
||||
u.xcoff64.n_value);
|
||||
}
|
||||
COPY_FIELD (internal, external, external_syment, n_scnum);
|
||||
COPY_FIELD (internal, external, external_syment, n_type);
|
||||
COPY_FIELD (internal, external, external_syment, n_sclass);
|
||||
COPY_FIELD (internal, external, external_syment, n_numaux);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Implement the API-defined ldgetname function. */
|
||||
|
||||
char *
|
||||
ldgetname (LDFILE *ldfile, SYMENT *symbol)
|
||||
{
|
||||
char *name;
|
||||
size_t offset;
|
||||
|
||||
/* If the zeroes field is nonzero, the name is in the symbol table
|
||||
entry itself. */
|
||||
if (symbol->n_zeroes != 0)
|
||||
return symbol->n_name;
|
||||
|
||||
/* Otherwise, the symbol table entry contains an offset into the
|
||||
string table, which starts after the end of the symbol table. */
|
||||
offset = (HEADER (ldfile).f_symptr
|
||||
+ HEADER (ldfile).f_nsyms * sizeof (struct external_syment)
|
||||
+ symbol->n_offset);
|
||||
if (offset >= ldfile->object_size)
|
||||
return NULL;
|
||||
|
||||
/* Make sure that the name is entirely contained within the object. */
|
||||
name = ldfile->object + offset;
|
||||
if (!string_within_bounds_p (name, ldfile->object_size - offset, '\0'))
|
||||
return NULL;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Implement the API-defined ldclose function. */
|
||||
|
||||
int
|
||||
ldclose (LDFILE *ldfile)
|
||||
{
|
||||
free_object (ldfile);
|
||||
if (ldfile->next_member >= 0
|
||||
&& read_archive_member (ldfile, ldfile->next_member))
|
||||
return FAILURE;
|
||||
|
||||
free_ldfile (ldfile);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
301
gcc/collect2-aix.h
Normal file
301
gcc/collect2-aix.h
Normal file
@ -0,0 +1,301 @@
|
||||
/* AIX cross support for collect2.
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
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
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* collect2-aix.c requires mmap support. It should otherwise be
|
||||
fairly portable. */
|
||||
#if defined(CROSS_DIRECTORY_STRUCTURE) \
|
||||
&& defined(TARGET_AIX_VERSION) \
|
||||
&& HAVE_MMAP
|
||||
|
||||
#define CROSS_AIX_SUPPORT 1
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Definitions adapted from bfd. (Fairly heavily adapted in some cases.)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* Compatiblity types for bfd. */
|
||||
typedef unsigned HOST_WIDE_INT bfd_vma;
|
||||
|
||||
/* The size of an archive's fl_magic field. */
|
||||
#define FL_MAGIC_SIZE 8
|
||||
|
||||
/* The expected contents of fl_magic for big archives. */
|
||||
#define FL_MAGIC_BIG_AR "<bigaf>\012"
|
||||
|
||||
/* The size of each offset string in the header of a big archive. */
|
||||
#define AR_BIG_OFFSET_SIZE 20
|
||||
|
||||
/* The format of the file header in a "big" XCOFF archive. */
|
||||
struct external_big_ar_filehdr
|
||||
{
|
||||
/* Magic string. */
|
||||
char fl_magic[FL_MAGIC_SIZE];
|
||||
|
||||
/* Offset of the member table (decimal ASCII string). */
|
||||
char fl_memoff[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* Offset of the global symbol table for 32-bit objects (decimal ASCII
|
||||
string). */
|
||||
char fl_symoff[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* Offset of the global symbol table for 64-bit objects (decimal ASCII
|
||||
string). */
|
||||
char fl_symoff64[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* Offset of the first member in the archive (decimal ASCII string). */
|
||||
char fl_firstmemoff[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* Offset of the last member in the archive (decimal ASCII string). */
|
||||
char fl_lastmemoff[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* Offset of the first member on the free list (decimal ASCII
|
||||
string). */
|
||||
char fl_freeoff[AR_BIG_OFFSET_SIZE];
|
||||
};
|
||||
|
||||
/* Each archive name is followed by this many bytes of magic string. */
|
||||
#define SXCOFFARFMAG 2
|
||||
|
||||
/* The format of a member header in a "big" XCOFF archive. */
|
||||
struct external_big_ar_member
|
||||
{
|
||||
/* File size not including the header (decimal ASCII string). */
|
||||
char ar_size[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* File offset of next archive member (decimal ASCII string). */
|
||||
char ar_nextoff[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* File offset of previous archive member (decimal ASCII string). */
|
||||
char ar_prevoff[AR_BIG_OFFSET_SIZE];
|
||||
|
||||
/* File mtime (decimal ASCII string). */
|
||||
char ar_date[12];
|
||||
|
||||
/* File UID (decimal ASCII string). */
|
||||
char ar_uid[12];
|
||||
|
||||
/* File GID (decimal ASCII string). */
|
||||
char ar_gid[12];
|
||||
|
||||
/* File mode (octal ASCII string). */
|
||||
char ar_mode[12];
|
||||
|
||||
/* Length of file name (decimal ASCII string). */
|
||||
char ar_namlen[4];
|
||||
|
||||
/* This structure is followed by the file name. The length of the
|
||||
name is given in the namlen field. If the length of the name is
|
||||
odd, the name is followed by a null byte. The name and optional
|
||||
null byte are followed by XCOFFARFMAG, which is not included in
|
||||
namlen. The contents of the archive member follow; the number of
|
||||
bytes is given in the size field. */
|
||||
};
|
||||
|
||||
/* The known values of f_magic in an XCOFF file header. */
|
||||
#define U802WRMAGIC 0730 /* Writeable text segments. */
|
||||
#define U802ROMAGIC 0735 /* Readonly sharable text segments. */
|
||||
#define U802TOCMAGIC 0737 /* Readonly text segments and TOC. */
|
||||
#define U803XTOCMAGIC 0757 /* Aix 4.3 64-bit XCOFF. */
|
||||
#define U64_TOCMAGIC 0767 /* AIX 5+ 64-bit XCOFF. */
|
||||
|
||||
/* The number of bytes in an XCOFF file's f_magic field. */
|
||||
#define F_MAGIC_SIZE 2
|
||||
|
||||
/* The format of a 32-bit XCOFF file header. */
|
||||
struct external_filehdr_32
|
||||
{
|
||||
/* The magic number. */
|
||||
char f_magic[F_MAGIC_SIZE];
|
||||
|
||||
/* The number of sections. */
|
||||
char f_nscns[2];
|
||||
|
||||
/* Time & date stamp. */
|
||||
char f_timdat[4];
|
||||
|
||||
/* The offset of the symbol table from the start of the file. */
|
||||
char f_symptr[4];
|
||||
|
||||
/* The number of entries in the symbol table. */
|
||||
char f_nsyms[4];
|
||||
|
||||
/* The size of the auxillary header. */
|
||||
char f_opthdr[2];
|
||||
|
||||
/* Flags. */
|
||||
char f_flags[2];
|
||||
};
|
||||
|
||||
/* The format of a 64-bit XCOFF file header. */
|
||||
struct external_filehdr_64
|
||||
{
|
||||
/* The magic number. */
|
||||
char f_magic[F_MAGIC_SIZE];
|
||||
|
||||
/* The number of sections. */
|
||||
char f_nscns[2];
|
||||
|
||||
/* Time & date stamp. */
|
||||
char f_timdat[4];
|
||||
|
||||
/* The offset of the symbol table from the start of the file. */
|
||||
char f_symptr[8];
|
||||
|
||||
/* The size of the auxillary header. */
|
||||
char f_opthdr[2];
|
||||
|
||||
/* Flags. */
|
||||
char f_flags[2];
|
||||
|
||||
/* The number of entries in the symbol table. */
|
||||
char f_nsyms[4];
|
||||
};
|
||||
|
||||
/* An internal representation of the XCOFF file header. */
|
||||
struct internal_filehdr
|
||||
{
|
||||
unsigned short f_magic;
|
||||
unsigned short f_nscns;
|
||||
long f_timdat;
|
||||
bfd_vma f_symptr;
|
||||
long f_nsyms;
|
||||
unsigned short f_opthdr;
|
||||
unsigned short f_flags;
|
||||
};
|
||||
|
||||
/* Symbol classes have their names in the debug section if this flag
|
||||
is set. */
|
||||
#define DBXMASK 0x80
|
||||
|
||||
/* The format of an XCOFF symbol-table entry. */
|
||||
struct external_syment
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
/* The name of the symbol. There is an implicit null character
|
||||
after the end of the array. */
|
||||
char n_name[8];
|
||||
struct {
|
||||
/* If n_zeroes is zero, n_offset is the offset the name from
|
||||
the start of the string table. */
|
||||
char n_zeroes[4];
|
||||
char n_offset[4];
|
||||
} u;
|
||||
} u;
|
||||
|
||||
/* The symbol's value. */
|
||||
char n_value[4];
|
||||
} xcoff32;
|
||||
struct {
|
||||
/* The symbol's value. */
|
||||
char n_value[8];
|
||||
|
||||
/* The offset of the symbol from the start of the string table. */
|
||||
char n_offset[4];
|
||||
} xcoff64;
|
||||
} u;
|
||||
|
||||
/* The number of the section to which this symbol belongs. */
|
||||
char n_scnum[2];
|
||||
|
||||
/* The type of symbol. (It can be interpreted as an n_lang
|
||||
and an n_cpu byte, but we don't care about that here.) */
|
||||
char n_type[2];
|
||||
|
||||
/* The class of symbol (a C_* value). */
|
||||
char n_sclass[1];
|
||||
|
||||
/* The number of auxillary symbols attached to this entry. */
|
||||
char n_numaux[1];
|
||||
};
|
||||
|
||||
/* Definitions required by collect2. */
|
||||
#define C_EXT 2
|
||||
|
||||
#define F_SHROBJ 0x2000
|
||||
|
||||
#define N_UNDEF ((short) 0)
|
||||
#define N_TMASK 060
|
||||
#define N_BTSHFT 4
|
||||
|
||||
#define DT_NON 0
|
||||
#define DT_FCN 2
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Local code.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* An internal representation of an XCOFF symbol-table entry,
|
||||
which is associated with the API-defined SYMENT type. */
|
||||
struct internal_syment
|
||||
{
|
||||
char n_name[9];
|
||||
unsigned int n_zeroes;
|
||||
bfd_vma n_offset;
|
||||
bfd_vma n_value;
|
||||
short n_scnum;
|
||||
unsigned short n_flags;
|
||||
unsigned short n_type;
|
||||
unsigned char n_sclass;
|
||||
unsigned char n_numaux;
|
||||
};
|
||||
typedef struct internal_syment SYMENT;
|
||||
|
||||
/* The internal representation of the API-defined LDFILE type. */
|
||||
struct internal_ldfile
|
||||
{
|
||||
/* The file handle for the associated file, or -1 if it hasn't been
|
||||
opened yet. */
|
||||
int fd;
|
||||
|
||||
/* The start of the current XCOFF object, if one has been mapped
|
||||
into memory. Null otherwise. */
|
||||
char *object;
|
||||
|
||||
/* The offset of OBJECT from the start of the containing page. */
|
||||
size_t page_offset;
|
||||
|
||||
/* The size of the file pointed to by OBJECT. Valid iff OFFSET
|
||||
is nonnull. */
|
||||
size_t object_size;
|
||||
|
||||
/* The offset of the next member in an archive after OBJECT,
|
||||
or -1 if this isn't an archive. Valid iff OFFSET is nonnull. */
|
||||
off_t next_member;
|
||||
|
||||
/* The parsed version of the XCOFF file header. */
|
||||
struct internal_filehdr filehdr;
|
||||
};
|
||||
typedef struct internal_ldfile LDFILE;
|
||||
|
||||
/* The API allows the file header to be directly accessed via this macro. */
|
||||
#define HEADER(FILE) ((FILE)->filehdr)
|
||||
|
||||
/* API-defined return codes. SUCCESS must be > 0 and FAILURE must be <= 0. */
|
||||
#define SUCCESS 1
|
||||
#define FAILURE 0
|
||||
|
||||
/* API-defined functions. */
|
||||
extern LDFILE *ldopen (char *, LDFILE *);
|
||||
extern char *ldgetname (LDFILE *, SYMENT *);
|
||||
extern int ldtbread (LDFILE *, long, SYMENT *);
|
||||
extern int ldclose (LDFILE *);
|
||||
|
||||
#endif
|
@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#define COLLECT
|
||||
|
||||
#include "collect2.h"
|
||||
#include "collect2-aix.h"
|
||||
#include "demangle.h"
|
||||
#include "obstack.h"
|
||||
#include "intl.h"
|
||||
@ -54,7 +55,9 @@ along with GCC; see the file COPYING3. If not see
|
||||
cross-versions are in the proper directories. */
|
||||
|
||||
#ifdef CROSS_DIRECTORY_STRUCTURE
|
||||
#ifndef CROSS_AIX_SUPPORT
|
||||
#undef OBJECT_FORMAT_COFF
|
||||
#endif
|
||||
#undef MD_EXEC_PREFIX
|
||||
#undef REAL_LD_FILE_NAME
|
||||
#undef REAL_NM_FILE_NAME
|
||||
@ -72,6 +75,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
|
||||
#ifdef OBJECT_FORMAT_COFF
|
||||
|
||||
#ifndef CROSS_DIRECTORY_STRUCTURE
|
||||
#include <a.out.h>
|
||||
#include <ar.h>
|
||||
|
||||
@ -86,6 +90,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#endif
|
||||
|
||||
#include <ldfcn.h>
|
||||
#endif
|
||||
|
||||
/* Some systems have an ISCOFF macro, but others do not. In some cases
|
||||
the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
|
||||
@ -2409,7 +2414,7 @@ scan_libraries (const char *prog_name)
|
||||
# define GCC_SYMZERO(X) 0
|
||||
|
||||
/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
|
||||
#ifdef _AIX51
|
||||
#if TARGET_AIX_VERSION >= 51
|
||||
# define GCC_CHECK_HDR(X) \
|
||||
((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
|
||||
|| (HEADER (X).f_magic == 0767 && aix64_flag))
|
||||
|
@ -187,3 +187,5 @@ do { \
|
||||
|
||||
/* This target uses the aix64.opt file. */
|
||||
#define TARGET_USES_AIX64_OPT 1
|
||||
|
||||
#define TARGET_AIX_VERSION 43
|
||||
|
@ -191,3 +191,5 @@ do { \
|
||||
but does not have crtbegin/end. */
|
||||
|
||||
#define TARGET_USE_JCR_SECTION 0
|
||||
|
||||
#define TARGET_AIX_VERSION 51
|
||||
|
@ -201,3 +201,5 @@ extern long long int atoll(const char *);
|
||||
but does not have crtbegin/end. */
|
||||
|
||||
#define TARGET_USE_JCR_SECTION 0
|
||||
|
||||
#define TARGET_AIX_VERSION 52
|
||||
|
@ -197,3 +197,5 @@ extern long long int atoll(const char *);
|
||||
but does not have crtbegin/end. */
|
||||
|
||||
#define TARGET_USE_JCR_SECTION 0
|
||||
|
||||
#define TARGET_AIX_VERSION 53
|
||||
|
@ -202,3 +202,5 @@ extern long long int atoll(const char *);
|
||||
/* Default to 128 bit long double. */
|
||||
|
||||
#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
|
||||
|
||||
#define TARGET_AIX_VERSION 61
|
||||
|
Loading…
Reference in New Issue
Block a user