00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "bfd.h"
00031 #include "sysdep.h"
00032 #include "libbfd.h"
00033
00034 #if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) || defined (HOST_HPPAMPEIX)
00035
00036
00037
00038
00039
00040 #include <sys/core.h>
00041 #include <sys/utsname.h>
00042
00043 #endif
00044
00045 #ifdef HOST_HPPABSD
00046
00047
00048
00049 #include "/hpux/usr/include/sys/core.h"
00050
00051 #endif
00052
00053 #include <sys/param.h>
00054 #ifdef HAVE_DIRENT_H
00055 # include <dirent.h>
00056 #else
00057 # ifdef HAVE_SYS_NDIR_H
00058 # include <sys/ndir.h>
00059 # endif
00060 # ifdef HAVE_SYS_DIR_H
00061 # include <sys/dir.h>
00062 # endif
00063 # ifdef HAVE_NDIR_H
00064 # include <ndir.h>
00065 # endif
00066 #endif
00067 #include <signal.h>
00068 #include <machine/reg.h>
00069 #include <sys/user.h>
00070 #include <sys/file.h>
00071
00072
00073
00074
00075
00076 #if defined(CORE_ANON_SHMEM)
00077 #define PROC_INFO_HAS_THREAD_ID (1)
00078 #endif
00079
00080
00081
00082
00083
00084 #if !defined(CORE_ANON_SHMEM)
00085 #define CORE_ANON_SHMEM 0x00000200
00086 #endif
00087
00088
00089
00090
00091
00092
00093 struct hpux_core_struct
00094 {
00095 int sig;
00096 int lwpid;
00097 unsigned long user_tid;
00098 char cmd[MAXCOMLEN + 1];
00099 };
00100
00101 #define core_hdr(bfd) ((bfd)->tdata.hpux_core_data)
00102 #define core_signal(bfd) (core_hdr(bfd)->sig)
00103 #define core_command(bfd) (core_hdr(bfd)->cmd)
00104 #define core_kernel_thread_id(bfd) (core_hdr(bfd)->lwpid)
00105 #define core_user_thread_id(bfd) (core_hdr(bfd)->user_tid)
00106
00107 static asection *make_bfd_asection
00108 PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma,
00109 unsigned int));
00110 static const bfd_target *hpux_core_core_file_p
00111 PARAMS ((bfd *));
00112 static char *hpux_core_core_file_failing_command
00113 PARAMS ((bfd *));
00114 static int hpux_core_core_file_failing_signal
00115 PARAMS ((bfd *));
00116 static bfd_boolean hpux_core_core_file_matches_executable_p
00117 PARAMS ((bfd *, bfd *));
00118 static void swap_abort
00119 PARAMS ((void));
00120
00121 static asection *
00122 make_bfd_asection (abfd, name, flags, size, vma, alignment_power)
00123 bfd *abfd;
00124 const char *name;
00125 flagword flags;
00126 bfd_size_type size;
00127 bfd_vma vma;
00128 unsigned int alignment_power;
00129 {
00130 asection *asect;
00131 char *newname;
00132
00133 newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
00134 if (!newname)
00135 return NULL;
00136
00137 strcpy (newname, name);
00138
00139 asect = bfd_make_section_anyway (abfd, newname);
00140 if (!asect)
00141 return NULL;
00142
00143 asect->flags = flags;
00144 asect->size = size;
00145 asect->vma = vma;
00146 asect->filepos = bfd_tell (abfd);
00147 asect->alignment_power = alignment_power;
00148
00149 return asect;
00150 }
00151
00152
00153
00154
00155 static int
00156 thread_section_p (bfd *abfd ATTRIBUTE_UNUSED,
00157 asection *sect,
00158 void *obj ATTRIBUTE_UNUSED)
00159 {
00160 return (strncmp (bfd_section_name (abfd, sect), ".reg/", 5) == 0);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 static const bfd_target *
00173 hpux_core_core_file_p (abfd)
00174 bfd *abfd;
00175 {
00176 int good_sections = 0;
00177 int unknown_sections = 0;
00178
00179 core_hdr (abfd) = (struct hpux_core_struct *)
00180 bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hpux_core_struct));
00181 if (!core_hdr (abfd))
00182 return NULL;
00183
00184 while (1)
00185 {
00186 int val;
00187 struct corehead core_header;
00188
00189 val = bfd_bread ((void *) &core_header,
00190 (bfd_size_type) sizeof core_header, abfd);
00191 if (val <= 0)
00192 break;
00193 switch (core_header.type)
00194 {
00195 case CORE_KERNEL:
00196 case CORE_FORMAT:
00197
00198 bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
00199 good_sections++;
00200 break;
00201 case CORE_EXEC:
00202 {
00203 struct proc_exec proc_exec;
00204 if (bfd_bread ((void *) &proc_exec, (bfd_size_type) core_header.len,
00205 abfd) != core_header.len)
00206 break;
00207 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
00208 good_sections++;
00209 }
00210 break;
00211 case CORE_PROC:
00212 {
00213 struct proc_info proc_info;
00214 char secname[100];
00215
00216
00217
00218
00219 if (bfd_bread (&proc_info, (bfd_size_type) core_header.len, abfd)
00220 != core_header.len)
00221 break;
00222
00223
00224
00225 if (bfd_seek (abfd, -((file_ptr) core_header.len), SEEK_CUR) != 0)
00226 break;
00227
00228 #if defined(PROC_INFO_HAS_THREAD_ID)
00229 core_kernel_thread_id (abfd) = proc_info.lwpid;
00230 core_user_thread_id (abfd) = proc_info.user_tid;
00231 #else
00232 core_kernel_thread_id (abfd) = 0;
00233 core_user_thread_id (abfd) = 0;
00234 #endif
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 if (core_kernel_thread_id (abfd) == 0)
00249 {
00250 if (!make_bfd_asection (abfd, ".reg",
00251 SEC_HAS_CONTENTS,
00252 core_header.len,
00253 (bfd_vma) offsetof (struct proc_info,
00254 hw_regs),
00255 2))
00256 goto fail;
00257 }
00258 else
00259 {
00260
00261
00262 if (proc_info.sig != -1)
00263 {
00264 if (!make_bfd_asection (abfd, ".reg",
00265 SEC_HAS_CONTENTS,
00266 core_header.len,
00267 (bfd_vma)offsetof (struct proc_info,
00268 hw_regs),
00269 2))
00270 goto fail;
00271 }
00272
00273 sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
00274 if (!make_bfd_asection (abfd, secname,
00275 SEC_HAS_CONTENTS,
00276 core_header.len,
00277 (bfd_vma) offsetof (struct proc_info,
00278 hw_regs),
00279 2))
00280 goto fail;
00281 }
00282 core_signal (abfd) = proc_info.sig;
00283 if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
00284 break;
00285 good_sections++;
00286 }
00287 break;
00288
00289 case CORE_DATA:
00290 case CORE_STACK:
00291 case CORE_TEXT:
00292 case CORE_MMF:
00293 case CORE_SHM:
00294 case CORE_ANON_SHMEM:
00295 if (!make_bfd_asection (abfd, ".data",
00296 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
00297 core_header.len,
00298 (bfd_vma) core_header.addr, 2))
00299 goto fail;
00300
00301 bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
00302 good_sections++;
00303 break;
00304
00305 case CORE_NONE:
00306
00307
00308
00309
00310
00311
00312 unknown_sections++;
00313 break;
00314
00315 default:
00316 goto fail;
00317 }
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 if (core_kernel_thread_id (abfd) != 0
00328 && bfd_get_section_by_name (abfd, ".reg") == NULL)
00329 {
00330 asection *asect = bfd_sections_find_if (abfd, thread_section_p, NULL);
00331 asection *reg_sect;
00332
00333 if (asect != NULL)
00334 {
00335 reg_sect = make_bfd_asection (abfd, ".reg", asect->flags,
00336 asect->size, asect->vma,
00337 asect->alignment_power);
00338 if (reg_sect == NULL)
00339 goto fail;
00340
00341 reg_sect->filepos = asect->filepos;
00342 }
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 if ((unknown_sections > 0) && (good_sections > 0))
00352 (*_bfd_error_handler)
00353 ("%s appears to be a core file,\nbut contains unknown sections. It may have been created on an incompatible\nversion of HP-UX. As a result, some information may be unavailable.\n",
00354 abfd->filename);
00355
00356 return abfd->xvec;
00357
00358 fail:
00359 bfd_release (abfd, core_hdr (abfd));
00360 core_hdr (abfd) = NULL;
00361 bfd_section_list_clear (abfd);
00362 return NULL;
00363 }
00364
00365 static char *
00366 hpux_core_core_file_failing_command (abfd)
00367 bfd *abfd;
00368 {
00369 return core_command (abfd);
00370 }
00371
00372 static int
00373 hpux_core_core_file_failing_signal (abfd)
00374 bfd *abfd;
00375 {
00376 return core_signal (abfd);
00377 }
00378
00379 static bfd_boolean
00380 hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd)
00381 bfd *core_bfd ATTRIBUTE_UNUSED;
00382 bfd *exec_bfd ATTRIBUTE_UNUSED;
00383 {
00384 return TRUE;
00385 }
00386
00387
00388 static void
00389 swap_abort ()
00390 {
00391 abort();
00392 }
00393
00394 #define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
00395 #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
00396 #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
00397 #define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
00398 #define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
00399 #define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
00400
00401 const bfd_target hpux_core_vec =
00402 {
00403 "hpux-core",
00404 bfd_target_unknown_flavour,
00405 BFD_ENDIAN_BIG,
00406 BFD_ENDIAN_BIG,
00407 (HAS_RELOC | EXEC_P |
00408 HAS_LINENO | HAS_DEBUG |
00409 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00410 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
00411 0,
00412 ' ',
00413 16,
00414 NO_GET64, NO_GETS64, NO_PUT64,
00415 NO_GET, NO_GETS, NO_PUT,
00416 NO_GET, NO_GETS, NO_PUT,
00417 NO_GET64, NO_GETS64, NO_PUT64,
00418 NO_GET, NO_GETS, NO_PUT,
00419 NO_GET, NO_GETS, NO_PUT,
00420
00421 {
00422 _bfd_dummy_target,
00423 _bfd_dummy_target,
00424 _bfd_dummy_target,
00425 hpux_core_core_file_p
00426 },
00427 {
00428 bfd_false, bfd_false,
00429 bfd_false, bfd_false
00430 },
00431 {
00432 bfd_false, bfd_false,
00433 bfd_false, bfd_false
00434 },
00435
00436 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
00437 BFD_JUMP_TABLE_COPY (_bfd_generic),
00438 BFD_JUMP_TABLE_CORE (hpux_core),
00439 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00440 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
00441 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
00442 BFD_JUMP_TABLE_WRITE (_bfd_generic),
00443 BFD_JUMP_TABLE_LINK (_bfd_nolink),
00444 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00445
00446 NULL,
00447
00448 (PTR) 0
00449 };