1 1.1 skrll /* BFD back end for Lynx core files 2 1.1.1.11 christos Copyright (C) 1993-2026 Free Software Foundation, Inc. 3 1.1 skrll Written by Stu Grossman of Cygnus Support. 4 1.1 skrll 5 1.1 skrll This file is part of BFD, the Binary File Descriptor library. 6 1.1 skrll 7 1.1 skrll This program is free software; you can redistribute it and/or modify 8 1.1 skrll it under the terms of the GNU General Public License as published by 9 1.1 skrll the Free Software Foundation; either version 3 of the License, or 10 1.1 skrll (at your option) any later version. 11 1.1 skrll 12 1.1 skrll This program is distributed in the hope that it will be useful, 13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 skrll GNU General Public License for more details. 16 1.1 skrll 17 1.1 skrll You should have received a copy of the GNU General Public License 18 1.1 skrll along with this program; if not, write to the Free Software 19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 skrll MA 02110-1301, USA. */ 21 1.1 skrll 22 1.1 skrll #include "sysdep.h" 23 1.1 skrll #include "bfd.h" 24 1.1 skrll #include "libbfd.h" 25 1.1 skrll 26 1.1 skrll #ifdef LYNX_CORE 27 1.1 skrll 28 1.1 skrll #include <sys/conf.h> 29 1.1 skrll #include <sys/kernel.h> 30 1.1 skrll /* sys/kernel.h should define this, but doesn't always, sigh. */ 31 1.1 skrll #ifndef __LYNXOS 32 1.1 skrll #define __LYNXOS 33 1.1 skrll #endif 34 1.1 skrll #include <sys/mem.h> 35 1.1 skrll #include <sys/signal.h> 36 1.1 skrll #include <sys/time.h> 37 1.1 skrll #include <sys/resource.h> 38 1.1 skrll #include <sys/itimer.h> 39 1.1 skrll #include <sys/file.h> 40 1.1 skrll #include <sys/proc.h> 41 1.1 skrll 42 1.1 skrll /* These are stored in the bfd's tdata */ 43 1.1 skrll 44 1.1 skrll struct lynx_core_struct 45 1.1 skrll { 46 1.1 skrll int sig; 47 1.1 skrll char cmd[PNMLEN + 1]; 48 1.1 skrll }; 49 1.1 skrll 50 1.1 skrll #define core_hdr(bfd) ((bfd)->tdata.lynx_core_data) 51 1.1 skrll #define core_signal(bfd) (core_hdr(bfd)->sig) 52 1.1 skrll #define core_command(bfd) (core_hdr(bfd)->cmd) 53 1.1 skrll 54 1.1 skrll #define lynx_core_file_matches_executable_p generic_core_file_matches_executable_p 55 1.1.1.2 christos #define lynx_core_file_pid _bfd_nocore_core_file_pid 56 1.1 skrll 57 1.1 skrll /* Handle Lynx core dump file. */ 58 1.1 skrll 59 1.1 skrll static asection * 60 1.1.1.3 christos make_bfd_asection (bfd *abfd, 61 1.1.1.3 christos const char *name, 62 1.1.1.3 christos flagword flags, 63 1.1.1.3 christos bfd_size_type size, 64 1.1.1.3 christos bfd_vma vma, 65 1.1.1.3 christos file_ptr filepos) 66 1.1 skrll { 67 1.1 skrll asection *asect; 68 1.1 skrll char *newname; 69 1.1 skrll 70 1.1 skrll newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1); 71 1.1 skrll if (!newname) 72 1.1 skrll return NULL; 73 1.1 skrll 74 1.1 skrll strcpy (newname, name); 75 1.1 skrll 76 1.1 skrll asect = bfd_make_section_with_flags (abfd, newname, flags); 77 1.1 skrll if (!asect) 78 1.1 skrll return NULL; 79 1.1 skrll 80 1.1 skrll asect->size = size; 81 1.1 skrll asect->vma = vma; 82 1.1 skrll asect->filepos = filepos; 83 1.1 skrll asect->alignment_power = 2; 84 1.1 skrll 85 1.1 skrll return asect; 86 1.1 skrll } 87 1.1 skrll 88 1.1.1.8 christos bfd_cleanup 89 1.1.1.3 christos lynx_core_file_p (bfd *abfd) 90 1.1 skrll { 91 1.1 skrll int secnum; 92 1.1 skrll struct pssentry pss; 93 1.1 skrll bfd_size_type tcontext_size; 94 1.1 skrll core_st_t *threadp; 95 1.1 skrll int pagesize; 96 1.1 skrll asection *newsect; 97 1.1.1.8 christos size_t amt; 98 1.1 skrll 99 1.1 skrll pagesize = getpagesize (); /* Serious cross-target issue here... This 100 1.1 skrll really needs to come from a system-specific 101 1.1 skrll header file. */ 102 1.1 skrll 103 1.1 skrll /* Get the pss entry from the core file */ 104 1.1 skrll 105 1.1.1.9 christos if (bfd_seek (abfd, 0, SEEK_SET) != 0) 106 1.1 skrll return NULL; 107 1.1 skrll 108 1.1 skrll amt = sizeof pss; 109 1.1.1.9 christos if (bfd_read (&pss, amt, abfd) != amt) 110 1.1 skrll { 111 1.1 skrll /* Too small to be a core file */ 112 1.1 skrll if (bfd_get_error () != bfd_error_system_call) 113 1.1 skrll bfd_set_error (bfd_error_wrong_format); 114 1.1 skrll return NULL; 115 1.1 skrll } 116 1.1 skrll 117 1.1 skrll amt = sizeof (struct lynx_core_struct); 118 1.1 skrll core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt); 119 1.1 skrll 120 1.1 skrll if (!core_hdr (abfd)) 121 1.1 skrll return NULL; 122 1.1 skrll 123 1.1.1.10 christos strncpy (core_command (abfd), pss.pname, PNMLEN); 124 1.1.1.10 christos core_command (abfd)[PNMLEN] = 0; 125 1.1 skrll 126 1.1 skrll /* Compute the size of the thread contexts */ 127 1.1 skrll 128 1.1 skrll tcontext_size = pss.threadcnt * sizeof (core_st_t); 129 1.1 skrll 130 1.1 skrll /* Save thread contexts */ 131 1.1.1.8 christos if (bfd_seek (abfd, pagesize, SEEK_SET) != 0) 132 1.1.1.8 christos goto fail; 133 1.1.1.8 christos threadp = (core_st_t *) _bfd_alloc_and_read (abfd, tcontext_size, 134 1.1.1.8 christos tcontext_size); 135 1.1.1.8 christos if (!threadp) 136 1.1 skrll goto fail; 137 1.1 skrll 138 1.1 skrll core_signal (abfd) = threadp->currsig; 139 1.1 skrll 140 1.1 skrll newsect = make_bfd_asection (abfd, ".stack", 141 1.1 skrll SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, 142 1.1 skrll pss.ssize, 143 1.1 skrll pss.slimit, 144 1.1 skrll pagesize + tcontext_size); 145 1.1 skrll if (!newsect) 146 1.1 skrll goto fail; 147 1.1 skrll 148 1.1 skrll newsect = make_bfd_asection (abfd, ".data", 149 1.1 skrll SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, 150 1.1 skrll pss.data_len + pss.bss_len, 151 1.1 skrll pss.data_start, 152 1.1 skrll pagesize + tcontext_size + pss.ssize 153 1.1 skrll #if defined (SPARC) || defined (__SPARC__) 154 1.1 skrll /* SPARC Lynx seems to start dumping 155 1.1.1.6 christos the .data section at a page 156 1.1.1.6 christos boundary. It's OK to check a 157 1.1.1.6 christos #define like SPARC here because this 158 1.1.1.6 christos file can only be compiled on a Lynx 159 1.1.1.6 christos host. */ 160 1.1 skrll + pss.data_start % pagesize 161 1.1 skrll #endif 162 1.1 skrll ); 163 1.1 skrll if (!newsect) 164 1.1 skrll goto fail; 165 1.1 skrll 166 1.1 skrll /* And, now for the .reg/XXX pseudo sections. Each thread has it's own 167 1.1 skrll .reg/XXX section, where XXX is the thread id (without leading zeros). The 168 1.1 skrll currently running thread (at the time of the core dump) also has an alias 169 1.1 skrll called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as 170 1.1 skrll opposed to `.regXXX' because GDB expects that .reg2 will be the floating- 171 1.1 skrll point registers. */ 172 1.1 skrll 173 1.1 skrll newsect = make_bfd_asection (abfd, ".reg", 174 1.1 skrll SEC_HAS_CONTENTS, 175 1.1 skrll sizeof (core_st_t), 176 1.1 skrll 0, 177 1.1 skrll pagesize); 178 1.1 skrll if (!newsect) 179 1.1 skrll goto fail; 180 1.1 skrll 181 1.1 skrll for (secnum = 0; secnum < pss.threadcnt; secnum++) 182 1.1 skrll { 183 1.1 skrll char secname[100]; 184 1.1 skrll 185 1.1 skrll sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid)); 186 1.1 skrll newsect = make_bfd_asection (abfd, secname, 187 1.1 skrll SEC_HAS_CONTENTS, 188 1.1 skrll sizeof (core_st_t), 189 1.1 skrll 0, 190 1.1 skrll pagesize + secnum * sizeof (core_st_t)); 191 1.1 skrll if (!newsect) 192 1.1 skrll goto fail; 193 1.1 skrll } 194 1.1 skrll 195 1.1.1.8 christos return _bfd_no_cleanup; 196 1.1 skrll 197 1.1 skrll fail: 198 1.1 skrll bfd_release (abfd, core_hdr (abfd)); 199 1.1 skrll core_hdr (abfd) = NULL; 200 1.1 skrll bfd_section_list_clear (abfd); 201 1.1 skrll return NULL; 202 1.1 skrll } 203 1.1 skrll 204 1.1 skrll char * 205 1.1.1.3 christos lynx_core_file_failing_command (bfd *abfd) 206 1.1 skrll { 207 1.1 skrll return core_command (abfd); 208 1.1 skrll } 209 1.1 skrll 210 1.1 skrll int 211 1.1.1.3 christos lynx_core_file_failing_signal (bfd *abfd) 212 1.1 skrll { 213 1.1 skrll return core_signal (abfd); 214 1.1 skrll } 215 1.1 skrll 216 1.1 skrll #endif /* LYNX_CORE */ 217