(root)/
binutils-2.41/
bfd/
irix-core.c
       1  /* BFD back-end for Irix core files.
       2     Copyright (C) 1993-2023 Free Software Foundation, Inc.
       3     Written by Stu Grossman, Cygnus Support.
       4     Converted to back-end form by Ian Lance Taylor, Cygnus Support
       5  
       6     This file is part of BFD, the Binary File Descriptor library.
       7  
       8     This program is free software; you can redistribute it and/or modify
       9     it under the terms of the GNU General Public License as published by
      10     the Free Software Foundation; either version 3 of the License, or
      11     (at your option) any later version.
      12  
      13     This program is distributed in the hope that it will be useful,
      14     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16     GNU General Public License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with this program; if not, write to the Free Software
      20     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
      21     MA 02110-1301, USA.  */
      22  
      23  
      24  /* This file can only be compiled on systems which use Irix style core
      25     files (namely, Irix 4 and Irix 5, so far).  */
      26  
      27  #include "sysdep.h"
      28  #include "bfd.h"
      29  #include "libbfd.h"
      30  
      31  #ifdef IRIX_CORE
      32  
      33  #include <core.out.h>
      34  
      35  struct sgi_core_struct
      36  {
      37    int sig;
      38    char cmd[CORE_NAMESIZE];
      39  };
      40  
      41  #define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
      42  #define core_signal(bfd) (core_hdr(bfd)->sig)
      43  #define core_command(bfd) (core_hdr(bfd)->cmd)
      44  
      45  #define irix_core_core_file_matches_executable_p generic_core_file_matches_executable_p
      46  #define irix_core_core_file_pid _bfd_nocore_core_file_pid
      47  
      48  static asection *make_bfd_asection
      49    (bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr);
      50  
      51  /* Helper function for irix_core_core_file_p:
      52     32-bit and 64-bit versions.  */
      53  
      54  #ifdef CORE_MAGIC64
      55  static int
      56  do_sections64 (bfd *abfd, struct coreout *coreout)
      57  {
      58    struct vmap64 vmap;
      59    char *secname;
      60    int i, val;
      61  
      62    for (i = 0; i < coreout->c_nvmap; i++)
      63      {
      64        val = bfd_bread (&vmap, (bfd_size_type) sizeof vmap, abfd);
      65        if (val != sizeof vmap)
      66  	break;
      67  
      68        switch (vmap.v_type)
      69  	{
      70  	case VDATA:
      71  	  secname = ".data";
      72  	  break;
      73  	case VSTACK:
      74  	  secname = ".stack";
      75  	  break;
      76  #ifdef VMAPFILE
      77  	case VMAPFILE:
      78  	  secname = ".mapfile";
      79  	  break;
      80  #endif
      81  	default:
      82  	  continue;
      83  	}
      84  
      85        /* A file offset of zero means that the
      86  	 section is not contained in the corefile.  */
      87        if (vmap.v_offset == 0)
      88  	continue;
      89  
      90        if (!make_bfd_asection (abfd, secname,
      91  			      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
      92  			      vmap.v_len, vmap.v_vaddr, vmap.v_offset))
      93  	/* Fail.  */
      94  	return 0;
      95      }
      96  
      97    return 1;
      98  }
      99  #endif
     100  
     101  /* 32-bit version.  */
     102  
     103  static int
     104  do_sections (bfd *abfd, struct coreout *coreout)
     105  {
     106    struct vmap vmap;
     107    char *secname;
     108    int i, val;
     109  
     110    for (i = 0; i < coreout->c_nvmap; i++)
     111      {
     112        val = bfd_bread (&vmap, (bfd_size_type) sizeof vmap, abfd);
     113        if (val != sizeof vmap)
     114  	break;
     115  
     116        switch (vmap.v_type)
     117  	{
     118  	case VDATA:
     119  	  secname = ".data";
     120  	  break;
     121  	case VSTACK:
     122  	  secname = ".stack";
     123  	  break;
     124  #ifdef VMAPFILE
     125  	case VMAPFILE:
     126  	  secname = ".mapfile";
     127  	  break;
     128  #endif
     129  	default:
     130  	  continue;
     131  	}
     132  
     133        /* A file offset of zero means that the
     134  	 section is not contained in the corefile.  */
     135        if (vmap.v_offset == 0)
     136  	continue;
     137  
     138        if (!make_bfd_asection (abfd, secname,
     139  			      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
     140  			      vmap.v_len, vmap.v_vaddr, vmap.v_offset))
     141  	/* Fail.  */
     142  	return 0;
     143      }
     144    return 1;
     145  }
     146  
     147  static asection *
     148  make_bfd_asection (bfd *abfd,
     149  		   const char *name,
     150  		   flagword flags,
     151  		   bfd_size_type size,
     152  		   bfd_vma vma,
     153  		   file_ptr filepos)
     154  {
     155    asection *asect;
     156  
     157    asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
     158    if (!asect)
     159      return NULL;
     160  
     161    asect->size = size;
     162    asect->vma = vma;
     163    asect->filepos = filepos;
     164    asect->alignment_power = 4;
     165  
     166    return asect;
     167  }
     168  
     169  static bfd_cleanup
     170  irix_core_core_file_p (bfd *abfd)
     171  {
     172    int val;
     173    struct coreout coreout;
     174    struct idesc *idg, *idf, *ids;
     175    size_t amt;
     176  
     177    val = bfd_bread (&coreout, (bfd_size_type) sizeof coreout, abfd);
     178    if (val != sizeof coreout)
     179      {
     180        if (bfd_get_error () != bfd_error_system_call)
     181  	bfd_set_error (bfd_error_wrong_format);
     182        return 0;
     183      }
     184  
     185    if (coreout.c_version != CORE_VERSION1)
     186      return 0;
     187  
     188    /* Have we got a corefile?  */
     189    switch (coreout.c_magic)
     190      {
     191      case CORE_MAGIC:	break;
     192  #ifdef CORE_MAGIC64
     193      case CORE_MAGIC64:	break;
     194  #endif
     195  #ifdef CORE_MAGICN32
     196      case CORE_MAGICN32:	break;
     197  #endif
     198      default:		return 0;	/* Un-identifiable or not corefile.  */
     199      }
     200  
     201    amt = sizeof (struct sgi_core_struct);
     202    core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, amt);
     203    if (!core_hdr (abfd))
     204      return NULL;
     205  
     206    strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
     207    core_signal (abfd) = coreout.c_sigcause;
     208  
     209    if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0)
     210      goto fail;
     211  
     212    /* Process corefile sections.  */
     213  #ifdef CORE_MAGIC64
     214    if (coreout.c_magic == (int) CORE_MAGIC64)
     215      {
     216        if (! do_sections64 (abfd, & coreout))
     217  	goto fail;
     218      }
     219    else
     220  #endif
     221      if (! do_sections (abfd, & coreout))
     222        goto fail;
     223  
     224    /* Make sure that the regs are contiguous within the core file.  */
     225  
     226    idg = &coreout.c_idesc[I_GPREGS];
     227    idf = &coreout.c_idesc[I_FPREGS];
     228    ids = &coreout.c_idesc[I_SPECREGS];
     229  
     230    if (idg->i_offset + idg->i_len != idf->i_offset
     231        || idf->i_offset + idf->i_len != ids->i_offset)
     232      goto fail;			/* Can't deal with non-contig regs */
     233  
     234    if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0)
     235      goto fail;
     236  
     237    if (!make_bfd_asection (abfd, ".reg",
     238  			  SEC_HAS_CONTENTS,
     239  			  idg->i_len + idf->i_len + ids->i_len,
     240  			  0,
     241  			  idg->i_offset))
     242      goto fail;
     243  
     244    /* OK, we believe you.  You're a core file (sure, sure).  */
     245    bfd_default_set_arch_mach (abfd, bfd_arch_mips, 0);
     246  
     247    return _bfd_no_cleanup;
     248  
     249   fail:
     250    bfd_release (abfd, core_hdr (abfd));
     251    core_hdr (abfd) = NULL;
     252    bfd_section_list_clear (abfd);
     253    return NULL;
     254  }
     255  
     256  static char *
     257  irix_core_core_file_failing_command (bfd *abfd)
     258  {
     259    return core_command (abfd);
     260  }
     261  
     262  static int
     263  irix_core_core_file_failing_signal (bfd *abfd)
     264  {
     265    return core_signal (abfd);
     266  }
     267  
     268  /* If somebody calls any byte-swapping routines, shoot them.  */
     269  static void
     270  swap_abort(void)
     271  {
     272    abort(); /* This way doesn't require any declaration for ANSI to fuck up */
     273  }
     274  
     275  #define	NO_GET ((bfd_vma (*) (const void *)) swap_abort)
     276  #define	NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
     277  #define	NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
     278  #define	NO_GET64 ((uint64_t (*) (const void *)) swap_abort)
     279  #define	NO_PUT64 ((void (*) (uint64_t, void *)) swap_abort)
     280  #define	NO_GETS64 ((int64_t (*) (const void *)) swap_abort)
     281  
     282  const bfd_target core_irix_vec =
     283    {
     284      "irix-core",
     285      bfd_target_unknown_flavour,
     286      BFD_ENDIAN_BIG,		/* target byte order */
     287      BFD_ENDIAN_BIG,		/* target headers byte order */
     288      (HAS_RELOC | EXEC_P |	/* object flags */
     289       HAS_LINENO | HAS_DEBUG |
     290       HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
     291      (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
     292      0,							   /* symbol prefix */
     293      ' ',						   /* ar_pad_char */
     294      16,							   /* ar_max_namelen */
     295      0,							   /* match_priority */
     296      TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
     297      NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit data */
     298      NO_GET, NO_GETS, NO_PUT,		/* 32 bit data */
     299      NO_GET, NO_GETS, NO_PUT,		/* 16 bit data */
     300      NO_GET64, NO_GETS64, NO_PUT64,	/* 64 bit hdrs */
     301      NO_GET, NO_GETS, NO_PUT,		/* 32 bit hdrs */
     302      NO_GET, NO_GETS, NO_PUT,		/* 16 bit hdrs */
     303  
     304      {				/* bfd_check_format */
     305        _bfd_dummy_target,		/* unknown format */
     306        _bfd_dummy_target,		/* object file */
     307        _bfd_dummy_target,		/* archive */
     308        irix_core_core_file_p		/* a core file */
     309      },
     310      {				/* bfd_set_format */
     311        _bfd_bool_bfd_false_error,
     312        _bfd_bool_bfd_false_error,
     313        _bfd_bool_bfd_false_error,
     314        _bfd_bool_bfd_false_error
     315      },
     316      {				/* bfd_write_contents */
     317        _bfd_bool_bfd_false_error,
     318        _bfd_bool_bfd_false_error,
     319        _bfd_bool_bfd_false_error,
     320        _bfd_bool_bfd_false_error
     321      },
     322  
     323      BFD_JUMP_TABLE_GENERIC (_bfd_generic),
     324      BFD_JUMP_TABLE_COPY (_bfd_generic),
     325      BFD_JUMP_TABLE_CORE (irix_core),
     326      BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
     327      BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
     328      BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
     329      BFD_JUMP_TABLE_WRITE (_bfd_generic),
     330      BFD_JUMP_TABLE_LINK (_bfd_nolink),
     331      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
     332  
     333      NULL,
     334  
     335      NULL			/* backend_data */
     336    };
     337  
     338  #endif /* IRIX_CORE */