xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/aix386-core.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* BFD back-end for AIX on PS/2 core files.
2*3d8817e4Smiod    This was based on trad-core.c, which was written by John Gilmore of
3*3d8817e4Smiod         Cygnus Support.
4*3d8817e4Smiod    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000,
5*3d8817e4Smiod    2001, 2002, 2004
6*3d8817e4Smiod    Free Software Foundation, Inc.
7*3d8817e4Smiod    Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>.
8*3d8817e4Smiod    Converted to back end form by Ian Lance Taylor <ian@cygnus.com>.
9*3d8817e4Smiod 
10*3d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
11*3d8817e4Smiod 
12*3d8817e4Smiod This program is free software; you can redistribute it and/or modify
13*3d8817e4Smiod it under the terms of the GNU General Public License as published by
14*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
15*3d8817e4Smiod (at your option) any later version.
16*3d8817e4Smiod 
17*3d8817e4Smiod This program is distributed in the hope that it will be useful,
18*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
19*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20*3d8817e4Smiod GNU General Public License for more details.
21*3d8817e4Smiod 
22*3d8817e4Smiod You should have received a copy of the GNU General Public License
23*3d8817e4Smiod along with this program; if not, write to the Free Software
24*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25*3d8817e4Smiod 
26*3d8817e4Smiod #include "bfd.h"
27*3d8817e4Smiod #include "sysdep.h"
28*3d8817e4Smiod #include "libbfd.h"
29*3d8817e4Smiod #include "coff/i386.h"
30*3d8817e4Smiod #include "coff/internal.h"
31*3d8817e4Smiod #include "libcoff.h"
32*3d8817e4Smiod 
33*3d8817e4Smiod #include <signal.h>
34*3d8817e4Smiod 
35*3d8817e4Smiod #if defined (_AIX) && defined (_I386)
36*3d8817e4Smiod #define NOCHECKS		/* This is for coredump.h.  */
37*3d8817e4Smiod #define _h_USER			/* Avoid including user.h from coredump.h.  */
38*3d8817e4Smiod #include <uinfo.h>
39*3d8817e4Smiod #include <sys/i386/coredump.h>
40*3d8817e4Smiod #endif /* _AIX && _I386 */
41*3d8817e4Smiod 
42*3d8817e4Smiod /* Maybe this could work on some other i386 but I have not tried it
43*3d8817e4Smiod  * mtranle@paris - Tue Sep 24 12:49:35 1991
44*3d8817e4Smiod  */
45*3d8817e4Smiod 
46*3d8817e4Smiod #ifndef COR_MAGIC
47*3d8817e4Smiod # define COR_MAGIC "core"
48*3d8817e4Smiod #endif
49*3d8817e4Smiod 
50*3d8817e4Smiod /* Need this cast because ptr is really void *.  */
51*3d8817e4Smiod #define core_hdr(bfd) \
52*3d8817e4Smiod     (((bfd->tdata.trad_core_data))->hdr)
53*3d8817e4Smiod #define core_section(bfd,n) \
54*3d8817e4Smiod     (((bfd)->tdata.trad_core_data)->sections[n])
55*3d8817e4Smiod #define core_regsec(bfd) \
56*3d8817e4Smiod     (((bfd)->tdata.trad_core_data)->reg_section)
57*3d8817e4Smiod #define core_reg2sec(bfd) \
58*3d8817e4Smiod     (((bfd)->tdata.trad_core_data)->reg2_section)
59*3d8817e4Smiod 
60*3d8817e4Smiod /* These are stored in the bfd's tdata.  */
61*3d8817e4Smiod struct trad_core_struct {
62*3d8817e4Smiod   struct corehdr *hdr;		/* core file header */
63*3d8817e4Smiod   asection *reg_section;
64*3d8817e4Smiod   asection *reg2_section;
65*3d8817e4Smiod   asection *sections[MAX_CORE_SEGS];
66*3d8817e4Smiod };
67*3d8817e4Smiod 
68*3d8817e4Smiod static void swap_abort PARAMS ((void));
69*3d8817e4Smiod 
70*3d8817e4Smiod static const bfd_target *
aix386_core_file_p(abfd)71*3d8817e4Smiod aix386_core_file_p (abfd)
72*3d8817e4Smiod      bfd *abfd;
73*3d8817e4Smiod {
74*3d8817e4Smiod   int i, n;
75*3d8817e4Smiod   unsigned char longbuf[4];	/* Raw bytes of various header fields */
76*3d8817e4Smiod   bfd_size_type core_size = sizeof (struct corehdr);
77*3d8817e4Smiod   bfd_size_type amt;
78*3d8817e4Smiod   struct corehdr *core;
79*3d8817e4Smiod   struct mergem {
80*3d8817e4Smiod     struct trad_core_struct coredata;
81*3d8817e4Smiod     struct corehdr internal_core;
82*3d8817e4Smiod   } *mergem;
83*3d8817e4Smiod 
84*3d8817e4Smiod   amt = sizeof (longbuf);
85*3d8817e4Smiod   if (bfd_bread ((PTR) longbuf, amt, abfd) != amt)
86*3d8817e4Smiod     {
87*3d8817e4Smiod       if (bfd_get_error () != bfd_error_system_call)
88*3d8817e4Smiod 	bfd_set_error (bfd_error_wrong_format);
89*3d8817e4Smiod       return 0;
90*3d8817e4Smiod     }
91*3d8817e4Smiod 
92*3d8817e4Smiod   if (strncmp (longbuf, COR_MAGIC, 4))
93*3d8817e4Smiod     return 0;
94*3d8817e4Smiod 
95*3d8817e4Smiod   if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
96*3d8817e4Smiod     return 0;
97*3d8817e4Smiod 
98*3d8817e4Smiod   amt = sizeof (struct mergem);
99*3d8817e4Smiod   mergem = (struct mergem *) bfd_zalloc (abfd, amt);
100*3d8817e4Smiod   if (mergem == NULL)
101*3d8817e4Smiod     return 0;
102*3d8817e4Smiod 
103*3d8817e4Smiod   core = &mergem->internal_core;
104*3d8817e4Smiod 
105*3d8817e4Smiod   if ((bfd_bread ((PTR) core, core_size, abfd)) != core_size)
106*3d8817e4Smiod     {
107*3d8817e4Smiod       if (bfd_get_error () != bfd_error_system_call)
108*3d8817e4Smiod 	bfd_set_error (bfd_error_wrong_format);
109*3d8817e4Smiod     loser:
110*3d8817e4Smiod       bfd_release (abfd, (char *) mergem);
111*3d8817e4Smiod       abfd->tdata.any = NULL;
112*3d8817e4Smiod       bfd_section_list_clear (abfd);
113*3d8817e4Smiod       return 0;
114*3d8817e4Smiod     }
115*3d8817e4Smiod 
116*3d8817e4Smiod   set_tdata (abfd, &mergem->coredata);
117*3d8817e4Smiod   core_hdr (abfd) = core;
118*3d8817e4Smiod 
119*3d8817e4Smiod   /* Create the sections.  */
120*3d8817e4Smiod   core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
121*3d8817e4Smiod   if (core_regsec (abfd) == NULL)
122*3d8817e4Smiod     goto loser;
123*3d8817e4Smiod 
124*3d8817e4Smiod   core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
125*3d8817e4Smiod   core_regsec (abfd)->size = sizeof (core->cd_regs);
126*3d8817e4Smiod   core_regsec (abfd)->vma = (bfd_vma) -1;
127*3d8817e4Smiod 
128*3d8817e4Smiod   /* We'll access the regs afresh in the core file, like any section.  */
129*3d8817e4Smiod   core_regsec (abfd)->filepos =
130*3d8817e4Smiod     (file_ptr) offsetof (struct corehdr, cd_regs[0]);
131*3d8817e4Smiod 
132*3d8817e4Smiod   core_reg2sec (abfd) = bfd_make_section_anyway (abfd, ".reg2");
133*3d8817e4Smiod   if (core_reg2sec (abfd) == NULL)
134*3d8817e4Smiod     /* bfd_release frees everything allocated after it's arg.  */
135*3d8817e4Smiod     goto loser;
136*3d8817e4Smiod 
137*3d8817e4Smiod   core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
138*3d8817e4Smiod   core_reg2sec (abfd)->size = sizeof (core->cd_fpregs);
139*3d8817e4Smiod   core_reg2sec (abfd)->vma = (bfd_vma) -1;
140*3d8817e4Smiod   core_reg2sec (abfd)->filepos =
141*3d8817e4Smiod     (file_ptr) offsetof (struct corehdr, cd_fpregs);
142*3d8817e4Smiod 
143*3d8817e4Smiod   for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++)
144*3d8817e4Smiod     {
145*3d8817e4Smiod       const char *sname;
146*3d8817e4Smiod       flagword flags;
147*3d8817e4Smiod 
148*3d8817e4Smiod       if (core->cd_segs[i].cs_offset == 0)
149*3d8817e4Smiod 	continue;
150*3d8817e4Smiod 
151*3d8817e4Smiod       switch (core->cd_segs[i].cs_type)
152*3d8817e4Smiod 	{
153*3d8817e4Smiod 	case COR_TYPE_DATA:
154*3d8817e4Smiod 	  sname = ".data";
155*3d8817e4Smiod 	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
156*3d8817e4Smiod 	  break;
157*3d8817e4Smiod 	case COR_TYPE_STACK:
158*3d8817e4Smiod 	  sname = ".stack";
159*3d8817e4Smiod 	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
160*3d8817e4Smiod 	  break;
161*3d8817e4Smiod 	case COR_TYPE_LIBDATA:
162*3d8817e4Smiod 	  sname = ".libdata";
163*3d8817e4Smiod 	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
164*3d8817e4Smiod 	  break;
165*3d8817e4Smiod 	case COR_TYPE_WRITE:
166*3d8817e4Smiod 	  sname = ".writeable";
167*3d8817e4Smiod 	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
168*3d8817e4Smiod 	  break;
169*3d8817e4Smiod 	case COR_TYPE_MSC:
170*3d8817e4Smiod 	  sname = ".misc";
171*3d8817e4Smiod 	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
172*3d8817e4Smiod 	  break;
173*3d8817e4Smiod 	default:
174*3d8817e4Smiod 	  sname = ".unknown";
175*3d8817e4Smiod 	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
176*3d8817e4Smiod 	  break;
177*3d8817e4Smiod 	}
178*3d8817e4Smiod       core_section (abfd, n) = bfd_make_section_anyway (abfd, sname);
179*3d8817e4Smiod       if (core_section (abfd, n) == NULL)
180*3d8817e4Smiod 	goto loser;
181*3d8817e4Smiod 
182*3d8817e4Smiod       core_section (abfd, n)->flags = flags;
183*3d8817e4Smiod       core_section (abfd, n)->size = core->cd_segs[i].cs_len;
184*3d8817e4Smiod       core_section (abfd, n)->vma       = core->cd_segs[i].cs_address;
185*3d8817e4Smiod       core_section (abfd, n)->filepos   = core->cd_segs[i].cs_offset;
186*3d8817e4Smiod       core_section (abfd, n)->alignment_power = 2;
187*3d8817e4Smiod       n++;
188*3d8817e4Smiod     }
189*3d8817e4Smiod 
190*3d8817e4Smiod   return abfd->xvec;
191*3d8817e4Smiod }
192*3d8817e4Smiod 
193*3d8817e4Smiod static char *
aix386_core_file_failing_command(abfd)194*3d8817e4Smiod aix386_core_file_failing_command (abfd)
195*3d8817e4Smiod      bfd *abfd;
196*3d8817e4Smiod {
197*3d8817e4Smiod   return core_hdr (abfd)->cd_comm;
198*3d8817e4Smiod }
199*3d8817e4Smiod 
200*3d8817e4Smiod static int
aix386_core_file_failing_signal(abfd)201*3d8817e4Smiod aix386_core_file_failing_signal (abfd)
202*3d8817e4Smiod      bfd *abfd;
203*3d8817e4Smiod {
204*3d8817e4Smiod   return core_hdr (abfd)->cd_cursig;
205*3d8817e4Smiod }
206*3d8817e4Smiod 
207*3d8817e4Smiod #define aix386_core_file_matches_executable_p generic_core_file_matches_executable_p
208*3d8817e4Smiod 
209*3d8817e4Smiod /* If somebody calls any byte-swapping routines, shoot them.  */
210*3d8817e4Smiod 
211*3d8817e4Smiod static void
swap_abort()212*3d8817e4Smiod swap_abort ()
213*3d8817e4Smiod {
214*3d8817e4Smiod   /* This way doesn't require any declaration for ANSI to fuck up.  */
215*3d8817e4Smiod   abort ();
216*3d8817e4Smiod }
217*3d8817e4Smiod 
218*3d8817e4Smiod #define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
219*3d8817e4Smiod #define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
220*3d8817e4Smiod #define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
221*3d8817e4Smiod #define	NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
222*3d8817e4Smiod #define	NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
223*3d8817e4Smiod #define	NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
224*3d8817e4Smiod 
225*3d8817e4Smiod const bfd_target aix386_core_vec = {
226*3d8817e4Smiod   "aix386-core",
227*3d8817e4Smiod   bfd_target_unknown_flavour,
228*3d8817e4Smiod   BFD_ENDIAN_BIG,		/* target byte order */
229*3d8817e4Smiod   BFD_ENDIAN_BIG,		/* target headers byte order */
230*3d8817e4Smiod   (HAS_RELOC | EXEC_P |		/* object flags */
231*3d8817e4Smiod    HAS_LINENO | HAS_DEBUG |
232*3d8817e4Smiod    HAS_SYMS | HAS_LOCALS | WP_TEXT),
233*3d8817e4Smiod 
234*3d8817e4Smiod   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
235*3d8817e4Smiod   0,				/* leading underscore */
236*3d8817e4Smiod   ' ',				/* ar_pad_char */
237*3d8817e4Smiod   16,				/* ar_max_namelen */
238*3d8817e4Smiod   NO_GET64, NO_GETS64, NO_PUT64,
239*3d8817e4Smiod   NO_GET, NO_GETS, NO_PUT,
240*3d8817e4Smiod   NO_GET, NO_GETS, NO_PUT,	/* data */
241*3d8817e4Smiod   NO_GET64, NO_GETS64, NO_PUT64,
242*3d8817e4Smiod   NO_GET, NO_GETS, NO_PUT,
243*3d8817e4Smiod   NO_GET, NO_GETS, NO_PUT,	/* hdrs */
244*3d8817e4Smiod 
245*3d8817e4Smiod   {_bfd_dummy_target, _bfd_dummy_target,
246*3d8817e4Smiod    _bfd_dummy_target, aix386_core_file_p},
247*3d8817e4Smiod   {bfd_false, bfd_false,	/* bfd_create_object */
248*3d8817e4Smiod    bfd_false, bfd_false},
249*3d8817e4Smiod   {bfd_false, bfd_false,	/* bfd_write_contents */
250*3d8817e4Smiod    bfd_false, bfd_false},
251*3d8817e4Smiod 
252*3d8817e4Smiod   BFD_JUMP_TABLE_GENERIC (_bfd_generic),
253*3d8817e4Smiod   BFD_JUMP_TABLE_COPY (_bfd_generic),
254*3d8817e4Smiod   BFD_JUMP_TABLE_CORE (aix386),
255*3d8817e4Smiod   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
256*3d8817e4Smiod   BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
257*3d8817e4Smiod   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
258*3d8817e4Smiod   BFD_JUMP_TABLE_WRITE (_bfd_generic),
259*3d8817e4Smiod   BFD_JUMP_TABLE_LINK (_bfd_nolink),
260*3d8817e4Smiod   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
261*3d8817e4Smiod 
262*3d8817e4Smiod   NULL,
263*3d8817e4Smiod 
264*3d8817e4Smiod   (PTR) 0
265*3d8817e4Smiod };
266