xref: /openbsd/gnu/usr.bin/binutils/bfd/aix386-core.c (revision 007c2a45)
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