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 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "libbfd.h"
00029 #include "libaout.h"
00030
00031 #include <stdio.h>
00032 #include <sys/types.h>
00033 #include <sys/param.h>
00034 #include <sys/dir.h>
00035 #include <signal.h>
00036
00037 #include <sys/user.h>
00038 #include <sys/paccess.h>
00039 #include <sys/region.h>
00040
00041 struct sco5_core_struct
00042 {
00043 struct user u;
00044 };
00045
00046
00047
00048 static asection *make_bfd_asection
00049 PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr));
00050 static struct user *read_uarea PARAMS ((bfd *, int));
00051 const bfd_target *sco5_core_file_p PARAMS ((bfd *abfd));
00052 char *sco5_core_file_failing_command PARAMS ((bfd *abfd));
00053 int sco5_core_file_failing_signal PARAMS ((bfd *abfd));
00054 bfd_boolean sco5_core_file_matches_executable_p
00055 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
00056 static void swap_abort PARAMS ((void));
00057
00058 static asection *
00059 make_bfd_asection (abfd, name, flags, size, vma, filepos)
00060 bfd *abfd;
00061 const char *name;
00062 flagword flags;
00063 bfd_size_type size;
00064 bfd_vma vma;
00065 file_ptr filepos;
00066 {
00067 asection *asect;
00068
00069 asect = bfd_make_section_anyway (abfd, name);
00070 if (!asect)
00071 return NULL;
00072 asect->flags = flags;
00073 asect->size = size;
00074 asect->vma = vma;
00075 asect->filepos = filepos;
00076 asect->alignment_power = 2;
00077
00078 return asect;
00079 }
00080
00081 static struct user *
00082 read_uarea(abfd, filepos)
00083 bfd *abfd;
00084 int filepos;
00085
00086 {
00087 struct sco5_core_struct *rawptr;
00088 bfd_size_type amt = sizeof (struct sco5_core_struct);
00089
00090 rawptr = (struct sco5_core_struct *) bfd_zmalloc (amt);
00091 if (rawptr == NULL)
00092 return NULL;
00093
00094 abfd->tdata.sco5_core_data = rawptr;
00095
00096 if (bfd_seek (abfd, (file_ptr) filepos, SEEK_SET) != 0
00097 || bfd_bread ((void *) &rawptr->u, (bfd_size_type) sizeof rawptr->u,
00098 abfd) != sizeof rawptr->u)
00099 {
00100 bfd_set_error (bfd_error_wrong_format);
00101 return NULL;
00102 }
00103
00104
00105 if (rawptr->u.u_dsize > 0x1000000)
00106 {
00107 bfd_set_error (bfd_error_wrong_format);
00108 return NULL;
00109 }
00110 if (rawptr->u.u_ssize > 0x1000000)
00111 {
00112 bfd_set_error (bfd_error_wrong_format);
00113 return NULL;
00114 }
00115 return &rawptr->u;
00116 }
00117
00118 const bfd_target *
00119 sco5_core_file_p (abfd)
00120 bfd *abfd;
00121 {
00122 int coffset_siz, val, nsecs, cheadoffs;
00123 int coresize;
00124 struct user *u;
00125 struct coreoffsets coffsets;
00126 struct coresecthead chead;
00127 char *secname;
00128 flagword flags;
00129
00130
00131
00132 {
00133 FILE *stream = bfd_cache_lookup (abfd);
00134 struct stat statbuf;
00135
00136 if (fstat (fileno (stream), &statbuf) < 0)
00137 {
00138 bfd_set_error (bfd_error_system_call);
00139 return NULL;
00140 }
00141 coresize = statbuf.st_size;
00142 }
00143
00144 if ((bfd_seek (abfd, (file_ptr) (coresize - sizeof coffset_siz),
00145 SEEK_SET) != 0)
00146 || bfd_bread ((void *) &coffset_siz, (bfd_size_type) sizeof coffset_siz,
00147 abfd) != sizeof coffset_siz)
00148 {
00149 bfd_set_error (bfd_error_wrong_format);
00150 return NULL;
00151 }
00152
00153
00154
00155 if ((bfd_seek (abfd, (file_ptr) (coresize - coffset_siz), SEEK_SET) != 0)
00156 || (bfd_bread ((void *) &coffsets, (bfd_size_type) sizeof coffsets, abfd)
00157 != sizeof coffsets)
00158 || ((coffsets.u_info != 1) && (coffsets.u_info != C_VERSION)))
00159 {
00160 bfd_set_error (bfd_error_wrong_format);
00161 return NULL;
00162 }
00163
00164 if (coffsets.u_info == 1)
00165 {
00166
00167
00168 u = read_uarea (abfd, coffsets.u_user);
00169 if (! u)
00170 goto fail;
00171
00172 if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS,
00173 (bfd_size_type) coffsets.u_usize,
00174 0 - (bfd_vma) u->u_ar0,
00175 (file_ptr) coffsets.u_user))
00176 goto fail;
00177
00178 if (!make_bfd_asection (abfd, ".data",
00179 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
00180 ((bfd_size_type) u->u_exdata.ux_dsize
00181 + u->u_exdata.ux_bsize),
00182 (bfd_vma) u->u_exdata.ux_datorg,
00183 (file_ptr) coffsets.u_data))
00184 goto fail;
00185
00186 if (!make_bfd_asection (abfd, ".stack",
00187 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
00188 (bfd_size_type) u->u_ssize * NBPC,
00189 (bfd_vma) u->u_sub,
00190 (file_ptr) coffsets.u_stack))
00191 goto fail;
00192
00193 return abfd->xvec;
00194 }
00195
00196
00197
00198
00199
00200
00201 if ((bfd_seek (abfd,
00202 (file_ptr) (coresize - coffset_siz - 2 * sizeof coffset_siz),
00203 SEEK_SET) != 0)
00204 || (bfd_bread ((void *) &nsecs, (bfd_size_type) sizeof nsecs, abfd)
00205 != sizeof nsecs)
00206 || (bfd_bread ((void *) &cheadoffs, (bfd_size_type) sizeof cheadoffs,
00207 abfd) != sizeof cheadoffs)
00208 || (bfd_seek (abfd, (file_ptr) cheadoffs, SEEK_SET) != 0)
00209 || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
00210 != sizeof chead)
00211 || (chead.cs_stype != CORES_OFFSETS)
00212 || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
00213 {
00214 bfd_set_error (bfd_error_wrong_format);
00215 goto fail;
00216 }
00217
00218
00219
00220
00221 nsecs--;
00222 for (; nsecs; nsecs--)
00223 {
00224 if ((bfd_seek (abfd, (file_ptr) chead.cs_hseek, SEEK_SET) != 0)
00225 || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
00226 != sizeof chead))
00227 {
00228 bfd_set_error (bfd_error_wrong_format);
00229 goto fail;
00230 }
00231
00232 switch (chead.cs_stype)
00233 {
00234 case CORES_MAGIC:
00235 if (chead.cs_x.csx_magic != COREMAGIC_NUMBER)
00236 {
00237 bfd_set_error (bfd_error_wrong_format);
00238 goto fail;
00239 }
00240 secname = NULL;
00241 nsecs++;
00242 break;
00243 case CORES_UAREA:
00244 u = read_uarea (abfd, chead.cs_sseek);
00245 if (! u)
00246 goto fail;
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 chead.cs_vaddr = 0 - (bfd_vma) u->u_ar0;
00267
00268 secname = ".reg";
00269 flags = SEC_HAS_CONTENTS;
00270
00271 break;
00272 case CORES_PREGION:
00273 switch (chead.cs_x.csx_preg.csxp_rtyp)
00274 {
00275 case PT_DATA:
00276 secname = ".data";
00277 break;
00278 case PT_STACK:
00279 secname = ".stack";
00280 break;
00281 case PT_SHMEM:
00282 secname = ".shmem";
00283 break;
00284 case PT_LIBDAT:
00285 secname = ".libdat";
00286 break;
00287 case PT_V86:
00288 secname = ".virt86";
00289 break;
00290 case PT_SHFIL:
00291 secname = ".mmfile";
00292 break;
00293 case PT_XDATA0:
00294 secname = ".Xdat0";
00295 break;
00296 default:
00297 secname = "";
00298 }
00299 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
00300 break;
00301 case CORES_PROC:
00302 case CORES_ITIMER:
00303 case CORES_SCOUTSNAME:
00304 secname = NULL;
00305 break;
00306 default:
00307 (*_bfd_error_handler) ("Unhandled SCO core file section type %d\n",
00308 chead.cs_stype);
00309 continue;
00310 }
00311
00312 if (secname
00313 && !make_bfd_asection (abfd, secname, flags,
00314 (bfd_size_type) chead.cs_vsize,
00315 (bfd_vma) chead.cs_vaddr,
00316 (file_ptr) chead.cs_sseek))
00317 goto fail;
00318
00319 }
00320
00321 return abfd->xvec;
00322
00323 fail:
00324 if (abfd->tdata.any)
00325 {
00326 bfd_release (abfd, abfd->tdata.any);
00327 abfd->tdata.any = NULL;
00328 }
00329 bfd_section_list_clear (abfd);
00330 return NULL;
00331 }
00332
00333 char *
00334 sco5_core_file_failing_command (abfd)
00335 bfd *abfd;
00336 {
00337 char *com = abfd->tdata.sco5_core_data->u.u_comm;
00338 if (*com)
00339 return com;
00340 else
00341 return NULL;
00342 }
00343
00344 int
00345 sco5_core_file_failing_signal (ignore_abfd)
00346 bfd *ignore_abfd;
00347 {
00348 return ((ignore_abfd->tdata.sco5_core_data->u.u_sysabort != 0)
00349 ? ignore_abfd->tdata.sco5_core_data->u.u_sysabort
00350 : -1);
00351 }
00352
00353 bfd_boolean
00354 sco5_core_file_matches_executable_p (core_bfd, exec_bfd)
00355 bfd *core_bfd ATTRIBUTE_UNUSED;
00356 bfd *exec_bfd ATTRIBUTE_UNUSED;
00357 {
00358 return TRUE;
00359 }
00360
00361
00362 static void
00363 swap_abort ()
00364 {
00365 abort ();
00366 }
00367
00368 #define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
00369 #define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
00370 #define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
00371 #define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
00372 #define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
00373 #define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
00374
00375 const bfd_target sco5_core_vec =
00376 {
00377 "sco5-core",
00378 bfd_target_unknown_flavour,
00379 BFD_ENDIAN_LITTLE,
00380 BFD_ENDIAN_LITTLE,
00381 (HAS_RELOC | EXEC_P |
00382 HAS_LINENO | HAS_DEBUG |
00383 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
00384 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC),
00385 0,
00386 ' ',
00387 16,
00388 NO_GET64, NO_GETS64, NO_PUT64,
00389 NO_GET, NO_GETS, NO_PUT,
00390 NO_GET, NO_GETS, NO_PUT,
00391 NO_GET64, NO_GETS64, NO_PUT64,
00392 NO_GET, NO_GETS, NO_PUT,
00393 NO_GET, NO_GETS, NO_PUT,
00394
00395 {
00396 _bfd_dummy_target,
00397 _bfd_dummy_target,
00398 _bfd_dummy_target,
00399 sco5_core_file_p
00400 },
00401 {
00402 bfd_false, bfd_false,
00403 bfd_false, bfd_false
00404 },
00405 {
00406 bfd_false, bfd_false,
00407 bfd_false, bfd_false
00408 },
00409
00410 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
00411 BFD_JUMP_TABLE_COPY (_bfd_generic),
00412 BFD_JUMP_TABLE_CORE (sco5),
00413 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00414 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
00415 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
00416 BFD_JUMP_TABLE_WRITE (_bfd_generic),
00417 BFD_JUMP_TABLE_LINK (_bfd_nolink),
00418 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00419
00420 NULL,
00421
00422 (PTR) 0
00423 };