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