summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog30
-rw-r--r--bfd/Makefile.am20
-rw-r--r--bfd/Makefile.in22
-rw-r--r--bfd/archures.c25
-rw-r--r--bfd/bfd-in2.h12
-rw-r--r--bfd/bfd.c29
-rw-r--r--bfd/doc/Makefile.in2
-rw-r--r--bfd/mach-o-target.c117
-rw-r--r--bfd/mach-o.c2163
-rw-r--r--bfd/mach-o.h490
-rw-r--r--bfd/pef-traceback.h215
-rw-r--r--bfd/pef.c1207
-rw-r--r--bfd/pef.h186
-rw-r--r--bfd/targets.c42
-rw-r--r--bfd/xsym.c2449
-rw-r--r--bfd/xsym.h699
16 files changed, 7660 insertions, 48 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 09714d1e04..d78a72d579 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,33 @@
+2002-11-06 Klee Dienes <kdienes@apple.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add mach-o.lo, pef.lo, and
+ xsym.lo.
+ (BFD32_BACKENDS_CFILES): Add mach-o.c, pef.c, and xsym.c.
+ (SOURCE_HFILES): Add mach-o.h, pef.h, pef-traceback.h, xsym.h
+ * archures.c (enum bfd_architecture): Add bfd_arch_m98k.
+ * bfd.c (struct bfd): Add private data for mach-o, pef, and sym.
+ * targets.c (enum bfd_flavour): Add flavours for mach-o, pef, and
+ sym.
+ (_bfd_target_vector): Add target vectors for mach-o, pef, and sym.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * xsym.c: New file. Contains support for the Apple/Metrowerks
+ xSYM debugging format.
+ * xsym.h: New file.
+ * pef.c: New file. Contains support for the Apple Code Fragment
+ Manager Preferred Executable Format
+ * pef.h: New file.
+ * pef-traceback.h: New file. Contains support for parsing PowerPC
+ traceback tables as used by PEF executables (and perhaps other
+ systems as well).
+ * mach-o.c: New file. Contains support for the Mach-O object file
+ format.
+ * mach-o.h: New file.
+ * mach-o-target.c: New file. Declares the mach-o targets
+ themselves. Included three times by mach-o.c; each time with a
+ different set of macros set.
+
2002-11-06 Graeme Peterson <gp@qnx.com>
* Makefile.am: Remove entries for elf32-qnx.[ch].
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 59c2668be5..0c1a798044 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -266,6 +266,7 @@ BFD32_BACKENDS = \
m68klynx.lo \
m68knetbsd.lo \
m88kmach3.lo \
+ mach-o.lo \
mipsbsd.lo \
newsos3.lo \
nlm.lo \
@@ -277,6 +278,7 @@ BFD32_BACKENDS = \
oasys.lo \
pc532-mach.lo \
pdp11.lo \
+ pef.lo \
pe-arm.lo \
pei-arm.lo \
pe-i386.lo \
@@ -306,7 +308,8 @@ BFD32_BACKENDS = \
vms-hdr.lo \
vms-misc.lo \
vms-tir.lo \
- xcofflink.lo
+ xcofflink.lo \
+ xsym.lo
BFD32_BACKENDS_CFILES = \
aout-adobe.c \
@@ -420,6 +423,7 @@ BFD32_BACKENDS_CFILES = \
m68klynx.c \
m68knetbsd.c \
m88kmach3.c \
+ mach-o.c \
mipsbsd.c \
newsos3.c \
nlm.c \
@@ -431,6 +435,7 @@ BFD32_BACKENDS_CFILES = \
oasys.c \
pc532-mach.c \
pdp11.c \
+ pef.c \
pe-arm.c \
pei-arm.c \
pe-i386.c \
@@ -459,7 +464,8 @@ BFD32_BACKENDS_CFILES = \
vms-hdr.c \
vms-misc.c \
vms-tir.c \
- xcofflink.c
+ xcofflink.c \
+ xsym.c
# The .o files needed by all of the 64 bit vectors that are configured into
# target_vector in targets.c if configured with --enable-targets=all
@@ -563,9 +569,10 @@ SOURCE_HFILES = \
elf64-hppa.h elfcode.h elfcore.h elflink.h \
freebsd.h genlink.h go32stub.h \
libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
- libnlm.h liboasys.h libpei.h libxcoff.h \
+ libnlm.h liboasys.h libpei.h libxcoff.h mach-o.h \
netbsd.h nlm-target.h nlmcode.h nlmswap.h ns32k.h \
- peicode.h som.h version.h vms.h xcoff-target.h
+ pef.h pef-traceback.h peicode.h som.h version.h \
+ vms.h xcoff-target.h xsym.h
## ... and all .h files which are in the build tree.
BUILD_HFILES = \
@@ -1327,6 +1334,8 @@ m68knetbsd.lo: m68knetbsd.c netbsd.h $(INCDIR)/filenames.h \
m88kmach3.lo: m88kmach3.c $(INCDIR)/filenames.h libaout.h \
$(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/aout64.h \
$(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+mach-o.lo: mach-o.c mach-o.h $(INCDIR)/filenames.h \
+ $(INCDIR)/libiberty.h mach-o-target.c
mipsbsd.lo: mipsbsd.c $(INCDIR)/filenames.h libaout.h \
$(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/aout64.h \
$(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
@@ -1358,6 +1367,8 @@ pc532-mach.lo: pc532-mach.c $(INCDIR)/filenames.h libaout.h \
pdp11.lo: pdp11.c $(INCDIR)/filenames.h libaout.h $(INCDIR)/bfdlink.h \
aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
$(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h $(INCDIR)/safe-ctype.h
+pef.lo: pef.c pef.h pef-traceback.h $(INCDIR)/filenames.h \
+ $(INCDIR)/libiberty.h
pe-arm.lo: pe-arm.c $(INCDIR)/filenames.h coff-arm.c \
$(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h \
@@ -1450,6 +1461,7 @@ vms-tir.lo: vms-tir.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
xcofflink.lo: xcofflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/xcoff.h libcoff.h \
libxcoff.h
+xsym.lo: xsym.c xsym.h $(INCDIR)/filenames.h
aix5ppc-core.lo: aix5ppc-core.c
aout64.lo: aout64.c aoutx.h $(INCDIR)/filenames.h $(INCDIR)/safe-ctype.h \
$(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index bce5486a9e..0104743b6f 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -393,6 +393,7 @@ BFD32_BACKENDS = \
m68klynx.lo \
m68knetbsd.lo \
m88kmach3.lo \
+ mach-o.lo \
mipsbsd.lo \
newsos3.lo \
nlm.lo \
@@ -404,6 +405,7 @@ BFD32_BACKENDS = \
oasys.lo \
pc532-mach.lo \
pdp11.lo \
+ pef.lo \
pe-arm.lo \
pei-arm.lo \
pe-i386.lo \
@@ -433,7 +435,8 @@ BFD32_BACKENDS = \
vms-hdr.lo \
vms-misc.lo \
vms-tir.lo \
- xcofflink.lo
+ xcofflink.lo \
+ xsym.lo
BFD32_BACKENDS_CFILES = \
@@ -548,6 +551,7 @@ BFD32_BACKENDS_CFILES = \
m68klynx.c \
m68knetbsd.c \
m88kmach3.c \
+ mach-o.c \
mipsbsd.c \
newsos3.c \
nlm.c \
@@ -559,6 +563,7 @@ BFD32_BACKENDS_CFILES = \
oasys.c \
pc532-mach.c \
pdp11.c \
+ pef.c \
pe-arm.c \
pei-arm.c \
pe-i386.c \
@@ -587,7 +592,8 @@ BFD32_BACKENDS_CFILES = \
vms-hdr.c \
vms-misc.c \
vms-tir.c \
- xcofflink.c
+ xcofflink.c \
+ xsym.c
# The .o files needed by all of the 64 bit vectors that are configured into
@@ -697,9 +703,10 @@ SOURCE_HFILES = \
elf64-hppa.h elfcode.h elfcore.h elflink.h \
freebsd.h genlink.h go32stub.h \
libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
- libnlm.h liboasys.h libpei.h libxcoff.h \
+ libnlm.h liboasys.h libpei.h libxcoff.h mach-o.h \
netbsd.h nlm-target.h nlmcode.h nlmswap.h ns32k.h \
- peicode.h som.h version.h vms.h xcoff-target.h
+ pef.h pef-traceback.h peicode.h som.h version.h \
+ vms.h xcoff-target.h xsym.h
BUILD_HFILES = \
@@ -778,7 +785,7 @@ configure.in version.h
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-TAR = tar
+TAR = gtar
GZIP_ENV = --best
SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES)
OBJECTS = $(libbfd_a_OBJECTS) $(libbfd_la_OBJECTS)
@@ -1858,6 +1865,8 @@ m68knetbsd.lo: m68knetbsd.c netbsd.h $(INCDIR)/filenames.h \
m88kmach3.lo: m88kmach3.c $(INCDIR)/filenames.h libaout.h \
$(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/aout64.h \
$(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
+mach-o.lo: mach-o.c mach-o.h $(INCDIR)/filenames.h \
+ $(INCDIR)/libiberty.h mach-o-target.c
mipsbsd.lo: mipsbsd.c $(INCDIR)/filenames.h libaout.h \
$(INCDIR)/bfdlink.h aout-target.h $(INCDIR)/aout/aout64.h \
$(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h
@@ -1889,6 +1898,8 @@ pc532-mach.lo: pc532-mach.c $(INCDIR)/filenames.h libaout.h \
pdp11.lo: pdp11.c $(INCDIR)/filenames.h libaout.h $(INCDIR)/bfdlink.h \
aout-target.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
$(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h $(INCDIR)/safe-ctype.h
+pef.lo: pef.c pef.h pef-traceback.h $(INCDIR)/filenames.h \
+ $(INCDIR)/libiberty.h
pe-arm.lo: pe-arm.c $(INCDIR)/filenames.h coff-arm.c \
$(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
$(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h \
@@ -1981,6 +1992,7 @@ vms-tir.lo: vms-tir.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
xcofflink.lo: xcofflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/xcoff.h libcoff.h \
libxcoff.h
+xsym.lo: xsym.c xsym.h $(INCDIR)/filenames.h
aix5ppc-core.lo: aix5ppc-core.c
aout64.lo: aout64.c aoutx.h $(INCDIR)/filenames.h $(INCDIR)/safe-ctype.h \
$(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
diff --git a/bfd/archures.c b/bfd/archures.c
index 1ab0cfa52c..485fef2740 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -4,21 +4,21 @@
Free Software Foundation, Inc.
Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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 Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program 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.
+ This program 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 this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
@@ -160,6 +160,7 @@ DESCRIPTION
. bfd_arch_alliant, {* Alliant *}
. bfd_arch_convex, {* Convex *}
. bfd_arch_m88k, {* Motorola 88xxx *}
+. bfd_arch_m98k, {* Motorola 98xxx *}
. bfd_arch_pyramid, {* Pyramid Technology *}
. bfd_arch_h8300, {* Hitachi H8/300 *}
.#define bfd_mach_h8300 1
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 018a0fd292..b58e7f5d39 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1551,6 +1551,7 @@ enum bfd_architecture
bfd_arch_alliant, /* Alliant */
bfd_arch_convex, /* Convex */
bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
bfd_arch_pyramid, /* Pyramid Technology */
bfd_arch_h8300, /* Hitachi H8/300 */
#define bfd_mach_h8300 1
@@ -3533,6 +3534,11 @@ struct _bfd
struct cisco_core_struct *cisco_core_data;
struct versados_data_struct *versados_data;
struct netbsd_core_struct *netbsd_core_data;
+ struct mach_o_data_struct *mach_o_data;
+ struct mach_o_fat_data_struct *mach_o_fat_data;
+ struct bfd_pef_data_struct *pef_data;
+ struct bfd_pef_xlib_data_struct *pef_xlib_data;
+ struct bfd_sym_data_struct *sym_data;
PTR any;
}
tdata;
@@ -3795,7 +3801,11 @@ enum bfd_flavour
bfd_target_msdos_flavour,
bfd_target_ovax_flavour,
bfd_target_evax_flavour,
- bfd_target_mmo_flavour
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
};
enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
diff --git a/bfd/bfd.c b/bfd/bfd.c
index bf45162165..cff7119ee2 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -4,21 +4,21 @@
Free Software Foundation, Inc.
Written by Cygnus Support.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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 Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program 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.
+ This program 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 this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
SECTION
@@ -180,6 +180,11 @@ CODE_FRAGMENT
. struct cisco_core_struct *cisco_core_data;
. struct versados_data_struct *versados_data;
. struct netbsd_core_struct *netbsd_core_data;
+. struct mach_o_data_struct *mach_o_data;
+. struct mach_o_fat_data_struct *mach_o_fat_data;
+. struct bfd_pef_data_struct *pef_data;
+. struct bfd_pef_xlib_data_struct *pef_xlib_data;
+. struct bfd_sym_data_struct *sym_data;
. PTR any;
. }
. tdata;
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index d25bbf2c74..ec09ffb70f 100644
--- a/bfd/doc/Makefile.in
+++ b/bfd/doc/Makefile.in
@@ -245,7 +245,7 @@ DIST_COMMON = ChangeLog Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-TAR = tar
+TAR = gtar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c
new file mode 100644
index 0000000000..b271bfc87f
--- /dev/null
+++ b/bfd/mach-o-target.c
@@ -0,0 +1,117 @@
+/* Mach-O support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TARGET_NAME
+#error TARGET_NAME must be defined
+#endif /* TARGET_NAME */
+
+#ifndef TARGET_STRING
+#error TARGET_STRING must be defined
+#endif /* TARGET_STRING */
+
+#ifndef TARGET_BIG_ENDIAN
+#error TARGET_BIG_ENDIAN must be defined
+#endif /* TARGET_BIG_ENDIAN */
+
+#ifndef TARGET_ARCHIVE
+#error TARGET_ARCHIVE must be defined
+#endif /* TARGET_ARCHIVE */
+
+#if ((TARGET_ARCHIVE) && (! TARGET_BIG_ENDIAN))
+#error Mach-O fat files must always be big-endian.
+#endif /* ((TARGET_ARCHIVE) && (! TARGET_BIG_ENDIAN)) */
+
+const bfd_target TARGET_NAME =
+{
+ TARGET_STRING, /* Name. */
+ bfd_target_mach_o_flavour,
+#if TARGET_BIG_ENDIAN
+ BFD_ENDIAN_BIG, /* Target byte order. */
+ BFD_ENDIAN_BIG, /* Target headers byte order. */
+#else
+ BFD_ENDIAN_LITTLE, /* Target byte order. */
+ BFD_ENDIAN_LITTLE, /* Target headers byte order. */
+#endif
+ (HAS_RELOC | EXEC_P | /* Object flags. */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
+ '_', /* symbol_leading_char. */
+ ' ', /* ar_pad_char. */
+ 16, /* ar_max_namelen. */
+
+#if TARGET_BIG_ENDIAN
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Hdrs. */
+#else
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
+#endif /* TARGET_BIG_ENDIAN */
+
+ { /* bfd_check_format. */
+#if TARGET_ARCHIVE
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ bfd_mach_o_archive_p,
+ _bfd_dummy_target,
+#else
+ _bfd_dummy_target,
+ bfd_mach_o_object_p,
+ _bfd_dummy_target,
+ bfd_mach_o_core_p
+#endif
+ },
+ { /* bfd_set_format. */
+ bfd_false,
+ bfd_mach_o_mkobject,
+ bfd_false,
+ bfd_mach_o_mkobject,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ bfd_mach_o_write_contents,
+ bfd_false,
+ bfd_mach_o_write_contents,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_mach_o),
+ BFD_JUMP_TABLE_COPY (bfd_mach_o),
+ BFD_JUMP_TABLE_CORE (bfd_mach_o),
+ BFD_JUMP_TABLE_ARCHIVE (bfd_mach_o),
+ BFD_JUMP_TABLE_SYMBOLS (bfd_mach_o),
+ BFD_JUMP_TABLE_RELOCS (bfd_mach_o),
+ BFD_JUMP_TABLE_WRITE (bfd_mach_o),
+ BFD_JUMP_TABLE_LINK (bfd_mach_o),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
+
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
new file mode 100644
index 0000000000..62432203d0
--- /dev/null
+++ b/bfd/mach-o.c
@@ -0,0 +1,2163 @@
+/* Mach-O support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "mach-o.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include <ctype.h>
+
+#ifndef BFD_IO_FUNCS
+#define BFD_IO_FUNCS 0
+#endif
+
+#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
+#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
+#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
+#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
+#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
+#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
+#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
+#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
+#define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
+#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
+#define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
+#define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
+#define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
+#define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
+#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+#define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
+#define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
+#define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_mach_o_bfd_final_link _bfd_generic_final_link
+#define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
+#define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+#define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
+#define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
+#define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
+
+static boolean bfd_mach_o_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *, bfd *, asymbol *));
+static boolean bfd_mach_o_bfd_copy_private_section_data PARAMS ((bfd *, asection *, bfd *, asection *));
+static boolean bfd_mach_o_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static long bfd_mach_o_count_symbols PARAMS ((bfd *));
+static long bfd_mach_o_get_symtab_upper_bound PARAMS ((bfd *));
+static long bfd_mach_o_get_symtab PARAMS ((bfd *, asymbol **));
+static void bfd_mach_o_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static void bfd_mach_o_print_symbol PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+static void bfd_mach_o_convert_architecture PARAMS ((bfd_mach_o_cpu_type, bfd_mach_o_cpu_subtype, enum bfd_architecture *, unsigned long *));
+static boolean bfd_mach_o_write_contents PARAMS ((bfd *));
+static int bfd_mach_o_sizeof_headers PARAMS ((bfd *, boolean));
+static asymbol * bfd_mach_o_make_empty_symbol PARAMS ((bfd *));
+static int bfd_mach_o_write_header PARAMS ((bfd *, bfd_mach_o_header *));
+static int bfd_mach_o_read_header PARAMS ((bfd *, bfd_mach_o_header *));
+static asection * bfd_mach_o_make_bfd_section PARAMS ((bfd *, bfd_mach_o_section *));
+static int bfd_mach_o_scan_read_section PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
+static int bfd_mach_o_scan_write_section PARAMS ((bfd *, bfd_mach_o_section *, bfd_vma));
+static int bfd_mach_o_scan_write_symtab_symbols PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_write_thread PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_dylinker PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_dylib PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_prebound_dylib PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_thread PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_write_symtab PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_dysymtab PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_symtab PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_segment PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_write_segment PARAMS ((bfd *, bfd_mach_o_load_command *));
+static int bfd_mach_o_scan_read_command PARAMS ((bfd *, bfd_mach_o_load_command *));
+static void bfd_mach_o_flatten_sections PARAMS ((bfd *));
+static const char * bfd_mach_o_i386_flavour_string PARAMS ((unsigned int));
+static const char * bfd_mach_o_ppc_flavour_string PARAMS ((unsigned int));
+
+/* The flags field of a section structure is separated into two parts a section
+ type and section attributes. The section types are mutually exclusive (it
+ can only have one type) but the section attributes are not (it may have more
+ than one attribute). */
+
+#define SECTION_TYPE 0x000000ff /* 256 section types. */
+#define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
+
+/* Constants for the section attributes part of the flags field of a section
+ structure. */
+
+#define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
+#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
+#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
+#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
+#define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
+#define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
+
+#define N_STAB 0xe0
+#define N_TYPE 0x1e
+#define N_EXT 0x01
+#define N_UNDF 0x0
+#define N_ABS 0x2
+#define N_SECT 0xe
+#define N_INDR 0xa
+
+boolean
+bfd_mach_o_valid (abfd)
+ bfd *abfd;
+{
+ if (abfd == NULL || abfd->xvec == NULL)
+ return 0;
+
+ if (! ((abfd->xvec == &mach_o_be_vec)
+ || (abfd->xvec == &mach_o_le_vec)
+ || (abfd->xvec == &mach_o_fat_vec)))
+ return 0;
+
+ if (abfd->tdata.mach_o_data == NULL)
+ return 0;
+ return 1;
+}
+
+/* Copy any private info we understand from the input symbol
+ to the output symbol. */
+
+static boolean
+bfd_mach_o_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol)
+ bfd *ibfd ATTRIBUTE_UNUSED;
+ asymbol *isymbol ATTRIBUTE_UNUSED;
+ bfd *obfd ATTRIBUTE_UNUSED;
+ asymbol *osymbol ATTRIBUTE_UNUSED;
+{
+ return true;
+}
+
+/* Copy any private info we understand from the input section
+ to the output section. */
+
+static boolean
+bfd_mach_o_bfd_copy_private_section_data (ibfd, isection, obfd, osection)
+ bfd *ibfd ATTRIBUTE_UNUSED;
+ asection *isection ATTRIBUTE_UNUSED;
+ bfd *obfd ATTRIBUTE_UNUSED;
+ asection *osection ATTRIBUTE_UNUSED;
+{
+ return true;
+}
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+static boolean
+bfd_mach_o_bfd_copy_private_bfd_data (ibfd, obfd)
+ bfd *ibfd;
+ bfd *obfd;
+{
+ BFD_ASSERT (bfd_mach_o_valid (ibfd));
+ BFD_ASSERT (bfd_mach_o_valid (obfd));
+
+ obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
+ obfd->tdata.mach_o_data->ibfd = ibfd;
+ return true;
+}
+
+static long
+bfd_mach_o_count_symbols (abfd)
+ bfd *abfd;
+{
+ bfd_mach_o_data_struct *mdata = NULL;
+ long nsyms = 0;
+ unsigned long i;
+
+ BFD_ASSERT (bfd_mach_o_valid (abfd));
+ mdata = abfd->tdata.mach_o_data;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
+ {
+ bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
+ nsyms += sym->nsyms;
+ }
+
+ return nsyms;
+}
+
+static long
+bfd_mach_o_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ long nsyms = bfd_mach_o_count_symbols (abfd);
+
+ if (nsyms < 0)
+ return nsyms;
+
+ return ((nsyms + 1) * sizeof (asymbol *));
+}
+
+static long
+bfd_mach_o_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
+ long nsyms = bfd_mach_o_count_symbols (abfd);
+ asymbol **csym = alocation;
+ unsigned long i, j;
+
+ if (nsyms < 0)
+ return nsyms;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
+ {
+ bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
+
+ if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
+ {
+ fprintf (stderr, "bfd_mach_o_get_symtab: unable to load symbols for section %lu\n", i);
+ return 0;
+ }
+
+ BFD_ASSERT (sym->symbols != NULL);
+
+ for (j = 0; j < sym->nsyms; j++)
+ {
+ BFD_ASSERT (csym < (alocation + nsyms));
+ *csym++ = &sym->symbols[j];
+ }
+ }
+ }
+
+ *csym++ = NULL;
+
+ return nsyms;
+}
+
+static void
+bfd_mach_o_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static void
+bfd_mach_o_print_symbol (abfd, afile, symbol, how)
+ bfd *abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ default:
+ bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
+ fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
+ }
+}
+
+static void
+bfd_mach_o_convert_architecture (mtype, msubtype, type, subtype)
+ bfd_mach_o_cpu_type mtype;
+ bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED;
+ enum bfd_architecture *type;
+ unsigned long *subtype;
+{
+ *subtype = bfd_arch_unknown;
+
+ switch (mtype)
+ {
+ case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
+ case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
+ case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
+ case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
+ case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
+ case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
+ case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
+ case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
+ case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
+ case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
+ case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
+ case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
+ default: *type = bfd_arch_unknown; break;
+ }
+
+ switch (*type)
+ {
+ case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
+ case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
+ default:
+ *subtype = bfd_arch_unknown;
+ }
+}
+
+static boolean
+bfd_mach_o_write_contents (abfd)
+ bfd *abfd;
+{
+ unsigned int i;
+ asection *s;
+
+ bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
+
+ /* Write data sections first in case they overlap header data to be
+ written later. */
+
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ ;
+
+#if 0
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ bfd_mach_o_load_command *cur = &mdata->commands[i];
+ if (cur->type != BFD_MACH_O_LC_SEGMENT)
+ break;
+
+ {
+ bfd_mach_o_segment_command *seg = &cur->command.segment;
+ char buf[1024];
+ bfd_vma nbytes = seg->filesize;
+ bfd_vma curoff = seg->fileoff;
+
+ while (nbytes > 0)
+ {
+ bfd_vma thisread = nbytes;
+
+ if (thisread > 1024)
+ thisread = 1024;
+
+ bfd_seek (abfd, curoff, SEEK_SET);
+ if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
+ return false;
+
+ bfd_seek (abfd, curoff, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
+ return false;
+
+ nbytes -= thisread;
+ curoff += thisread;
+ }
+ }
+ }
+#endif
+
+ /* Now write header information. */
+ if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
+ return false;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ unsigned char buf[8];
+ bfd_mach_o_load_command *cur = &mdata->commands[i];
+ unsigned long typeflag;
+
+ typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
+
+ bfd_h_put_32 (abfd, typeflag, buf);
+ bfd_h_put_32 (abfd, cur->len, buf + 4);
+
+ bfd_seek (abfd, cur->offset, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
+ return false;
+
+ switch (cur->type)
+ {
+ case BFD_MACH_O_LC_SEGMENT:
+ if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
+ return false;
+ break;
+ case BFD_MACH_O_LC_SYMTAB:
+ if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
+ return false;
+ break;
+ case BFD_MACH_O_LC_SYMSEG:
+ break;
+ case BFD_MACH_O_LC_THREAD:
+ case BFD_MACH_O_LC_UNIXTHREAD:
+ if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
+ return false;
+ break;
+ case BFD_MACH_O_LC_LOADFVMLIB:
+ case BFD_MACH_O_LC_IDFVMLIB:
+ case BFD_MACH_O_LC_IDENT:
+ case BFD_MACH_O_LC_FVMFILE:
+ case BFD_MACH_O_LC_PREPAGE:
+ case BFD_MACH_O_LC_DYSYMTAB:
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
+ case BFD_MACH_O_LC_ID_DYLIB:
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ case BFD_MACH_O_LC_ID_DYLINKER:
+ case BFD_MACH_O_LC_PREBOUND_DYLIB:
+ case BFD_MACH_O_LC_ROUTINES:
+ case BFD_MACH_O_LC_SUB_FRAMEWORK:
+ break;
+ default:
+ fprintf (stderr,
+ "unable to write unknown load command 0x%lx\n",
+ (long) cur->type);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static int
+bfd_mach_o_sizeof_headers (a, b)
+ bfd *a ATTRIBUTE_UNUSED;
+ boolean b ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+/* Make an empty symbol. This is required only because
+ bfd_make_section_anyway wants to create a symbol for the section. */
+
+static asymbol *
+bfd_mach_o_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ asymbol *new;
+
+ new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+ if (new == NULL)
+ return new;
+ new->the_bfd = abfd;
+ return new;
+}
+
+static int
+bfd_mach_o_write_header (abfd, header)
+ bfd *abfd;
+ bfd_mach_o_header *header;
+{
+ unsigned char buf[28];
+
+ bfd_h_put_32 (abfd, header->magic, buf + 0);
+ bfd_h_put_32 (abfd, header->cputype, buf + 4);
+ bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
+ bfd_h_put_32 (abfd, header->filetype, buf + 12);
+ bfd_h_put_32 (abfd, header->ncmds, buf + 16);
+ bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
+ bfd_h_put_32 (abfd, header->flags, buf + 24);
+
+ bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
+ return -1;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_read_header (abfd, header)
+ bfd *abfd;
+ bfd_mach_o_header *header;
+{
+ unsigned char buf[28];
+ bfd_vma (*get32) PARAMS ((const bfd_byte *)) = NULL;
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ if (bfd_bread ((PTR) buf, 28, abfd) != 28)
+ return -1;
+
+ if (bfd_getb32 (buf) == 0xfeedface)
+ {
+ header->byteorder = BFD_ENDIAN_BIG;
+ header->magic = 0xfeedface;
+ get32 = bfd_getb32;
+ }
+ else if (bfd_getl32 (buf) == 0xfeedface)
+ {
+ header->byteorder = BFD_ENDIAN_LITTLE;
+ header->magic = 0xfeedface;
+ get32 = bfd_getl32;
+ }
+ else
+ {
+ header->byteorder = BFD_ENDIAN_UNKNOWN;
+ return -1;
+ }
+
+ header->cputype = (*get32) (buf + 4);
+ header->cpusubtype = (*get32) (buf + 8);
+ header->filetype = (*get32) (buf + 12);
+ header->ncmds = (*get32) (buf + 16);
+ header->sizeofcmds = (*get32) (buf + 20);
+ header->flags = (*get32) (buf + 24);
+
+ return 0;
+}
+
+static asection *
+bfd_mach_o_make_bfd_section (abfd, section)
+ bfd *abfd;
+ bfd_mach_o_section *section;
+{
+ asection *bfdsec;
+ char *sname;
+ const char *prefix = "LC_SEGMENT";
+ unsigned int snamelen;
+
+ snamelen = strlen (prefix) + 1
+ + strlen (section->segname) + 1
+ + strlen (section->sectname) + 1;
+
+ sname = (char *) bfd_alloc (abfd, snamelen);
+ if (sname == NULL)
+ return NULL;
+ sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
+
+ bfdsec = bfd_make_section_anyway (abfd, sname);
+ if (bfdsec == NULL)
+ return NULL;
+
+ bfdsec->vma = section->addr;
+ bfdsec->lma = section->addr;
+ bfdsec->_raw_size = section->size;
+ bfdsec->filepos = section->offset;
+ bfdsec->alignment_power = section->align;
+
+ if (section->flags & BFD_MACH_O_S_ZEROFILL)
+ bfdsec->flags = SEC_ALLOC;
+ else
+ bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
+
+ return bfdsec;
+}
+
+static int
+bfd_mach_o_scan_read_section (abfd, section, offset)
+ bfd *abfd;
+ bfd_mach_o_section *section;
+ bfd_vma offset;
+{
+ unsigned char buf[68];
+
+ bfd_seek (abfd, offset, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 68, abfd) != 68)
+ return -1;
+
+ memcpy (section->sectname, buf, 16);
+ section->sectname[16] = '\0';
+ memcpy (section->segname, buf + 16, 16);
+ section->segname[16] = '\0';
+ section->addr = bfd_h_get_32 (abfd, buf + 32);
+ section->size = bfd_h_get_32 (abfd, buf + 36);
+ section->offset = bfd_h_get_32 (abfd, buf + 40);
+ section->align = bfd_h_get_32 (abfd, buf + 44);
+ section->reloff = bfd_h_get_32 (abfd, buf + 48);
+ section->nreloc = bfd_h_get_32 (abfd, buf + 52);
+ section->flags = bfd_h_get_32 (abfd, buf + 56);
+ section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
+ section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
+ section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
+
+ if (section->bfdsection == NULL)
+ return -1;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_write_section (abfd, section, offset)
+ bfd *abfd;
+ bfd_mach_o_section *section;
+ bfd_vma offset;
+{
+ unsigned char buf[68];
+
+ memcpy (buf, section->sectname, 16);
+ memcpy (buf + 16, section->segname, 16);
+ bfd_h_put_32 (abfd, section->addr, buf + 32);
+ bfd_h_put_32 (abfd, section->size, buf + 36);
+ bfd_h_put_32 (abfd, section->offset, buf + 40);
+ bfd_h_put_32 (abfd, section->align, buf + 44);
+ bfd_h_put_32 (abfd, section->reloff, buf + 48);
+ bfd_h_put_32 (abfd, section->nreloc, buf + 52);
+ bfd_h_put_32 (abfd, section->flags, buf + 56);
+ /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
+ /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
+
+ bfd_seek (abfd, offset, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
+ return -1;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_write_symtab_symbols (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_symtab_command *sym = &command->command.symtab;
+ asymbol *s = NULL;
+ unsigned long i;
+
+ for (i = 0; i < sym->nsyms; i++)
+ {
+ unsigned char buf[12];
+ bfd_vma symoff = sym->symoff + (i * 12);
+ unsigned char ntype = 0;
+ unsigned char nsect = 0;
+ short ndesc = 0;
+
+ s = &sym->symbols[i];
+
+ /* Don't set this from the symbol information; use stored values. */
+#if 0
+ if (s->flags & BSF_GLOBAL)
+ ntype |= N_EXT;
+ if (s->flags & BSF_DEBUGGING)
+ ntype |= N_STAB;
+
+ if (s->section == bfd_und_section_ptr)
+ ntype |= N_UNDF;
+ else if (s->section == bfd_abs_section_ptr)
+ ntype |= N_ABS;
+ else
+ ntype |= N_SECT;
+#endif
+
+ /* Instead just set from the stored values. */
+ ntype = (s->udata.i >> 24) & 0xff;
+ nsect = (s->udata.i >> 16) & 0xff;
+ ndesc = s->udata.i & 0xffff;
+
+ bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
+ bfd_h_put_8 (abfd, ntype, buf + 4);
+ bfd_h_put_8 (abfd, nsect, buf + 5);
+ bfd_h_put_16 (abfd, ndesc, buf + 6);
+ bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
+
+ bfd_seek (abfd, symoff, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
+ 12, (unsigned long) symoff);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
+ bfd *abfd;
+ bfd_mach_o_symtab_command *sym;
+ asymbol *s;
+ unsigned long i;
+{
+ bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
+ bfd_vma symoff = sym->symoff + (i * 12);
+ unsigned char buf[12];
+ unsigned char type = -1;
+ unsigned char section = -1;
+ short desc = -1;
+ long value = -1;
+ unsigned long stroff = -1;
+ unsigned int symtype = -1;
+
+ BFD_ASSERT (sym->strtab != NULL);
+
+ bfd_seek (abfd, symoff, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 12, abfd) != 12)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
+ 12, (unsigned long) symoff);
+ return -1;
+ }
+
+ stroff = bfd_h_get_32 (abfd, buf);
+ type = bfd_h_get_8 (abfd, buf + 4);
+ symtype = (type & 0x0e);
+ section = bfd_h_get_8 (abfd, buf + 5) - 1;
+ desc = bfd_h_get_16 (abfd, buf + 6);
+ value = bfd_h_get_32 (abfd, buf + 8);
+
+ if (stroff >= sym->strsize)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
+ (unsigned long) stroff, (unsigned long) sym->strsize);
+ return -1;
+ }
+
+ s->the_bfd = abfd;
+ s->name = sym->strtab + stroff;
+ s->value = value;
+ s->udata.i = (type << 24) | (section << 16) | desc;
+ s->flags = 0x0;
+
+ if (type & BFD_MACH_O_N_STAB)
+ {
+ s->flags |= BSF_DEBUGGING;
+ s->section = bfd_und_section_ptr;
+ }
+ else
+ {
+ if (type & BFD_MACH_O_N_PEXT)
+ {
+ type &= ~BFD_MACH_O_N_PEXT;
+ s->flags |= BSF_GLOBAL;
+ }
+
+ if (type & BFD_MACH_O_N_EXT)
+ {
+ type &= ~BFD_MACH_O_N_EXT;
+ s->flags |= BSF_GLOBAL;
+ }
+
+ switch (symtype)
+ {
+ case BFD_MACH_O_N_UNDF:
+ s->section = bfd_und_section_ptr;
+ break;
+ case BFD_MACH_O_N_PBUD:
+ s->section = bfd_und_section_ptr;
+ break;
+ case BFD_MACH_O_N_ABS:
+ s->section = bfd_abs_section_ptr;
+ break;
+ case BFD_MACH_O_N_SECT:
+ if ((section > 0) && (section <= mdata->nsects))
+ {
+ s->section = mdata->sections[section - 1]->bfdsection;
+ s->value = s->value - mdata->sections[section - 1]->addr;
+ }
+ else
+ {
+ /* Mach-O uses 0 to mean "no section"; not an error. */
+ if (section != 0)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
+ "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
+ s->name, section, mdata->nsects);
+ }
+ s->section = bfd_und_section_ptr;
+ }
+ break;
+ case BFD_MACH_O_N_INDR:
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
+ "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
+ s->name);
+ s->section = bfd_und_section_ptr;
+ break;
+ default:
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
+ "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
+ s->name, symtype);
+ s->section = bfd_und_section_ptr;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int
+bfd_mach_o_scan_read_symtab_strtab (abfd, sym)
+ bfd *abfd;
+ bfd_mach_o_symtab_command *sym;
+{
+ BFD_ASSERT (sym->strtab == NULL);
+
+ if (abfd->flags & BFD_IN_MEMORY)
+ {
+ struct bfd_in_memory *b;
+
+ b = (struct bfd_in_memory *) abfd->iostream;
+
+ if ((sym->stroff + sym->strsize) > b->size)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return -1;
+ }
+ sym->strtab = b->buffer + sym->stroff;
+ return 0;
+ }
+
+ sym->strtab = bfd_alloc (abfd, sym->strsize);
+ if (sym->strtab == NULL)
+ return -1;
+
+ bfd_seek (abfd, sym->stroff, SEEK_SET);
+ if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
+ sym->strsize, sym->stroff);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+bfd_mach_o_scan_read_symtab_symbols (abfd, sym)
+ bfd *abfd;
+ bfd_mach_o_symtab_command *sym;
+{
+ unsigned long i;
+ int ret;
+
+ BFD_ASSERT (sym->symbols == NULL);
+ sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
+
+ if (sym->symbols == NULL)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
+ return -1;
+ }
+
+ ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
+ if (ret != 0)
+ return ret;
+
+ for (i = 0; i < sym->nsyms; i++)
+ {
+ ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int
+bfd_mach_o_scan_read_dysymtab_symbol (abfd, dysym, sym, s, i)
+ bfd *abfd;
+ bfd_mach_o_dysymtab_command *dysym;
+ bfd_mach_o_symtab_command *sym;
+ asymbol *s;
+ unsigned long i;
+{
+ unsigned long isymoff = dysym->indirectsymoff + (i * 4);
+ unsigned long symindex;
+ unsigned char buf[4];
+
+ BFD_ASSERT (i < dysym->nindirectsyms);
+
+ bfd_seek (abfd, isymoff, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 4, abfd) != 4)
+ {
+ fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
+ (unsigned long) 4, isymoff);
+ return -1;
+ }
+ symindex = bfd_h_get_32 (abfd, buf);
+
+ return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
+}
+
+static const char *
+bfd_mach_o_i386_flavour_string (flavour)
+ unsigned int flavour;
+{
+ switch ((int) flavour)
+ {
+ case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
+ case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
+ case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
+ case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
+ case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
+ case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
+ case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
+ case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
+ case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
+ case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
+ case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
+ case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
+ default: return "UNKNOWN";
+ }
+}
+
+static const char *
+bfd_mach_o_ppc_flavour_string (flavour)
+ unsigned int flavour;
+{
+ switch ((int) flavour)
+ {
+ case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
+ case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
+ case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
+ case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
+ default: return "UNKNOWN";
+ }
+}
+
+static int
+bfd_mach_o_scan_write_thread (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_thread_command *cmd = &command->command.thread;
+ unsigned int i;
+ unsigned char buf[8];
+ bfd_vma offset;
+ unsigned int nflavours;
+
+ BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
+ || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
+
+ offset = 8;
+ nflavours = 0;
+ for (i = 0; i < cmd->nflavours; i++)
+ {
+ BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
+ BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
+
+ bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
+ bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
+
+ bfd_seek (abfd, command->offset + offset, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
+ return -1;
+
+ offset += cmd->flavours[i].size + 8;
+ }
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_dylinker (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
+ unsigned char buf[4];
+ unsigned int nameoff;
+ asection *bfdsec;
+ char *sname;
+ const char *prefix;
+
+ BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
+ || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 4, abfd) != 4)
+ return -1;
+
+ nameoff = bfd_h_get_32 (abfd, buf + 0);
+
+ cmd->name_offset = command->offset + nameoff;
+ cmd->name_len = command->len - nameoff;
+
+ if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
+ prefix = "LC_LOAD_DYLINKER";
+ else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
+ prefix = "LC_ID_DYLINKER";
+ else
+ abort ();
+
+ sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
+ if (sname == NULL)
+ return -1;
+ strcpy (sname, prefix);
+
+ bfdsec = bfd_make_section_anyway (abfd, sname);
+ if (bfdsec == NULL)
+ return -1;
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->_raw_size = command->len - 8;
+ bfdsec->filepos = command->offset + 8;
+ bfdsec->alignment_power = 0;
+ bfdsec->flags = SEC_HAS_CONTENTS;
+
+ cmd->section = bfdsec;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_dylib (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_dylib_command *cmd = &command->command.dylib;
+ unsigned char buf[16];
+ unsigned int nameoff;
+ asection *bfdsec;
+ char *sname;
+ const char *prefix;
+
+ BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
+ || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
+ || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 16, abfd) != 16)
+ return -1;
+
+ nameoff = bfd_h_get_32 (abfd, buf + 0);
+ cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
+ cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
+ cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
+
+ cmd->name_offset = command->offset + nameoff;
+ cmd->name_len = command->len - nameoff;
+
+ if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
+ prefix = "LC_LOAD_DYLIB";
+ else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
+ prefix = "LC_LOAD_WEAK_DYLIB";
+ else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
+ prefix = "LC_ID_DYLIB";
+ else
+ abort ();
+
+ sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
+ if (sname == NULL)
+ return -1;
+ strcpy (sname, prefix);
+
+ bfdsec = bfd_make_section_anyway (abfd, sname);
+ if (bfdsec == NULL)
+ return -1;
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->_raw_size = command->len - 8;
+ bfdsec->filepos = command->offset + 8;
+ bfdsec->alignment_power = 0;
+ bfdsec->flags = SEC_HAS_CONTENTS;
+
+ cmd->section = bfdsec;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_prebound_dylib (abfd, command)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ bfd_mach_o_load_command *command ATTRIBUTE_UNUSED;
+{
+ /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_thread (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_data_struct *mdata = NULL;
+ bfd_mach_o_thread_command *cmd = &command->command.thread;
+ unsigned char buf[8];
+ bfd_vma offset;
+ unsigned int nflavours;
+ unsigned int i;
+
+ BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
+ || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
+
+ BFD_ASSERT (bfd_mach_o_valid (abfd));
+ mdata = abfd->tdata.mach_o_data;
+
+ offset = 8;
+ nflavours = 0;
+ while (offset != command->len)
+ {
+ if (offset >= command->len)
+ return -1;
+
+ bfd_seek (abfd, command->offset + offset, SEEK_SET);
+
+ if (bfd_bread ((PTR) buf, 8, abfd) != 8)
+ return -1;
+
+ offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
+ nflavours++;
+ }
+
+ cmd->flavours =
+ ((bfd_mach_o_thread_flavour *)
+ bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour)));
+ if (cmd->flavours == NULL)
+ return -1;
+ cmd->nflavours = nflavours;
+
+ offset = 8;
+ nflavours = 0;
+ while (offset != command->len)
+ {
+ if (offset >= command->len)
+ return -1;
+
+ if (nflavours >= cmd->nflavours)
+ return -1;
+
+ bfd_seek (abfd, command->offset + offset, SEEK_SET);
+
+ if (bfd_bread ((PTR) buf, 8, abfd) != 8)
+ return -1;
+
+ cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
+ cmd->flavours[nflavours].offset = command->offset + offset + 8;
+ cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
+ offset += cmd->flavours[nflavours].size + 8;
+ nflavours++;
+ }
+
+ for (i = 0; i < nflavours; i++)
+ {
+ asection *bfdsec;
+ unsigned int snamelen;
+ char *sname;
+ const char *flavourstr;
+ const char *prefix = "LC_THREAD";
+ unsigned int i = 0;
+
+ switch (mdata->header.cputype)
+ {
+ case BFD_MACH_O_CPU_TYPE_POWERPC:
+ flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
+ break;
+ case BFD_MACH_O_CPU_TYPE_I386:
+ flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
+ break;
+ default:
+ flavourstr = "UNKNOWN_ARCHITECTURE";
+ break;
+ }
+
+ snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
+ sname = (char *) bfd_alloc (abfd, snamelen);
+ if (sname == NULL)
+ return -1;
+
+ for (;;)
+ {
+ sprintf (sname, "%s.%s.%u", prefix, flavourstr, i);
+ if (bfd_get_section_by_name (abfd, sname) == NULL) {
+ break;
+ }
+ i++;
+ }
+
+ bfdsec = bfd_make_section (abfd, sname);
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->_raw_size = cmd->flavours[i].size;
+ bfdsec->filepos = cmd->flavours[i].offset;
+ bfdsec->alignment_power = 0x0;
+ bfdsec->flags = SEC_HAS_CONTENTS;
+
+ cmd->section = bfdsec;
+ }
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_write_symtab (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_symtab_command *seg = &command->command.symtab;
+ unsigned char buf[16];
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
+
+ bfd_h_put_32 (abfd, seg->symoff, buf);
+ bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
+ bfd_h_put_32 (abfd, seg->stroff, buf + 8);
+ bfd_h_put_32 (abfd, seg->strsize, buf + 12);
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
+ return -1;
+
+ if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
+ return -1;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_dysymtab (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
+ unsigned char buf[72];
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 72, abfd) != 72)
+ return -1;
+
+ seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
+ seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
+ seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
+ seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
+ seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
+ seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
+ seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
+ seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
+ seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
+ seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
+ seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
+ seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
+ seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
+ seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
+ seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
+ seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
+ seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
+ seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_symtab (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ bfd_mach_o_symtab_command *seg = &command->command.symtab;
+ unsigned char buf[16];
+ asection *bfdsec;
+ char *sname;
+ const char *prefix = "LC_SYMTAB.stabs";
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 16, abfd) != 16)
+ return -1;
+
+ seg->symoff = bfd_h_get_32 (abfd, buf);
+ seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
+ seg->stroff = bfd_h_get_32 (abfd, buf + 8);
+ seg->strsize = bfd_h_get_32 (abfd, buf + 12);
+ seg->symbols = NULL;
+ seg->strtab = NULL;
+
+ sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
+ if (sname == NULL)
+ return -1;
+ strcpy (sname, prefix);
+
+ bfdsec = bfd_make_section_anyway (abfd, sname);
+ if (bfdsec == NULL)
+ return -1;
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->_raw_size = seg->nsyms * 12;
+ bfdsec->filepos = seg->symoff;
+ bfdsec->alignment_power = 0;
+ bfdsec->flags = SEC_HAS_CONTENTS;
+
+ seg->stabs_segment = bfdsec;
+
+ prefix = "LC_SYMTAB.stabstr";
+ sname = (char *) bfd_alloc (abfd, strlen (prefix) + 1);
+ if (sname == NULL)
+ return -1;
+ strcpy (sname, prefix);
+
+ bfdsec = bfd_make_section_anyway (abfd, sname);
+ if (bfdsec == NULL)
+ return -1;
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->_raw_size = seg->strsize;
+ bfdsec->filepos = seg->stroff;
+ bfdsec->alignment_power = 0;
+ bfdsec->flags = SEC_HAS_CONTENTS;
+
+ seg->stabstr_segment = bfdsec;
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_segment (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ unsigned char buf[48];
+ bfd_mach_o_segment_command *seg = &command->command.segment;
+ unsigned long i;
+ asection *bfdsec;
+ char *sname;
+ const char *prefix = "LC_SEGMENT";
+ unsigned int snamelen;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 48, abfd) != 48)
+ return -1;
+
+ memcpy (seg->segname, buf, 16);
+ seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
+ seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
+ seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
+ seg->filesize = bfd_h_get_32 (abfd, buf + 28);
+ /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
+ /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
+ seg->nsects = bfd_h_get_32 (abfd, buf + 40);
+ seg->flags = bfd_h_get_32 (abfd, buf + 44);
+
+ snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
+ sname = (char *) bfd_alloc (abfd, snamelen);
+ if (sname == NULL)
+ return -1;
+ sprintf (sname, "%s.%s", prefix, seg->segname);
+
+ bfdsec = bfd_make_section_anyway (abfd, sname);
+ if (bfdsec == NULL)
+ return -1;
+
+ bfdsec->vma = seg->vmaddr;
+ bfdsec->lma = seg->vmaddr;
+ bfdsec->_raw_size = seg->filesize;
+ bfdsec->filepos = seg->fileoff;
+ bfdsec->alignment_power = 0x0;
+ bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
+
+ seg->segment = bfdsec;
+
+ if (seg->nsects != 0)
+ {
+ seg->sections =
+ ((bfd_mach_o_section *)
+ bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section)));
+ if (seg->sections == NULL)
+ return -1;
+
+ for (i = 0; i < seg->nsects; i++)
+ {
+ bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
+
+ if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i], segoff) != 0)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_write_segment (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ unsigned char buf[48];
+ bfd_mach_o_segment_command *seg = &command->command.segment;
+ unsigned long i;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
+
+ memcpy (buf, seg->segname, 16);
+ bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
+ bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
+ bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
+ bfd_h_put_32 (abfd, seg->filesize, buf + 28);
+ bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
+ bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
+ bfd_h_put_32 (abfd, seg->nsects, buf + 40);
+ bfd_h_put_32 (abfd, seg->flags, buf + 44);
+
+ bfd_seek (abfd, command->offset + 8, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
+ return -1;
+
+ {
+ char buf[1024];
+ bfd_vma nbytes = seg->filesize;
+ bfd_vma curoff = seg->fileoff;
+
+ while (nbytes > 0)
+ {
+ bfd_vma thisread = nbytes;
+
+ if (thisread > 1024)
+ thisread = 1024;
+
+ bfd_seek (abfd, curoff, SEEK_SET);
+ if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
+ return -1;
+
+ bfd_seek (abfd, curoff, SEEK_SET);
+ if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
+ return -1;
+
+ nbytes -= thisread;
+ curoff += thisread;
+ }
+ }
+
+ for (i = 0; i < seg->nsects; i++)
+ {
+ bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
+
+ if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+bfd_mach_o_scan_read_command (abfd, command)
+ bfd *abfd;
+ bfd_mach_o_load_command *command;
+{
+ unsigned char buf[8];
+
+ bfd_seek (abfd, command->offset, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 8, abfd) != 8)
+ return -1;
+
+ command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
+ command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD) ? 1 : 0;
+ command->len = bfd_h_get_32 (abfd, buf + 4);
+
+ switch (command->type)
+ {
+ case BFD_MACH_O_LC_SEGMENT:
+ if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_SYMTAB:
+ if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_SYMSEG:
+ break;
+ case BFD_MACH_O_LC_THREAD:
+ case BFD_MACH_O_LC_UNIXTHREAD:
+ if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ case BFD_MACH_O_LC_ID_DYLINKER:
+ if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ case BFD_MACH_O_LC_ID_DYLIB:
+ case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
+ if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_PREBOUND_DYLIB:
+ if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_LOADFVMLIB:
+ case BFD_MACH_O_LC_IDFVMLIB:
+ case BFD_MACH_O_LC_IDENT:
+ case BFD_MACH_O_LC_FVMFILE:
+ case BFD_MACH_O_LC_PREPAGE:
+ case BFD_MACH_O_LC_ROUTINES:
+ case BFD_MACH_O_LC_SUB_FRAMEWORK:
+ break;
+ case BFD_MACH_O_LC_DYSYMTAB:
+ if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
+ return -1;
+ break;
+ case BFD_MACH_O_LC_SUB_UMBRELLA:
+ case BFD_MACH_O_LC_SUB_CLIENT:
+ case BFD_MACH_O_LC_SUB_LIBRARY:
+ case BFD_MACH_O_LC_TWOLEVEL_HINTS:
+ case BFD_MACH_O_LC_PREBIND_CKSUM:
+ break;
+ default:
+ fprintf (stderr, "unable to read unknown load command 0x%lx\n",
+ (unsigned long) command->type);
+ break;
+ }
+
+ return 0;
+}
+
+static void
+bfd_mach_o_flatten_sections (abfd)
+ bfd *abfd;
+{
+ bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
+ long csect = 0;
+ unsigned long i, j;
+
+ mdata->nsects = 0;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
+ {
+ bfd_mach_o_segment_command *seg = &mdata->commands[i].command.segment;
+ mdata->nsects += seg->nsects;
+ }
+ }
+
+ mdata->sections = bfd_alloc (abfd, mdata->nsects * sizeof (bfd_mach_o_section *));
+ csect = 0;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
+ {
+ bfd_mach_o_segment_command *seg = &mdata->commands[i].command.segment;
+
+ BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
+
+ for (j = 0; j < seg->nsects; j++)
+ mdata->sections[csect++] = &seg->sections[j];
+ }
+ }
+}
+
+int
+bfd_mach_o_scan_start_address (abfd)
+ bfd *abfd;
+{
+ bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
+ bfd_mach_o_thread_command *cmd = NULL;
+ unsigned long i;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
+ (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
+ {
+ if (cmd == NULL)
+ cmd = &mdata->commands[i].command.thread;
+ else
+ return 0;
+ }
+ }
+
+ if (cmd == NULL)
+ return 0;
+
+ for (i = 0; i < cmd->nflavours; i++)
+ {
+ if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
+ && (cmd->flavours[i].flavour == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
+ {
+ unsigned char buf[4];
+
+ bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
+
+ if (bfd_bread (buf, 4, abfd) != 4)
+ return -1;
+
+ abfd->start_address = bfd_h_get_32 (abfd, buf);
+ }
+ else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
+ && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
+ {
+ unsigned char buf[4];
+
+ bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
+
+ if (bfd_bread (buf, 4, abfd) != 4)
+ return -1;
+
+ abfd->start_address = bfd_h_get_32 (abfd, buf);
+ }
+ }
+
+ return 0;
+}
+
+int
+bfd_mach_o_scan (abfd, header)
+ bfd *abfd;
+ bfd_mach_o_header *header;
+{
+ unsigned int i;
+ bfd_mach_o_data_struct *mdata = NULL;
+ enum bfd_architecture cputype;
+ unsigned long cpusubtype;
+
+ mdata = ((bfd_mach_o_data_struct *)
+ bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
+ if (mdata == NULL)
+ return -1;
+
+ mdata->header = *header;
+ mdata->symbols = NULL;
+
+ abfd->flags = abfd->xvec->object_flags | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS));
+ abfd->tdata.mach_o_data = mdata;
+
+ bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype, &cputype, &cpusubtype);
+ if (cputype == bfd_arch_unknown)
+ {
+ fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
+ header->cputype, header->cpusubtype);
+ return -1;
+ }
+
+ bfd_set_arch_mach (abfd, cputype, cpusubtype);
+
+ if (header->ncmds != 0)
+ {
+ mdata->commands =
+ ((bfd_mach_o_load_command *)
+ bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command)));
+ if (mdata->commands == NULL)
+ return -1;
+
+ for (i = 0; i < header->ncmds; i++)
+ {
+ bfd_mach_o_load_command *cur = &mdata->commands[i];
+
+ if (i == 0)
+ cur->offset = 28;
+ else
+ {
+ bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
+ cur->offset = prev->offset + prev->len;
+ }
+
+ if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
+ return -1;
+ }
+ }
+
+ if (bfd_mach_o_scan_start_address (abfd) < 0)
+ {
+#if 0
+ fprintf (stderr, "bfd_mach_o_scan: unable to scan start address: %s\n",
+ bfd_errmsg (bfd_get_error ()));
+ abfd->tdata.mach_o_data = NULL;
+ return -1;
+#endif
+ }
+
+ bfd_mach_o_flatten_sections (abfd);
+
+ return 0;
+}
+
+boolean
+bfd_mach_o_mkobject (abfd)
+ bfd *abfd;
+{
+ bfd_mach_o_data_struct *mdata = NULL;
+
+ mdata = ((bfd_mach_o_data_struct *)
+ bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
+ if (mdata == NULL)
+ return false;
+ abfd->tdata.mach_o_data = mdata;
+
+ mdata->header.magic = 0;
+ mdata->header.cputype = 0;
+ mdata->header.cpusubtype = 0;
+ mdata->header.filetype = 0;
+ mdata->header.ncmds = 0;
+ mdata->header.sizeofcmds = 0;
+ mdata->header.flags = 0;
+ mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
+ mdata->commands = NULL;
+ mdata->nsymbols = 0;
+ mdata->symbols = NULL;
+ mdata->nsects = 0;
+ mdata->sections = NULL;
+ mdata->ibfd = NULL;
+
+ return true;
+}
+
+const bfd_target *
+bfd_mach_o_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_mach_o_header header;
+
+ if (bfd_mach_o_read_header (abfd, &header) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (! ((header.byteorder == BFD_ENDIAN_BIG)
+ || (header.byteorder == BFD_ENDIAN_LITTLE)))
+ {
+ fprintf (stderr, "unknown header byte-order value 0x%lx\n", (long) header.byteorder);
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (! (((header.byteorder == BFD_ENDIAN_BIG)
+ && (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
+ && (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG))
+ ||
+ ((header.byteorder == BFD_ENDIAN_LITTLE)
+ && (abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
+ && (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE))))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ abfd->tdata.mach_o_data = NULL;
+
+ if (bfd_mach_o_scan (abfd, &header) != 0)
+ {
+ abfd->tdata.mach_o_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+const bfd_target *
+bfd_mach_o_core_p (abfd)
+ bfd *abfd;
+{
+ bfd_mach_o_header header;
+
+ bfd_set_error (bfd_error_wrong_format);
+
+ if (bfd_mach_o_read_header (abfd, &header) != 0)
+ return NULL;
+
+ if (! ((header.byteorder == BFD_ENDIAN_BIG)
+ || (header.byteorder == BFD_ENDIAN_LITTLE)))
+ {
+ fprintf (stderr, "unknown header byte-order value 0x%lx\n", (long) header.byteorder);
+ abort ();
+ }
+
+ if (! (((header.byteorder == BFD_ENDIAN_BIG)
+ && (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
+ && (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG))
+ ||
+ ((header.byteorder == BFD_ENDIAN_LITTLE)
+ && (abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
+ && (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE))))
+ return NULL;
+
+ if (header.filetype != BFD_MACH_O_MH_CORE)
+ return NULL;
+
+ abfd->tdata.mach_o_data = NULL;
+ if (bfd_mach_o_scan (abfd, &header) != 0)
+ {
+ abfd->tdata.mach_o_data = NULL;
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+typedef struct mach_o_fat_archentry
+{
+ unsigned long cputype;
+ unsigned long cpusubtype;
+ unsigned long offset;
+ unsigned long size;
+ unsigned long align;
+ bfd *abfd;
+} mach_o_fat_archentry;
+
+typedef struct mach_o_fat_data_struct
+{
+ unsigned long magic;
+ unsigned long nfat_arch;
+ mach_o_fat_archentry *archentries;
+} mach_o_fat_data_struct;
+
+const bfd_target *
+bfd_mach_o_archive_p (abfd)
+ bfd *abfd;
+{
+ mach_o_fat_data_struct *adata;
+ unsigned char buf[20];
+ unsigned long i;
+
+ bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 8, abfd) != 8)
+ return NULL;
+
+ adata = (mach_o_fat_data_struct *)
+ bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
+ if (adata == NULL)
+ return NULL;
+
+ adata->magic = bfd_getb32 (buf);
+ adata->nfat_arch = bfd_getb32 (buf + 4);
+ if (adata->magic != 0xcafebabe)
+ return NULL;
+
+ adata->archentries = (mach_o_fat_archentry *)
+ bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
+ if (adata->archentries == NULL)
+ return NULL;
+
+ for (i = 0; i < adata->nfat_arch; i++)
+ {
+ bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
+
+ if (bfd_bread ((PTR) buf, 20, abfd) != 20)
+ return NULL;
+ adata->archentries[i].cputype = bfd_getb32 (buf);
+ adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
+ adata->archentries[i].offset = bfd_getb32 (buf + 8);
+ adata->archentries[i].size = bfd_getb32 (buf + 12);
+ adata->archentries[i].align = bfd_getb32 (buf + 16);
+ adata->archentries[i].abfd = NULL;
+ }
+
+ abfd->tdata.mach_o_fat_data = adata;
+ return abfd->xvec;
+}
+
+bfd *
+bfd_mach_o_openr_next_archived_file (archive, prev)
+ bfd *archive;
+ bfd *prev;
+{
+ mach_o_fat_data_struct *adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
+ mach_o_fat_archentry *entry = NULL;
+ unsigned long i;
+
+ BFD_ASSERT (adata != NULL);
+
+ /* Find index of previous entry. */
+ if (prev == NULL)
+ i = 0; /* Start at first one. */
+ else
+ {
+ for (i = 0; i < adata->nfat_arch; i++)
+ {
+ if (adata->archentries[i].abfd == prev)
+ break;
+ }
+
+ if (i == adata->nfat_arch)
+ {
+ /* Not found. */
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ i++; /* Get next entry. */
+ }
+
+ if (i >= adata->nfat_arch)
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+
+ entry = &adata->archentries[i];
+ if (entry->abfd == NULL)
+ {
+ bfd *nbfd = _bfd_new_bfd_contained_in (archive);
+ char *s = NULL;
+
+ if (nbfd == NULL)
+ return NULL;
+
+ nbfd->origin = entry->offset;
+ s = bfd_malloc (strlen (archive->filename) + 1);
+ if (s == NULL)
+ return NULL;
+ strcpy (s, archive->filename);
+ nbfd->filename = s;
+ nbfd->iostream = NULL;
+ entry->abfd = nbfd;
+ }
+
+ return entry->abfd;
+}
+
+int bfd_mach_o_lookup_section
+ (bfd *abfd, asection *section,
+ bfd_mach_o_load_command **mcommand, bfd_mach_o_section **msection)
+{
+ struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
+ unsigned int i, j, num;
+
+ bfd_mach_o_load_command *ncmd = NULL;
+ bfd_mach_o_section *nsect = NULL;
+
+ BFD_ASSERT (mcommand != NULL);
+ BFD_ASSERT (msection != NULL);
+
+ num = 0;
+ for (i = 0; i < md->header.ncmds; i++)
+ {
+ struct bfd_mach_o_load_command *cmd = &md->commands[i];
+ struct bfd_mach_o_segment_command *seg = NULL;
+
+ if (cmd->type != BFD_MACH_O_LC_SEGMENT)
+ continue;
+ seg = &cmd->command.segment;
+
+ if (seg->segment == section)
+ {
+ if (num == 0)
+ ncmd = cmd;
+ num++;
+ }
+
+ for (j = 0; j < seg->nsects; j++)
+ {
+ struct bfd_mach_o_section *sect = &seg->sections[j];
+
+ if (sect->bfdsection == section)
+ {
+ if (num == 0)
+ nsect = sect;
+ num++;
+ }
+ }
+ }
+
+ *mcommand = ncmd;
+ *msection = nsect;
+ return num;
+}
+
+int
+bfd_mach_o_lookup_command
+ (bfd *abfd, bfd_mach_o_load_command_type type,
+ bfd_mach_o_load_command **mcommand)
+{
+ struct mach_o_data_struct *md = NULL;
+ bfd_mach_o_load_command *ncmd = NULL;
+ unsigned int i, num;
+
+ md = abfd->tdata.mach_o_data;
+
+ BFD_ASSERT (md != NULL);
+ BFD_ASSERT (mcommand != NULL);
+
+ num = 0;
+ for (i = 0; i < md->header.ncmds; i++)
+ {
+ struct bfd_mach_o_load_command *cmd = &md->commands[i];
+
+ if (cmd->type != type)
+ continue;
+
+ if (num == 0)
+ ncmd = cmd;
+ num++;
+ }
+
+ *mcommand = ncmd;
+ return num;
+}
+
+unsigned long
+bfd_mach_o_stack_addr (type)
+ enum bfd_mach_o_cpu_type type;
+{
+ switch (type)
+ {
+ case BFD_MACH_O_CPU_TYPE_MC680x0:
+ return 0x04000000;
+ case BFD_MACH_O_CPU_TYPE_MC88000:
+ return 0xffffe000;
+ case BFD_MACH_O_CPU_TYPE_POWERPC:
+ return 0xc0000000;
+ case BFD_MACH_O_CPU_TYPE_I386:
+ return 0xc0000000;
+ case BFD_MACH_O_CPU_TYPE_SPARC:
+ return 0xf0000000;
+ case BFD_MACH_O_CPU_TYPE_I860:
+ return 0;
+ case BFD_MACH_O_CPU_TYPE_HPPA:
+ return (0xc0000000-0x04000000);
+ default:
+ return 0;
+ }
+}
+
+int
+bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
+ bfd *abfd;
+ unsigned char **rbuf;
+ unsigned int *rlen;
+{
+ bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
+ unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
+ unsigned int i = 0;
+
+ for (i = 0; i < mdata->header.ncmds; i++)
+ {
+ bfd_mach_o_load_command *cur = &mdata->commands[i];
+ bfd_mach_o_segment_command *seg = NULL;
+
+ if (cur->type != BFD_MACH_O_LC_SEGMENT)
+ continue;
+
+ seg = &cur->command.segment;
+
+ if ((seg->vmaddr + seg->vmsize) == stackaddr)
+ {
+ unsigned long start = seg->fileoff;
+ unsigned long end = seg->fileoff + seg->filesize;
+ unsigned char *buf = bfd_malloc (1024);
+ unsigned long size = 1024;
+
+ for (;;)
+ {
+ bfd_size_type nread = 0;
+ unsigned long offset;
+ int found_nonnull = 0;
+
+ if (size > (end - start))
+ size = (end - start);
+
+ buf = bfd_realloc (buf, size);
+
+ bfd_seek (abfd, end - size, SEEK_SET);
+ nread = bfd_bread (buf, size, abfd);
+
+ if (nread != size)
+ return -1;
+
+ for (offset = 4; offset <= size; offset += 4)
+ {
+ unsigned long val = *((unsigned long *) (buf + size - offset));
+
+ if (! found_nonnull)
+ {
+ if (val != 0)
+ found_nonnull = 1;
+ }
+ else if (val == 0x0)
+ {
+ unsigned long bottom = seg->fileoff + seg->filesize - offset;
+ unsigned long top = seg->fileoff + seg->filesize - 4;
+
+ *rbuf = bfd_malloc (top - bottom);
+ *rlen = top - bottom;
+
+ memcpy (*rbuf, buf + size - *rlen, *rlen);
+ return 0;
+ }
+ }
+
+ if (size == (end - start))
+ break;
+
+ size *= 2;
+ }
+ }
+ }
+
+ return -1;
+}
+
+char *
+bfd_mach_o_core_file_failing_command (abfd)
+ bfd *abfd;
+{
+ unsigned char *buf = NULL;
+ unsigned int len = 0;
+ int ret = -1;
+
+ ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
+ if (ret < 0)
+ return NULL;
+
+ return buf;
+}
+
+int
+bfd_mach_o_core_file_failing_signal (abfd)
+ bfd *abfd ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+boolean
+bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
+ bfd *core_bfd ATTRIBUTE_UNUSED;
+ bfd *exec_bfd ATTRIBUTE_UNUSED;
+{
+ return true;
+}
+
+#define TARGET_NAME mach_o_be_vec
+#define TARGET_STRING "mach-o-be"
+#define TARGET_BIG_ENDIAN 1
+#define TARGET_ARCHIVE 0
+
+#include "mach-o-target.c"
+
+#undef TARGET_NAME
+#undef TARGET_STRING
+#undef TARGET_BIG_ENDIAN
+#undef TARGET_ARCHIVE
+
+#define TARGET_NAME mach_o_le_vec
+#define TARGET_STRING "mach-o-le"
+#define TARGET_BIG_ENDIAN 0
+#define TARGET_ARCHIVE 0
+
+#include "mach-o-target.c"
+
+#undef TARGET_NAME
+#undef TARGET_STRING
+#undef TARGET_BIG_ENDIAN
+#undef TARGET_ARCHIVE
+
+#define TARGET_NAME mach_o_fat_vec
+#define TARGET_STRING "mach-o-fat"
+#define TARGET_BIG_ENDIAN 1
+#define TARGET_ARCHIVE 1
+
+#include "mach-o-target.c"
+
+#undef TARGET_NAME
+#undef TARGET_STRING
+#undef TARGET_BIG_ENDIAN
+#undef TARGET_ARCHIVE
+
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
new file mode 100644
index 0000000000..c368c1e521
--- /dev/null
+++ b/bfd/mach-o.h
@@ -0,0 +1,490 @@
+/* Mach-O support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _BFD_MACH_O_H_
+#define _BFD_MACH_O_H_
+
+#include "bfd.h"
+
+#define BFD_MACH_O_N_STAB 0xe0 /* If any of these bits set, a symbolic debugging entry. */
+#define BFD_MACH_O_N_PEXT 0x10 /* Private external symbol bit. */
+#define BFD_MACH_O_N_TYPE 0x0e /* Mask for the type bits. */
+#define BFD_MACH_O_N_EXT 0x01 /* External symbol bit, set for external symbols. */
+#define BFD_MACH_O_N_UNDF 0x00 /* Undefined, n_sect == NO_SECT. */
+#define BFD_MACH_O_N_ABS 0x02 /* Absolute, n_sect == NO_SECT. */
+#define BFD_MACH_O_N_SECT 0x0e /* Defined in section number n_sect. */
+#define BFD_MACH_O_N_PBUD 0x0c /* Prebound undefined (defined in a dylib). */
+#define BFD_MACH_O_N_INDR 0x0a /* Indirect. */
+
+typedef enum bfd_mach_o_ppc_thread_flavour
+ {
+ BFD_MACH_O_PPC_THREAD_STATE = 1,
+ BFD_MACH_O_PPC_FLOAT_STATE = 2,
+ BFD_MACH_O_PPC_EXCEPTION_STATE = 3,
+ BFD_MACH_O_PPC_VECTOR_STATE = 4
+ }
+bfd_mach_o_ppc_thread_flavour;
+
+typedef enum bfd_mach_o_i386_thread_flavour
+ {
+ BFD_MACH_O_i386_NEW_THREAD_STATE = 1,
+ BFD_MACH_O_i386_FLOAT_STATE = 2,
+ BFD_MACH_O_i386_ISA_PORT_MAP_STATE = 3,
+ BFD_MACH_O_i386_V86_ASSIST_STATE = 4,
+ BFD_MACH_O_i386_REGS_SEGS_STATE = 5,
+ BFD_MACH_O_i386_THREAD_SYSCALL_STATE = 6,
+ BFD_MACH_O_i386_THREAD_STATE_NONE = 7,
+ BFD_MACH_O_i386_SAVED_STATE = 8,
+ BFD_MACH_O_i386_THREAD_STATE = -1,
+ BFD_MACH_O_i386_THREAD_FPSTATE = -2,
+ BFD_MACH_O_i386_THREAD_EXCEPTSTATE = -3,
+ BFD_MACH_O_i386_THREAD_CTHREADSTATE = -4,
+ }
+bfd_mach_o_i386_thread_flavour;
+
+#define BFD_MACH_O_LC_REQ_DYLD 0x80000000
+
+typedef enum bfd_mach_o_load_command_type
+ {
+ BFD_MACH_O_LC_SEGMENT = 0x1, /* File segment to be mapped. */
+ BFD_MACH_O_LC_SYMTAB = 0x2, /* Link-edit stab symbol table info (obsolete). */
+ BFD_MACH_O_LC_SYMSEG = 0x3, /* Link-edit gdb symbol table info. */
+ BFD_MACH_O_LC_THREAD = 0x4, /* Thread. */
+ BFD_MACH_O_LC_UNIXTHREAD = 0x5, /* UNIX thread (includes a stack). */
+ BFD_MACH_O_LC_LOADFVMLIB = 0x6, /* Load a fixed VM shared library. */
+ BFD_MACH_O_LC_IDFVMLIB = 0x7, /* Fixed VM shared library id. */
+ BFD_MACH_O_LC_IDENT = 0x8, /* Object identification information (obsolete). */
+ BFD_MACH_O_LC_FVMFILE = 0x9, /* Fixed VM file inclusion. */
+ BFD_MACH_O_LC_PREPAGE = 0xa, /* Prepage command (internal use). */
+ BFD_MACH_O_LC_DYSYMTAB = 0xb, /* Dynamic link-edit symbol table info. */
+ BFD_MACH_O_LC_LOAD_DYLIB = 0xc, /* Load a dynamicly linked shared library. */
+ BFD_MACH_O_LC_ID_DYLIB = 0xd, /* Dynamicly linked shared lib identification. */
+ BFD_MACH_O_LC_LOAD_DYLINKER = 0xe, /* Load a dynamic linker. */
+ BFD_MACH_O_LC_ID_DYLINKER = 0xf, /* Dynamic linker identification. */
+ BFD_MACH_O_LC_PREBOUND_DYLIB = 0x10,/* Modules prebound for a dynamicly. */
+ BFD_MACH_O_LC_ROUTINES = 0x11, /* Image routines. */
+ BFD_MACH_O_LC_SUB_FRAMEWORK = 0x12, /* Sub framework. */
+ BFD_MACH_O_LC_SUB_UMBRELLA = 0x13, /* Sub umbrella. */
+ BFD_MACH_O_LC_SUB_CLIENT = 0x14, /* Sub client. */
+ BFD_MACH_O_LC_SUB_LIBRARY = 0x15, /* Sub library. */
+ BFD_MACH_O_LC_TWOLEVEL_HINTS = 0x16,/* Two-level namespace lookup hints. */
+ BFD_MACH_O_LC_PREBIND_CKSUM = 0x17, /* Prebind checksum. */
+ /* Load a dynamicly linked shared library that is allowed to be
+ missing (weak). */
+ BFD_MACH_O_LC_LOAD_WEAK_DYLIB = 0x18
+ }
+bfd_mach_o_load_command_type;
+
+typedef enum bfd_mach_o_cpu_type
+ {
+ BFD_MACH_O_CPU_TYPE_VAX = 1,
+ BFD_MACH_O_CPU_TYPE_MC680x0 = 6,
+ BFD_MACH_O_CPU_TYPE_I386 = 7,
+ BFD_MACH_O_CPU_TYPE_MIPS = 8,
+ BFD_MACH_O_CPU_TYPE_MC98000 = 10,
+ BFD_MACH_O_CPU_TYPE_HPPA = 11,
+ BFD_MACH_O_CPU_TYPE_ARM = 12,
+ BFD_MACH_O_CPU_TYPE_MC88000 = 13,
+ BFD_MACH_O_CPU_TYPE_SPARC = 14,
+ BFD_MACH_O_CPU_TYPE_I860 = 15,
+ BFD_MACH_O_CPU_TYPE_ALPHA = 16,
+ BFD_MACH_O_CPU_TYPE_POWERPC = 18
+ }
+bfd_mach_o_cpu_type;
+
+typedef enum bfd_mach_o_filetype
+ {
+ BFD_MACH_O_MH_OBJECT = 1,
+ BFD_MACH_O_MH_EXECUTE = 2,
+ BFD_MACH_O_MH_FVMLIB = 3,
+ BFD_MACH_O_MH_CORE = 4,
+ BFD_MACH_O_MH_PRELOAD = 5,
+ BFD_MACH_O_MH_DYLIB = 6,
+ BFD_MACH_O_MH_DYLINKER = 7,
+ BFD_MACH_O_MH_BUNDLE = 8
+ }
+bfd_mach_o_filetype;
+
+/* Constants for the type of a section. */
+
+typedef enum bfd_mach_o_section_type
+ {
+ /* Regular section. */
+ BFD_MACH_O_S_REGULAR = 0x0,
+
+ /* Zero fill on demand section. */
+ BFD_MACH_O_S_ZEROFILL = 0x1,
+
+ /* Section with only literal C strings. */
+ BFD_MACH_O_S_CSTRING_LITERALS = 0x2,
+
+ /* Section with only 4 byte literals. */
+ BFD_MACH_O_S_4BYTE_LITERALS = 0x3,
+
+ /* Section with only 8 byte literals. */
+ BFD_MACH_O_S_8BYTE_LITERALS = 0x4,
+
+ /* Section with only pointers to literals. */
+ BFD_MACH_O_S_LITERAL_POINTERS = 0x5,
+
+ /* For the two types of symbol pointers sections and the symbol stubs
+ section they have indirect symbol table entries. For each of the
+ entries in the section the indirect symbol table entries, in
+ corresponding order in the indirect symbol table, start at the index
+ stored in the reserved1 field of the section structure. Since the
+ indirect symbol table entries correspond to the entries in the
+ section the number of indirect symbol table entries is inferred from
+ the size of the section divided by the size of the entries in the
+ section. For symbol pointers sections the size of the entries in
+ the section is 4 bytes and for symbol stubs sections the byte size
+ of the stubs is stored in the reserved2 field of the section
+ structure. */
+
+ /* Section with only non-lazy symbol pointers. */
+ BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS = 0x6,
+
+ /* Section with only lazy symbol pointers. */
+ BFD_MACH_O_S_LAZY_SYMBOL_POINTERS = 0x7,
+
+ /* Section with only symbol stubs, byte size of stub in the reserved2 field. */
+ BFD_MACH_O_S_SYMBOL_STUBS = 0x8,
+
+ /* Section with only function pointers for initialization. */
+ BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS = 0x9
+ }
+bfd_mach_o_section_type;
+
+typedef unsigned long bfd_mach_o_cpu_subtype;
+
+typedef struct bfd_mach_o_header
+{
+ unsigned long magic;
+ unsigned long cputype;
+ unsigned long cpusubtype;
+ unsigned long filetype;
+ unsigned long ncmds;
+ unsigned long sizeofcmds;
+ unsigned long flags;
+ enum bfd_endian byteorder;
+}
+bfd_mach_o_header;
+
+typedef struct bfd_mach_o_section
+{
+ asection *bfdsection;
+ char sectname[16 + 1];
+ char segname[16 + 1];
+ bfd_vma addr;
+ bfd_vma size;
+ bfd_vma offset;
+ unsigned long align;
+ bfd_vma reloff;
+ unsigned long nreloc;
+ unsigned long flags;
+ unsigned long reserved1;
+ unsigned long reserved2;
+}
+bfd_mach_o_section;
+
+typedef struct bfd_mach_o_segment_command
+{
+ char segname[16];
+ bfd_vma vmaddr;
+ bfd_vma vmsize;
+ bfd_vma fileoff;
+ unsigned long filesize;
+ unsigned long nsects;
+ unsigned long flags;
+ bfd_mach_o_section *sections;
+ asection *segment;
+}
+bfd_mach_o_segment_command;
+
+typedef struct bfd_mach_o_symtab_command
+{
+ unsigned long symoff;
+ unsigned long nsyms;
+ unsigned long stroff;
+ unsigned long strsize;
+ asymbol *symbols;
+ char *strtab;
+ asection *stabs_segment;
+ asection *stabstr_segment;
+}
+bfd_mach_o_symtab_command;
+
+/* This is the second set of the symbolic information which is used to support
+ the data structures for the dynamicly link editor.
+
+ The original set of symbolic information in the symtab_command which contains
+ the symbol and string tables must also be present when this load command is
+ present. When this load command is present the symbol table is organized
+ into three groups of symbols:
+ local symbols (static and debugging symbols) - grouped by module
+ defined external symbols - grouped by module (sorted by name if not lib)
+ undefined external symbols (sorted by name)
+ In this load command there are offsets and counts to each of the three groups
+ of symbols.
+
+ This load command contains a the offsets and sizes of the following new
+ symbolic information tables:
+ table of contents
+ module table
+ reference symbol table
+ indirect symbol table
+ The first three tables above (the table of contents, module table and
+ reference symbol table) are only present if the file is a dynamicly linked
+ shared library. For executable and object modules, which are files
+ containing only one module, the information that would be in these three
+ tables is determined as follows:
+ table of contents - the defined external symbols are sorted by name
+ module table - the file contains only one module so everything in the
+ file is part of the module.
+ reference symbol table - is the defined and undefined external symbols
+
+ For dynamicly linked shared library files this load command also contains
+ offsets and sizes to the pool of relocation entries for all sections
+ separated into two groups:
+ external relocation entries
+ local relocation entries
+ For executable and object modules the relocation entries continue to hang
+ off the section structures. */
+
+typedef struct bfd_mach_o_dysymtab_command
+{
+ /* The symbols indicated by symoff and nsyms of the LC_SYMTAB load command
+ are grouped into the following three groups:
+ local symbols (further grouped by the module they are from)
+ defined external symbols (further grouped by the module they are from)
+ undefined symbols
+
+ The local symbols are used only for debugging. The dynamic binding
+ process may have to use them to indicate to the debugger the local
+ symbols for a module that is being bound.
+
+ The last two groups are used by the dynamic binding process to do the
+ binding (indirectly through the module table and the reference symbol
+ table when this is a dynamicly linked shared library file). */
+
+ unsigned long ilocalsym; /* Index to local symbols. */
+ unsigned long nlocalsym; /* Number of local symbols. */
+ unsigned long iextdefsym; /* Index to externally defined symbols. */
+ unsigned long nextdefsym; /* Number of externally defined symbols. */
+ unsigned long iundefsym; /* Index to undefined symbols. */
+ unsigned long nundefsym; /* Number of undefined symbols. */
+
+ /* For the for the dynamic binding process to find which module a symbol
+ is defined in the table of contents is used (analogous to the ranlib
+ structure in an archive) which maps defined external symbols to modules
+ they are defined in. This exists only in a dynamicly linked shared
+ library file. For executable and object modules the defined external
+ symbols are sorted by name and is use as the table of contents. */
+
+ unsigned long tocoff; /* File offset to table of contents. */
+ unsigned long ntoc; /* Number of entries in table of contents. */
+
+ /* To support dynamic binding of "modules" (whole object files) the symbol
+ table must reflect the modules that the file was created from. This is
+ done by having a module table that has indexes and counts into the merged
+ tables for each module. The module structure that these two entries
+ refer to is described below. This exists only in a dynamicly linked
+ shared library file. For executable and object modules the file only
+ contains one module so everything in the file belongs to the module. */
+
+ unsigned long modtaboff; /* File offset to module table. */
+ unsigned long nmodtab; /* Number of module table entries. */
+
+ /* To support dynamic module binding the module structure for each module
+ indicates the external references (defined and undefined) each module
+ makes. For each module there is an offset and a count into the
+ reference symbol table for the symbols that the module references.
+ This exists only in a dynamicly linked shared library file. For
+ executable and object modules the defined external symbols and the
+ undefined external symbols indicates the external references. */
+
+ unsigned long extrefsymoff; /* Offset to referenced symbol table. */
+ unsigned long nextrefsyms; /* Number of referenced symbol table entries. */
+
+ /* The sections that contain "symbol pointers" and "routine stubs" have
+ indexes and (implied counts based on the size of the section and fixed
+ size of the entry) into the "indirect symbol" table for each pointer
+ and stub. For every section of these two types the index into the
+ indirect symbol table is stored in the section header in the field
+ reserved1. An indirect symbol table entry is simply a 32bit index into
+ the symbol table to the symbol that the pointer or stub is referring to.
+ The indirect symbol table is ordered to match the entries in the section. */
+
+ unsigned long indirectsymoff; /* File offset to the indirect symbol table. */
+ unsigned long nindirectsyms; /* Number of indirect symbol table entries. */
+
+ /* To support relocating an individual module in a library file quickly the
+ external relocation entries for each module in the library need to be
+ accessed efficiently. Since the relocation entries can't be accessed
+ through the section headers for a library file they are separated into
+ groups of local and external entries further grouped by module. In this
+ case the presents of this load command who's extreloff, nextrel,
+ locreloff and nlocrel fields are non-zero indicates that the relocation
+ entries of non-merged sections are not referenced through the section
+ structures (and the reloff and nreloc fields in the section headers are
+ set to zero).
+
+ Since the relocation entries are not accessed through the section headers
+ this requires the r_address field to be something other than a section
+ offset to identify the item to be relocated. In this case r_address is
+ set to the offset from the vmaddr of the first LC_SEGMENT command.
+
+ The relocation entries are grouped by module and the module table
+ entries have indexes and counts into them for the group of external
+ relocation entries for that the module.
+
+ For sections that are merged across modules there must not be any
+ remaining external relocation entries for them (for merged sections
+ remaining relocation entries must be local). */
+
+ unsigned long extreloff; /* Offset to external relocation entries. */
+ unsigned long nextrel; /* Number of external relocation entries. */
+
+ /* All the local relocation entries are grouped together (they are not
+ grouped by their module since they are only used if the object is moved
+ from it staticly link edited address). */
+
+ unsigned long locreloff; /* Offset to local relocation entries. */
+ unsigned long nlocrel; /* Number of local relocation entries. */
+}
+bfd_mach_o_dysymtab_command;
+
+/* An indirect symbol table entry is simply a 32bit index into the symbol table
+ to the symbol that the pointer or stub is refering to. Unless it is for a
+ non-lazy symbol pointer section for a defined symbol which strip(1) as
+ removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the
+ symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. */
+
+#define INDIRECT_SYMBOL_LOCAL 0x80000000
+#define INDIRECT_SYMBOL_ABS 0x40000000
+
+typedef struct bfd_mach_o_thread_flavour
+{
+ unsigned long flavour;
+ bfd_vma offset;
+ unsigned long size;
+}
+bfd_mach_o_thread_flavour;
+
+typedef struct bfd_mach_o_thread_command
+{
+ unsigned long nflavours;
+ bfd_mach_o_thread_flavour *flavours;
+ asection *section;
+}
+bfd_mach_o_thread_command;
+
+typedef struct bfd_mach_o_dylinker_command
+{
+ unsigned long cmd; /* LC_ID_DYLIB or LC_LOAD_DYLIB. */
+ unsigned long cmdsize; /* Includes pathname string. */
+ unsigned long name_offset; /* Offset to library's path name. */
+ unsigned long name_len; /* Offset to library's path name. */
+ asection *section;
+}
+bfd_mach_o_dylinker_command;
+
+typedef struct bfd_mach_o_dylib_command
+{
+ unsigned long cmd; /* LC_ID_DYLIB or LC_LOAD_DYLIB. */
+ unsigned long cmdsize; /* Includes pathname string. */
+ unsigned long name_offset; /* Offset to library's path name. */
+ unsigned long name_len; /* Offset to library's path name. */
+ unsigned long timestamp; /* Library's build time stamp. */
+ unsigned long current_version; /* Library's current version number. */
+ unsigned long compatibility_version; /* Library's compatibility vers number. */
+ asection *section;
+}
+bfd_mach_o_dylib_command;
+
+typedef struct bfd_mach_o_prebound_dylib_command
+{
+ unsigned long cmd; /* LC_PREBOUND_DYLIB. */
+ unsigned long cmdsize; /* Includes strings. */
+ unsigned long name; /* Library's path name. */
+ unsigned long nmodules; /* Number of modules in library. */
+ unsigned long linked_modules; /* Bit vector of linked modules. */
+ asection *section;
+}
+bfd_mach_o_prebound_dylib_command;
+
+typedef struct bfd_mach_o_load_command
+{
+ bfd_mach_o_load_command_type type;
+ unsigned int type_required;
+ bfd_vma offset;
+ bfd_vma len;
+ union
+ {
+ bfd_mach_o_segment_command segment;
+ bfd_mach_o_symtab_command symtab;
+ bfd_mach_o_dysymtab_command dysymtab;
+ bfd_mach_o_thread_command thread;
+ bfd_mach_o_dylib_command dylib;
+ bfd_mach_o_dylinker_command dylinker;
+ bfd_mach_o_prebound_dylib_command prebound_dylib;
+ }
+ command;
+}
+bfd_mach_o_load_command;
+
+typedef struct mach_o_data_struct
+{
+ bfd_mach_o_header header;
+ bfd_mach_o_load_command *commands;
+ unsigned long nsymbols;
+ asymbol *symbols;
+ unsigned long nsects;
+ bfd_mach_o_section **sections;
+ bfd *ibfd;
+}
+mach_o_data_struct;
+
+typedef struct mach_o_data_struct bfd_mach_o_data_struct;
+
+boolean bfd_mach_o_valid PARAMS ((bfd *));
+int bfd_mach_o_scan_read_symtab_symbol PARAMS ((bfd *, bfd_mach_o_symtab_command *, asymbol *, unsigned long));
+int bfd_mach_o_scan_read_symtab_strtab PARAMS ((bfd *, bfd_mach_o_symtab_command *));
+int bfd_mach_o_scan_read_symtab_symbols PARAMS ((bfd *, bfd_mach_o_symtab_command *));
+int bfd_mach_o_scan_read_dysymtab_symbol PARAMS ((bfd *, bfd_mach_o_dysymtab_command *, bfd_mach_o_symtab_command *, asymbol *, unsigned long));
+int bfd_mach_o_scan_start_address PARAMS ((bfd *));
+int bfd_mach_o_scan PARAMS ((bfd *, bfd_mach_o_header *));
+boolean bfd_mach_o_mkobject PARAMS ((bfd *));
+const bfd_target * bfd_mach_o_object_p PARAMS ((bfd *));
+const bfd_target * bfd_mach_o_core_p PARAMS ((bfd *));
+const bfd_target * bfd_mach_o_archive_p PARAMS ((bfd *));
+bfd * bfd_mach_o_openr_next_archived_file PARAMS ((bfd *, bfd *));
+int bfd_mach_o_lookup_section PARAMS ((bfd *, asection *, bfd_mach_o_load_command **, bfd_mach_o_section **));
+int bfd_mach_o_lookup_command PARAMS ((bfd *, bfd_mach_o_load_command_type, bfd_mach_o_load_command **));
+unsigned long bfd_mach_o_stack_addr PARAMS ((enum bfd_mach_o_cpu_type));
+int bfd_mach_o_core_fetch_environment PARAMS ((bfd *, unsigned char **, unsigned int *));
+char * bfd_mach_o_core_file_failing_command PARAMS ((bfd *));
+int bfd_mach_o_core_file_failing_signal PARAMS ((bfd *));
+boolean bfd_mach_o_core_file_matches_executable_p PARAMS ((bfd *, bfd *));
+
+extern const bfd_target mach_o_be_vec;
+extern const bfd_target mach_o_le_vec;
+extern const bfd_target mach_o_fat_vec;
+
+#endif /* _BFD_MACH_O_H_ */
diff --git a/bfd/pef-traceback.h b/bfd/pef-traceback.h
new file mode 100644
index 0000000000..15f43b6e59
--- /dev/null
+++ b/bfd/pef-traceback.h
@@ -0,0 +1,215 @@
+/* PowerPC traceback table support for BFD.
+ Copyright 1993, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Originally written by Ira Ruben, 06/28/93 */
+
+/* This is a compiler independent representation of the AIX Version 3 traceback table (in
+ sys/debug.h), which occurs, usually, one per procedure (routine). The table is marked by
+ a multiple of 4 32-bit word of zeroes in the instruction space. The traceback table is
+ also referred to as "procedure-end table".
+
+ The AIX traceback table representation on which this header is based is defined as a
+ series of bit field struct specifications. Bit fields are compiler dependent! Thus,
+ the definitions presented here follow the original header and the existing documentation
+ (such as it is), but define the fields as BIT MASKS and other macros. The mask names,
+ however, where chosen as the original field names to give some compatibility with the
+ original header and to agree with the documentation. */
+
+#ifndef __TRACEBACK__
+#define __TRACEBACK__
+
+#define TB_C 0U /* C */
+#define TB_FORTRAN 1U /* FORTRAN */
+#define TB_PASCAL 2U /* Pascal */
+#define TB_ADA 3U /* ADA */
+#define TB_PL1 4U /* PL1 */
+#define TB_BASIC 5U /* Basic */
+#define TB_LISP 6U /* Lisp */
+#define TB_COBOL 7U /* eCobol */
+#define TB_MODULA2 8U /* Modula2 */
+#define TB_CPLUSPLUS 9U /* C++ */
+#define TB_RPG 10U /* RPG */
+#define TB_PL8 11U /* PL8 */
+#define TB_ASM 12U /* Asm */
+
+/* flags 1 */
+
+#define TB_GLOBALLINK 0x80U /* Routine is Global Linkage. */
+#define TB_is_eprol 0x40U /* Out-of-line prolog or epilog routine. */
+#define TB_HAS_TBOFF 0x20U /* tb_offset set (extension field). */
+#define TB_INT_PROC 0x10U /* Internal leaf routine. */
+#define TB_HAS_CTL 0x08U /* Has controlled automatic storage. */
+#define TB_TOCLESS 0X04U /* Routine has no TOC. */
+#define TB_FP_PRESENT 0x02U /* Routine has floating point ops. */
+#define TB_LOG_ABORT 0x01U /* fp_present && log/abort compiler opt. */
+
+/* flags 2 */
+
+#define TB_INT_HNDL 0x80U /* Routine is an interrupt handler. */
+#define TB_NAME_PRESENT 0x40U /* Name_len/name set (extension field). */
+#define TB_USES_ALLOCA 0x20U /* Uses alloca() to allocate storage. */
+#define TB_CL_DIS_inv 0x1CU /* On-condition directives (see below). */
+#define TB_SAVES_CR 0x02U /* Routine saves the CR. */
+#define TB_SAVES_LR 0x01U /* Routine saves the LR. */
+
+/* cl_dis_inv "on condition" settings: */
+
+#define TB_CL_DIS_INV(x) (((x) & cl_dis_inv) >> 2U)
+
+#define TB_WALK_ONCOND 0U /* Walk stack without restoring state. */
+#define TB_DISCARD_ONCOND 1U /* Walk stack and discard. */
+#define TB_INVOKE_ONCOND 2U /* Invoke a specific system routine. */
+
+/* flags 3 */
+
+#define TB_STORES_BC 0x80U /* Routine saves frame ptr of caller. */
+#define TB_SPARE2 0X40U /* Spare bit. */
+#define TB_FPR_SAVED 0x3fU /* Number of FPRs saved (max of 32). */
+ /* (Last reg saved is ALWAYS fpr31). */
+
+#define TB_NUM_FPR_SAVED(x) ((x) & fpr_saved)
+
+/* flags 4 */
+
+#define TB_HAS_VEC_INFO 0x80U /* Routine uses vectors. */
+#define TB_SPARE3 0X40U /* Spare bit. */
+#define TB_GPR_SAVED 0x3fU /* Number of GPRs saved (max of 32). */
+ /* (Last reg saved is ALWAYS gpr31). */
+
+#define TB_NUM_GPR_SAVED(x) ((x) & gpr_saved)
+
+/* flags 5 */
+
+#define TB_FLOATPARAMS 0xfeU /* Number of floating point parameters. */
+#define TB_PARAMSONSTK 0X01U /* All parameters are on the stack. */
+
+#define TB_NUM_FLOATPARAMS(X) (((x) & floatparams) >> 1U)
+
+/* traceback_table (fixed portion). */
+
+struct traceback_table
+{
+ /* Traceback table layout (fixed portion): */
+
+ unsigned char version; /* Traceback format version. */
+ unsigned char lang; /* Language indicators: */
+ unsigned char flags1; /* Flag bits #1: */
+ unsigned char flags2; /* Flag bits #2: */
+ unsigned char flags3; /* Flag bits #3: */
+ unsigned char flags4; /* Flag bits #4: */
+ unsigned char fixedparams; /* Number of fixed point parameters. */
+ unsigned char flags5; /* Flag bits #5: */
+};
+
+/* traceback_table (optional) extensions. */
+
+/* Optional portions exist independently in the order presented below,
+ not as a structure or a union. Whether or not portions exist is
+ determinable from bit-fields within the fixed portion above. */
+
+/* The following is present only if fixedparams or floatparams are non
+ zero and it immediately follows the fixed portion of the traceback
+ table... */
+
+/* Order and type encoding of parameters: */
+struct traceback_table_fixedparams
+{
+ unsigned long paraminfo;
+};
+
+/* Left-justified bit-encoding as follows: */
+#define FIXED_PARAM 0 /* '0' ==> fixed param (1 gpr or word). */
+#define SPFP_PARAM 2 /* '10' ==> single-precision float param. */
+#define DPFP_PARAM 3 /* '11' ==> double-precision float param. */
+
+#define PARAM_ENCODING(x, bit) /* Yields xxx_PARAM as a function of "bit". */ \
+ ((((x)&(1UL<<(31UL-(bit++))))==0UL) /* Values 0:31 (left-to-right). "bit" is */ \
+ ? FIXED_PARAM /* an L-value that's left incremented to */ \
+ : ((((x)&(1UL<<(31UL-(bit++))))==0)/* the next bit position for the next */ \
+ ? SPFP_PARAM /* parameter. This will be 1 or 2 bit */ \
+ : DPFP_PARAM)) /* positions later. */
+
+/* The following is present only if has_tboff (in flags1) in fixed part is present... */
+
+/* Offset from start of code to TracebackTbl. */
+struct traceback_table_tboff
+{
+ unsigned long tb_offset;
+};
+
+/* The following is present only if int_hndl (in flags2) in fixed part is present ... */
+
+/* What interrupts are handled by the routine. */
+struct traceback_table_interrupts
+{
+ long hand_mask;
+};
+
+/* The following are present only if has_ctl (in flags1) in fixed part is present... */
+
+/* Controlled automatic storage info: */
+struct traceback_table_anchors
+{
+ unsigned long ctl_info; /* Number of controlled automatic anchors. */
+ long ctl_info_disp[1]; /* Array of stack displacements where each. */
+}; /* Anchor is located (array STARTS here). */
+
+/* The following are present only if name_present (in flags2) in fixed
+ part is present... */
+
+/* Routine name: */
+struct traceback_table_routine
+{
+ unsigned short name_len; /* Length of name that follows. */
+ char name[1]; /* Name starts here (NOT null terminated). */
+};
+
+/* The following are present only if uses_alloca (in flags2) in fixed
+ part is present... */
+
+/* Register auto storage when alloca() is used. */
+struct traceback_table_alloca
+{
+ char alloca_reg;
+};
+
+/* The following are present only if has_vec_info (in flags4) in fixed
+ part is present... */
+
+/* Vector info: */
+struct traceback_table_vector
+{
+ unsigned char vec_flags1; /* Vec info bits #1: */
+
+#define TB_VR_SAVED 0xFCU /* Number of saved vector registers. */
+#define TB_SAVES_VRSAVE 0x02U /* Saves VRsave. */
+#define TB_HAS_VARARGS 0x01U /* Routine has a variable argument list. */
+
+#define TB_NUM_VR_SAVED(x) (((x) & TB_VR_SAVED) >> 2U)
+
+ unsigned char vec_flags2; /* Vec info bits #2: */
+
+#define TB_VECTORPARAMS 0xfeU /* Number of vector parameters. */
+#define TB_VEC_PRESENT 0x01U /* Routine uses at least one vec instr. */
+
+#define VECPARAMS(x) (((x) & TB_VECTORPARAMS) >> 1U)
+};
+
+#endif
diff --git a/bfd/pef.c b/bfd/pef.c
new file mode 100644
index 0000000000..bb0d6c5c96
--- /dev/null
+++ b/bfd/pef.c
@@ -0,0 +1,1207 @@
+/* PEF support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <ctype.h>
+
+#include "pef.h"
+#include "pef-traceback.h"
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include "libiberty.h"
+
+#ifndef BFD_IO_FUNCS
+#define BFD_IO_FUNCS 0
+#endif
+
+#define bfd_pef_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_pef_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_pef_new_section_hook _bfd_generic_new_section_hook
+#define bfd_pef_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define bfd_pef_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_pef_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define bfd_pef_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_pef_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_pef_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define bfd_pef_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
+#define bfd_pef_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
+#define bfd_pef_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+
+#define bfd_pef_set_arch_mach _bfd_generic_set_arch_mach
+
+#define bfd_pef_get_section_contents _bfd_generic_get_section_contents
+#define bfd_pef_set_section_contents _bfd_generic_set_section_contents
+
+#define bfd_pef_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define bfd_pef_bfd_relax_section bfd_generic_relax_section
+#define bfd_pef_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_pef_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_pef_bfd_discard_group bfd_generic_discard_group
+#define bfd_pef_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_pef_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
+#define bfd_pef_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_pef_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_pef_bfd_final_link _bfd_generic_final_link
+#define bfd_pef_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_pef_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+static void bfd_pef_print_symbol
+PARAMS ((bfd *abfd, PTR afile, asymbol *symbol, bfd_print_symbol_type how));
+static void bfd_pef_convert_architecture
+PARAMS ((unsigned long architecture,
+ enum bfd_architecture *type, unsigned long *subtype));
+static boolean bfd_pef_mkobject PARAMS ((bfd *abfd));
+static int bfd_pef_parse_traceback_table
+PARAMS ((bfd *abfd, asection *section, unsigned char *buf,
+ size_t len, size_t pos, asymbol *sym, FILE *file));
+static const char *bfd_pef_section_name PARAMS ((bfd_pef_section *section));
+static unsigned long bfd_pef_section_flags PARAMS ((bfd_pef_section *section));
+static asection *bfd_pef_make_bfd_section PARAMS ((bfd *abfd, bfd_pef_section *section));
+static int bfd_pef_read_header PARAMS ((bfd *abfd, bfd_pef_header *header));
+static const bfd_target *bfd_pef_object_p PARAMS ((bfd *));
+static int bfd_pef_parse_traceback_tables
+PARAMS ((bfd *abfd, asection *sec, unsigned char *buf,
+ size_t len, long *nsym, asymbol **csym));
+static int bfd_pef_parse_function_stub
+PARAMS ((bfd *abfd, unsigned char *buf, size_t len, unsigned long *offset));
+static int bfd_pef_parse_function_stubs
+PARAMS ((bfd *abfd, asection *codesec, unsigned char *codebuf, size_t codelen,
+ unsigned char *loaderbuf, size_t loaderlen, unsigned long *nsym, asymbol **csym));
+static long bfd_pef_parse_symbols PARAMS ((bfd *abfd, asymbol **csym));
+static long bfd_pef_count_symbols PARAMS ((bfd *abfd));
+static long bfd_pef_get_symtab_upper_bound PARAMS ((bfd *));
+static long bfd_pef_get_symtab PARAMS ((bfd *, asymbol **));
+static asymbol *bfd_pef_make_empty_symbol PARAMS ((bfd *));
+static void bfd_pef_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static int bfd_pef_sizeof_headers PARAMS ((bfd *, boolean));
+
+static int bfd_pef_xlib_read_header PARAMS ((bfd *abfd, bfd_pef_xlib_header *header));
+static int bfd_pef_xlib_scan PARAMS ((bfd *abfd, bfd_pef_xlib_header *header));
+static const bfd_target *bfd_pef_xlib_object_p PARAMS ((bfd *abfd));
+
+static void
+bfd_pef_print_symbol (abfd, afile, symbol, how)
+ bfd *abfd;
+ PTR afile;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) afile;
+ switch (how) {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ default:
+ bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
+ fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
+ if (strncmp (symbol->name, "__traceback_", strlen ("__traceback_")) == 0) {
+ char *buf = alloca (symbol->udata.i);
+ size_t offset = symbol->value + 4;
+ size_t len = symbol->udata.i;
+ int ret;
+
+ bfd_get_section_contents (abfd, symbol->section, buf, offset, len);
+ ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf, len, 0, NULL, file);
+ if (ret < 0) {
+ fprintf (file, " [ERROR]");
+ }
+ }
+ }
+}
+
+static void bfd_pef_convert_architecture (architecture, type, subtype)
+ unsigned long architecture;
+ enum bfd_architecture *type;
+ unsigned long *subtype;
+{
+ *subtype = bfd_arch_unknown;
+ *type = bfd_arch_unknown;
+
+ const unsigned long ARCH_POWERPC = 0x70777063; /* 'pwpc' */
+ const unsigned long ARCH_M68K = 0x6d36386b; /* 'm68k' */
+
+ if (architecture == ARCH_POWERPC)
+ *type = bfd_arch_powerpc;
+ else if (architecture == ARCH_M68K)
+ *type = bfd_arch_m68k;
+}
+
+static boolean
+bfd_pef_mkobject (abfd)
+ bfd *abfd ATTRIBUTE_UNUSED;
+{
+ return true;
+}
+
+static int
+bfd_pef_parse_traceback_table (abfd, section, buf, len, pos, sym, file)
+ bfd *abfd;
+ asection *section;
+ unsigned char *buf;
+ size_t len;
+ size_t pos;
+ asymbol *sym;
+ FILE *file;
+{
+ struct traceback_table table;
+ size_t offset;
+ const char *s;
+ asymbol tmpsymbol;
+
+ if (sym == NULL) { sym = &tmpsymbol; }
+
+ sym->name = NULL;
+ sym->value = 0;
+ sym->the_bfd = abfd;
+ sym->section = section;
+ sym->flags = 0;
+ sym->udata.i = 0;
+
+ /* memcpy is fine since all fields are unsigned char */
+
+ if ((pos + 8) > len) { return -1; }
+ memcpy (&table, buf + pos, 8);
+
+ /* calling code relies on returned symbols having a name and correct offset */
+
+ if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS)) {
+ return -1;
+ }
+ if (! (table.flags2 & TB_NAME_PRESENT)) {
+ return -1;
+ }
+ if (! table.flags1 & TB_HAS_TBOFF) {
+ return -1;
+ }
+
+ offset = 8;
+
+ if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams)) {
+ offset += 4;
+ }
+
+ if (table.flags1 & TB_HAS_TBOFF) {
+
+ struct traceback_table_tboff off;
+
+ if ((pos + offset + 4) > len) { return -1; }
+ off.tb_offset = bfd_getb32 (buf + pos + offset);
+ offset += 4;
+
+ /* need to subtract 4 because the offset includes the 0x0L
+ preceding the table */
+
+ if (file != NULL) {
+ fprintf (file, " [offset = 0x%lx]", off.tb_offset);
+ }
+
+ if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset))) {
+ return -1;
+ }
+ sym->value = pos - off.tb_offset - 4;
+ }
+
+ if (table.flags2 & TB_INT_HNDL) {
+ offset += 4;
+ }
+
+ if (table.flags1 & TB_HAS_CTL) {
+
+ struct traceback_table_anchors anchors;
+
+ if ((pos + offset + 4) > len) { return -1; }
+ anchors.ctl_info = bfd_getb32 (buf + pos + offset);
+ offset += 4;
+
+ if (anchors.ctl_info > 1024) {
+ return -1;
+ }
+
+ offset += anchors.ctl_info * 4;
+ }
+
+ if (table.flags2 & TB_NAME_PRESENT) {
+
+ struct traceback_table_routine name;
+ char *namebuf;
+
+ if ((pos + offset + 2) > len) { return -1; }
+ name.name_len = bfd_getb16 (buf + pos + offset);
+ offset += 2;
+
+ if (name.name_len > 4096) { return -1; }
+
+ if ((pos + offset + name.name_len) > len) { return -1; }
+
+ namebuf = (char *) bfd_alloc (abfd, name.name_len + 1);
+ if (namebuf == NULL) { return -1; }
+
+ memcpy (namebuf, buf + pos + offset, name.name_len);
+ namebuf[name.name_len] = '\0';
+
+ /* strip leading period inserted by compiler */
+ if (namebuf[0] == '.') {
+ memmove (namebuf, namebuf + 1, name.name_len + 1);
+ }
+
+ sym->name = namebuf;
+
+ for (s = sym->name; (*s != '\0'); s++) {
+ if (! isprint (*s)) {
+ return -1;
+ }
+ }
+
+ offset += name.name_len;
+ }
+
+ if (table.flags2 & TB_USES_ALLOCA) {
+ offset += 4;
+ }
+
+ if (table.flags4 & TB_HAS_VEC_INFO) {
+ offset += 4;
+ }
+
+ if (file != NULL) {
+ fprintf (file, " [length = 0x%lx]", (long) offset);
+ }
+ return offset;
+}
+
+static const char *bfd_pef_section_name (section)
+ bfd_pef_section *section;
+{
+ switch (section->section_kind) {
+ case BFD_PEF_SECTION_CODE: return "code";
+ case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
+ case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
+ case BFD_PEF_SECTION_CONSTANT: return "constant";
+ case BFD_PEF_SECTION_LOADER: return "loader";
+ case BFD_PEF_SECTION_DEBUG: return "debug";
+ case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
+ case BFD_PEF_SECTION_EXCEPTION: return "exception";
+ case BFD_PEF_SECTION_TRACEBACK: return "traceback";
+ default: return "unknown";
+ }
+}
+
+static unsigned long bfd_pef_section_flags (section)
+ bfd_pef_section *section;
+{
+ switch (section->section_kind) {
+ case BFD_PEF_SECTION_CODE:
+ return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
+ case BFD_PEF_SECTION_UNPACKED_DATA:
+ case BFD_PEF_SECTION_PACKED_DATA:
+ case BFD_PEF_SECTION_CONSTANT:
+ case BFD_PEF_SECTION_LOADER:
+ case BFD_PEF_SECTION_DEBUG:
+ case BFD_PEF_SECTION_EXEC_DATA:
+ case BFD_PEF_SECTION_EXCEPTION:
+ case BFD_PEF_SECTION_TRACEBACK:
+ default:
+ return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ }
+}
+
+static asection *
+bfd_pef_make_bfd_section (abfd, section)
+ bfd *abfd;
+ bfd_pef_section *section;
+{
+ asection *bfdsec;
+ const char *name = bfd_pef_section_name (section);
+
+ bfdsec = bfd_make_section_anyway (abfd, name);
+ if (bfdsec == NULL) { return NULL; }
+
+ bfdsec->vma = section->default_address + section->container_offset;
+ bfdsec->lma = section->default_address + section->container_offset;
+ bfdsec->_raw_size = section->container_length;
+ bfdsec->filepos = section->container_offset;
+ bfdsec->alignment_power = section->alignment;
+
+ bfdsec->flags = bfd_pef_section_flags (section);
+
+ return bfdsec;
+}
+
+int bfd_pef_parse_loader_header (abfd, buf, len, header)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ unsigned char *buf;
+ size_t len;
+ bfd_pef_loader_header *header;
+{
+ BFD_ASSERT (len == 56);
+
+ header->main_section = bfd_getb32 (buf);
+ header->main_offset = bfd_getb32 (buf + 4);
+ header->init_section = bfd_getb32 (buf + 8);
+ header->init_offset = bfd_getb32 (buf + 12);
+ header->term_section = bfd_getb32 (buf + 16);
+ header->term_offset = bfd_getb32 (buf + 20);
+ header->imported_library_count = bfd_getb32 (buf + 24);
+ header->total_imported_symbol_count = bfd_getb32 (buf + 28);
+ header->reloc_section_count = bfd_getb32 (buf + 32);
+ header->reloc_instr_offset = bfd_getb32 (buf + 36);
+ header->loader_strings_offset = bfd_getb32 (buf + 40);
+ header->export_hash_offset = bfd_getb32 (buf + 44);
+ header->export_hash_table_power = bfd_getb32 (buf + 48);
+ header->exported_symbol_count = bfd_getb32 (buf + 52);
+
+ return 0;
+}
+
+int bfd_pef_parse_imported_library (abfd, buf, len, header)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ unsigned char *buf;
+ size_t len;
+ bfd_pef_imported_library *header;
+{
+ BFD_ASSERT (len == 24);
+
+ header->name_offset = bfd_getb32 (buf);
+ header->old_implementation_version = bfd_getb32 (buf + 4);
+ header->current_version = bfd_getb32 (buf + 8);
+ header->imported_symbol_count = bfd_getb32 (buf + 12);
+ header->first_imported_symbol = bfd_getb32 (buf + 16);
+ header->options = buf[20];
+ header->reserved_a = buf[21];
+ header->reserved_b = bfd_getb16 (buf + 22);
+
+ return 0;
+}
+
+int bfd_pef_parse_imported_symbol (abfd, buf, len, symbol)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ unsigned char *buf;
+ size_t len;
+ bfd_pef_imported_symbol *symbol;
+{
+ unsigned long value;
+
+ BFD_ASSERT (len == 4);
+
+ value = bfd_getb32 (buf);
+ symbol->class = value >> 24;
+ symbol->name = value & 0x00ffffff;
+
+ return 0;
+}
+
+int bfd_pef_scan_section (abfd, section)
+ bfd *abfd;
+ bfd_pef_section *section;
+{
+ unsigned char buf[28];
+
+ bfd_seek (abfd, section->header_offset, SEEK_SET);
+ if (bfd_bread ((PTR) buf, 28, abfd) != 28) { return -1; }
+
+ section->name_offset = bfd_h_get_32 (abfd, buf);
+ section->default_address = bfd_h_get_32 (abfd, buf + 4);
+ section->total_length = bfd_h_get_32 (abfd, buf + 8);
+ section->unpacked_length = bfd_h_get_32 (abfd, buf + 12);
+ section->container_length = bfd_h_get_32 (abfd, buf + 16);
+ section->container_offset = bfd_h_get_32 (abfd, buf + 20);
+ section->section_kind = buf[24];
+ section->share_kind = buf[25];
+ section->alignment = buf[26];
+ section->reserved = buf[27];
+
+ section->bfd_section = bfd_pef_make_bfd_section (abfd, section);
+ if (section->bfd_section == NULL) { return -1; }
+
+ return 0;
+}
+
+void
+bfd_pef_print_loader_header (abfd, header, file)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ bfd_pef_loader_header *header;
+ FILE *file;
+{
+ fprintf (file, "main_section: %ld\n", header->main_section);
+ fprintf (file, "main_offset: %lu\n", header->main_offset);
+ fprintf (file, "init_section: %ld\n", header->init_section);
+ fprintf (file, "init_offset: %lu\n", header->init_offset);
+ fprintf (file, "term_section: %ld\n", header->term_section);
+ fprintf (file, "term_offset: %lu\n", header->term_offset);
+ fprintf (file, "imported_library_count: %lu\n", header->imported_library_count);
+ fprintf (file, "total_imported_symbol_count: %lu\n", header->total_imported_symbol_count);
+ fprintf (file, "reloc_section_count: %lu\n", header->reloc_section_count);
+ fprintf (file, "reloc_instr_offset: %lu\n", header->reloc_instr_offset);
+ fprintf (file, "loader_strings_offset: %lu\n", header->loader_strings_offset);
+ fprintf (file, "export_hash_offset: %lu\n", header->export_hash_offset);
+ fprintf (file, "export_hash_table_power: %lu\n", header->export_hash_table_power);
+ fprintf (file, "exported_symbol_count: %lu\n", header->exported_symbol_count);
+}
+
+int
+bfd_pef_print_loader_section (abfd, file)
+ bfd *abfd;
+ FILE *file;
+{
+ bfd_pef_loader_header header;
+ asection *loadersec = NULL;
+ unsigned char *loaderbuf = NULL;
+ size_t loaderlen = 0;
+ int ret;
+
+ loadersec = bfd_get_section_by_name (abfd, "loader");
+ if (loadersec == NULL) { return -1; }
+
+ loaderlen = bfd_section_size (abfd, loadersec);
+ loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
+ { free (loaderbuf); return -1; }
+ if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen)
+ { free (loaderbuf); return -1; }
+
+ if (loaderlen < 56) { free (loaderbuf); return -1; }
+ ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
+ if (ret < 0) { free (loaderbuf); return -1; }
+
+ bfd_pef_print_loader_header (abfd, &header, file);
+ return 0;
+}
+
+int
+bfd_pef_scan_start_address (abfd)
+ bfd *abfd;
+{
+ bfd_pef_loader_header header;
+ asection *section;
+
+ asection *loadersec = NULL;
+ unsigned char *loaderbuf = NULL;
+ size_t loaderlen = 0;
+ int ret;
+
+ loadersec = bfd_get_section_by_name (abfd, "loader");
+ if (loadersec == NULL) { goto end; }
+
+ loaderlen = bfd_section_size (abfd, loadersec);
+ loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) { goto error; }
+ if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) { goto error; }
+
+ if (loaderlen < 56) { goto error; }
+ ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
+ if (ret < 0) { goto error; }
+
+ if (header.main_section < 0) { goto end; }
+
+ for (section = abfd->sections; section != NULL; section = section->next) {
+ if ((section->index + 1) == header.main_section) { break; }
+ }
+
+ if (section == NULL) { goto error; }
+
+ abfd->start_address = section->vma + header.main_offset;
+
+ end:
+ if (loaderbuf != NULL) { free (loaderbuf); }
+ return 0;
+
+ error:
+ if (loaderbuf != NULL) { free (loaderbuf); }
+ return -1;
+}
+
+int
+bfd_pef_scan (abfd, header)
+ bfd *abfd;
+ bfd_pef_header *header;
+{
+ unsigned int i;
+ bfd_pef_data_struct *mdata = NULL;
+ enum bfd_architecture cputype;
+ unsigned long cpusubtype;
+
+ if ((header->tag1 != BFD_PEF_TAG1) || (header->tag2 != BFD_PEF_TAG2)) {
+ return -1;
+ }
+
+ mdata = ((bfd_pef_data_struct *)
+ bfd_alloc (abfd, sizeof (bfd_pef_data_struct)));
+ if (mdata == NULL) { return -1; }
+
+ bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype);
+ if (cputype == bfd_arch_unknown) {
+ fprintf (stderr, "bfd_pef_scan: unknown architecture 0x%lx\n", header->architecture);
+ return -1;
+ }
+ bfd_set_arch_mach (abfd, cputype, cpusubtype);
+
+ mdata->header = *header;
+
+ abfd->flags = abfd->xvec->object_flags | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS));
+
+ if (header->section_count != 0) {
+
+ mdata->sections =
+ ((bfd_pef_section *)
+ bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section)));
+ if (mdata->sections == NULL) { return -1; }
+
+ for (i = 0; i < header->section_count; i++) {
+ bfd_pef_section *cur = &mdata->sections[i];
+ cur->header_offset = 40 + (i * 28);
+ if (bfd_pef_scan_section (abfd, cur) < 0) {
+ return -1;
+ }
+ }
+ }
+
+ if (bfd_pef_scan_start_address (abfd) < 0) {
+#if 0
+ fprintf (stderr, "bfd_pef_scan: unable to scan start address: %s\n",
+ bfd_errmsg (bfd_get_error ()));
+ abfd->tdata.pef_data = NULL;
+ return -1;
+#endif
+ }
+
+ abfd->tdata.pef_data = mdata;
+
+ return 0;
+}
+
+static int
+bfd_pef_read_header (abfd, header)
+ bfd *abfd;
+ bfd_pef_header *header;
+{
+ unsigned char buf[40];
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ if (bfd_bread ((PTR) buf, 40, abfd) != 40) { return -1; }
+
+ header->tag1 = bfd_getb32 (buf);
+ header->tag2 = bfd_getb32 (buf + 4);
+ header->architecture = bfd_getb32 (buf + 8);
+ header->format_version = bfd_getb32 (buf + 12);
+ header->timestamp = bfd_getb32 (buf + 16);
+ header->old_definition_version = bfd_getb32 (buf + 20);
+ header->old_implementation_version = bfd_getb32 (buf + 24);
+ header->current_version = bfd_getb32 (buf + 28);
+ header->section_count = bfd_getb32 (buf + 32) + 1;
+ header->instantiated_section_count = bfd_getb32 (buf + 34);
+ header->reserved = bfd_getb32 (buf + 36);
+
+ return 0;
+}
+
+static const bfd_target *
+bfd_pef_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_pef_header header;
+
+ abfd->tdata.pef_data = NULL;
+
+ if (bfd_pef_read_header (abfd, &header) != 0) {
+ abfd->tdata.pef_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_pef_scan (abfd, &header) != 0) {
+ abfd->tdata.pef_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+static int bfd_pef_parse_traceback_tables (abfd, sec, buf, len, nsym, csym)
+ bfd *abfd;
+ asection *sec;
+ unsigned char *buf;
+ size_t len;
+ long *nsym;
+ asymbol **csym;
+{
+ char *name;
+
+ asymbol function;
+ asymbol traceback;
+
+ const char *const tbprefix = "__traceback_";
+ size_t tbnamelen;
+
+ size_t pos = 0;
+ unsigned long count = 0;
+ int ret;
+
+ for (;;) {
+
+ /* we're reading symbols two at a time */
+
+ if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL))) {
+ break;
+ }
+
+ pos += 3;
+ pos -= (pos % 4);
+
+ while ((pos + 4) <= len) {
+ if (bfd_getb32 (buf + pos) == 0) {
+ break;
+ }
+ pos += 4;
+ }
+
+ if ((pos + 4) > len) {
+ break;
+ }
+
+ ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4, &function, 0);
+ if (ret < 0) {
+ /* skip over 0x0L to advance to next possible traceback table */
+ pos += 4;
+ continue;
+ }
+
+ BFD_ASSERT (function.name != NULL);
+
+ /* Don't bother to compute the name if we are just
+ counting symbols */
+
+ if (csym)
+ {
+ tbnamelen = strlen (tbprefix) + strlen (function.name);
+ name = bfd_alloc (abfd, tbnamelen + 1);
+ if (name == NULL) {
+ bfd_release (abfd, (PTR) function.name);
+ function.name = NULL;
+ break;
+ }
+ snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
+ traceback.name = name;
+ traceback.value = pos;
+ traceback.the_bfd = abfd;
+ traceback.section = sec;
+ traceback.flags = 0;
+ traceback.udata.i = ret;
+
+ *(csym[count]) = function;
+ *(csym[count + 1]) = traceback;
+ }
+
+ pos += ret;
+ count += 2;
+ }
+
+ *nsym = count;
+ return 0;
+}
+
+static int bfd_pef_parse_function_stub (abfd, buf, len, offset)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ unsigned char *buf;
+ size_t len;
+ unsigned long *offset;
+{
+ BFD_ASSERT (len == 24);
+
+ if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000) { return -1; }
+ if (bfd_getb32 (buf + 4) != 0x90410014) { return -1; }
+ if (bfd_getb32 (buf + 8) != 0x800c0000) { return -1; }
+ if (bfd_getb32 (buf + 12) != 0x804c0004) { return -1; }
+ if (bfd_getb32 (buf + 16) != 0x7c0903a6) { return -1; }
+ if (bfd_getb32 (buf + 20) != 0x4e800420) { return -1; }
+
+ if (offset != NULL) {
+ *offset = (bfd_getb32 (buf) & 0x0000ffff) / 4;
+ }
+
+ return 0;
+}
+
+static int bfd_pef_parse_function_stubs (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, nsym, csym)
+ bfd *abfd;
+ asection *codesec;
+ unsigned char *codebuf;
+ size_t codelen;
+ unsigned char *loaderbuf;
+ size_t loaderlen;
+ unsigned long *nsym;
+ asymbol **csym;
+{
+ const char *const sprefix = "__stub_";
+
+ size_t codepos = 0;
+ unsigned long count = 0;
+
+ bfd_pef_loader_header header;
+ bfd_pef_imported_library *libraries = NULL;
+ bfd_pef_imported_symbol *imports = NULL;
+
+ unsigned long i;
+ int ret;
+
+ if (loaderlen < 56) { goto error; }
+
+ ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
+ if (ret < 0) { goto error; }
+
+ libraries = (bfd_pef_imported_library *) bfd_malloc
+ (header.imported_library_count * sizeof (bfd_pef_imported_library));
+ imports = (bfd_pef_imported_symbol *) bfd_malloc
+ (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
+
+ if (loaderlen < (56 + (header.imported_library_count * 24))) { goto error; }
+ for (i = 0; i < header.imported_library_count; i++) {
+ ret = bfd_pef_parse_imported_library
+ (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
+ if (ret < 0) { goto error; }
+ }
+
+ if (loaderlen < (56 + (header.imported_library_count * 24) + (header.total_imported_symbol_count * 4)))
+ { goto error; }
+ for (i = 0; i < header.total_imported_symbol_count; i++) {
+ ret = bfd_pef_parse_imported_symbol
+ (abfd, loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4), 4, &imports[i]);
+ if (ret < 0) { goto error; }
+ }
+
+ codepos = 0;
+
+ for (;;) {
+
+ asymbol sym;
+ const char *symname;
+ char *name;
+ unsigned long index;
+ int ret;
+
+ if (csym && (csym[count] == NULL)) { break; }
+
+ codepos += 3;
+ codepos -= (codepos % 4);
+
+ while ((codepos + 4) <= codelen) {
+ if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000) {
+ break;
+ }
+ codepos += 4;
+ }
+
+ if ((codepos + 4) > codelen) {
+ break;
+ }
+
+ ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &index);
+ if (ret < 0) { codepos += 24; continue; }
+
+ if (index >= header.total_imported_symbol_count) { codepos += 24; continue; }
+
+ {
+ size_t max, namelen;
+ const char *s;
+
+ if (loaderlen < (header.loader_strings_offset + imports[index].name)) { goto error; }
+
+ max = loaderlen - (header.loader_strings_offset + imports[index].name);
+ symname = loaderbuf + header.loader_strings_offset + imports[index].name;
+ namelen = 0;
+ for (s = symname; s < (symname + max); s++) {
+ if (*s == '\0') { break; }
+ if (! isprint (*s)) { goto error; }
+ namelen++;
+ }
+ if (*s != '\0') { goto error; }
+
+ name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
+ if (name == NULL) { break; }
+
+ snprintf (name, strlen (sprefix) + namelen + 1, "%s%s", sprefix, symname);
+ sym.name = name;
+ }
+
+ sym.value = codepos;
+ sym.the_bfd = abfd;
+ sym.section = codesec;
+ sym.flags = 0;
+ sym.udata.i = 0;
+
+ codepos += 24;
+
+ if (csym != NULL) {
+ *(csym[count]) = sym;
+ }
+ count++;
+ }
+
+ goto end;
+
+ end:
+ if (libraries != NULL) { free (libraries); }
+ if (imports != NULL) { free (imports); }
+ *nsym = count;
+ return 0;
+
+ error:
+ if (libraries != NULL) { free (libraries); }
+ if (imports != NULL) { free (imports); }
+ *nsym = count;
+ return -1;
+}
+
+static long bfd_pef_parse_symbols (abfd, csym)
+ bfd *abfd;
+ asymbol **csym;
+{
+ unsigned long count = 0;
+
+ asection *codesec = NULL;
+ unsigned char *codebuf = NULL;
+ size_t codelen = 0;
+
+ asection *loadersec = NULL;
+ unsigned char *loaderbuf = NULL;
+ size_t loaderlen = 0;
+
+ codesec = bfd_get_section_by_name (abfd, "code");
+ if (codesec != NULL)
+ {
+ codelen = bfd_section_size (abfd, codesec);
+ codebuf = (unsigned char *) bfd_malloc (codelen);
+ if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0) { goto end; }
+ if (bfd_bread ((PTR) codebuf, codelen, abfd) != codelen) { goto end; }
+ }
+
+ loadersec = bfd_get_section_by_name (abfd, "loader");
+ if (loadersec != NULL)
+ {
+ loaderlen = bfd_section_size (abfd, loadersec);
+ loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) { goto end; }
+ if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) { goto end; }
+ }
+
+ count = 0;
+ if (codesec != NULL)
+ {
+ unsigned long ncount = 0;
+ bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen, &ncount, csym);
+ count += ncount;
+ }
+
+ if ((codesec != NULL) && (loadersec != NULL))
+ {
+ unsigned long ncount = 0;
+ bfd_pef_parse_function_stubs
+ (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, &ncount,
+ (csym != NULL) ? (csym + count) : NULL);
+ count += ncount;
+ }
+
+ if (csym != NULL) {
+ csym[count] = NULL;
+ }
+
+ end:
+ if (codebuf != NULL)
+ free (codebuf);
+
+ if (loaderbuf != NULL)
+ free (loaderbuf);
+
+ return count;
+}
+
+static long
+bfd_pef_count_symbols (abfd)
+ bfd *abfd;
+{
+ return bfd_pef_parse_symbols (abfd, NULL);
+}
+
+static long
+bfd_pef_get_symtab_upper_bound (abfd)
+ bfd *abfd;
+{
+ long nsyms = bfd_pef_count_symbols (abfd);
+ if (nsyms < 0) { return nsyms; }
+ return ((nsyms + 1) * sizeof (asymbol *));
+}
+
+static long
+bfd_pef_get_symtab (abfd, alocation)
+ bfd *abfd;
+ asymbol **alocation;
+{
+ long i;
+ asymbol *syms;
+ long ret;
+
+ long nsyms = bfd_pef_count_symbols (abfd);
+ if (nsyms < 0) { return nsyms; }
+
+ syms = bfd_alloc (abfd, nsyms * sizeof (asymbol));
+ if (syms == NULL) { return -1; }
+
+ for (i = 0; i < nsyms; i++) {
+ alocation[i] = &syms[i];
+ }
+ alocation[nsyms] = NULL;
+
+ ret = bfd_pef_parse_symbols (abfd, alocation);
+ if (ret != nsyms) {
+ return 0;
+ }
+
+ return ret;
+}
+
+static asymbol *
+bfd_pef_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ return (asymbol *) bfd_alloc (abfd, sizeof (asymbol));
+}
+
+static void
+bfd_pef_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static int
+bfd_pef_sizeof_headers (abfd, exec)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ boolean exec ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+const bfd_target pef_vec =
+{
+ "pef", /* name */
+ bfd_target_pef_flavour, /* flavour */
+ BFD_ENDIAN_BIG, /* byteorder */
+ BFD_ENDIAN_BIG, /* header_byteorder */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ { /* bfd_check_format */
+ _bfd_dummy_target,
+ bfd_pef_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format */
+ bfd_false,
+ bfd_pef_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_pef),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (bfd_pef),
+ BFD_JUMP_TABLE_RELOCS (bfd_pef),
+ BFD_JUMP_TABLE_WRITE (bfd_pef),
+ BFD_JUMP_TABLE_LINK (bfd_pef),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
+
+#define bfd_pef_xlib_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_pef_xlib_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_pef_xlib_new_section_hook _bfd_generic_new_section_hook
+#define bfd_pef_xlib_get_section_contents _bfd_generic_get_section_contents
+#define bfd_pef_xlib_set_section_contents _bfd_generic_set_section_contents
+#define bfd_pef_xlib_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define bfd_pef_xlib_set_section_contents_in_window _bfd_generic_set_section_contents_in_window
+
+static int
+bfd_pef_xlib_read_header (abfd, header)
+ bfd *abfd;
+ bfd_pef_xlib_header *header;
+{
+ unsigned char buf[76];
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ if (bfd_bread ((PTR) buf, 76, abfd) != 76) { return -1; }
+
+ header->tag1 = bfd_getb32 (buf);
+ header->tag2 = bfd_getb32 (buf + 4);
+ header->current_format = bfd_getb32 (buf + 8);
+ header->container_strings_offset = bfd_getb32 (buf + 12);
+ header->export_hash_offset = bfd_getb32 (buf + 16);
+ header->export_key_offset = bfd_getb32 (buf + 20);
+ header->export_symbol_offset = bfd_getb32 (buf + 24);
+ header->export_names_offset = bfd_getb32 (buf + 28);
+ header->export_hash_table_power = bfd_getb32 (buf + 32);
+ header->exported_symbol_count = bfd_getb32 (buf + 36);
+ header->frag_name_offset = bfd_getb32 (buf + 40);
+ header->frag_name_length = bfd_getb32 (buf + 44);
+ header->dylib_path_offset = bfd_getb32 (buf + 48);
+ header->dylib_path_length = bfd_getb32 (buf + 52);
+ header->cpu_family = bfd_getb32 (buf + 56);
+ header->cpu_model = bfd_getb32 (buf + 60);
+ header->date_time_stamp = bfd_getb32 (buf + 64);
+ header->current_version = bfd_getb32 (buf + 68);
+ header->old_definition_version = bfd_getb32 (buf + 72);
+ header->old_implementation_version = bfd_getb32 (buf + 76);
+
+ return 0;
+}
+
+int
+bfd_pef_xlib_scan (abfd, header)
+ bfd *abfd;
+ bfd_pef_xlib_header *header;
+{
+ bfd_pef_xlib_data_struct *mdata = NULL;
+
+ if ((header->tag1 != BFD_PEF_XLIB_TAG1)
+ || ((header->tag2 != BFD_PEF_VLIB_TAG2) && (header->tag2 != BFD_PEF_BLIB_TAG2))) {
+ return -1;
+ }
+
+ mdata = ((bfd_pef_xlib_data_struct *)
+ bfd_alloc (abfd, sizeof (bfd_pef_xlib_data_struct)));
+ if (mdata == NULL) { return -1; }
+
+ mdata->header = *header;
+
+ abfd->flags = abfd->xvec->object_flags | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS));
+
+ abfd->tdata.pef_xlib_data = mdata;
+
+ return 0;
+}
+
+static const bfd_target *
+bfd_pef_xlib_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_pef_xlib_header header;
+
+ abfd->tdata.pef_xlib_data = NULL;
+
+ if (bfd_pef_xlib_read_header (abfd, &header) != 0) {
+ abfd->tdata.pef_xlib_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_pef_xlib_scan (abfd, &header) != 0) {
+ abfd->tdata.pef_xlib_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+const bfd_target pef_xlib_vec =
+{
+ "pef-xlib", /* name */
+ bfd_target_pef_xlib_flavour, /* flavour */
+ BFD_ENDIAN_BIG, /* byteorder */
+ BFD_ENDIAN_BIG, /* header_byteorder */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ { /* bfd_check_format */
+ _bfd_dummy_target,
+ bfd_pef_xlib_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format */
+ bfd_false,
+ bfd_pef_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_pef_xlib),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
+
diff --git a/bfd/pef.h b/bfd/pef.h
new file mode 100644
index 0000000000..e909be4027
--- /dev/null
+++ b/bfd/pef.h
@@ -0,0 +1,186 @@
+/* PEF support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+
+#include <stdio.h>
+
+struct bfd_pef_header
+{
+ unsigned long tag1;
+ unsigned long tag2;
+ unsigned long architecture;
+ unsigned long format_version;
+ unsigned long timestamp;
+ unsigned long old_definition_version;
+ unsigned long old_implementation_version;
+ unsigned long current_version;
+ unsigned short section_count;
+ unsigned short instantiated_section_count;
+ unsigned long reserved;
+};
+typedef struct bfd_pef_header bfd_pef_header;
+
+struct bfd_pef_loader_header
+{
+ long main_section;
+ unsigned long main_offset;
+ long init_section;
+ unsigned long init_offset;
+ long term_section;
+ unsigned long term_offset;
+ unsigned long imported_library_count;
+ unsigned long total_imported_symbol_count;
+ unsigned long reloc_section_count;
+ unsigned long reloc_instr_offset;
+ unsigned long loader_strings_offset;
+ unsigned long export_hash_offset;
+ unsigned long export_hash_table_power;
+ unsigned long exported_symbol_count;
+};
+typedef struct bfd_pef_loader_header bfd_pef_loader_header;
+
+struct bfd_pef_imported_library
+{
+ unsigned long name_offset;
+ unsigned long old_implementation_version;
+ unsigned long current_version;
+ unsigned long imported_symbol_count;
+ unsigned long first_imported_symbol;
+ unsigned char options;
+ unsigned char reserved_a;
+ unsigned short reserved_b;
+};
+typedef struct bfd_pef_imported_library bfd_pef_imported_library;
+
+enum bfd_pef_imported_library_options
+ {
+ BFD_PEF_WEAK_IMPORT_LIB = 0x40,
+ BFD_PEF_INIT_LIB_BEFORE = 0x80
+ };
+
+struct bfd_pef_imported_symbol
+{
+ unsigned char class;
+ unsigned long name;
+};
+typedef struct bfd_pef_imported_symbol bfd_pef_imported_symbol;
+
+enum bfd_pef_imported_symbol_class
+ {
+ BFD_PEF_CODE_SYMBOL = 0x00,
+ BFD_PEF_DATA_SYMBOL = 0x01,
+ BFD_PEF_TVECTOR_SYMBOL = 0x02,
+ BFD_PEF_TOC_SYMBOL = 0x03,
+ BFD_PEF_GLUE_SYMBOL = 0x04,
+ BFD_PEF_UNDEFINED_SYMBOL = 0x0F,
+ BFD_PEF_WEAK_IMPORT_SYMBOL_MASK = 0x80
+ };
+
+#define BFD_PEF_TAG1 0x4A6F7921 /* 'Joy!' */
+#define BFD_PEF_TAG2 0x70656666 /* 'peff' */
+
+#define BFD_PEF_VERSION 0x00000001
+
+struct bfd_pef_section
+{
+ long name_offset;
+ unsigned long header_offset;
+ unsigned long default_address;
+ unsigned long total_length;
+ unsigned long unpacked_length;
+ unsigned long container_length;
+ unsigned long container_offset;
+ unsigned char section_kind;
+ unsigned char share_kind;
+ unsigned char alignment;
+ unsigned char reserved;
+ asection *bfd_section;
+};
+typedef struct bfd_pef_section bfd_pef_section;
+
+#define BFD_PEF_SECTION_CODE 0
+#define BFD_PEF_SECTION_UNPACKED_DATA 1
+#define BFD_PEF_SECTION_PACKED_DATA 2
+#define BFD_PEF_SECTION_CONSTANT 3
+#define BFD_PEF_SECTION_LOADER 4
+#define BFD_PEF_SECTION_DEBUG 5
+#define BFD_PEF_SECTION_EXEC_DATA 6
+#define BFD_PEF_SECTION_EXCEPTION 7
+#define BFD_PEF_SECTION_TRACEBACK 8
+
+#define BFD_PEF_SHARE_PROCESS 1
+#define BFD_PEF_SHARE_GLOBAL 4
+#define BFD_PEF_SHARE_PROTECTED 5
+
+struct bfd_pef_data_struct
+{
+ bfd_pef_header header;
+ bfd_pef_section *sections;
+ bfd *ibfd;
+};
+typedef struct bfd_pef_data_struct bfd_pef_data_struct;
+
+#define BFD_PEF_XLIB_TAG1 0xF04D6163 /* '?Mac' */
+#define BFD_PEF_VLIB_TAG2 0x564C6962 /* 'VLib' */
+#define BFD_PEF_BLIB_TAG2 0x424C6962 /* 'BLib' */
+
+#define BFD_PEF_XLIB_VERSION 0x00000001
+
+struct bfd_pef_xlib_header
+{
+ unsigned long tag1;
+ unsigned long tag2;
+ unsigned long current_format;
+ unsigned long container_strings_offset;
+ unsigned long export_hash_offset;
+ unsigned long export_key_offset;
+ unsigned long export_symbol_offset;
+ unsigned long export_names_offset;
+ unsigned long export_hash_table_power;
+ unsigned long exported_symbol_count;
+
+ unsigned long frag_name_offset;
+ unsigned long frag_name_length;
+ unsigned long dylib_path_offset;
+ unsigned long dylib_path_length;
+ unsigned long cpu_family;
+ unsigned long cpu_model;
+ unsigned long date_time_stamp;
+ unsigned long current_version;
+ unsigned long old_definition_version;
+ unsigned long old_implementation_version;
+};
+typedef struct bfd_pef_xlib_header bfd_pef_xlib_header;
+
+struct bfd_pef_xlib_data_struct
+{
+ bfd_pef_xlib_header header;
+};
+typedef struct bfd_pef_xlib_data_struct bfd_pef_xlib_data_struct;
+
+int bfd_pef_parse_loader_header PARAMS ((bfd *, unsigned char *, size_t, bfd_pef_loader_header *));
+int bfd_pef_print_loader_section PARAMS ((bfd *, FILE *));
+void bfd_pef_print_loader_header PARAMS ((bfd *, bfd_pef_loader_header *, FILE *));
+int bfd_pef_parse_imported_library PARAMS ((bfd *, unsigned char *, size_t, bfd_pef_imported_library *));
+int bfd_pef_parse_imported_symbol PARAMS ((bfd *, unsigned char *, size_t, bfd_pef_imported_symbol *));
+int bfd_pef_scan_section PARAMS ((bfd *, bfd_pef_section *));
+int bfd_pef_scan_start_address PARAMS ((bfd *));
+int bfd_pef_scan PARAMS ((bfd *, bfd_pef_header *));
diff --git a/bfd/targets.c b/bfd/targets.c
index b9c86a1bdd..6a68eaa13f 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -4,21 +4,21 @@
Free Software Foundation, Inc.
Written by Cygnus Support.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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 Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program 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.
+ This program 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 this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
@@ -155,7 +155,11 @@ DESCRIPTION
. bfd_target_msdos_flavour,
. bfd_target_ovax_flavour,
. bfd_target_evax_flavour,
-. bfd_target_mmo_flavour
+. bfd_target_mmo_flavour,
+. bfd_target_mach_o_flavour,
+. bfd_target_pef_flavour,
+. bfd_target_pef_xlib_flavour,
+. bfd_target_sym_flavour
.};
.
.enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
@@ -645,6 +649,9 @@ extern const bfd_target m68knetbsd_vec;
extern const bfd_target m68ksysvcoff_vec;
extern const bfd_target m88kbcs_vec;
extern const bfd_target m88kmach3_vec;
+extern const bfd_target mach_o_be_vec;
+extern const bfd_target mach_o_le_vec;
+extern const bfd_target mach_o_fat_vec;
extern const bfd_target mcore_pe_big_vec;
extern const bfd_target mcore_pe_little_vec;
extern const bfd_target mcore_pei_big_vec;
@@ -661,6 +668,8 @@ extern const bfd_target or32coff_big_vec;
extern const bfd_target pc532machaout_vec;
extern const bfd_target pc532netbsd_vec;
extern const bfd_target pdp11_aout_vec;
+extern const bfd_target pef_vec;
+extern const bfd_target pef_xlib_vec;
extern const bfd_target pmac_xcoff_vec;
extern const bfd_target ppcboot_vec;
extern const bfd_target riscix_vec;
@@ -680,6 +689,7 @@ extern const bfd_target sparclynx_aout_vec;
extern const bfd_target sparclynx_coff_vec;
extern const bfd_target sparcnetbsd_vec;
extern const bfd_target sunos_big_vec;
+extern const bfd_target sym_vec;
extern const bfd_target tic30_aout_vec;
extern const bfd_target tic30_coff_vec;
extern const bfd_target tic4x_coff0_beh_vec;
@@ -957,6 +967,9 @@ static const bfd_target * const _bfd_target_vector[] = {
&m68ksysvcoff_vec,
&m88kbcs_vec,
&m88kmach3_vec,
+ &mach_o_be_vec,
+ &mach_o_le_vec,
+ &mach_o_fat_vec,
&mcore_pe_big_vec,
&mcore_pe_little_vec,
&mcore_pei_big_vec,
@@ -984,6 +997,8 @@ static const bfd_target * const _bfd_target_vector[] = {
&pc532machaout_vec,
&pc532netbsd_vec,
&pdp11_aout_vec,
+ &pef_vec,
+ &pef_xlib_vec,
#if 0
/* This has the same magic number as RS/6000. */
&pmac_xcoff_vec,
@@ -1013,6 +1028,7 @@ static const bfd_target * const _bfd_target_vector[] = {
&sparclynx_coff_vec,
&sparcnetbsd_vec,
&sunos_big_vec,
+ &sym_vec,
&tic30_aout_vec,
&tic30_coff_vec,
&tic54x_coff0_beh_vec,
diff --git a/bfd/xsym.c b/bfd/xsym.c
new file mode 100644
index 0000000000..99b4eb719c
--- /dev/null
+++ b/bfd/xsym.c
@@ -0,0 +1,2449 @@
+/* xSYM symbol-file support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "xsym.h"
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define bfd_sym_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_sym_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_sym_new_section_hook _bfd_generic_new_section_hook
+#define bfd_sym_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define bfd_sym_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_sym_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define bfd_sym_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_sym_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_sym_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define bfd_sym_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
+#define bfd_sym_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
+#define bfd_sym_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+#define bfd_sym_set_arch_mach _bfd_generic_set_arch_mach
+#define bfd_sym_get_section_contents _bfd_generic_get_section_contents
+#define bfd_sym_set_section_contents _bfd_generic_set_section_contents
+#define bfd_sym_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define bfd_sym_bfd_relax_section bfd_generic_relax_section
+#define bfd_sym_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_sym_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_sym_bfd_discard_group bfd_generic_discard_group
+#define bfd_sym_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_sym_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
+#define bfd_sym_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_sym_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_sym_bfd_final_link _bfd_generic_final_link
+#define bfd_sym_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_sym_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+
+static int pstrcmp PARAMS ((unsigned char *, unsigned char *));
+static unsigned long compute_offset
+ PARAMS ((unsigned long, unsigned long, unsigned long, unsigned long));
+
+extern const bfd_target sym_vec;
+
+static int
+pstrcmp (a, b)
+ unsigned char *a;
+ unsigned char *b;
+{
+ unsigned char clen;
+ int ret;
+
+ clen = (a[0] > b[0]) ? a[0] : b[0];
+ ret = memcmp (a + 1, b + 1, clen);
+ if (ret != 0)
+ return ret;
+
+ if (a[0] == b[0])
+ return 0;
+ else if (a[0] < b[0])
+ return -1;
+ else
+ return 0;
+}
+
+static unsigned long
+compute_offset (first_page, page_size, entry_size, index)
+ unsigned long first_page;
+ unsigned long page_size;
+ unsigned long entry_size;
+ unsigned long index;
+{
+ unsigned long entries_per_page = page_size / entry_size;
+ unsigned long page_number = first_page + (index / entries_per_page);
+ unsigned long page_offset = (index % entries_per_page) * entry_size;
+
+ return (page_number * page_size) + page_offset;
+}
+
+boolean
+bfd_sym_mkobject (abfd)
+ bfd *abfd ATTRIBUTE_UNUSED;
+{
+ return (boolean) true;
+}
+
+void
+bfd_sym_print_symbol (abfd, afile, symbol, how)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ PTR afile ATTRIBUTE_UNUSED;
+ asymbol *symbol ATTRIBUTE_UNUSED;
+ bfd_print_symbol_type how ATTRIBUTE_UNUSED;
+{
+ return;
+}
+
+boolean
+bfd_sym_valid (abfd)
+ bfd *abfd;
+{
+ if (abfd == NULL || abfd->xvec == NULL)
+ return 0;
+
+ return (abfd->xvec == &sym_vec);
+}
+
+unsigned char *
+bfd_sym_read_name_table (abfd, dshb)
+ bfd *abfd;
+ bfd_sym_header_block *dshb;
+{
+ unsigned char *rstr;
+ long ret;
+ size_t table_size = dshb->dshb_nte.dti_page_count * dshb->dshb_page_size;
+ size_t table_offset = dshb->dshb_nte.dti_first_page * dshb->dshb_page_size;
+
+ rstr = (unsigned char *) bfd_alloc (abfd, table_size);
+ if (rstr == NULL)
+ return rstr;
+
+ bfd_seek (abfd, table_offset, SEEK_SET);
+ ret = bfd_bread (rstr, table_size, abfd);
+ if ((ret < 0) || ((unsigned long) ret != table_size))
+ {
+ bfd_release (abfd, rstr);
+ return NULL;
+ }
+
+ return rstr;
+}
+
+void
+bfd_sym_parse_file_reference_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_file_reference *entry;
+{
+ BFD_ASSERT (len == 6);
+
+ entry->fref_frte_index = bfd_getb16 (buf);
+ entry->fref_offset = bfd_getb32 (buf + 2);
+}
+
+void
+bfd_sym_parse_disk_table_v32 (buf, len, table)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_table_info *table;
+{
+ BFD_ASSERT (len == 8);
+
+ table->dti_first_page = bfd_getb16 (buf);
+ table->dti_page_count = bfd_getb16 (buf + 2);
+ table->dti_object_count = bfd_getb32 (buf + 4);
+}
+
+void
+bfd_sym_parse_header_v32 (buf, len, header)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_header_block *header;
+{
+ BFD_ASSERT (len == 154);
+
+ memcpy (header->dshb_id, buf, 32);
+ header->dshb_page_size = bfd_getb16 (buf + 32);
+ header->dshb_hash_page = bfd_getb16 (buf + 34);
+ header->dshb_root_mte = bfd_getb16 (buf + 36);
+ header->dshb_mod_date = bfd_getb32 (buf + 38);
+
+ bfd_sym_parse_disk_table_v32 (buf + 42, 8, &header->dshb_frte);
+ bfd_sym_parse_disk_table_v32 (buf + 50, 8, &header->dshb_rte);
+ bfd_sym_parse_disk_table_v32 (buf + 58, 8, &header->dshb_mte);
+ bfd_sym_parse_disk_table_v32 (buf + 66, 8, &header->dshb_cmte);
+ bfd_sym_parse_disk_table_v32 (buf + 74, 8, &header->dshb_cvte);
+ bfd_sym_parse_disk_table_v32 (buf + 82, 8, &header->dshb_csnte);
+ bfd_sym_parse_disk_table_v32 (buf + 90, 8, &header->dshb_clte);
+ bfd_sym_parse_disk_table_v32 (buf + 98, 8, &header->dshb_ctte);
+ bfd_sym_parse_disk_table_v32 (buf + 106, 8, &header->dshb_tte);
+ bfd_sym_parse_disk_table_v32 (buf + 114, 8, &header->dshb_nte);
+ bfd_sym_parse_disk_table_v32 (buf + 122, 8, &header->dshb_tinfo);
+ bfd_sym_parse_disk_table_v32 (buf + 130, 8, &header->dshb_fite);
+ bfd_sym_parse_disk_table_v32 (buf + 138, 8, &header->dshb_const);
+
+ memcpy (&header->dshb_file_creator, buf + 146, 4);
+ memcpy (&header->dshb_file_type, buf + 150, 4);
+}
+
+int
+bfd_sym_read_header_v32 (abfd, header)
+ bfd *abfd;
+ bfd_sym_header_block *header;
+{
+ unsigned char buf[154];
+ long ret;
+
+ ret = bfd_bread (buf, 154, abfd);
+ if (ret != 154)
+ return -1;
+
+ bfd_sym_parse_header_v32 (buf, 154, header);
+
+ return 0;
+}
+
+int
+bfd_sym_read_header_v34 (abfd, header)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ bfd_sym_header_block *header ATTRIBUTE_UNUSED;
+{
+ abort ();
+}
+
+int
+bfd_sym_read_header (abfd, header, version)
+ bfd *abfd;
+ bfd_sym_header_block *header;
+ bfd_sym_version version;
+{
+ switch (version)
+ {
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ return bfd_sym_read_header_v34 (abfd, header);
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ return bfd_sym_read_header_v32 (abfd, header);
+ case BFD_SYM_VERSION_3_1:
+ default:
+ return false;
+ }
+}
+
+int
+bfd_sym_read_version (abfd, version)
+ bfd *abfd;
+ bfd_sym_version *version;
+{
+ unsigned char version_string[32];
+ long ret;
+
+ ret = bfd_bread (version_string, sizeof (version_string), abfd);
+ if (ret != sizeof (version_string))
+ return -1;
+
+ if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_1) == 0)
+ *version = BFD_SYM_VERSION_3_1;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_2) == 0)
+ *version = BFD_SYM_VERSION_3_2;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_3) == 0)
+ *version = BFD_SYM_VERSION_3_3;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_4) == 0)
+ *version = BFD_SYM_VERSION_3_4;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_5) == 0)
+ *version = BFD_SYM_VERSION_3_5;
+ else
+ return -1;
+
+ return 0;
+}
+
+void
+bfd_sym_display_table_summary (f, dti, name)
+ FILE *f;
+ bfd_sym_table_info *dti;
+ const char *name;
+{
+ fprintf (f, "%-6s %13ld %13ld %13ld\n",
+ name,
+ dti->dti_first_page,
+ dti->dti_page_count,
+ dti->dti_object_count);
+}
+
+void
+bfd_sym_display_header (f, dshb)
+ FILE *f;
+ bfd_sym_header_block *dshb;
+{
+ fprintf (f, " Version: %.*s\n", dshb->dshb_id[0], dshb->dshb_id + 1);
+ fprintf (f, " Page Size: 0x%x\n", dshb->dshb_page_size);
+ fprintf (f, " Hash Page: %lu\n", dshb->dshb_hash_page);
+ fprintf (f, " Root MTE: %lu\n", dshb->dshb_root_mte);
+ fprintf (f, " Modification Date: ");
+ fprintf (f, "[unimplemented]");
+ fprintf (f, " (0x%lx)\n", dshb->dshb_mod_date);
+
+ fprintf (f, " File Creator: %.4s Type: %.4s\n\n",
+ dshb->dshb_file_creator, dshb->dshb_file_type);
+
+ fprintf (f, "Table Name First Page Page Count Object Count\n");
+ fprintf (f, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+
+ bfd_sym_display_table_summary (f, &dshb->dshb_nte, "NTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_rte, "RTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_mte, "MTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_frte, "FRTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_cmte, "CMTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_cvte, "CVTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_csnte, "CSNTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_clte, "CLTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_ctte, "CTTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_tte, "TTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_tinfo, "TINFO");
+ bfd_sym_display_table_summary (f, &dshb->dshb_fite, "FITE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_const, "CONST");
+
+ fprintf (f, "\n");
+}
+
+void
+bfd_sym_parse_resources_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_resources_table_entry *entry;
+{
+ BFD_ASSERT (len == 18);
+
+ memcpy (&entry->rte_res_type, buf, 4);
+ entry->rte_res_number = bfd_getb16 (buf + 4);
+ entry->rte_nte_index = bfd_getb32 (buf + 6);
+ entry->rte_mte_first = bfd_getb16 (buf + 10);
+ entry->rte_mte_last = bfd_getb16 (buf + 12);
+ entry->rte_res_size = bfd_getb32 (buf + 14);
+}
+
+void
+bfd_sym_parse_modules_table_entry_v33 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_modules_table_entry *entry;
+{
+ BFD_ASSERT (len == 46);
+
+ entry->mte_rte_index = bfd_getb16 (buf);
+ entry->mte_res_offset = bfd_getb32 (buf + 2);
+ entry->mte_size = bfd_getb32 (buf + 6);
+ entry->mte_kind = buf[10];
+ entry->mte_scope = buf[11];
+ entry->mte_parent = bfd_getb16 (buf + 12);
+ bfd_sym_parse_file_reference_v32 (buf + 14, 6, &entry->mte_imp_fref);
+ entry->mte_imp_end = bfd_getb32 (buf + 20);
+ entry->mte_nte_index = bfd_getb32 (buf + 24);
+ entry->mte_cmte_index = bfd_getb16 (buf + 28);
+ entry->mte_cvte_index = bfd_getb32 (buf + 30);
+ entry->mte_clte_index = bfd_getb16 (buf + 34);
+ entry->mte_ctte_index = bfd_getb16 (buf + 36);
+ entry->mte_csnte_idx_1 = bfd_getb32 (buf + 38);
+ entry->mte_csnte_idx_2 = bfd_getb32 (buf + 42);
+}
+
+void
+bfd_sym_parse_file_references_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_file_references_table_entry *entry;
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 10);
+
+ memset (entry, 0, sizeof (bfd_sym_file_references_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_FILE_NAME_INDEX_3_2:
+ entry->filename.type = BFD_SYM_FILE_NAME_INDEX;
+ entry->filename.nte_index = bfd_getb32 (buf + 2);
+ entry->filename.mod_date = bfd_getb32 (buf + 6);
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.file_offset = bfd_getb32 (buf + 2);
+ }
+}
+
+void
+bfd_sym_parse_contained_modules_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_contained_modules_table_entry *entry;
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 6);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_modules_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.nte_index = bfd_getb32 (buf + 2);
+ break;
+ }
+}
+
+void
+bfd_sym_parse_contained_variables_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_contained_variables_table_entry *entry;
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 26);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_variables_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
+ entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
+ bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
+ break;
+
+ default:
+ entry->entry.tte_index = type;
+ entry->entry.nte_index = bfd_getb32 (buf + 2);
+ entry->entry.file_delta = bfd_getb16 (buf + 6);
+ entry->entry.scope = buf[8];
+ entry->entry.la_size = buf[9];
+
+ if (entry->entry.la_size == BFD_SYM_CVTE_SCA)
+ {
+ entry->entry.address.scstruct.sca_kind = buf[10];
+ entry->entry.address.scstruct.sca_class = buf[11];
+ entry->entry.address.scstruct.sca_offset = bfd_getb32 (buf + 12);
+ }
+ else if (entry->entry.la_size <= BFD_SYM_CVTE_SCA)
+ {
+ memcpy (&entry->entry.address.lastruct.la, buf + 10, BFD_SYM_CVTE_SCA);
+ entry->entry.address.lastruct.la_kind = buf[23];
+ }
+ else if (entry->entry.la_size == BFD_SYM_CVTE_BIG_LA)
+ {
+ entry->entry.address.biglastruct.big_la = bfd_getb32 (buf + 10);
+ entry->entry.address.biglastruct.big_la_kind = buf[12];
+ }
+ }
+}
+
+void
+bfd_sym_parse_contained_statements_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_contained_statements_table_entry *entry;
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 8);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_statements_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
+ entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
+ bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.mte_offset = bfd_getb16 (buf + 2);
+ entry->entry.file_delta = bfd_getb32 (buf + 4);
+ break;
+ }
+}
+
+void
+bfd_sym_parse_contained_labels_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_contained_labels_table_entry *entry;
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 12);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_labels_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
+ entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
+ bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.mte_offset = bfd_getb16 (buf + 2);
+ entry->entry.nte_index = bfd_getb32 (buf + 4);
+ entry->entry.file_delta = bfd_getb16 (buf + 8);
+ entry->entry.scope = bfd_getb16 (buf + 10);
+ break;
+ }
+}
+
+void
+bfd_sym_parse_type_table_entry_v32 (buf, len, entry)
+ unsigned char *buf;
+ size_t len;
+ bfd_sym_type_table_entry *entry;
+{
+ BFD_ASSERT (len == 4);
+
+ *entry = bfd_getb32 (buf);
+}
+
+int
+bfd_sym_fetch_resources_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_resources_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_resources_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size;
+ unsigned char buf[18];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ return -1;
+
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 18;
+ parser = bfd_sym_parse_resources_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_1:
+ default:
+ return -1;
+ }
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_rte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_modules_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_modules_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_modules_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size;
+ unsigned char buf[46];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ return -1;
+
+ case BFD_SYM_VERSION_3_3:
+ entry_size = 46;
+ parser = bfd_sym_parse_modules_table_entry_v33;
+ break;
+
+ case BFD_SYM_VERSION_3_2:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ return -1;
+ }
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_mte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_file_references_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_file_references_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_file_references_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[8];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 10;
+ parser = bfd_sym_parse_file_references_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_frte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_modules_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_contained_modules_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_modules_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[6];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 6;
+ parser = bfd_sym_parse_contained_modules_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_cmte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_variables_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_contained_variables_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_variables_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[26];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 26;
+ parser = bfd_sym_parse_contained_variables_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_cvte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_statements_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_contained_statements_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_statements_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[8];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 8;
+ parser = bfd_sym_parse_contained_statements_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_csnte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_labels_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_contained_labels_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_labels_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[12];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 12;
+ parser = bfd_sym_parse_contained_labels_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_clte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_types_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_contained_types_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_types_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[0];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 0;
+ parser = NULL;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_ctte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_file_references_index_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_file_references_index_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_file_references_index_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[0];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 0;
+ parser = NULL;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_fite.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_constant_pool_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_constant_pool_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_constant_pool_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[0];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 0;
+ parser = NULL;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_fite.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_type_table_entry (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_type_table_entry *entry;
+ unsigned long index;
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_type_table_entry *) = NULL;
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[4];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 4;
+ parser = bfd_sym_parse_type_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_tte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_type_information_table_entry (abfd, entry, offset)
+ bfd *abfd;
+ bfd_sym_type_information_table_entry *entry;
+ unsigned long offset;
+{
+ unsigned char buf[4];
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return -1;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+
+ if (bfd_bread (buf, 4, abfd) != 4)
+ return -1;
+ entry->nte_index = bfd_getb32 (buf);
+
+ if (bfd_bread (buf, 2, abfd) != 2)
+ return -1;
+ entry->physical_size = bfd_getb16 (buf);
+
+ if (entry->physical_size & 0x8000)
+ {
+ if (bfd_bread (buf, 4, abfd) != 4)
+ return -1;
+ entry->physical_size &= 0x7fff;
+ entry->logical_size = bfd_getb32 (buf);
+ entry->offset = offset + 10;
+ }
+ else
+ {
+ if (bfd_bread (buf, 2, abfd) != 2)
+ return -1;
+ entry->physical_size &= 0x7fff;
+ entry->logical_size = bfd_getb16 (buf);
+ entry->offset = offset + 8;
+ }
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_type_table_information (abfd, entry, index)
+ bfd *abfd;
+ bfd_sym_type_information_table_entry *entry;
+ unsigned long index;
+{
+ bfd_sym_type_table_entry tindex;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sdata->header.dshb_tte.dti_object_count <= 99)
+ return -1;
+ if (index < 100)
+ return -1;
+
+ if (bfd_sym_fetch_type_table_entry (abfd, &tindex, index - 100) < 0)
+ return -1;
+ if (bfd_sym_fetch_type_information_table_entry (abfd, entry, tindex) < 0)
+ return -1;
+
+ return 0;
+}
+
+const unsigned char *
+bfd_sym_symbol_name (abfd, index)
+ bfd *abfd;
+ unsigned long index;
+{
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (index == 0)
+ return "";
+
+ index *= 2;
+ if ((index / sdata->header.dshb_page_size) > sdata->header.dshb_nte.dti_page_count)
+ return "\009[INVALID]";
+
+ return ((const unsigned char *) sdata->name_table + index);
+}
+
+const unsigned char *
+bfd_sym_module_name (abfd, index)
+ bfd *abfd;
+ unsigned long index;
+{
+ bfd_sym_modules_table_entry entry;
+
+ if (bfd_sym_fetch_modules_table_entry (abfd, &entry, index) < 0)
+ return "\011[INVALID]";
+
+ return bfd_sym_symbol_name (abfd, entry.mte_nte_index);
+}
+
+const char *
+bfd_sym_unparse_storage_kind (kind)
+ enum bfd_sym_storage_kind kind;
+{
+ switch (kind)
+ {
+ case BFD_SYM_STORAGE_KIND_LOCAL: return "LOCAL";
+ case BFD_SYM_STORAGE_KIND_VALUE: return "VALUE";
+ case BFD_SYM_STORAGE_KIND_REFERENCE: return "REFERENCE";
+ case BFD_SYM_STORAGE_KIND_WITH: return "WITH";
+ default: return "[UNKNOWN]";
+ }
+}
+
+const char *
+bfd_sym_unparse_storage_class (kind)
+ enum bfd_sym_storage_class kind;
+{
+ switch (kind)
+ {
+ case BFD_SYM_STORAGE_CLASS_REGISTER: return "REGISTER";
+ case BFD_SYM_STORAGE_CLASS_GLOBAL: return "GLOBAL";
+ case BFD_SYM_STORAGE_CLASS_FRAME_RELATIVE: return "FRAME_RELATIVE";
+ case BFD_SYM_STORAGE_CLASS_STACK_RELATIVE: return "STACK_RELATIVE";
+ case BFD_SYM_STORAGE_CLASS_ABSOLUTE: return "ABSOLUTE";
+ case BFD_SYM_STORAGE_CLASS_CONSTANT: return "CONSTANT";
+ case BFD_SYM_STORAGE_CLASS_RESOURCE: return "RESOURCE";
+ case BFD_SYM_STORAGE_CLASS_BIGCONSTANT: return "BIGCONSTANT";
+ default: return "[UNKNOWN]";
+ }
+}
+
+const char *
+bfd_sym_unparse_module_kind (kind)
+ enum bfd_sym_module_kind kind;
+{
+ switch (kind)
+ {
+ case BFD_SYM_MODULE_KIND_NONE: return "NONE";
+ case BFD_SYM_MODULE_KIND_PROGRAM: return "PROGRAM";
+ case BFD_SYM_MODULE_KIND_UNIT: return "UNIT";
+ case BFD_SYM_MODULE_KIND_PROCEDURE: return "PROCEDURE";
+ case BFD_SYM_MODULE_KIND_FUNCTION: return "FUNCTION";
+ case BFD_SYM_MODULE_KIND_DATA: return "DATA";
+ case BFD_SYM_MODULE_KIND_BLOCK: return "BLOCK";
+ default: return "[UNKNOWN]";
+ }
+}
+
+const char *
+bfd_sym_unparse_symbol_scope (scope)
+ enum bfd_sym_symbol_scope scope;
+{
+ switch (scope)
+ {
+ case BFD_SYM_SYMBOL_SCOPE_LOCAL: return "LOCAL";
+ case BFD_SYM_SYMBOL_SCOPE_GLOBAL: return "GLOBAL";
+ default:
+ return "[UNKNOWN]";
+ }
+}
+
+void
+bfd_sym_print_file_reference (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_file_reference *entry;
+{
+ bfd_sym_file_references_table_entry frtentry;
+ int ret;
+
+ ret = bfd_sym_fetch_file_references_table_entry (abfd, &frtentry, entry->fref_frte_index);
+ fprintf (f, "FILE ");
+
+ if ((ret < 0) || (frtentry.generic.type != BFD_SYM_FILE_NAME_INDEX))
+ fprintf (f, "[INVALID]");
+ else
+ fprintf (f, "\"%.*s\"",
+ bfd_sym_symbol_name (abfd, frtentry.filename.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, frtentry.filename.nte_index)[1]);
+
+ fprintf (f, " (FRTE %lu)", entry->fref_frte_index);
+}
+
+void
+bfd_sym_print_resources_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_resources_table_entry *entry;
+{
+ fprintf (f, " \"%.*s\" (NTE %lu), type \"%.4s\", num %u, size %lu, MTE %lu -- %lu",
+ bfd_sym_symbol_name (abfd, entry->rte_nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->rte_nte_index)[1],
+ entry->rte_nte_index, entry->rte_res_type, entry->rte_res_number,
+ entry->rte_res_size, entry->rte_mte_first, entry->rte_mte_last);
+}
+
+void
+bfd_sym_print_modules_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_modules_table_entry *entry;
+{
+ fprintf (f, "\"%.*s\" (NTE %lu)",
+ bfd_sym_symbol_name (abfd, entry->mte_nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->mte_nte_index)[1],
+ entry->mte_nte_index);
+
+ fprintf (f, "\n ");
+
+ bfd_sym_print_file_reference (abfd, f, &entry->mte_imp_fref);
+ fprintf (f, " range %lu -- %lu", entry->mte_imp_fref.fref_offset, entry->mte_imp_end);
+
+ fprintf (f, "\n ");
+
+ fprintf (f, "kind %s", bfd_sym_unparse_module_kind (entry->mte_kind));
+ fprintf (f, ", scope %s", bfd_sym_unparse_symbol_scope (entry->mte_scope));
+
+ fprintf (f, ", RTE %lu, offset %lu, size %lu",
+ entry->mte_rte_index, entry->mte_res_offset, entry->mte_size);
+
+ fprintf (f, "\n ");
+
+ fprintf (f, "CMTE %lu, CVTE %lu, CLTE %lu, CTTE %lu, CSNTE1 %lu, CSNTE2 %lu",
+ entry->mte_cmte_index, entry->mte_cvte_index,
+ entry->mte_clte_index, entry->mte_ctte_index,
+ entry->mte_csnte_idx_1, entry->mte_csnte_idx_2);
+
+ if (entry->mte_parent != 0)
+ fprintf (f, ", parent %lu", entry->mte_parent);
+ else
+ fprintf (f, ", no parent");
+
+ if (entry->mte_cmte_index != 0)
+ fprintf (f, ", child %lu", entry->mte_cmte_index);
+ else
+ fprintf (f, ", no child");
+
+#if 0
+ {
+ MTE bfd_sym_modules_table_entry pentry;
+
+ ret = bfd_sym_fetch_modules_table_entry (abfd, &pentry, entry->mte_parent);
+ if (ret < 0)
+ fprintf (f, " parent MTE %lu [INVALID]\n", entry->mte_parent);
+ else
+ fprintf (f, " parent MTE %lu \"%.*s\"\n",
+ entry->mte_parent,
+ bfd_sym_symbol_name (abfd, pentry.mte_nte_index)[0],
+ &bfd_sym_symbol_name (abfd, pentry.mte_nte_index)[1]);
+ }
+#endif
+}
+
+void
+bfd_sym_print_file_references_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_file_references_table_entry *entry;
+{
+ switch (entry->generic.type)
+ {
+ case BFD_SYM_FILE_NAME_INDEX:
+ fprintf (f, "FILE \"%.*s\" (NTE %lu), modtime ",
+ bfd_sym_symbol_name (abfd, entry->filename.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->filename.nte_index)[1],
+ entry->filename.nte_index);
+
+ fprintf (f, "[UNIMPLEMENTED]");
+ /* printModDate (entry->filename.mod_date); */
+ fprintf (f, " (0x%lx)", entry->filename.mod_date);
+ break;
+
+ case BFD_SYM_END_OF_LIST:
+ fprintf (f, "END");
+ break;
+
+ default:
+ fprintf (f, "\"%.*s\" (MTE %lu), offset %lu",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.file_offset);
+ break;
+ }
+}
+
+void
+bfd_sym_print_contained_modules_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_contained_modules_table_entry *entry;
+{
+ switch (entry->generic.type)
+ {
+ case BFD_SYM_END_OF_LIST:
+ fprintf (f, "END");
+ break;
+
+ default:
+ fprintf (f, "\"%.*s\" (MTE %lu, NTE %lu)",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.nte_index);
+ break;
+ }
+}
+
+void
+bfd_sym_print_contained_variables_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_contained_variables_table_entry *entry;
+{
+ if (entry->generic.type == BFD_SYM_END_OF_LIST)
+ {
+ fprintf (f, "END");
+ return;
+ }
+
+ if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
+ {
+ bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
+ fprintf (f, " offset %lu", entry->file.fref.fref_offset);
+ return;
+ }
+
+ fprintf (f, "\"%.*s\" (NTE %lu)",
+ bfd_sym_symbol_name (abfd, entry->entry.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->entry.nte_index)[1],
+ entry->entry.nte_index);
+
+ fprintf (f, ", TTE %lu", entry->entry.tte_index);
+ fprintf (f, ", offset %lu", entry->entry.file_delta);
+ fprintf (f, ", scope %s", bfd_sym_unparse_symbol_scope (entry->entry.scope));
+
+ if (entry->entry.la_size == BFD_SYM_CVTE_SCA)
+ fprintf (f, ", latype %s, laclass %s, laoffset %lu",
+ bfd_sym_unparse_storage_kind (entry->entry.address.scstruct.sca_kind),
+ bfd_sym_unparse_storage_class (entry->entry.address.scstruct.sca_class),
+ entry->entry.address.scstruct.sca_offset);
+ else if (entry->entry.la_size <= BFD_SYM_CVTE_LA_MAX_SIZE)
+ {
+ unsigned long i;
+
+ fprintf (f, ", la [");
+ for (i = 0; i < entry->entry.la_size; i++)
+ fprintf (f, "0x%02x ", entry->entry.address.lastruct.la[i]);
+ fprintf (f, "]");
+ }
+ else if (entry->entry.la_size == BFD_SYM_CVTE_BIG_LA)
+ fprintf (f, ", bigla %lu, biglakind %u",
+ entry->entry.address.biglastruct.big_la,
+ entry->entry.address.biglastruct.big_la_kind);
+
+ else
+ fprintf (f, ", la [INVALID]");
+}
+
+void
+bfd_sym_print_contained_statements_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_contained_statements_table_entry *entry;
+{
+ if (entry->generic.type == BFD_SYM_END_OF_LIST)
+ {
+ fprintf (f, "END");
+ return;
+ }
+
+ if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
+ {
+ bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
+ fprintf (f, " offset %lu", entry->file.fref.fref_offset);
+ return;
+ }
+
+ fprintf (f, "\"%.*s\" (MTE %lu), offset %lu, delta %lu",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.mte_offset,
+ entry->entry.file_delta);
+}
+
+void
+bfd_sym_print_contained_labels_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_contained_labels_table_entry *entry;
+{
+ if (entry->generic.type == BFD_SYM_END_OF_LIST)
+ {
+ fprintf (f, "END");
+ return;
+ }
+
+ if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
+ {
+ bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
+ fprintf (f, " offset %lu", entry->file.fref.fref_offset);
+ return;
+ }
+
+ fprintf (f, "\"%.*s\" (MTE %lu), offset %lu, delta %lu, scope %s",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.mte_offset,
+ entry->entry.file_delta,
+ bfd_sym_unparse_symbol_scope (entry->entry.scope));
+}
+
+void
+bfd_sym_print_contained_types_table_entry (abfd, f, entry)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ FILE *f;
+ bfd_sym_contained_types_table_entry *entry ATTRIBUTE_UNUSED;
+{
+ fprintf (f, "[UNIMPLEMENTED]");
+}
+
+const char *
+bfd_sym_type_operator_name (num)
+ unsigned char num;
+{
+ switch (num)
+ {
+ case 1: return "TTE";
+ case 2: return "PointerTo";
+ case 3: return "ScalarOf";
+ case 4: return "ConstantOf";
+ case 5: return "EnumerationOf";
+ case 6: return "VectorOf";
+ case 7: return "RecordOf";
+ case 8: return "UnionOf";
+ case 9: return "SubRangeOf";
+ case 10: return "SetOf";
+ case 11: return "NamedTypeOf";
+ case 12: return "ProcOf";
+ case 13: return "ValueOf";
+ case 14: return "ArrayOf";
+ default: return "[UNKNOWN OPERATOR]";
+ }
+}
+
+const char *
+bfd_sym_type_basic_name (num)
+ unsigned char num;
+{
+ switch (num)
+ {
+ case 0: return "void";
+ case 1: return "pascal string";
+ case 2: return "unsigned long";
+ case 3: return "signed long";
+ case 4: return "extended (10 bytes)";
+ case 5: return "pascal boolean (1 byte)";
+ case 6: return "unsigned byte";
+ case 7: return "signed byte";
+ case 8: return "character (1 byte)";
+ case 9: return "wide character (2 bytes)";
+ case 10: return "unsigned short";
+ case 11: return "signed short";
+ case 12: return "singled";
+ case 13: return "double";
+ case 14: return "extended (12 bytes)";
+ case 15: return "computational (8 bytes)";
+ case 16: return "c string";
+ case 17: return "as-is string";
+ default: return "[UNKNOWN BASIC TYPE]";
+ }
+}
+
+int
+bfd_sym_fetch_long (buf, len, offset, offsetptr, value)
+ unsigned char *buf;
+ unsigned long len;
+ unsigned long offset;
+ unsigned long *offsetptr;
+ long *value;
+{
+ int ret;
+
+ if (offset >= len)
+ {
+ *value = 0;
+ offset += 0;
+ ret = -1;
+ }
+ else if (! (buf[offset] & 0x80))
+ {
+ *value = buf[offset];
+ offset += 1;
+ ret = 0;
+ }
+ else if (buf[offset] == 0xc0)
+ {
+ if ((offset + 5) > len)
+ {
+ *value = 0;
+ offset = len;
+ ret = -1;
+ }
+ else
+ {
+ *value = bfd_getb32 (buf + offset + 1);
+ offset += 5;
+ ret = 0;
+ }
+ }
+ else if ((buf[offset] & 0xc0) == 0xc0)
+ {
+ *value = -(buf[offset] & 0x3f);
+ offset += 1;
+ ret = 0;
+ }
+ else if ((buf[offset] & 0xc0) == 0x80)
+ {
+ if ((offset + 2) > len)
+ {
+ *value = 0;
+ offset = len;
+ ret = -1;
+ }
+ else
+ {
+ *value = bfd_getb16 (buf + offset) & 0x3fff;
+ offset += 2;
+ ret = 0;
+ }
+ }
+ else
+ abort ();
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+
+ return ret;
+}
+
+void
+bfd_sym_print_type_information (abfd, f, buf, len, offset, offsetptr)
+ bfd *abfd;
+ FILE *f;
+ unsigned char *buf;
+ unsigned long len;
+ unsigned long offset;
+ unsigned long *offsetptr;
+{
+ unsigned int type;
+
+ if (offset >= len)
+ {
+ fprintf (f, "[NULL]");
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+ return;
+ }
+
+ type = buf[offset];
+ offset++;
+
+ if (! (type & 0x80))
+ {
+ fprintf (f, "[%s] (0x%x)", bfd_sym_type_basic_name (type & 0x7f), type);
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+ return;
+ }
+
+ if (type & 0x40)
+ fprintf (f, "[packed ");
+ else
+ fprintf (f, "[");
+
+ switch (type & 0x3f)
+ {
+ case 1:
+ {
+ long value;
+ bfd_sym_type_information_table_entry tinfo;
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &value);
+ if (value <= 0)
+ fprintf (f, "[INVALID]");
+ else
+ {
+ if (bfd_sym_fetch_type_table_information (abfd, &tinfo, value) < 0)
+ fprintf (f, "[INVALID]");
+ else
+ fprintf (f, "\"%.*s\"",
+ bfd_sym_symbol_name (abfd, tinfo.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, tinfo.nte_index)[1]);
+ }
+ fprintf (f, " (TTE %lu)", value);
+ break;
+ }
+
+ case 2:
+ fprintf (f, "pointer (0x%x) to ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+
+ case 3:
+ {
+ unsigned long value;
+
+ fprintf (f, "scalar (0x%x) of ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &value);
+ fprintf (f, " (%lu)", value);
+ break;
+ }
+
+ case 5:
+ {
+ unsigned long lower, upper, nelem;
+ unsigned long i;
+
+ fprintf (f, "enumeration (0x%x) of ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &lower);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &upper);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &nelem);
+ fprintf (f, " from %lu to %lu with %lu elements: ", lower, upper, nelem);
+
+ for (i = 0; i < nelem; i++)
+ {
+ fprintf (f, "\n ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ }
+ break;
+ }
+
+ case 6:
+ fprintf (f, "vector (0x%x)", type);
+ fprintf (f, "\n index ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ fprintf (f, "\n target ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+
+ case 7:
+ case 8:
+ {
+ long nrec, eloff, i;
+
+ if ((type & 0x3f) == 7)
+ fprintf (f, "record (0x%x) of ", type);
+ else
+ fprintf (f, "union (0x%x) of ", type);
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &nrec);
+ fprintf (f, "%lu elements: ", nrec);
+
+ for (i = 0; i < nrec; i++)
+ {
+ bfd_sym_fetch_long (buf, len, offset, &offset, &eloff);
+ fprintf (f, "\n ");
+ fprintf (f, "offset %lu: ", eloff);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ }
+ break;
+ }
+
+ case 9:
+ fprintf (f, "subrange (0x%x) of ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ fprintf (f, " lower ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ fprintf (f, " upper ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+
+ case 11:
+ {
+ long value;
+
+ fprintf (f, "named type (0x%x) ", type);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &value);
+ if (value <= 0)
+ fprintf (f, "[INVALID]");
+ else
+ fprintf (f, "\"%.*s\"",
+ bfd_sym_symbol_name (abfd, value)[0],
+ &bfd_sym_symbol_name (abfd, value)[1]);
+
+ fprintf (f, " (NTE %lu) with type ", value);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+ }
+
+ default:
+ fprintf (f, "%s (0x%x)", bfd_sym_type_operator_name (type), type);
+ break;
+ }
+
+ if (type == (0x40 | 0x6))
+ {
+ /* Vector. */
+ long n, width, m;
+ long l;
+ long i;
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &n);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &width);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &m);
+ /* fprintf (f, "\n "); */
+ fprintf (f, " N %ld, width %ld, M %ld, ", n, width, m);
+ for (i = 0; i < m; i++)
+ {
+ bfd_sym_fetch_long (buf, len, offset, &offset, &l);
+ if (i != 0)
+ fprintf (f, " ");
+ fprintf (f, "%ld", l);
+ }
+ }
+ else if (type & 0x40)
+ {
+ /* Other packed type. */
+ long msb, lsb;
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &msb);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &lsb);
+ /* fprintf (f, "\n "); */
+ fprintf (f, " msb %ld, lsb %ld", msb, lsb);
+ }
+
+ fprintf (f, "]");
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+}
+
+void
+bfd_sym_print_type_information_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ bfd_sym_type_information_table_entry *entry;
+{
+ unsigned char *buf;
+ unsigned long offset;
+ unsigned int i;
+
+ fprintf (f, "\"%.*s\" (NTE %lu), %lu bytes at %lu, logical size %lu",
+ bfd_sym_symbol_name (abfd, entry->nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->nte_index)[1],
+ entry->nte_index,
+ entry->physical_size, entry->offset, entry->logical_size);
+
+ fprintf (f, "\n ");
+
+ buf = alloca (entry->physical_size);
+ if (buf == NULL)
+ {
+ fprintf (f, "[ERROR]\n");
+ return;
+ }
+ if (bfd_seek (abfd, entry->offset, SEEK_SET) < 0)
+ {
+ fprintf (f, "[ERROR]\n");
+ return;
+ }
+ if (bfd_bread (buf, entry->physical_size, abfd) != entry->physical_size)
+ {
+ fprintf (f, "[ERROR]\n");
+ return;
+ }
+
+ fprintf (f, "[");
+ for (i = 0; i < entry->physical_size; i++)
+ {
+ if (i == 0)
+ fprintf (f, "0x%02x", buf[i]);
+ else
+ fprintf (f, " 0x%02x", buf[i]);
+ }
+
+ fprintf (f, "]");
+ fprintf (f, "\n ");
+
+ bfd_sym_print_type_information (abfd, f, buf, entry->physical_size, 0, &offset);
+
+ if (offset != entry->physical_size)
+ fprintf (f, "\n [parser used %lu bytes instead of %lu]", offset, entry->physical_size); }
+
+void
+bfd_sym_print_file_references_index_table_entry (abfd, f, entry)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ FILE *f;
+ bfd_sym_file_references_index_table_entry *entry ATTRIBUTE_UNUSED;
+{
+ fprintf (f, "[UNIMPLEMENTED]");
+}
+
+void
+bfd_sym_print_constant_pool_entry (abfd, f, entry)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ FILE *f;
+ bfd_sym_constant_pool_entry *entry ATTRIBUTE_UNUSED;
+{
+ fprintf (f, "[UNIMPLEMENTED]");
+}
+
+unsigned char *
+bfd_sym_display_name_table_entry (abfd, f, entry)
+ bfd *abfd;
+ FILE *f;
+ unsigned char *entry;
+{
+ unsigned long index;
+ unsigned long offset;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+ index = (entry - sdata->name_table) / 2;
+
+ if ((sdata->version >= BFD_SYM_VERSION_3_4) && (entry[0] == 255) && (entry[1] == 0))
+ {
+ unsigned short length = bfd_getb16 (entry + 2);
+ fprintf (f, "[%8lu] \"%.*s\"\n", index, length, entry + 4);
+ offset = 2 + length + 1;
+ }
+ else
+ {
+ if (! ((entry[0] == 0) || ((entry[0] == 1) && (entry[1] == '\0'))))
+ fprintf (f, "[%8lu] \"%.*s\"\n", index, entry[0], entry + 1);
+
+ if (sdata->version >= BFD_SYM_VERSION_3_4)
+ offset = entry[0] + 2;
+ else
+ offset = entry[0] + 1;
+ }
+
+ return (entry + offset + (offset % 2));
+}
+
+void
+bfd_sym_display_name_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long name_table_len;
+ unsigned char *name_table, *name_table_end, *cur;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ name_table_len = sdata->header.dshb_nte.dti_page_count * sdata->header.dshb_page_size;
+ name_table = sdata->name_table;
+ name_table_end = name_table + name_table_len;
+
+ fprintf (f, "name table (NTE) contains %lu bytes:\n\n", name_table_len);
+
+ cur = name_table;
+ for (;;)
+ {
+ cur = bfd_sym_display_name_table_entry (abfd, f, cur);
+ if (cur >= name_table_end)
+ break;
+ }
+}
+
+void
+bfd_sym_display_resources_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_resources_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "resource table (RTE) contains %lu objects:\n\n",
+ sdata->header.dshb_rte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_rte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_resources_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_resources_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_modules_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_modules_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "module table (MTE) contains %lu objects:\n\n",
+ sdata->header.dshb_mte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_mte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_modules_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_modules_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_file_references_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_file_references_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "file reference table (FRTE) contains %lu objects:\n\n",
+ sdata->header.dshb_frte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_frte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_file_references_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_file_references_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_modules_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_contained_modules_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained modules table (CMTE) contains %lu objects:\n\n",
+ sdata->header.dshb_cmte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_cmte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_modules_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_modules_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_variables_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_contained_variables_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained variables table (CVTE) contains %lu objects:\n\n",
+ sdata->header.dshb_cvte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_cvte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_variables_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_variables_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+
+ fprintf (f, "\n");
+}
+
+void
+bfd_sym_display_contained_statements_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_contained_statements_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained statements table (CSNTE) contains %lu objects:\n\n",
+ sdata->header.dshb_csnte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_csnte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_statements_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_statements_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_labels_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_contained_labels_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained labels table (CLTE) contains %lu objects:\n\n",
+ sdata->header.dshb_clte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_clte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_labels_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_labels_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_types_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_contained_types_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained types table (CTTE) contains %lu objects:\n\n",
+ sdata->header.dshb_ctte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_ctte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_types_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_types_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_file_references_index_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_file_references_index_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "file references index table (FITE) contains %lu objects:\n\n",
+ sdata->header.dshb_fite.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_fite.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_file_references_index_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_file_references_index_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_constant_pool (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_constant_pool_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "constant pool (CONST) contains %lu objects:\n\n",
+ sdata->header.dshb_const.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_const.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_constant_pool_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_constant_pool_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_type_information_table (abfd, f)
+ bfd *abfd;
+ FILE *f;
+{
+ unsigned long i;
+ bfd_sym_type_table_entry index;
+ bfd_sym_type_information_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sdata->header.dshb_tte.dti_object_count > 99)
+ fprintf (f, "type table (TINFO) contains %lu objects:\n\n",
+ sdata->header.dshb_tte.dti_object_count - 99);
+ else
+ {
+ fprintf (f, "type table (TINFO) contains [INVALID] objects:\n\n");
+ return;
+ }
+
+ for (i = 100; i <= sdata->header.dshb_tte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_type_table_entry (abfd, &index, i - 100) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] (TINFO %lu) ", i, index);
+
+ if (bfd_sym_fetch_type_information_table_entry (abfd, &entry, index) < 0)
+ fprintf (f, "[INVALID]");
+ else
+ bfd_sym_print_type_information_table_entry (abfd, f, &entry);
+
+ fprintf (f, "\n");
+ }
+ }
+}
+
+const bfd_target *
+bfd_sym_object_p (abfd)
+ bfd *abfd;
+{
+ bfd_sym_data_struct *mdata = NULL;
+ asection *bfdsec;
+ const char *name = "symbols";
+
+ mdata = ((bfd_sym_data_struct *)
+ bfd_alloc (abfd, sizeof (bfd_sym_data_struct)));
+ if (mdata == NULL)
+ return NULL;
+
+ abfd->tdata.sym_data = mdata;
+
+ mdata->name_table = 0;
+ mdata->sbfd = abfd;
+
+ bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_sym_read_version (abfd, &mdata->version) != 0)
+ {
+ abfd->tdata.sym_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0)
+ {
+ abfd->tdata.sym_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ mdata->name_table = bfd_sym_read_name_table (abfd, &mdata->header);
+ if (mdata->name_table == NULL)
+ {
+ abfd->tdata.sym_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ bfdsec = bfd_make_section_anyway (abfd, name);
+ if (bfdsec == NULL)
+ {
+ abfd->tdata.sym_data = NULL;
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->_raw_size = 0;
+ bfdsec->filepos = 0;
+ bfdsec->alignment_power = 0;
+
+ bfdsec->flags = SEC_HAS_CONTENTS;
+
+ return abfd->xvec;
+}
+
+asymbol *
+bfd_sym_make_empty_symbol (abfd)
+ bfd *abfd;
+{
+ return (asymbol *) bfd_alloc (abfd, sizeof (asymbol));
+}
+
+void
+bfd_sym_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asymbol *symbol;
+ symbol_info *ret;
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+long
+bfd_sym_get_symtab_upper_bound (abfd)
+ bfd *abfd ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+long
+bfd_sym_get_symtab (abfd, sym)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asymbol **sym ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+int
+bfd_sym_sizeof_headers (abfd, exec)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ boolean exec ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
+const bfd_target sym_vec =
+{
+ "sym", /* name */
+ bfd_target_sym_flavour, /* flavour */
+ BFD_ENDIAN_BIG, /* byteorder */
+ BFD_ENDIAN_BIG, /* header_byteorder */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
+ | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
+ 0, /* symbol_leading_char */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
+ { /* bfd_check_format */
+ _bfd_dummy_target,
+ bfd_sym_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format */
+ bfd_false,
+ bfd_sym_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_sym),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (bfd_sym),
+ BFD_JUMP_TABLE_RELOCS (bfd_sym),
+ BFD_JUMP_TABLE_WRITE (bfd_sym),
+ BFD_JUMP_TABLE_LINK (bfd_sym),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
+
diff --git a/bfd/xsym.h b/bfd/xsym.h
new file mode 100644
index 0000000000..388da85059
--- /dev/null
+++ b/bfd/xsym.h
@@ -0,0 +1,699 @@
+/* xSYM symbol-file support for BFD.
+ Copyright 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ 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 Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "bfd.h"
+#include <stdio.h>
+
+#ifndef __xSYM_H__
+#define __xSYM_H__
+
+#define BFD_SYM_VERSION_STR_3_1 "\013Version 3.1"
+#define BFD_SYM_VERSION_STR_3_2 "\013Version 3.2"
+#define BFD_SYM_VERSION_STR_3_3 "\013Version 3.3"
+#define BFD_SYM_VERSION_STR_3_4 "\013Version 3.4"
+#define BFD_SYM_VERSION_STR_3_5 "\013Version 3.5"
+#define BFD_SYM_END_OF_LIST_3_2 0xffff
+#define BFD_SYM_END_OF_LIST_3_4 0xffffffff
+#define BFD_SYM_END_OF_LIST BFD_SYM_END_OF_LIST_3_4
+#define BFD_SYM_FILE_NAME_INDEX_3_2 0xfffe
+#define BFD_SYM_FILE_NAME_INDEX_3_4 0xfffffffe
+#define BFD_SYM_FILE_NAME_INDEX BFD_SYM_FILE_NAME_INDEX_3_4
+#define BFD_SYM_SOURCE_FILE_CHANGE_3_2 0xfffe
+#define BFD_SYM_SOURCE_FILE_CHANGE_3_4 0xfffffffe
+#define BFD_SYM_SOURCE_FILE_CHANGE BFD_SYM_SOURCE_FILE_CHANGE_3_4
+#define BFD_SYM_MAXIMUM_LEGAL_INDEX_3_2 0xfffd
+#define BFD_SYM_MAXIMUM_LEGAL_INDEX_3_4 0xfffffffd
+#define BFD_SYM_MAXIMUM_LEGAL_INDEX BFD_SYM_MAXIMUM_LEGAL_INDEX_3_4
+
+enum bfd_sym_storage_class
+{
+ BFD_SYM_STORAGE_CLASS_REGISTER = 0,
+ BFD_SYM_STORAGE_CLASS_GLOBAL = 1,
+ BFD_SYM_STORAGE_CLASS_FRAME_RELATIVE = 2,
+ BFD_SYM_STORAGE_CLASS_STACK_RELATIVE = 3,
+ BFD_SYM_STORAGE_CLASS_ABSOLUTE = 4,
+ BFD_SYM_STORAGE_CLASS_CONSTANT = 5,
+ BFD_SYM_STORAGE_CLASS_BIGCONSTANT = 6,
+ BFD_SYM_STORAGE_CLASS_RESOURCE = 99
+};
+typedef enum bfd_sym_storage_class bfd_sym_storage_class;
+
+enum bfd_sym_storage_kind
+{
+ BFD_SYM_STORAGE_KIND_LOCAL = 0,
+ BFD_SYM_STORAGE_KIND_VALUE = 1,
+ BFD_SYM_STORAGE_KIND_REFERENCE = 2,
+ BFD_SYM_STORAGE_KIND_WITH = 3
+};
+typedef enum bfd_sym_storage_kind bfd_sym_storage_kind;
+
+enum bfd_sym_version
+{
+ BFD_SYM_VERSION_3_1,
+ BFD_SYM_VERSION_3_2,
+ BFD_SYM_VERSION_3_3,
+ BFD_SYM_VERSION_3_4,
+ BFD_SYM_VERSION_3_5
+};
+typedef enum bfd_sym_version bfd_sym_version;
+
+enum bfd_sym_module_kind
+{
+ BFD_SYM_MODULE_KIND_NONE = 0,
+ BFD_SYM_MODULE_KIND_PROGRAM = 1,
+ BFD_SYM_MODULE_KIND_UNIT = 2,
+ BFD_SYM_MODULE_KIND_PROCEDURE = 3,
+ BFD_SYM_MODULE_KIND_FUNCTION = 4,
+ BFD_SYM_MODULE_KIND_DATA = 5,
+ BFD_SYM_MODULE_KIND_BLOCK = 6
+};
+typedef enum bfd_sym_module_kind bfd_sym_module_kind;
+
+enum bfd_sym_symbol_scope
+{
+ BFD_SYM_SYMBOL_SCOPE_LOCAL = 0, /* Object is seen only inside current scope. */
+ BFD_SYM_SYMBOL_SCOPE_GLOBAL = 1 /* Object has global scope. */
+};
+typedef enum bfd_sym_symbol_scope bfd_sym_symbol_scope;
+
+struct bfd_sym_file_reference
+{
+ unsigned long fref_frte_index; /* File reference table index. */
+ unsigned long fref_offset; /* Absolute offset into source file. */
+};
+typedef struct bfd_sym_file_reference bfd_sym_file_reference;
+
+/* NAME TABLE (NTE). */
+
+/* RESOURCES TABLE (RTE)
+
+ All code and data is *defined* to reside in a resource. Even A5
+ relative data is defined to reside in a dummy resource of ResType
+ 'gbld'. Code always resides in a resource. Because a code/data
+ is built of many modules, when walking through a resource we must
+ point back to the modules in the order they were defined. This is
+ done by requiring the entries in the Modules Entry table to be
+ ordered by resource/resource-number and by the location in that
+ resource. Hence, the resource table entry points to the first
+ module making up that resource. All modules table entries following
+ that first one with the same restype/resnum are contiguous and offset
+ from that first entry. */
+
+struct bfd_sym_resources_table_entry
+{
+ unsigned char rte_res_type[4]; /* Resource Type. */
+ unsigned short rte_res_number; /* Resource Number. */
+ unsigned long rte_nte_index; /* Name of the resource. */
+ unsigned long rte_mte_first; /* Index of first module in the resource. */
+ unsigned long rte_mte_last; /* Index of the last module in the resource. */
+ unsigned long rte_res_size; /* Size of the resource. */
+};
+typedef struct bfd_sym_resources_table_entry bfd_sym_resources_table_entry;
+
+/* MODULES TABLE (MTE)
+
+ Modules table entries are ordered by their appearance in a resource.
+ (Note that having a single module copied into two resources is not
+ possible). Modules map back to their resource via an index into the
+ resource table and an offset into the resource. Modules also point
+ to their source files, both the definition module and implemention
+ module. Because modules can be textually nested within other
+ modules, a link to the parent (containing) module is required. This
+ module can textually contain other modules. A link to the contiguous
+ list of child (contained) modules is required. Variables, statements,
+ and types defined in the module are pointed to by indexing the head of
+ the contiguous lists of contained variables, contained statements,
+ and contained types. */
+
+struct bfd_sym_modules_table_entry
+{
+ unsigned long mte_rte_index; /* Which resource it is in. */
+ unsigned long mte_res_offset; /* Offset into the resource. */
+ unsigned long mte_size; /* Size of module. */
+ char mte_kind; /* What kind of module this is. */
+ char mte_scope; /* How visible is it? */
+ unsigned long mte_parent; /* Containing module. */
+ bfd_sym_file_reference mte_imp_fref; /* Implementation source. */
+ unsigned long mte_imp_end; /* End of implementation source. */
+ unsigned long mte_nte_index; /* The name of the module. */
+ unsigned long mte_cmte_index; /* Modules contained in this. */
+ unsigned long mte_cvte_index; /* Variables contained in this. */
+ unsigned long mte_clte_index; /* Local labels defined here. */
+ unsigned long mte_ctte_index; /* Types contained in this. */
+ unsigned long mte_csnte_idx_1; /* CSNTE index of mte_snbr_first. */
+ unsigned long mte_csnte_idx_2; /* CSNTE index of mte_snbr_last. */
+};
+typedef struct bfd_sym_modules_table_entry bfd_sym_modules_table_entry;
+
+/* FILE REFERENCES TABLE (FRTE)
+
+ The FILE REFERENCES TABLE maps from source file to module & offset.
+ The table is ordered by increasing file offset. Each new offset
+ references a module.
+
+ FRT = FILE_SOURCE_START
+ FILE_SOURCE_INCREMENT*
+ END_OF_LIST.
+
+ *** THIS MECHANISM IS VERY SLOW FOR FILE+STATEMENT_NUMBER TO
+ *** MODULE/CODE ADDRESS OPERATIONS. ANOTHER MECHANISM IS
+ *** REQUIRED!! */
+
+union bfd_sym_file_references_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, FILE_NAME_INDEX, or module table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* FILE_NAME_INDEX. */
+ unsigned long type;
+ unsigned long nte_index;
+ unsigned long mod_date;
+ }
+ filename;
+
+ struct
+ {
+ /* < FILE_NAME_INDEX. */
+ unsigned long mte_index;
+ unsigned long file_offset;
+ }
+ entry;
+};
+typedef union bfd_sym_file_references_table_entry bfd_sym_file_references_table_entry;
+
+/* CONTAINED MODULES TABLE (CMTE)
+
+ Contained Modules are lists of indices into the modules table. The
+ lists are terminated by an END_OF_LIST index. All entries are of the
+ same size, hence mapping an index into a CMTE list is simple.
+
+ CMT = MTE_INDEX* END_OF_LIST. */
+
+union bfd_sym_contained_modules_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, index. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ unsigned long mte_index; /* Index into the Modules Table. */
+ unsigned long nte_index; /* The name of the module. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_modules_table_entry bfd_sym_contained_modules_table_entry;
+
+/* CONTAINED VARIABLES TABLE (CVTE)
+
+ Contained Variables map into the module table, file table, name table, and type
+ table. Contained Variables are a contiguous list of source file change record,
+ giving the name of and offset into the source file corresponding to all variables
+ following. Variable definition records contain an index into the name table (giving
+ the text of the variable as it appears in the source code), an index into the type
+ table giving the type of the variable, an increment added to the source file
+ offset giving the start of the implementation of the variable, and a storage
+ class address, giving information on variable's runtime address.
+
+ CVT = SOURCE_FILE_CHANGE SYMBOL_INFO* END_OF_LIST.
+ SYMBOL_INFO = SYMBOL_DEFINITION | SOURCE_FILE_CHANGE .
+
+ All entries are of the same size, making the fetching of data simple. The
+ variable entries in the list are in ALPHABETICAL ORDER to simplify the display of
+ available variables for several of the debugger's windows. */
+
+/* 'la_size' determines the variant used below:
+
+ == BFD_SYM_CVTE_SCA
+ Traditional STORAGE_CLASS_ADDRESS;
+
+ <= BFD_SYM_CVTE_LA_MAX_SIZE
+ That many logical address bytes ("in-situ");
+
+ == BFD_SYM_CVTE_BIG_LA
+ Logical address bytes in constant pool, at offset 'big_la'. */
+
+#define BFD_SYM_CVTE_SCA 0 /* Indicate SCA variant of CVTE. */
+#define BFD_SYM_CVTE_LA_MAX_SIZE 13 /* Max# of logical address bytes in a CVTE. */
+#define BFD_SYM_CVTE_BIG_LA 127 /* Indicates LA redirection to constant pool. */
+
+union bfd_sym_contained_variables_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, or type table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref;
+ }
+ file;
+
+ struct
+ {
+ /* < SOURCE_FILE_CHANGE. */
+ unsigned long tte_index;
+ unsigned long nte_index;
+ unsigned long file_delta; /* Increment from previous source. */
+ unsigned char scope;
+ unsigned char la_size; /* #bytes of LAs below. */
+
+ union
+ {
+ /* la_size == BFD_SYM_CVTE_SCA. */
+ struct
+ {
+ unsigned char sca_kind; /* Distinguish local from value/var formal. */
+ unsigned char sca_class; /* The storage class itself. */
+ unsigned long sca_offset;
+ }
+ scstruct;
+
+ /* la_size <= BFD_SYM_CVTE_LA_MAX_SIZE. */
+ struct {
+ unsigned char la[BFD_SYM_CVTE_LA_MAX_SIZE]; /* Logical address bytes. */
+ unsigned char la_kind; /* Eqv. cvte_location.sca_kind. */
+ }
+ lastruct;
+
+ /* la_size == BFD_SYM_CVTE_BIG_LA 127. */
+ struct
+ {
+ unsigned long big_la; /* Logical address bytes in constant pool. */
+ unsigned char big_la_kind; /* Eqv. cvte_location.sca_kind. */
+ }
+ biglastruct;
+ }
+ address;
+ }
+ entry;
+};
+typedef union bfd_sym_contained_variables_table_entry bfd_sym_contained_variables_table_entry;
+
+/* CONTAINED STATEMENTS TABLE (CSNTE)
+
+ Contained Statements table. This table is similar to the Contained
+ Variables table except that instead of VARIABLE_DEFINITION entries, this
+ module contains STATEMENT_NUMBER_DEFINITION entries. A statement number
+ definition points back to the containing module (via an index into
+ the module entry table) and contains the file and resource deltas
+ to add to the previous values to get to this statement.
+ All entries are of the same size, making the fetching of data simple. The
+ entries in the table are in order of increasing statement number within the
+ source file.
+
+ The Contained Statements table is indexed from two places. An MTE contains
+ an index to the first statement number within the module. An FRTE contains
+ an index to the first statement in the table (Possibly. This is slow.) Or
+ a table of fast statement number to CSNTE entry mappings indexes into the
+ table. Choice not yet made. */
+
+union bfd_sym_contained_statements_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, or statement table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref; /* File name table. */
+ }
+ file;
+
+ struct
+ {
+ unsigned long mte_index; /* Which module contains it. */
+ unsigned long file_delta; /* Where it is defined. */
+ unsigned long mte_offset; /* Where it is in the module. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_statements_table_entry bfd_sym_contained_statements_table_entry;
+
+/* CONTAINED LABELS TABLE (CLTE)
+
+ Contained Labels table names those labels local to the module. It is similar
+ to the Contained Statements table. */
+
+union bfd_sym_contained_labels_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, index. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref;
+ }
+ file;
+
+ struct
+ {
+ /* < SOURCE_FILE_CHANGE. */
+ unsigned long mte_index; /* Which module contains us. */
+ unsigned long mte_offset; /* Where it is in the module. */
+ unsigned long nte_index; /* The name of the label. */
+ unsigned long file_delta; /* Where it is defined. */
+ unsigned short scope; /* How visible the label is. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_labels_table_entry bfd_sym_contained_labels_table_entry;
+
+/* CONTAINED TYPES TABLE (CTTE)
+
+ Contained Types define the named types that are in the module. It is used to
+ map name indices into type indices. The type entries in the table are in
+ alphabetical order by type name. */
+
+union bfd_sym_contained_types_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, or type table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref;
+ }
+ file;
+
+ struct
+ {
+ /* < SOURCE_FILE_CHANGE. */
+ unsigned long tte_index;
+ unsigned long nte_index;
+ unsigned long file_delta; /* From last file definition. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_types_table_entry bfd_sym_contained_types_table_entry;
+
+/* TYPE TABLE (TTE). */
+
+typedef unsigned long bfd_sym_type_table_entry;
+
+/* TYPE INFORMATION TABLE (TINFO). */
+
+struct bfd_sym_type_information_table_entry
+{
+ unsigned long nte_index;
+ unsigned long physical_size;
+ unsigned long logical_size;
+ unsigned long offset;
+};
+typedef struct bfd_sym_type_information_table_entry bfd_sym_type_information_table_entry;
+
+/* FILE REFERENCES INDEX TABLE (FITE)
+
+ The FRTE INDEX TABLE indexes into the FILE REFERENCE TABLE above. The FRTE
+ at that index is the FILE_SOURCE_START for a series of files. The FRTEs are
+ indexed from 1. The list is terminated with an END_OF_LIST. */
+
+union bfd_sym_file_references_index_table_entry
+{
+ struct
+ {
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ unsigned long frte_index; /* Index into the FRTE table. */
+ unsigned long nte_index; /* Name table index, gives filename. */
+ }
+ entry;
+};
+typedef union bfd_sym_file_references_index_table_entry bfd_sym_file_references_index_table_entry;
+
+/* CONSTANT POOL (CONST)
+
+ The CONSTANT_POOL consists of entries that start on word boundaries. The entries
+ are referenced by byte index into the constant pool, not by record number.
+
+ Each entry takes the form:
+
+ <16-bit size>
+ <that many bytes of stuff>
+
+ Entries do not cross page boundaries. */
+
+typedef short bfd_sym_constant_pool_entry;
+
+/* The DISK_SYMBOL_HEADER_BLOCK is the first record in a .SYM file,
+ defining the physical characteristics of the symbolic information.
+ The remainder of the * .SYM file is stored in fixed block
+ allocations. For the purposes of paging, the * file is considered
+ to be an array of dshb_page_size blocks, with block 0 (and *
+ possibly more) devoted to the DISK_SYMBOL_HEADER_BLOCK.
+
+ The dti_object_count field means that the allowed indices for that
+ type of object are 0 .. dti_object_count. An index of 0, although
+ allowed, is never done. However, an 0th entry is created in the
+ table. That entry is filled with all zeroes. The reason for this
+ is to avoid off-by-one programming errors that would otherwise
+ occur: an index of k *MEANS* k, not k-1 when going to the disk
+ table. */
+
+struct bfd_sym_table_info
+{
+ unsigned long dti_first_page; /* First page for this table. */
+ unsigned long dti_page_count; /* Number of pages for the table. */
+ unsigned long dti_object_count; /* Number of objects in the table. */
+};
+typedef struct bfd_sym_table_info bfd_sym_table_info;
+
+struct bfd_sym_header_block
+{
+ unsigned char dshb_id[32]; /* Version information. */
+ unsigned short dshb_page_size; /* Size of the pages/blocks. */
+ unsigned long dshb_hash_page; /* Disk page for the hash table. */
+ unsigned long dshb_root_mte; /* MTE index of the program root. */
+ unsigned long dshb_mod_date; /* modification date of executable. */
+ bfd_sym_table_info dshb_frte; /* Per TABLE information. */
+ bfd_sym_table_info dshb_rte;
+ bfd_sym_table_info dshb_mte;
+ bfd_sym_table_info dshb_cmte;
+ bfd_sym_table_info dshb_cvte;
+ bfd_sym_table_info dshb_csnte;
+ bfd_sym_table_info dshb_clte;
+ bfd_sym_table_info dshb_ctte;
+ bfd_sym_table_info dshb_tte;
+ bfd_sym_table_info dshb_nte;
+ bfd_sym_table_info dshb_tinfo;
+ bfd_sym_table_info dshb_fite; /* File information. */
+ bfd_sym_table_info dshb_const; /* Constant pool. */
+
+ unsigned char dshb_file_creator[4]; /* Executable's creator. */
+ unsigned char dshb_file_type[4]; /* Executable's file type. */
+};
+typedef struct bfd_sym_header_block bfd_sym_header_block;
+
+struct bfd_sym_data_struct
+{
+ unsigned char *name_table;
+ bfd_sym_header_block header;
+ bfd_sym_version version;
+ bfd *sbfd;
+};
+typedef struct bfd_sym_data_struct bfd_sym_data_struct;
+
+extern boolean bfd_sym_mkobject
+ PARAMS ((bfd *));
+extern void bfd_sym_print_symbol
+ PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+extern boolean bfd_sym_valid
+ PARAMS ((bfd *));
+extern unsigned char * bfd_sym_read_name_table
+ PARAMS ((bfd *, bfd_sym_header_block *));
+extern void bfd_sym_parse_file_reference_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_file_reference *));
+extern void bfd_sym_parse_disk_table_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_table_info *));
+extern void bfd_sym_parse_header_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_header_block *));
+extern int bfd_sym_read_header_v32
+ PARAMS ((bfd *, bfd_sym_header_block *));
+extern int bfd_sym_read_header_v34
+ PARAMS ((bfd *, bfd_sym_header_block *));
+extern int bfd_sym_read_header
+ PARAMS ((bfd *, bfd_sym_header_block *, bfd_sym_version));
+extern int bfd_sym_read_version
+ PARAMS ((bfd *, bfd_sym_version *));
+extern void bfd_sym_display_table_summary
+ PARAMS ((FILE *, bfd_sym_table_info *, const char *));
+extern void bfd_sym_display_header
+ PARAMS ((FILE *, bfd_sym_header_block *));
+extern void bfd_sym_parse_resources_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_resources_table_entry *));
+extern void bfd_sym_parse_modules_table_entry_v33
+ PARAMS ((unsigned char *, size_t, bfd_sym_modules_table_entry *));
+extern void bfd_sym_parse_file_references_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_file_references_table_entry *));
+extern void bfd_sym_parse_contained_modules_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_contained_modules_table_entry *));
+extern void bfd_sym_parse_contained_variables_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_contained_variables_table_entry *));
+extern void bfd_sym_parse_contained_statements_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_contained_statements_table_entry *));
+extern void bfd_sym_parse_contained_labels_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_contained_labels_table_entry *));
+extern void bfd_sym_parse_type_table_entry_v32
+ PARAMS ((unsigned char *, size_t, bfd_sym_type_table_entry *));
+extern int bfd_sym_fetch_resources_table_entry
+ PARAMS ((bfd *, bfd_sym_resources_table_entry *, unsigned long));
+extern int bfd_sym_fetch_modules_table_entry
+ PARAMS ((bfd *, bfd_sym_modules_table_entry *, unsigned long));
+extern int bfd_sym_fetch_file_references_table_entry
+ PARAMS ((bfd *, bfd_sym_file_references_table_entry *, unsigned long));
+extern int bfd_sym_fetch_contained_modules_table_entry
+ PARAMS ((bfd *, bfd_sym_contained_modules_table_entry *, unsigned long));
+extern int bfd_sym_fetch_contained_variables_table_entry
+ PARAMS ((bfd *, bfd_sym_contained_variables_table_entry *, unsigned long));
+extern int bfd_sym_fetch_contained_statements_table_entry
+ PARAMS ((bfd *, bfd_sym_contained_statements_table_entry *, unsigned long));
+extern int bfd_sym_fetch_contained_labels_table_entry
+ PARAMS ((bfd *, bfd_sym_contained_labels_table_entry *, unsigned long));
+extern int bfd_sym_fetch_contained_types_table_entry
+ PARAMS ((bfd *, bfd_sym_contained_types_table_entry *, unsigned long));
+extern int bfd_sym_fetch_file_references_index_table_entry
+ PARAMS ((bfd *, bfd_sym_file_references_index_table_entry *, unsigned long));
+extern int bfd_sym_fetch_constant_pool_entry
+ PARAMS ((bfd *, bfd_sym_constant_pool_entry *, unsigned long));
+extern int bfd_sym_fetch_type_table_entry
+ PARAMS ((bfd *, bfd_sym_type_table_entry *, unsigned long));
+extern int bfd_sym_fetch_type_information_table_entry
+ PARAMS ((bfd *, bfd_sym_type_information_table_entry *, unsigned long));
+extern int bfd_sym_fetch_type_table_information
+ PARAMS ((bfd *, bfd_sym_type_information_table_entry *, unsigned long));
+extern const unsigned char * bfd_sym_symbol_name
+ PARAMS ((bfd *, unsigned long));
+extern const unsigned char * bfd_sym_module_name
+ PARAMS ((bfd *, unsigned long));
+extern const char * bfd_sym_unparse_storage_kind
+ PARAMS ((enum bfd_sym_storage_kind));
+extern const char * bfd_sym_unparse_storage_class
+ PARAMS ((enum bfd_sym_storage_class));
+extern const char * bfd_sym_unparse_module_kind
+ PARAMS ((enum bfd_sym_module_kind));
+extern const char * bfd_sym_unparse_symbol_scope
+ PARAMS ((enum bfd_sym_symbol_scope));
+extern void bfd_sym_print_file_reference
+ PARAMS ((bfd *, FILE *, bfd_sym_file_reference *));
+extern void bfd_sym_print_resources_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_resources_table_entry *));
+extern void bfd_sym_print_modules_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_modules_table_entry *));
+extern void bfd_sym_print_file_references_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_file_references_table_entry *));
+extern void bfd_sym_print_contained_modules_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_contained_modules_table_entry *));
+extern void bfd_sym_print_contained_variables_table_entry
+ PARAMS ((bfd *, FILE *f, bfd_sym_contained_variables_table_entry *));
+extern void bfd_sym_print_contained_statements_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_contained_statements_table_entry *));
+extern void bfd_sym_print_contained_labels_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_contained_labels_table_entry *));
+extern void bfd_sym_print_contained_types_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_contained_types_table_entry *));
+extern const char * bfd_sym_type_operator_name
+ PARAMS ((unsigned char));
+extern const char * bfd_sym_type_basic_name
+ PARAMS ((unsigned char));
+extern int bfd_sym_fetch_long
+ PARAMS ((unsigned char *, unsigned long, unsigned long, unsigned long *, long *));
+extern void bfd_sym_print_type_information
+ PARAMS ((bfd *, FILE *, unsigned char *, unsigned long, unsigned long, unsigned long *));
+extern void bfd_sym_print_type_information_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_type_information_table_entry *));
+extern void bfd_sym_print_file_references_index_table_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_file_references_index_table_entry *));
+extern void bfd_sym_print_constant_pool_entry
+ PARAMS ((bfd *, FILE *, bfd_sym_constant_pool_entry *));
+extern unsigned char * bfd_sym_display_name_table_entry
+ PARAMS ((bfd *, FILE *, unsigned char *));
+extern void bfd_sym_display_name_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_resources_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_modules_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_file_references_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_contained_modules_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_contained_variables_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_contained_statements_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_contained_labels_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_contained_types_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_file_references_index_table
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_constant_pool
+ PARAMS ((bfd *, FILE *));
+extern void bfd_sym_display_type_information_table
+ PARAMS ((bfd *, FILE *));
+extern const bfd_target * bfd_sym_object_p
+ PARAMS ((bfd *));
+extern asymbol * bfd_sym_make_empty_symbol
+ PARAMS ((bfd *));
+extern void bfd_sym_get_symbol_info
+ PARAMS ((bfd *, asymbol *, symbol_info *));
+extern long bfd_sym_get_symtab_upper_bound
+ PARAMS ((bfd *));
+extern long bfd_sym_get_symtab
+ PARAMS ((bfd *, asymbol **));
+extern int bfd_sym_sizeof_headers
+ PARAMS ((bfd *, boolean));
+
+#endif /* __xSYM_H__ */