aix386-core.c revision 1.3
159191Skris/* BFD back-end for AIX on PS/2 core files. 259191Skris This was based on trad-core.c, which was written by John Gilmore of 359191Skris Cygnus Support. 459191Skris Copyright (C) 1988-2015 Free Software Foundation, Inc. 559191Skris Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>. 659191Skris Converted to back end form by Ian Lance Taylor <ian@cygnus.com>. 759191Skris 859191Skris This file is part of BFD, the Binary File Descriptor library. 959191Skris 1059191Skris This program is free software; you can redistribute it and/or modify 1159191Skris it under the terms of the GNU General Public License as published by 1259191Skris the Free Software Foundation; either version 3 of the License, or 1359191Skris (at your option) any later version. 1459191Skris 1559191Skris This program is distributed in the hope that it will be useful, 1659191Skris but WITHOUT ANY WARRANTY; without even the implied warranty of 17111147Snectar MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1859191Skris GNU General Public License for more details. 1959191Skris 2059191Skris You should have received a copy of the GNU General Public License 2159191Skris along with this program; if not, write to the Free Software 2259191Skris Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 2359191Skris MA 02110-1301, USA. */ 2459191Skris 2559191Skris#include "sysdep.h" 2659191Skris#include "bfd.h" 2759191Skris#include "libbfd.h" 2859191Skris#include "coff/i386.h" 2959191Skris#include "coff/internal.h" 3059191Skris#include "libcoff.h" 3159191Skris 3259191Skris#include <signal.h> 3359191Skris 3459191Skris#if defined (_AIX) && defined (_I386) 3559191Skris#define NOCHECKS /* This is for coredump.h. */ 3659191Skris#define _h_USER /* Avoid including user.h from coredump.h. */ 3759191Skris#include <uinfo.h> 3859191Skris#include <sys/i386/coredump.h> 3959191Skris#endif /* _AIX && _I386 */ 4059191Skris 4159191Skris/* Maybe this could work on some other i386 but I have not tried it 4259191Skris * mtranle@paris - Tue Sep 24 12:49:35 1991 4359191Skris */ 4459191Skris 4559191Skris#ifndef COR_MAGIC 4659191Skris# define COR_MAGIC "core" 4759191Skris#endif 4859191Skris 4959191Skris/* Need this cast because ptr is really void *. */ 5059191Skris#define core_hdr(bfd) \ 5159191Skris (((bfd->tdata.trad_core_data))->hdr) 5259191Skris#define core_section(bfd,n) \ 5359191Skris (((bfd)->tdata.trad_core_data)->sections[n]) 5459191Skris#define core_regsec(bfd) \ 5559191Skris (((bfd)->tdata.trad_core_data)->reg_section) 5659191Skris#define core_reg2sec(bfd) \ 5759191Skris (((bfd)->tdata.trad_core_data)->reg2_section) 5859191Skris 5959191Skris/* These are stored in the bfd's tdata. */ 6059191Skrisstruct trad_core_struct 6159191Skris{ 6259191Skris struct corehdr *hdr; /* core file header */ 63111147Snectar asection *reg_section; 64111147Snectar asection *reg2_section; 65238405Sjkim asection *sections[MAX_CORE_SEGS]; 66111147Snectar}; 67111147Snectar 68111147Snectarstatic const bfd_target * 69111147Snectaraix386_core_file_p (bfd *abfd) 7059191Skris{ 7159191Skris int i, n; 7259191Skris unsigned char longbuf[4]; /* Raw bytes of various header fields */ 7359191Skris bfd_size_type core_size = sizeof (struct corehdr); 7459191Skris bfd_size_type amt; 7559191Skris struct corehdr *core; 7659191Skris struct mergem 7759191Skris { 7859191Skris struct trad_core_struct coredata; 7959191Skris struct corehdr internal_core; 8059191Skris } *mergem; 8159191Skris flagword flags; 8259191Skris 8359191Skris amt = sizeof (longbuf); 8459191Skris if (bfd_bread (longbuf, amt, abfd) != amt) 8559191Skris { 8659191Skris if (bfd_get_error () != bfd_error_system_call) 8759191Skris bfd_set_error (bfd_error_wrong_format); 8859191Skris return 0; 89109998Smarkm } 9059191Skris 9159191Skris if (strncmp (longbuf, COR_MAGIC, 4)) 9259191Skris return 0; 9359191Skris 9459191Skris if (bfd_seek (abfd, (file_ptr) 0, 0) != 0) 9559191Skris return 0; 9659191Skris 9759191Skris amt = sizeof (struct mergem); 9859191Skris mergem = (struct mergem *) bfd_zalloc (abfd, amt); 9959191Skris if (mergem == NULL) 10059191Skris return 0; 10159191Skris 10259191Skris core = &mergem->internal_core; 10359191Skris 10459191Skris if ((bfd_bread (core, core_size, abfd)) != core_size) 10559191Skris { 106 if (bfd_get_error () != bfd_error_system_call) 107 bfd_set_error (bfd_error_wrong_format); 108 loser: 109 bfd_release (abfd, (char *) mergem); 110 abfd->tdata.any = NULL; 111 bfd_section_list_clear (abfd); 112 return 0; 113 } 114 115 set_tdata (abfd, &mergem->coredata); 116 core_hdr (abfd) = core; 117 118 /* Create the sections. */ 119 flags = SEC_HAS_CONTENTS; 120 core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg", 121 flags); 122 if (core_regsec (abfd) == NULL) 123 goto loser; 124 125 core_regsec (abfd)->size = sizeof (core->cd_regs); 126 core_regsec (abfd)->vma = (bfd_vma) -1; 127 128 /* We'll access the regs afresh in the core file, like any section. */ 129 core_regsec (abfd)->filepos = 130 (file_ptr) offsetof (struct corehdr, cd_regs[0]); 131 132 flags = SEC_HAS_CONTENTS; 133 core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2", 134 flags); 135 if (core_reg2sec (abfd) == NULL) 136 /* bfd_release frees everything allocated after it's arg. */ 137 goto loser; 138 139 core_reg2sec (abfd)->size = sizeof (core->cd_fpregs); 140 core_reg2sec (abfd)->vma = (bfd_vma) -1; 141 core_reg2sec (abfd)->filepos = 142 (file_ptr) offsetof (struct corehdr, cd_fpregs); 143 144 for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++) 145 { 146 const char *sname; 147 flagword flags; 148 149 if (core->cd_segs[i].cs_offset == 0) 150 continue; 151 152 switch (core->cd_segs[i].cs_type) 153 { 154 case COR_TYPE_DATA: 155 sname = ".data"; 156 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 157 break; 158 case COR_TYPE_STACK: 159 sname = ".stack"; 160 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 161 break; 162 case COR_TYPE_LIBDATA: 163 sname = ".libdata"; 164 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 165 break; 166 case COR_TYPE_WRITE: 167 sname = ".writeable"; 168 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 169 break; 170 case COR_TYPE_MSC: 171 sname = ".misc"; 172 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 173 break; 174 default: 175 sname = ".unknown"; 176 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 177 break; 178 } 179 core_section (abfd, n) = bfd_make_section_anyway_with_flags (abfd, 180 sname, 181 flags); 182 if (core_section (abfd, n) == NULL) 183 goto loser; 184 185 core_section (abfd, n)->size = core->cd_segs[i].cs_len; 186 core_section (abfd, n)->vma = core->cd_segs[i].cs_address; 187 core_section (abfd, n)->filepos = core->cd_segs[i].cs_offset; 188 core_section (abfd, n)->alignment_power = 2; 189 n++; 190 } 191 192 return abfd->xvec; 193} 194 195static char * 196aix386_core_file_failing_command (bfd *abfd) 197{ 198 return core_hdr (abfd)->cd_comm; 199} 200 201static int 202aix386_core_file_failing_signal (bfd *abfd) 203{ 204 return core_hdr (abfd)->cd_cursig; 205} 206 207#define aix386_core_file_matches_executable_p generic_core_file_matches_executable_p 208 209#define aix386_core_file_pid _bfd_nocore_core_file_pid 210 211/* If somebody calls any byte-swapping routines, shoot them. */ 212 213static void 214swap_abort (void) 215{ 216 /* This way doesn't require any declaration for ANSI to fuck up. */ 217 abort (); 218} 219 220#define NO_GET ((bfd_vma (*) (const void *)) swap_abort) 221#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) 222#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) 223#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) 224#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) 225#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) 226 227const bfd_target core_aix386_vec = 228{ 229 "aix386-core", 230 bfd_target_unknown_flavour, 231 BFD_ENDIAN_BIG, /* target byte order */ 232 BFD_ENDIAN_BIG, /* target headers byte order */ 233 (HAS_RELOC | EXEC_P | /* object flags */ 234 HAS_LINENO | HAS_DEBUG | 235 HAS_SYMS | HAS_LOCALS | WP_TEXT), 236 237 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 238 0, /* leading underscore */ 239 ' ', /* ar_pad_char */ 240 16, /* ar_max_namelen */ 241 0, /* match priority. */ 242 NO_GET64, NO_GETS64, NO_PUT64, 243 NO_GET, NO_GETS, NO_PUT, 244 NO_GET, NO_GETS, NO_PUT, /* data */ 245 NO_GET64, NO_GETS64, NO_PUT64, 246 NO_GET, NO_GETS, NO_PUT, 247 NO_GET, NO_GETS, NO_PUT, /* hdrs */ 248 249 {_bfd_dummy_target, _bfd_dummy_target, 250 _bfd_dummy_target, aix386_core_file_p}, 251 {bfd_false, bfd_false, /* bfd_create_object */ 252 bfd_false, bfd_false}, 253 {bfd_false, bfd_false, /* bfd_write_contents */ 254 bfd_false, bfd_false}, 255 256 BFD_JUMP_TABLE_GENERIC (_bfd_generic), 257 BFD_JUMP_TABLE_COPY (_bfd_generic), 258 BFD_JUMP_TABLE_CORE (aix386), 259 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), 260 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), 261 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), 262 BFD_JUMP_TABLE_WRITE (_bfd_generic), 263 BFD_JUMP_TABLE_LINK (_bfd_nolink), 264 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 265 266 NULL, 267 268 NULL 269}; 270