1 /* IBM RS/6000 "XCOFF" back-end for BFD. 2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 2000 3 Free Software Foundation, Inc. 4 FIXME: Can someone provide a transliteration of this name into ASCII? 5 Using the following chars caused a compiler warning on HIUX (so I replaced 6 them with octal escapes), and isn't useful without an understanding of what 7 character set it is. 8 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, 9 and John Gilmore. 10 Archive support from Damon A. Permezel. 11 Contributed by IBM Corporation and Cygnus Support. 12 13 This file is part of BFD, the Binary File Descriptor library. 14 15 This program is free software; you can redistribute it and/or modify 16 it under the terms of the GNU General Public License as published by 17 the Free Software Foundation; either version 2 of the License, or 18 (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 GNU General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program; if not, write to the Free Software 27 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 28 29 /* This port currently only handles reading object files, except when 30 compiled on an RS/6000 host. -- no archive support, no core files. 31 In all cases, it does not support writing. 32 33 FIXMEmgo comments are left from Metin Ozisik's original port. 34 35 This is in a separate file from coff-rs6000.c, because it includes 36 system include files that conflict with coff/rs6000.h. 37 */ 38 39 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */ 40 #define RS6000COFF_C 1 41 42 /* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so 43 we have to define _LONG_LONG for older versions of gcc to get the 44 proper alignments in the user structure. */ 45 #if defined(_AIX41) && !defined(_LONG_LONG) 46 #define _LONG_LONG 47 #endif 48 49 #include "bfd.h" 50 #include "sysdep.h" 51 #include "libbfd.h" 52 53 #ifdef AIX_CORE 54 55 /* AOUTHDR is defined by the above. We need another defn of it, from the 56 system include files. Punt the old one and get us a new name for the 57 typedef in the system include files. */ 58 #ifdef AOUTHDR 59 #undef AOUTHDR 60 #endif 61 #define AOUTHDR second_AOUTHDR 62 63 #undef SCNHDR 64 65 66 /* ------------------------------------------------------------------------ */ 67 /* Support for core file stuff.. */ 68 /* ------------------------------------------------------------------------ */ 69 70 #include <sys/user.h> 71 #include <sys/ldr.h> 72 #include <sys/core.h> 73 74 75 /* Number of special purpose registers supported by gdb. This value 76 should match `tm.h' in gdb directory. Clean this mess up and use 77 the macros in sys/reg.h. FIXMEmgo. */ 78 79 #define NUM_OF_SPEC_REGS 7 80 81 #define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr) 82 83 /* AIX 4.1 Changed the names and locations of a few items in the core file, 84 this seems to be the quickest/easiest way to deal with it. 85 86 Note however that encoding magic addresses (STACK_END_ADDR) is going 87 to be _very_ fragile. But I don't see any easy way to get that info 88 right now. 89 90 AIX 4.3 defines an entirely new structure (core_dumpx). Yet the 91 basic logic stays the same and we can still use our macro 92 redefinition mechanism to effect the necessary changes. */ 93 94 #ifdef AIX_CORE_DUMPX_CORE 95 #define CORE_DATA_SIZE_FIELD c_dataorg 96 #define CORE_COMM_FIELD c_u.U_proc.pi_comm 97 #define SAVE_FIELD c_flt.hctx.r32 98 #define STACK_END_ADDR coredata.c_stackorg + coredata.c_size 99 #define LOADER_OFFSET_FIELD c_loader 100 #define LOADER_REGION_SIZE coredata.c_lsize 101 #define CORE_DUMP core_dumpx 102 #else 103 #ifdef CORE_VERSION_1 104 #define CORE_DATA_SIZE_FIELD c_u.U_dsize 105 #define CORE_COMM_FIELD c_u.U_comm 106 #define SAVE_FIELD c_mst 107 #define STACK_END_ADDR 0x2ff23000 108 #define LOADER_OFFSET_FIELD c_tab 109 #define LOADER_REGION_SIZE 0x7ffffff 110 #define CORE_DUMP core_dump 111 #else 112 #define CORE_DATA_SIZE_FIELD c_u.u_dsize 113 #define CORE_COMM_FIELD c_u.u_comm 114 #define SAVE_FIELD c_u.u_save 115 #define STACK_END_ADDR 0x2ff80000 116 #define LOADER_OFFSET_FIELD c_tab 117 #define LOADER_REGION_SIZE 0x7ffffff 118 #define CORE_DUMP core_dump 119 #endif 120 #endif 121 122 /* These are stored in the bfd's tdata */ 123 typedef struct { 124 struct CORE_DUMP hdr; /* core file header */ 125 } Rs6kCorData; 126 127 static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword, 128 bfd_size_type, bfd_vma, file_ptr)); 129 130 static asection * 131 make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) 132 bfd *abfd; 133 CONST char *name; 134 flagword flags; 135 bfd_size_type _raw_size; 136 bfd_vma vma; 137 file_ptr filepos; 138 { 139 asection *asect; 140 141 asect = bfd_make_section_anyway (abfd, name); 142 if (!asect) 143 return NULL; 144 145 asect->flags = flags; 146 asect->_raw_size = _raw_size; 147 asect->vma = vma; 148 asect->filepos = filepos; 149 asect->alignment_power = 8; 150 151 return asect; 152 } 153 154 /* Decide if a given bfd represents a `core' file or not. There really is no 155 magic number or anything like, in rs6000coff. */ 156 157 const bfd_target * 158 rs6000coff_core_p (abfd) 159 bfd *abfd; 160 { 161 struct CORE_DUMP coredata; 162 struct stat statbuf; 163 bfd_size_type nread; 164 char *tmpptr; 165 166 if (bfd_seek (abfd, 0, SEEK_SET) != 0) 167 return NULL; 168 169 nread = bfd_read (&coredata, 1, sizeof (struct CORE_DUMP), abfd); 170 if (nread != sizeof (struct CORE_DUMP)) 171 { 172 if (bfd_get_error () != bfd_error_system_call) 173 bfd_set_error (bfd_error_wrong_format); 174 return NULL; 175 } 176 177 if (bfd_stat (abfd, &statbuf) < 0) 178 { 179 bfd_set_error (bfd_error_system_call); 180 return NULL; 181 } 182 183 /* If the core file ulimit is too small, the system will first 184 omit the data segment, then omit the stack, then decline to 185 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID 186 are always set) (this is based on experimentation on AIX 3.2). 187 Now, the thing is that GDB users will be surprised 188 if segments just silently don't appear (well, maybe they would 189 think to check "info files", I don't know). 190 191 For the data segment, we have no choice but to keep going if it's 192 not there, since the default behavior is not to dump it (regardless 193 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment, 194 if it's not there, we refuse to have anything to do with this core 195 file. The usefulness of a core dump without a stack segment is pretty 196 limited anyway. */ 197 198 if (!(coredata.c_flag & UBLOCK_VALID) 199 || !(coredata.c_flag & LE_VALID)) 200 { 201 bfd_set_error (bfd_error_wrong_format); 202 return NULL; 203 } 204 205 if (!(coredata.c_flag & USTACK_VALID)) 206 { 207 bfd_set_error (bfd_error_file_truncated); 208 return NULL; 209 } 210 211 /* Don't check the core file size for a full core, AIX 4.1 includes 212 additional shared library sections in a full core. */ 213 if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC)) 214 && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size) 215 { 216 /* If the size is wrong, it means we're misinterpreting something. */ 217 bfd_set_error (bfd_error_wrong_format); 218 return NULL; 219 } 220 221 #ifdef AIX_CORE_DUMPX_CORE 222 /* For the core_dumpx format, make sure c_entries == 0 If it does 223 not, the core file uses the old format */ 224 if (coredata.c_entries != 0) 225 { 226 bfd_set_error (bfd_error_wrong_format); 227 return NULL; 228 } 229 #else 230 /* Sanity check on the c_tab field. */ 231 if ((u_long) coredata.c_tab < sizeof coredata || 232 (u_long) coredata.c_tab >= statbuf.st_size || 233 (long) coredata.c_tab >= (long)coredata.c_stack) 234 { 235 bfd_set_error (bfd_error_wrong_format); 236 return NULL; 237 } 238 #endif 239 240 /* Issue warning if the core file was truncated during writing. */ 241 if (coredata.c_flag & CORE_TRUNC) 242 (*_bfd_error_handler) (_("%s: warning core file truncated"), 243 bfd_get_filename (abfd)); 244 245 /* Allocate core file header. */ 246 tmpptr = (char*) bfd_zalloc (abfd, sizeof (Rs6kCorData)); 247 if (!tmpptr) 248 return NULL; 249 250 set_tdata (abfd, tmpptr); 251 252 /* Copy core file header. */ 253 core_hdr (abfd) = coredata; 254 255 /* .stack section. */ 256 if (!make_bfd_asection (abfd, ".stack", 257 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, 258 (bfd_size_type) coredata.c_size, 259 (bfd_vma) (STACK_END_ADDR - coredata.c_size), 260 (file_ptr) coredata.c_stack)) 261 return NULL; 262 263 /* .reg section for GPRs and special registers. */ 264 if (!make_bfd_asection (abfd, ".reg", 265 SEC_HAS_CONTENTS, 266 (bfd_size_type) ((32 + NUM_OF_SPEC_REGS) * 4), 267 (bfd_vma) 0, 268 (file_ptr) ((char *) &coredata.SAVE_FIELD 269 - (char *) &coredata))) 270 return NULL; 271 272 /* .reg2 section for FPRs (floating point registers). */ 273 if (!make_bfd_asection (abfd, ".reg2", 274 SEC_HAS_CONTENTS, 275 (bfd_size_type) 8 * 32, /* 32 FPRs. */ 276 (bfd_vma) 0, 277 (file_ptr) ((char *) &coredata.SAVE_FIELD.fpr[0] 278 - (char *) &coredata))) 279 return NULL; 280 281 /* .ldinfo section. 282 To actually find out how long this section is in this particular 283 core dump would require going down the whole list of struct ld_info's. 284 See if we can just fake it. */ 285 if (!make_bfd_asection (abfd, ".ldinfo", 286 SEC_HAS_CONTENTS, 287 (bfd_size_type) LOADER_REGION_SIZE, 288 (bfd_vma) 0, 289 (file_ptr) coredata.LOADER_OFFSET_FIELD)) 290 return NULL; 291 292 #ifndef CORE_VERSION_1 293 /* .data section if present. 294 AIX 3 dumps the complete data section and sets FULL_CORE if the 295 ulimit is large enough, otherwise the data section is omitted. 296 AIX 4 sets FULL_CORE even if the core file is truncated, we have 297 to examine coredata.c_datasize below to find out the actual size of 298 the .data section. */ 299 if (coredata.c_flag & FULL_CORE) 300 { 301 if (!make_bfd_asection (abfd, ".data", 302 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, 303 (bfd_size_type) coredata.CORE_DATA_SIZE_FIELD, 304 (bfd_vma) 305 CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD), 306 (file_ptr) coredata.c_stack + coredata.c_size)) 307 return NULL; 308 } 309 #endif 310 311 #ifdef CORE_VERSION_1 312 /* AIX 4 adds data sections from loaded objects to the core file, 313 which can be found by examining ldinfo, and anonymously mmapped 314 regions. */ 315 { 316 struct ld_info ldinfo; 317 bfd_size_type ldinfo_size; 318 file_ptr ldinfo_offset = (file_ptr) coredata.LOADER_OFFSET_FIELD; 319 320 /* .data section from executable. */ 321 if (coredata.c_datasize) 322 { 323 if (!make_bfd_asection (abfd, ".data", 324 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, 325 (bfd_size_type) coredata.c_datasize, 326 (bfd_vma) 327 CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD), 328 (file_ptr) coredata.c_data)) 329 return NULL; 330 } 331 332 /* .data sections from loaded objects. */ 333 ldinfo_size = (char *) &ldinfo.ldinfo_filename[0] 334 - (char *) &ldinfo.ldinfo_next; 335 while (1) 336 { 337 if (bfd_seek (abfd, ldinfo_offset, SEEK_SET) != 0) 338 return NULL; 339 if (bfd_read (&ldinfo, ldinfo_size, 1, abfd) != ldinfo_size) 340 return NULL; 341 if (ldinfo.ldinfo_core) 342 { 343 if (!make_bfd_asection (abfd, ".data", 344 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, 345 (bfd_size_type) ldinfo.ldinfo_datasize, 346 (bfd_vma) ldinfo.ldinfo_dataorg, 347 (file_ptr) ldinfo.ldinfo_core)) 348 return NULL; 349 } 350 if (ldinfo.ldinfo_next == 0) 351 break; 352 ldinfo_offset += ldinfo.ldinfo_next; 353 } 354 355 /* .vmdata sections from anonymously mmapped regions. */ 356 if (coredata.c_vmregions) 357 { 358 int i; 359 360 if (bfd_seek (abfd, (file_ptr) coredata.c_vmm, SEEK_SET) != 0) 361 return NULL; 362 363 for (i = 0; i < coredata.c_vmregions; i++) 364 { 365 struct vm_info vminfo; 366 367 if (bfd_read (&vminfo, sizeof (vminfo), 1, abfd) != sizeof (vminfo)) 368 return NULL; 369 if (vminfo.vminfo_offset) 370 { 371 if (!make_bfd_asection (abfd, ".vmdata", 372 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS, 373 (bfd_size_type) vminfo.vminfo_size, 374 (bfd_vma) vminfo.vminfo_addr, 375 (file_ptr) vminfo.vminfo_offset)) 376 return NULL; 377 } 378 } 379 } 380 } 381 #endif 382 383 return abfd->xvec; /* this is garbage for now. */ 384 } 385 386 387 388 /* return `true' if given core is from the given executable.. */ 389 boolean 390 rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd) 391 bfd *core_bfd; 392 bfd *exec_bfd; 393 { 394 struct CORE_DUMP coredata; 395 struct ld_info ldinfo; 396 bfd_size_type size; 397 char *path, *s; 398 size_t alloc; 399 const char *str1, *str2; 400 boolean ret; 401 402 if (bfd_seek (core_bfd, 0, SEEK_SET) != 0 403 || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata) 404 return false; 405 406 if (bfd_seek (core_bfd, (long) coredata.LOADER_OFFSET_FIELD, SEEK_SET) != 0) 407 return false; 408 409 size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next; 410 if (bfd_read (&ldinfo, size, 1, core_bfd) != size) 411 return false; 412 413 alloc = 100; 414 path = bfd_malloc (alloc); 415 if (path == NULL) 416 return false; 417 s = path; 418 419 while (1) 420 { 421 if (bfd_read (s, 1, 1, core_bfd) != 1) 422 { 423 free (path); 424 return false; 425 } 426 if (*s == '\0') 427 break; 428 ++s; 429 if (s == path + alloc) 430 { 431 char *n; 432 433 alloc *= 2; 434 n = bfd_realloc (path, alloc); 435 if (n == NULL) 436 { 437 free (path); 438 return false; 439 } 440 s = n + (path - s); 441 path = n; 442 } 443 } 444 445 str1 = strrchr (path, '/'); 446 str2 = strrchr (exec_bfd->filename, '/'); 447 448 /* step over character '/' */ 449 str1 = str1 != NULL ? str1 + 1 : path; 450 str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename; 451 452 if (strcmp (str1, str2) == 0) 453 ret = true; 454 else 455 ret = false; 456 457 free (path); 458 459 return ret; 460 } 461 462 char * 463 rs6000coff_core_file_failing_command (abfd) 464 bfd *abfd; 465 { 466 char *com = core_hdr (abfd).CORE_COMM_FIELD; 467 if (*com) 468 return com; 469 else 470 return 0; 471 } 472 473 int 474 rs6000coff_core_file_failing_signal (abfd) 475 bfd *abfd; 476 { 477 return core_hdr (abfd).c_signo; 478 } 479 480 481 boolean 482 rs6000coff_get_section_contents (abfd, section, location, offset, count) 483 bfd *abfd; 484 sec_ptr section; 485 PTR location; 486 file_ptr offset; 487 bfd_size_type count; 488 { 489 if (count == 0) 490 return true; 491 492 /* Reading a core file's sections will be slightly different. For the 493 rest of them we can use bfd_generic_get_section_contents () I suppose. */ 494 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */ 495 496 if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) { 497 498 struct mstsave mstatus; 499 int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus; 500 501 /* Assert that the only way this code will be executed is reading the 502 whole section. */ 503 if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS))) 504 (*_bfd_error_handler) 505 (_("ERROR! in rs6000coff_get_section_contents()\n")); 506 507 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure 508 in the core file. */ 509 510 /* read GPR's into the location. */ 511 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1 512 || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr)) 513 return (false); /* on error */ 514 515 /* increment location to the beginning of special registers in the section, 516 reset register offset value to the beginning of first special register 517 in mstsave structure, and read special registers. */ 518 519 location = (PTR) ((char*)location + sizeof (mstatus.gpr)); 520 regoffset = (char*)&mstatus.iar - (char*)&mstatus; 521 522 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1 523 || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) != 524 4 * NUM_OF_SPEC_REGS) 525 return (false); /* on error */ 526 527 /* increment location address, and read the special registers.. */ 528 /* FIXMEmgo */ 529 return (true); 530 } 531 532 /* else, use default bfd section content transfer. */ 533 else 534 return _bfd_generic_get_section_contents 535 (abfd, section, location, offset, count); 536 } 537 538 #endif /* AIX_CORE */ 539