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 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 25 26 #include "bfd.h" 27 #include "sysdep.h" 28 #include "libbfd.h" 29 #include "coff/i386.h" 30 #include "coff/internal.h" 31 #include "libcoff.h" 32 33 #include <signal.h> 34 35 #if defined (_AIX) && defined (_I386) 36 #define NOCHECKS /* This is for coredump.h. */ 37 #define _h_USER /* Avoid including user.h from coredump.h. */ 38 #include <uinfo.h> 39 #include <sys/i386/coredump.h> 40 #endif /* _AIX && _I386 */ 41 42 /* Maybe this could work on some other i386 but I have not tried it 43 * mtranle@paris - Tue Sep 24 12:49:35 1991 44 */ 45 46 #ifndef COR_MAGIC 47 # define COR_MAGIC "core" 48 #endif 49 50 /* Need this cast because ptr is really void *. */ 51 #define core_hdr(bfd) \ 52 (((bfd->tdata.trad_core_data))->hdr) 53 #define core_section(bfd,n) \ 54 (((bfd)->tdata.trad_core_data)->sections[n]) 55 #define core_regsec(bfd) \ 56 (((bfd)->tdata.trad_core_data)->reg_section) 57 #define core_reg2sec(bfd) \ 58 (((bfd)->tdata.trad_core_data)->reg2_section) 59 60 /* These are stored in the bfd's tdata. */ 61 struct trad_core_struct { 62 struct corehdr *hdr; /* core file header */ 63 asection *reg_section; 64 asection *reg2_section; 65 asection *sections[MAX_CORE_SEGS]; 66 }; 67 68 static void swap_abort PARAMS ((void)); 69 70 static const bfd_target * 71 aix386_core_file_p (abfd) 72 bfd *abfd; 73 { 74 int i, n; 75 unsigned char longbuf[4]; /* Raw bytes of various header fields */ 76 bfd_size_type core_size = sizeof (struct corehdr); 77 bfd_size_type amt; 78 struct corehdr *core; 79 struct mergem { 80 struct trad_core_struct coredata; 81 struct corehdr internal_core; 82 } *mergem; 83 84 amt = sizeof (longbuf); 85 if (bfd_bread ((PTR) longbuf, amt, abfd) != amt) 86 { 87 if (bfd_get_error () != bfd_error_system_call) 88 bfd_set_error (bfd_error_wrong_format); 89 return 0; 90 } 91 92 if (strncmp (longbuf, COR_MAGIC, 4)) 93 return 0; 94 95 if (bfd_seek (abfd, (file_ptr) 0, 0) != 0) 96 return 0; 97 98 amt = sizeof (struct mergem); 99 mergem = (struct mergem *) bfd_zalloc (abfd, amt); 100 if (mergem == NULL) 101 return 0; 102 103 core = &mergem->internal_core; 104 105 if ((bfd_bread ((PTR) core, core_size, abfd)) != core_size) 106 { 107 if (bfd_get_error () != bfd_error_system_call) 108 bfd_set_error (bfd_error_wrong_format); 109 loser: 110 bfd_release (abfd, (char *) mergem); 111 abfd->tdata.any = NULL; 112 bfd_section_list_clear (abfd); 113 return 0; 114 } 115 116 set_tdata (abfd, &mergem->coredata); 117 core_hdr (abfd) = core; 118 119 /* Create the sections. */ 120 core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg"); 121 if (core_regsec (abfd) == NULL) 122 goto loser; 123 124 core_regsec (abfd)->flags = SEC_HAS_CONTENTS; 125 core_regsec (abfd)->_raw_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 core_reg2sec (abfd) = bfd_make_section_anyway (abfd, ".reg2"); 133 if (core_reg2sec (abfd) == NULL) 134 /* bfd_release frees everything allocated after it's arg. */ 135 goto loser; 136 137 core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; 138 core_reg2sec (abfd)->_raw_size = sizeof (core->cd_fpregs); 139 core_reg2sec (abfd)->vma = (bfd_vma) -1; 140 core_reg2sec (abfd)->filepos = 141 (file_ptr) offsetof (struct corehdr, cd_fpregs); 142 143 for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++) 144 { 145 const char *sname; 146 flagword flags; 147 148 if (core->cd_segs[i].cs_offset == 0) 149 continue; 150 151 switch (core->cd_segs[i].cs_type) 152 { 153 case COR_TYPE_DATA: 154 sname = ".data"; 155 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 156 break; 157 case COR_TYPE_STACK: 158 sname = ".stack"; 159 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 160 break; 161 case COR_TYPE_LIBDATA: 162 sname = ".libdata"; 163 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 164 break; 165 case COR_TYPE_WRITE: 166 sname = ".writeable"; 167 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 168 break; 169 case COR_TYPE_MSC: 170 sname = ".misc"; 171 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 172 break; 173 default: 174 sname = ".unknown"; 175 flags = SEC_ALLOC + SEC_HAS_CONTENTS; 176 break; 177 } 178 core_section (abfd, n) = bfd_make_section_anyway (abfd, sname); 179 if (core_section (abfd, n) == NULL) 180 goto loser; 181 182 core_section (abfd, n)->flags = flags; 183 core_section (abfd, n)->_raw_size = core->cd_segs[i].cs_len; 184 core_section (abfd, n)->vma = core->cd_segs[i].cs_address; 185 core_section (abfd, n)->filepos = core->cd_segs[i].cs_offset; 186 core_section (abfd, n)->alignment_power = 2; 187 n++; 188 } 189 190 return abfd->xvec; 191 } 192 193 static char * 194 aix386_core_file_failing_command (abfd) 195 bfd *abfd; 196 { 197 return core_hdr (abfd)->cd_comm; 198 } 199 200 static int 201 aix386_core_file_failing_signal (abfd) 202 bfd *abfd; 203 { 204 return core_hdr (abfd)->cd_cursig; 205 } 206 207 static bfd_boolean 208 aix386_core_file_matches_executable_p (core_bfd, exec_bfd) 209 bfd *core_bfd; 210 bfd *exec_bfd; 211 { 212 /* FIXME: We have no way of telling at this point. */ 213 return TRUE; 214 } 215 216 /* If somebody calls any byte-swapping routines, shoot them. */ 217 218 static void 219 swap_abort () 220 { 221 /* This way doesn't require any declaration for ANSI to fuck up. */ 222 abort (); 223 } 224 225 #define NO_GET ((bfd_vma (*) (const void *)) swap_abort) 226 #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort) 227 #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort) 228 #define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort) 229 #define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort) 230 #define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort) 231 232 const bfd_target aix386_core_vec = { 233 "aix386-core", 234 bfd_target_unknown_flavour, 235 BFD_ENDIAN_BIG, /* target byte order */ 236 BFD_ENDIAN_BIG, /* target headers byte order */ 237 (HAS_RELOC | EXEC_P | /* object flags */ 238 HAS_LINENO | HAS_DEBUG | 239 HAS_SYMS | HAS_LOCALS | WP_TEXT), 240 241 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ 242 0, /* leading underscore */ 243 ' ', /* ar_pad_char */ 244 16, /* ar_max_namelen */ 245 NO_GET64, NO_GETS64, NO_PUT64, 246 NO_GET, NO_GETS, NO_PUT, 247 NO_GET, NO_GETS, NO_PUT, /* data */ 248 NO_GET64, NO_GETS64, NO_PUT64, 249 NO_GET, NO_GETS, NO_PUT, 250 NO_GET, NO_GETS, NO_PUT, /* hdrs */ 251 252 {_bfd_dummy_target, _bfd_dummy_target, 253 _bfd_dummy_target, aix386_core_file_p}, 254 {bfd_false, bfd_false, /* bfd_create_object */ 255 bfd_false, bfd_false}, 256 {bfd_false, bfd_false, /* bfd_write_contents */ 257 bfd_false, bfd_false}, 258 259 BFD_JUMP_TABLE_GENERIC (_bfd_generic), 260 BFD_JUMP_TABLE_COPY (_bfd_generic), 261 BFD_JUMP_TABLE_CORE (aix386), 262 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), 263 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), 264 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), 265 BFD_JUMP_TABLE_WRITE (_bfd_generic), 266 BFD_JUMP_TABLE_LINK (_bfd_nolink), 267 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 268 269 NULL, 270 271 (PTR) 0 272 }; 273