From Vladimir Prus <ghost@cs.msu.su>:
[deliverable/binutils-gdb.git] / gdb / corelow.c
CommitLineData
c906108c 1/* Core dump and executable file functions below target vector, for GDB.
4646aa9d 2
197e01b6 3 Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996,
9353355f 4 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
961cb7b5 5 Free Software Foundation, Inc.
c906108c 6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
c906108c 13
c5aa993b
JM
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
c906108c 18
c5aa993b
JM
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
197e01b6
EZ
21 Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
c906108c
SS
23
24#include "defs.h"
0e24ac5d 25#include "arch-utils.h"
c906108c
SS
26#include "gdb_string.h"
27#include <errno.h>
28#include <signal.h>
29#include <fcntl.h>
fc24370e
MS
30#ifdef HAVE_SYS_FILE_H
31#include <sys/file.h> /* needed for F_OK and friends */
32#endif
c5aa993b 33#include "frame.h" /* required by inferior.h */
c906108c
SS
34#include "inferior.h"
35#include "symtab.h"
36#include "command.h"
37#include "bfd.h"
38#include "target.h"
39#include "gdbcore.h"
40#include "gdbthread.h"
4e052eda 41#include "regcache.h"
0e24ac5d 42#include "regset.h"
990f9fe3 43#include "symfile.h"
4646aa9d 44#include "exec.h"
dbda9972 45#include "readline/readline.h"
0e24ac5d 46#include "gdb_assert.h"
60250e8b 47#include "exceptions.h"
a77053c2 48#include "solib.h"
0e24ac5d 49
8e860359
CF
50#ifndef O_BINARY
51#define O_BINARY 0
52#endif
53
ee28ca0f
AC
54#ifndef O_LARGEFILE
55#define O_LARGEFILE 0
56#endif
57
00e32a35
AC
58/* List of all available core_fns. On gdb startup, each core file
59 register reader calls deprecated_add_core_fns() to register
60 information on each core format it is prepared to read. */
c906108c
SS
61
62static struct core_fns *core_file_fns = NULL;
63
2acceee2
JM
64/* The core_fns for a core file handler that is prepared to read the core
65 file currently open on core_bfd. */
66
67static struct core_fns *core_vec = NULL;
68
0e24ac5d
MK
69/* FIXME: kettenis/20031023: Eventually this variable should
70 disappear. */
71
72struct gdbarch *core_gdbarch = NULL;
73
a14ed312 74static void core_files_info (struct target_ops *);
c906108c 75
a14ed312 76static struct core_fns *sniff_core_bfd (bfd *);
2acceee2 77
020cc13c 78static int gdb_check_format (bfd *);
2acceee2 79
a14ed312 80static void core_open (char *, int);
c906108c 81
a14ed312 82static void core_detach (char *, int);
c906108c 83
a14ed312 84static void core_close (int);
c906108c 85
74b7792f
AC
86static void core_close_cleanup (void *ignore);
87
a14ed312 88static void get_core_registers (int);
c906108c 89
4efb68b1 90static void add_to_thread_list (bfd *, asection *, void *);
c906108c 91
5a168c78 92static int ignore (CORE_ADDR, bfd_byte *);
c906108c 93
39f77062 94static int core_file_thread_alive (ptid_t tid);
c906108c 95
a14ed312 96static void init_core_ops (void);
c906108c 97
a14ed312 98void _initialize_corelow (void);
c906108c
SS
99
100struct target_ops core_ops;
101
102/* Link a new core_fns into the global core_file_fns list. Called on gdb
103 startup by the _initialize routine in each core file register reader, to
104 register information about each format the the reader is prepared to
105 handle. */
106
107void
00e32a35 108deprecated_add_core_fns (struct core_fns *cf)
c906108c 109{
c5aa993b 110 cf->next = core_file_fns;
c906108c
SS
111 core_file_fns = cf;
112}
113
2acceee2
JM
114/* The default function that core file handlers can use to examine a
115 core file BFD and decide whether or not to accept the job of
116 reading the core file. */
117
118int
fba45db2 119default_core_sniffer (struct core_fns *our_fns, bfd *abfd)
2acceee2
JM
120{
121 int result;
122
123 result = (bfd_get_flavour (abfd) == our_fns -> core_flavour);
124 return (result);
125}
126
127/* Walk through the list of core functions to find a set that can
128 handle the core file open on ABFD. Default to the first one in the
ee923081 129 list if nothing matches. Returns pointer to set that is
2acceee2
JM
130 selected. */
131
132static struct core_fns *
fba45db2 133sniff_core_bfd (bfd *abfd)
2acceee2
JM
134{
135 struct core_fns *cf;
136 struct core_fns *yummy = NULL;
137 int matches = 0;;
138
0e24ac5d
MK
139 /* Don't sniff if we have support for register sets in CORE_GDBARCH. */
140 if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
141 return NULL;
142
2acceee2
JM
143 for (cf = core_file_fns; cf != NULL; cf = cf->next)
144 {
145 if (cf->core_sniffer (cf, abfd))
146 {
147 yummy = cf;
148 matches++;
149 }
150 }
151 if (matches > 1)
152 {
8a3fe4f8 153 warning (_("\"%s\": ambiguous core format, %d handlers match"),
2acceee2
JM
154 bfd_get_filename (abfd), matches);
155 }
156 else if (matches == 0)
157 {
8a3fe4f8 158 warning (_("\"%s\": no core file handler recognizes format, using default"),
2acceee2
JM
159 bfd_get_filename (abfd));
160 }
161 if (yummy == NULL)
162 {
163 yummy = core_file_fns;
164 }
165 return (yummy);
166}
167
168/* The default is to reject every core file format we see. Either
169 BFD has to recognize it, or we have to provide a function in the
170 core file handler that recognizes it. */
171
172int
fba45db2 173default_check_format (bfd *abfd)
2acceee2
JM
174{
175 return (0);
176}
177
178/* Attempt to recognize core file formats that BFD rejects. */
179
020cc13c 180static int
fba45db2 181gdb_check_format (bfd *abfd)
2acceee2
JM
182{
183 struct core_fns *cf;
184
185 for (cf = core_file_fns; cf != NULL; cf = cf->next)
186 {
187 if (cf->check_format (abfd))
188 {
81a9a963 189 return (1);
2acceee2
JM
190 }
191 }
81a9a963 192 return (0);
2acceee2 193}
c906108c
SS
194
195/* Discard all vestiges of any previous core file and mark data and stack
196 spaces as empty. */
197
c906108c 198static void
fba45db2 199core_close (int quitting)
c906108c
SS
200{
201 char *name;
202
203 if (core_bfd)
204 {
39f77062 205 inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */
c906108c 206
7a292a7a 207 /* Clear out solib state while the bfd is still open. See
c5aa993b 208 comments in clear_solib in solib.c. */
7a292a7a
SS
209#ifdef CLEAR_SOLIB
210 CLEAR_SOLIB ();
a77053c2
MK
211#else
212 clear_solib ();
7a292a7a
SS
213#endif
214
c906108c
SS
215 name = bfd_get_filename (core_bfd);
216 if (!bfd_close (core_bfd))
8a3fe4f8 217 warning (_("cannot close \"%s\": %s"),
c906108c 218 name, bfd_errmsg (bfd_get_error ()));
b8c9b27d 219 xfree (name);
c906108c 220 core_bfd = NULL;
c906108c
SS
221 if (core_ops.to_sections)
222 {
b8c9b27d 223 xfree (core_ops.to_sections);
c906108c
SS
224 core_ops.to_sections = NULL;
225 core_ops.to_sections_end = NULL;
226 }
227 }
2acceee2 228 core_vec = NULL;
0e24ac5d 229 core_gdbarch = NULL;
c906108c
SS
230}
231
74b7792f
AC
232static void
233core_close_cleanup (void *ignore)
234{
235 core_close (0/*ignored*/);
236}
237
c906108c
SS
238/* Look for sections whose names start with `.reg/' so that we can extract the
239 list of threads in a core file. */
240
241static void
4efb68b1 242add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
c906108c
SS
243{
244 int thread_id;
245 asection *reg_sect = (asection *) reg_sect_arg;
246
247 if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
248 return;
249
250 thread_id = atoi (bfd_section_name (abfd, asect) + 5);
251
39f77062 252 add_thread (pid_to_ptid (thread_id));
c906108c
SS
253
254/* Warning, Will Robinson, looking at BFD private data! */
255
256 if (reg_sect != NULL
c5aa993b 257 && asect->filepos == reg_sect->filepos) /* Did we find .reg? */
39f77062 258 inferior_ptid = pid_to_ptid (thread_id); /* Yes, make it current */
c906108c
SS
259}
260
261/* This routine opens and sets up the core file bfd. */
262
263static void
fba45db2 264core_open (char *filename, int from_tty)
c906108c
SS
265{
266 const char *p;
267 int siggy;
268 struct cleanup *old_chain;
269 char *temp;
270 bfd *temp_bfd;
271 int ontop;
272 int scratch_chan;
ee28ca0f 273 int flags;
c906108c
SS
274
275 target_preopen (from_tty);
276 if (!filename)
277 {
8a3fe4f8
AC
278 if (core_bfd)
279 error (_("No core file specified. (Use `detach' to stop debugging a core file.)"));
280 else
281 error (_("No core file specified."));
c906108c
SS
282 }
283
284 filename = tilde_expand (filename);
285 if (filename[0] != '/')
286 {
1754f103 287 temp = concat (current_directory, "/", filename, (char *)NULL);
b8c9b27d 288 xfree (filename);
c906108c
SS
289 filename = temp;
290 }
291
b8c9b27d 292 old_chain = make_cleanup (xfree, filename);
c906108c 293
ee28ca0f
AC
294 flags = O_BINARY | O_LARGEFILE;
295 if (write_files)
296 flags |= O_RDWR;
297 else
298 flags |= O_RDONLY;
299 scratch_chan = open (filename, flags, 0);
c906108c
SS
300 if (scratch_chan < 0)
301 perror_with_name (filename);
302
9f76c2cd
MM
303 temp_bfd = bfd_fopen (filename, gnutarget,
304 write_files ? FOPEN_RUB : FOPEN_RB,
305 scratch_chan);
c906108c
SS
306 if (temp_bfd == NULL)
307 perror_with_name (filename);
308
2acceee2
JM
309 if (!bfd_check_format (temp_bfd, bfd_core) &&
310 !gdb_check_format (temp_bfd))
c906108c
SS
311 {
312 /* Do it after the err msg */
313 /* FIXME: should be checking for errors from bfd_close (for one thing,
c5aa993b
JM
314 on error it does not free all the storage associated with the
315 bfd). */
5c65bbb6 316 make_cleanup_bfd_close (temp_bfd);
8a3fe4f8 317 error (_("\"%s\" is not a core dump: %s"),
c906108c
SS
318 filename, bfd_errmsg (bfd_get_error ()));
319 }
320
321 /* Looks semi-reasonable. Toss the old core file and work on the new. */
322
c5aa993b 323 discard_cleanups (old_chain); /* Don't free filename any more */
c906108c
SS
324 unpush_target (&core_ops);
325 core_bfd = temp_bfd;
74b7792f 326 old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
c906108c 327
0e24ac5d
MK
328 /* FIXME: kettenis/20031023: This is very dangerous. The
329 CORE_GDBARCH that results from this call may very well be
330 different from CURRENT_GDBARCH. However, its methods may only
331 work if it is selected as the current architecture, because they
332 rely on swapped data (see gdbarch.c). We should get rid of that
333 swapped data. */
334 core_gdbarch = gdbarch_from_bfd (core_bfd);
335
2acceee2
JM
336 /* Find a suitable core file handler to munch on core_bfd */
337 core_vec = sniff_core_bfd (core_bfd);
338
c906108c
SS
339 validate_files ();
340
341 /* Find the data section */
342 if (build_section_table (core_bfd, &core_ops.to_sections,
343 &core_ops.to_sections_end))
8a3fe4f8 344 error (_("\"%s\": Can't find sections: %s"),
c906108c
SS
345 bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
346
2f1b5984
MK
347 /* If we have no exec file, try to set the architecture from the
348 core file. We don't do this unconditionally since an exec file
349 typically contains more information that helps us determine the
350 architecture than a core file. */
351 if (!exec_bfd)
352 set_gdbarch_from_file (core_bfd);
cbda0a99 353
c906108c
SS
354 ontop = !push_target (&core_ops);
355 discard_cleanups (old_chain);
356
20d2ca3e
AC
357 /* This is done first, before anything has a chance to query the
358 inferior for information such as symbols. */
9353355f 359 post_create_inferior (&core_ops, from_tty);
20d2ca3e 360
c906108c
SS
361 p = bfd_core_file_failing_command (core_bfd);
362 if (p)
a3f17187 363 printf_filtered (_("Core was generated by `%s'.\n"), p);
c906108c
SS
364
365 siggy = bfd_core_file_failing_signal (core_bfd);
366 if (siggy > 0)
8e6a3c35 367 /* NOTE: target_signal_from_host() converts a target signal value
e26cc349 368 into gdb's internal signal value. Unfortunately gdb's internal
8e6a3c35
AC
369 value is called ``target_signal'' and this function got the
370 name ..._from_host(). */
a3f17187 371 printf_filtered (_("Program terminated with signal %d, %s.\n"), siggy,
8e6a3c35 372 target_signal_to_string (target_signal_from_host (siggy)));
c906108c
SS
373
374 /* Build up thread list from BFD sections. */
375
376 init_thread_list ();
377 bfd_map_over_sections (core_bfd, add_to_thread_list,
378 bfd_get_section_by_name (core_bfd, ".reg"));
379
380 if (ontop)
381 {
382 /* Fetch all registers from core file. */
383 target_fetch_registers (-1);
384
c906108c
SS
385 /* Now, set up the frame cache, and print the top of stack. */
386 flush_cached_frames ();
0f7d239c 387 select_frame (get_current_frame ());
b04f3ab4 388 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
c906108c
SS
389 }
390 else
391 {
392 warning (
c5aa993b 393 "you won't be able to access this core file until you terminate\n\
c906108c
SS
394your %s; do ``info files''", target_longname);
395 }
396}
397
398static void
fba45db2 399core_detach (char *args, int from_tty)
c906108c
SS
400{
401 if (args)
8a3fe4f8 402 error (_("Too many arguments"));
c906108c
SS
403 unpush_target (&core_ops);
404 reinit_frame_cache ();
405 if (from_tty)
a3f17187 406 printf_filtered (_("No core file now.\n"));
c906108c
SS
407}
408
de57eccd
JM
409
410/* Try to retrieve registers from a section in core_bfd, and supply
411 them to core_vec->core_read_registers, as the register set numbered
412 WHICH.
413
39f77062
KB
414 If inferior_ptid is zero, do the single-threaded thing: look for a
415 section named NAME. If inferior_ptid is non-zero, do the
de57eccd 416 multi-threaded thing: look for a section named "NAME/PID", where
39f77062 417 PID is the shortest ASCII decimal representation of inferior_ptid.
de57eccd
JM
418
419 HUMAN_NAME is a human-readable name for the kind of registers the
420 NAME section contains, for use in error messages.
421
422 If REQUIRED is non-zero, print an error if the core file doesn't
423 have a section by the appropriate name. Otherwise, just do nothing. */
424
425static void
426get_core_register_section (char *name,
427 int which,
428 char *human_name,
429 int required)
430{
3ecda457 431 static char *section_name = NULL;
7be0c536 432 struct bfd_section *section;
de57eccd
JM
433 bfd_size_type size;
434 char *contents;
435
3ecda457 436 xfree (section_name);
39f77062 437 if (PIDGET (inferior_ptid))
3ecda457 438 section_name = xstrprintf ("%s/%d", name, PIDGET (inferior_ptid));
de57eccd 439 else
3ecda457 440 section_name = xstrdup (name);
de57eccd
JM
441
442 section = bfd_get_section_by_name (core_bfd, section_name);
443 if (! section)
444 {
445 if (required)
8a3fe4f8 446 warning (_("Couldn't find %s registers in core file."), human_name);
de57eccd
JM
447 return;
448 }
449
450 size = bfd_section_size (core_bfd, section);
451 contents = alloca (size);
452 if (! bfd_get_section_contents (core_bfd, section, contents,
453 (file_ptr) 0, size))
454 {
8a3fe4f8 455 warning (_("Couldn't read %s registers from `%s' section in core file."),
de57eccd
JM
456 human_name, name);
457 return;
458 }
459
0e24ac5d
MK
460 if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
461 {
462 const struct regset *regset;
463
464 regset = gdbarch_regset_from_core_section (core_gdbarch, name, size);
465 if (regset == NULL)
466 {
467 if (required)
8a3fe4f8 468 warning (_("Couldn't recognize %s registers in core file."),
0e24ac5d
MK
469 human_name);
470 return;
471 }
472
473 regset->supply_regset (regset, current_regcache, -1, contents, size);
474 return;
475 }
476
477 gdb_assert (core_vec);
e2544d02 478 core_vec->core_read_registers (contents, size, which,
de57eccd
JM
479 ((CORE_ADDR)
480 bfd_section_vma (core_bfd, section)));
481}
482
483
c906108c
SS
484/* Get the registers out of a core file. This is the machine-
485 independent part. Fetch_core_registers is the machine-dependent
486 part, typically implemented in the xm-file for each architecture. */
487
488/* We just get all the registers, so we don't use regno. */
489
c906108c 490static void
fba45db2 491get_core_registers (int regno)
c906108c 492{
de57eccd 493 int status;
c906108c 494
0e24ac5d
MK
495 if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
496 && (core_vec == NULL || core_vec->core_read_registers == NULL))
c906108c
SS
497 {
498 fprintf_filtered (gdb_stderr,
c5aa993b 499 "Can't fetch registers from this type of core file\n");
c906108c
SS
500 return;
501 }
502
de57eccd
JM
503 get_core_register_section (".reg", 0, "general-purpose", 1);
504 get_core_register_section (".reg2", 2, "floating-point", 0);
505 get_core_register_section (".reg-xfp", 3, "extended floating-point", 0);
c906108c 506
2b9e5f3f 507 deprecated_registers_fetched ();
c906108c
SS
508}
509
c906108c 510static void
fba45db2 511core_files_info (struct target_ops *t)
c906108c
SS
512{
513 print_section_info (t, core_bfd);
514}
e2544d02
RM
515\f
516static LONGEST
517core_xfer_partial (struct target_ops *ops, enum target_object object,
961cb7b5
MK
518 const char *annex, gdb_byte *readbuf,
519 const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
e2544d02
RM
520{
521 switch (object)
522 {
523 case TARGET_OBJECT_MEMORY:
524 if (readbuf)
c8e73a31
AC
525 return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
526 0/*write*/, NULL, ops);
e2544d02 527 if (writebuf)
c8e73a31
AC
528 return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
529 1/*write*/, NULL, ops);
e2544d02
RM
530 return -1;
531
532 case TARGET_OBJECT_AUXV:
533 if (readbuf)
534 {
535 /* When the aux vector is stored in core file, BFD
536 represents this with a fake section called ".auxv". */
537
c4c5b7ba 538 struct bfd_section *section;
e2544d02
RM
539 bfd_size_type size;
540 char *contents;
541
542 section = bfd_get_section_by_name (core_bfd, ".auxv");
543 if (section == NULL)
544 return -1;
545
546 size = bfd_section_size (core_bfd, section);
547 if (offset >= size)
548 return 0;
549 size -= offset;
550 if (size > len)
551 size = len;
403e1656
MK
552 if (size > 0
553 && !bfd_get_section_contents (core_bfd, section, readbuf,
554 (file_ptr) offset, size))
e2544d02 555 {
8a3fe4f8 556 warning (_("Couldn't read NT_AUXV note in core file."));
e2544d02
RM
557 return -1;
558 }
559
560 return size;
561 }
562 return -1;
563
403e1656
MK
564 case TARGET_OBJECT_WCOOKIE:
565 if (readbuf)
566 {
567 /* When the StackGhost cookie is stored in core file, BFD
568 represents this with a fake section called ".wcookie". */
569
570 struct bfd_section *section;
571 bfd_size_type size;
572 char *contents;
573
574 section = bfd_get_section_by_name (core_bfd, ".wcookie");
575 if (section == NULL)
576 return -1;
577
578 size = bfd_section_size (core_bfd, section);
579 if (offset >= size)
580 return 0;
581 size -= offset;
582 if (size > len)
583 size = len;
584 if (size > 0
585 && !bfd_get_section_contents (core_bfd, section, readbuf,
586 (file_ptr) offset, size))
587 {
8a3fe4f8 588 warning (_("Couldn't read StackGhost cookie in core file."));
403e1656
MK
589 return -1;
590 }
591
592 return size;
593 }
594 return -1;
595
e2544d02
RM
596 default:
597 if (ops->beneath != NULL)
598 return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
599 readbuf, writebuf, offset, len);
600 return -1;
601 }
602}
603
c906108c
SS
604\f
605/* If mourn is being called in all the right places, this could be say
606 `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
607
608static int
5a168c78 609ignore (CORE_ADDR addr, bfd_byte *contents)
c906108c
SS
610{
611 return 0;
612}
613
614
615/* Okay, let's be honest: threads gleaned from a core file aren't
616 exactly lively, are they? On the other hand, if we don't claim
617 that each & every one is alive, then we don't get any of them
618 to appear in an "info thread" command, which is quite a useful
619 behaviour.
c5aa993b 620 */
c906108c 621static int
39f77062 622core_file_thread_alive (ptid_t tid)
c906108c
SS
623{
624 return 1;
625}
626
627/* Fill in core_ops with its defined operations and properties. */
628
629static void
fba45db2 630init_core_ops (void)
c906108c
SS
631{
632 core_ops.to_shortname = "core";
633 core_ops.to_longname = "Local core dump file";
634 core_ops.to_doc =
635 "Use a core file as a target. Specify the filename of the core file.";
636 core_ops.to_open = core_open;
637 core_ops.to_close = core_close;
638 core_ops.to_attach = find_default_attach;
c906108c 639 core_ops.to_detach = core_detach;
c906108c 640 core_ops.to_fetch_registers = get_core_registers;
e2544d02 641 core_ops.to_xfer_partial = core_xfer_partial;
c8e73a31 642 core_ops.deprecated_xfer_memory = xfer_memory;
c906108c
SS
643 core_ops.to_files_info = core_files_info;
644 core_ops.to_insert_breakpoint = ignore;
645 core_ops.to_remove_breakpoint = ignore;
646 core_ops.to_create_inferior = find_default_create_inferior;
c906108c 647 core_ops.to_thread_alive = core_file_thread_alive;
c906108c
SS
648 core_ops.to_stratum = core_stratum;
649 core_ops.to_has_memory = 1;
650 core_ops.to_has_stack = 1;
651 core_ops.to_has_registers = 1;
c5aa993b 652 core_ops.to_magic = OPS_MAGIC;
c906108c
SS
653}
654
655/* non-zero if we should not do the add_target call in
656 _initialize_corelow; not initialized (i.e., bss) so that
657 the target can initialize it (i.e., data) if appropriate.
658 This needs to be set at compile time because we don't know
659 for sure whether the target's initialize routine is called
660 before us or after us. */
661int coreops_suppress_target;
662
663void
fba45db2 664_initialize_corelow (void)
c906108c
SS
665{
666 init_core_ops ();
667
668 if (!coreops_suppress_target)
669 add_target (&core_ops);
670}
This page took 0.50895 seconds and 4 git commands to generate.