12159047fSniklas /* BFD back-end for AIX on PS/2 core files.
22159047fSniklas This was based on trad-core.c, which was written by John Gilmore of
32159047fSniklas Cygnus Support.
4c074d1c9Sdrahn Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000,
5*007c2a45Smiod 2001, 2002, 2004
6b305b0f1Sespie Free Software Foundation, Inc.
72159047fSniklas Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>.
82159047fSniklas Converted to back end form by Ian Lance Taylor <ian@cygnus.com>.
92159047fSniklas
102159047fSniklas This file is part of BFD, the Binary File Descriptor library.
112159047fSniklas
122159047fSniklas This program is free software; you can redistribute it and/or modify
132159047fSniklas it under the terms of the GNU General Public License as published by
142159047fSniklas the Free Software Foundation; either version 2 of the License, or
152159047fSniklas (at your option) any later version.
162159047fSniklas
172159047fSniklas This program is distributed in the hope that it will be useful,
182159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
192159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
202159047fSniklas GNU General Public License for more details.
212159047fSniklas
222159047fSniklas You should have received a copy of the GNU General Public License
232159047fSniklas along with this program; if not, write to the Free Software
242159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
252159047fSniklas
262159047fSniklas #include "bfd.h"
272159047fSniklas #include "sysdep.h"
282159047fSniklas #include "libbfd.h"
292159047fSniklas #include "coff/i386.h"
302159047fSniklas #include "coff/internal.h"
312159047fSniklas #include "libcoff.h"
322159047fSniklas
332159047fSniklas #include <signal.h>
342159047fSniklas
352159047fSniklas #if defined (_AIX) && defined (_I386)
36b55d4692Sfgsch #define NOCHECKS /* This is for coredump.h. */
37b55d4692Sfgsch #define _h_USER /* Avoid including user.h from coredump.h. */
382159047fSniklas #include <uinfo.h>
392159047fSniklas #include <sys/i386/coredump.h>
402159047fSniklas #endif /* _AIX && _I386 */
412159047fSniklas
42b55d4692Sfgsch /* Maybe this could work on some other i386 but I have not tried it
432159047fSniklas * mtranle@paris - Tue Sep 24 12:49:35 1991
442159047fSniklas */
452159047fSniklas
462159047fSniklas #ifndef COR_MAGIC
472159047fSniklas # define COR_MAGIC "core"
482159047fSniklas #endif
492159047fSniklas
50b55d4692Sfgsch /* Need this cast because ptr is really void *. */
512159047fSniklas #define core_hdr(bfd) \
522159047fSniklas (((bfd->tdata.trad_core_data))->hdr)
532159047fSniklas #define core_section(bfd,n) \
542159047fSniklas (((bfd)->tdata.trad_core_data)->sections[n])
552159047fSniklas #define core_regsec(bfd) \
562159047fSniklas (((bfd)->tdata.trad_core_data)->reg_section)
572159047fSniklas #define core_reg2sec(bfd) \
582159047fSniklas (((bfd)->tdata.trad_core_data)->reg2_section)
592159047fSniklas
60b55d4692Sfgsch /* These are stored in the bfd's tdata. */
612159047fSniklas struct trad_core_struct {
622159047fSniklas struct corehdr *hdr; /* core file header */
632159047fSniklas asection *reg_section;
642159047fSniklas asection *reg2_section;
652159047fSniklas asection *sections[MAX_CORE_SEGS];
662159047fSniklas };
672159047fSniklas
68e93f7393Sniklas static void swap_abort PARAMS ((void));
69e93f7393Sniklas
702159047fSniklas static const bfd_target *
aix386_core_file_p(abfd)712159047fSniklas aix386_core_file_p (abfd)
722159047fSniklas bfd *abfd;
732159047fSniklas {
742159047fSniklas int i, n;
752159047fSniklas unsigned char longbuf[4]; /* Raw bytes of various header fields */
76c074d1c9Sdrahn bfd_size_type core_size = sizeof (struct corehdr);
77c074d1c9Sdrahn bfd_size_type amt;
782159047fSniklas struct corehdr *core;
792159047fSniklas struct mergem {
802159047fSniklas struct trad_core_struct coredata;
812159047fSniklas struct corehdr internal_core;
822159047fSniklas } *mergem;
832159047fSniklas
84c074d1c9Sdrahn amt = sizeof (longbuf);
85c074d1c9Sdrahn if (bfd_bread ((PTR) longbuf, amt, abfd) != amt)
862159047fSniklas {
872159047fSniklas if (bfd_get_error () != bfd_error_system_call)
882159047fSniklas bfd_set_error (bfd_error_wrong_format);
892159047fSniklas return 0;
902159047fSniklas }
912159047fSniklas
92b55d4692Sfgsch if (strncmp (longbuf, COR_MAGIC, 4))
93b55d4692Sfgsch return 0;
942159047fSniklas
95c074d1c9Sdrahn if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
96b55d4692Sfgsch return 0;
972159047fSniklas
98c074d1c9Sdrahn amt = sizeof (struct mergem);
99c074d1c9Sdrahn mergem = (struct mergem *) bfd_zalloc (abfd, amt);
1002159047fSniklas if (mergem == NULL)
1012159047fSniklas return 0;
1022159047fSniklas
1032159047fSniklas core = &mergem->internal_core;
1042159047fSniklas
105c074d1c9Sdrahn if ((bfd_bread ((PTR) core, core_size, abfd)) != core_size)
1062159047fSniklas {
1072159047fSniklas if (bfd_get_error () != bfd_error_system_call)
1082159047fSniklas bfd_set_error (bfd_error_wrong_format);
109c074d1c9Sdrahn loser:
1102159047fSniklas bfd_release (abfd, (char *) mergem);
111c074d1c9Sdrahn abfd->tdata.any = NULL;
112c074d1c9Sdrahn bfd_section_list_clear (abfd);
1132159047fSniklas return 0;
1142159047fSniklas }
1152159047fSniklas
1162159047fSniklas set_tdata (abfd, &mergem->coredata);
1172159047fSniklas core_hdr (abfd) = core;
1182159047fSniklas
119c074d1c9Sdrahn /* Create the sections. */
120c074d1c9Sdrahn core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
1212159047fSniklas if (core_regsec (abfd) == NULL)
1222159047fSniklas goto loser;
1232159047fSniklas
1242159047fSniklas core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
1252159047fSniklas core_regsec (abfd)->_raw_size = sizeof (core->cd_regs);
126c074d1c9Sdrahn core_regsec (abfd)->vma = (bfd_vma) -1;
1272159047fSniklas
128b55d4692Sfgsch /* We'll access the regs afresh in the core file, like any section. */
129b55d4692Sfgsch core_regsec (abfd)->filepos =
130b55d4692Sfgsch (file_ptr) offsetof (struct corehdr, cd_regs[0]);
131c074d1c9Sdrahn
132c074d1c9Sdrahn core_reg2sec (abfd) = bfd_make_section_anyway (abfd, ".reg2");
133c074d1c9Sdrahn if (core_reg2sec (abfd) == NULL)
134c074d1c9Sdrahn /* bfd_release frees everything allocated after it's arg. */
135c074d1c9Sdrahn goto loser;
136c074d1c9Sdrahn
137c074d1c9Sdrahn core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
138c074d1c9Sdrahn core_reg2sec (abfd)->_raw_size = sizeof (core->cd_fpregs);
139c074d1c9Sdrahn core_reg2sec (abfd)->vma = (bfd_vma) -1;
140b55d4692Sfgsch core_reg2sec (abfd)->filepos =
141b55d4692Sfgsch (file_ptr) offsetof (struct corehdr, cd_fpregs);
1422159047fSniklas
143c074d1c9Sdrahn for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++)
144c074d1c9Sdrahn {
145c074d1c9Sdrahn const char *sname;
146c074d1c9Sdrahn flagword flags;
147c074d1c9Sdrahn
148c074d1c9Sdrahn if (core->cd_segs[i].cs_offset == 0)
149c074d1c9Sdrahn continue;
150c074d1c9Sdrahn
151c074d1c9Sdrahn switch (core->cd_segs[i].cs_type)
152c074d1c9Sdrahn {
153c074d1c9Sdrahn case COR_TYPE_DATA:
154c074d1c9Sdrahn sname = ".data";
155c074d1c9Sdrahn flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
156c074d1c9Sdrahn break;
157c074d1c9Sdrahn case COR_TYPE_STACK:
158c074d1c9Sdrahn sname = ".stack";
159c074d1c9Sdrahn flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
160c074d1c9Sdrahn break;
161c074d1c9Sdrahn case COR_TYPE_LIBDATA:
162c074d1c9Sdrahn sname = ".libdata";
163c074d1c9Sdrahn flags = SEC_ALLOC + SEC_HAS_CONTENTS;
164c074d1c9Sdrahn break;
165c074d1c9Sdrahn case COR_TYPE_WRITE:
166c074d1c9Sdrahn sname = ".writeable";
167c074d1c9Sdrahn flags = SEC_ALLOC + SEC_HAS_CONTENTS;
168c074d1c9Sdrahn break;
169c074d1c9Sdrahn case COR_TYPE_MSC:
170c074d1c9Sdrahn sname = ".misc";
171c074d1c9Sdrahn flags = SEC_ALLOC + SEC_HAS_CONTENTS;
172c074d1c9Sdrahn break;
173c074d1c9Sdrahn default:
174c074d1c9Sdrahn sname = ".unknown";
175c074d1c9Sdrahn flags = SEC_ALLOC + SEC_HAS_CONTENTS;
176c074d1c9Sdrahn break;
177c074d1c9Sdrahn }
178c074d1c9Sdrahn core_section (abfd, n) = bfd_make_section_anyway (abfd, sname);
179c074d1c9Sdrahn if (core_section (abfd, n) == NULL)
180c074d1c9Sdrahn goto loser;
181c074d1c9Sdrahn
182c074d1c9Sdrahn core_section (abfd, n)->flags = flags;
183c074d1c9Sdrahn core_section (abfd, n)->_raw_size = core->cd_segs[i].cs_len;
184c074d1c9Sdrahn core_section (abfd, n)->vma = core->cd_segs[i].cs_address;
185c074d1c9Sdrahn core_section (abfd, n)->filepos = core->cd_segs[i].cs_offset;
186c074d1c9Sdrahn core_section (abfd, n)->alignment_power = 2;
187c074d1c9Sdrahn n++;
188c074d1c9Sdrahn }
1892159047fSniklas
1902159047fSniklas return abfd->xvec;
1912159047fSniklas }
1922159047fSniklas
1932159047fSniklas static char *
aix386_core_file_failing_command(abfd)1942159047fSniklas aix386_core_file_failing_command (abfd)
1952159047fSniklas bfd *abfd;
1962159047fSniklas {
1972159047fSniklas return core_hdr (abfd)->cd_comm;
1982159047fSniklas }
1992159047fSniklas
2002159047fSniklas static int
aix386_core_file_failing_signal(abfd)2012159047fSniklas aix386_core_file_failing_signal (abfd)
2022159047fSniklas bfd *abfd;
2032159047fSniklas {
2042159047fSniklas return core_hdr (abfd)->cd_cursig;
2052159047fSniklas }
2062159047fSniklas
207c074d1c9Sdrahn static bfd_boolean
aix386_core_file_matches_executable_p(core_bfd,exec_bfd)2082159047fSniklas aix386_core_file_matches_executable_p (core_bfd, exec_bfd)
2092159047fSniklas bfd *core_bfd;
2102159047fSniklas bfd *exec_bfd;
2112159047fSniklas {
212b55d4692Sfgsch /* FIXME: We have no way of telling at this point. */
213c074d1c9Sdrahn return TRUE;
2142159047fSniklas }
2152159047fSniklas
2162159047fSniklas /* If somebody calls any byte-swapping routines, shoot them. */
217b55d4692Sfgsch
218e93f7393Sniklas static void
swap_abort()2192159047fSniklas swap_abort ()
2202159047fSniklas {
221b55d4692Sfgsch /* This way doesn't require any declaration for ANSI to fuck up. */
222b55d4692Sfgsch abort ();
2232159047fSniklas }
224b55d4692Sfgsch
225*007c2a45Smiod #define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
226*007c2a45Smiod #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
227*007c2a45Smiod #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
228*007c2a45Smiod #define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
229*007c2a45Smiod #define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
230*007c2a45Smiod #define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
2312159047fSniklas
232b55d4692Sfgsch const bfd_target aix386_core_vec = {
2332159047fSniklas "aix386-core",
2342159047fSniklas bfd_target_unknown_flavour,
235c88b1d6cSniklas BFD_ENDIAN_BIG, /* target byte order */
236c074d1c9Sdrahn BFD_ENDIAN_BIG, /* target headers byte order */
2372159047fSniklas (HAS_RELOC | EXEC_P | /* object flags */
2382159047fSniklas HAS_LINENO | HAS_DEBUG |
2392159047fSniklas HAS_SYMS | HAS_LOCALS | WP_TEXT),
2402159047fSniklas
2412159047fSniklas (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
2422159047fSniklas 0, /* leading underscore */
2432159047fSniklas ' ', /* ar_pad_char */
2442159047fSniklas 16, /* ar_max_namelen */
245*007c2a45Smiod NO_GET64, NO_GETS64, NO_PUT64,
2462159047fSniklas NO_GET, NO_GETS, NO_PUT,
2472159047fSniklas NO_GET, NO_GETS, NO_PUT, /* data */
248*007c2a45Smiod NO_GET64, NO_GETS64, NO_PUT64,
2492159047fSniklas NO_GET, NO_GETS, NO_PUT,
2502159047fSniklas NO_GET, NO_GETS, NO_PUT, /* hdrs */
2512159047fSniklas
2522159047fSniklas {_bfd_dummy_target, _bfd_dummy_target,
2532159047fSniklas _bfd_dummy_target, aix386_core_file_p},
2542159047fSniklas {bfd_false, bfd_false, /* bfd_create_object */
2552159047fSniklas bfd_false, bfd_false},
2562159047fSniklas {bfd_false, bfd_false, /* bfd_write_contents */
2572159047fSniklas bfd_false, bfd_false},
2582159047fSniklas
2592159047fSniklas BFD_JUMP_TABLE_GENERIC (_bfd_generic),
2602159047fSniklas BFD_JUMP_TABLE_COPY (_bfd_generic),
2612159047fSniklas BFD_JUMP_TABLE_CORE (aix386),
2622159047fSniklas BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
2632159047fSniklas BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
2642159047fSniklas BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
2652159047fSniklas BFD_JUMP_TABLE_WRITE (_bfd_generic),
2662159047fSniklas BFD_JUMP_TABLE_LINK (_bfd_nolink),
2672159047fSniklas BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2682159047fSniklas
269b305b0f1Sespie NULL,
270b305b0f1Sespie
2712159047fSniklas (PTR) 0
2722159047fSniklas };
273