Make writing to files work properly. (Fixes to BFD are also needed.)

* core.c (core_open):  Open file ourselves, read or r/w, depending on
write_files.  Use bfd_fdopenr.
* gdbcore.h (write_files):  New variable.
* exec.c (write_files):  Define variable, add set&show for it.
(exec_file_command):  Use write_files to open for read or r/write.

Make shared library reading happen automatically.  These changes
are mostly from Peter Schauer <pes@regent.e-technik.tu-muenchen.de>.

* inferior.h (stop_soon_quietly):  Add to exported variables.
* infrun.c (child_create_inferior):  call solib hook, if defined.
(child_attach):  call solib hook, if defined.
* solib.c:  Include inferior.h.  Add from_tty to so_list as kludge.
(find_solib):  Use lookup_misc_func rather than hand-rolled.
(symbol_add_stub):  New stub for catch_errors.
(solib_add):  Avoid output if !from_tty.  Catch errors rather
than just calling symbol_file_add and bombing.
(solib_create_inferior_hook):  Interface with the target process
to let it read and alloc shared libs, then figure out what it did.

* core.c (validate_files):  Fix typo, soften warning.
(Fix from Hiroto Kagotani <kagotani@cs.titech.ac.jp>.)

* utils.c (fputs_demangled):  Avoid duplicate printing if
demangling is off.  (Fix from J.T. Conklin <jtc@cayenne.com>.)

* infrun.c (proceed):  Cast -1 to (CORE_ADDR) before comparing.
(Fix from pierre@la.tce.com (Pierre Willard).)

* main.c (catch_errors):  Change argument to a char * from an int,
since a char * can point to a struct full of glop, but an int
is not guaranteed to be able to hold a pointer.
* breakpoint.c (breakpoint_cond_eval, bpstat_stop_status,
breakpoint_re_set_one, breakpoint_re_set):  Adapt.
* core.c (core_open, solib_add_stub):  Adapt.
* remote-vx.c (symbol_stub, add_symbol_stub, callers):  Adapt.
This commit is contained in:
John Gilmore
1991-09-04 07:43:50 +00:00
parent 7c589d2562
commit bdbd5f5086
11 changed files with 454 additions and 271 deletions

View File

@@ -3,19 +3,19 @@
This file is part of GDB.
GDB is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GDB is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GDB; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "defs.h"
@@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "frame.h"
#include "inferior.h"
#include "target.h"
#include "gdbcmd.h"
#ifdef USG
#include <sys/types.h>
@@ -30,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/param.h>
#include <fcntl.h>
#include <string.h>
#include "gdbcore.h"
@@ -44,21 +46,21 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern char *getenv();
extern void child_create_inferior (), child_attach ();
extern void add_syms_addr_command ();
extern void symbol_file_command ();
/* The Binary File Descriptor handle for the executable file. */
bfd *exec_bfd = NULL;
/* The base and bounds of the table of the exec file's sections. */
/* Whether to open exec and core files read-only or read-write. */
struct section_table *exec_sections, *exec_sections_end;
int write_files = 0;
/* Forward decl */
extern struct target_ops exec_ops;
/* ARGSUSED */
void
exec_close (quitting)
int quitting;
@@ -67,6 +69,11 @@ exec_close (quitting)
bfd_close (exec_bfd);
exec_bfd = NULL;
}
if (exec_ops.sections) {
free (exec_ops.sections);
exec_ops.sections = NULL;
exec_ops.sections_end = NULL;
}
}
void
@@ -89,8 +96,8 @@ exec_file_command (filename, from_tty)
filename = tilde_expand (filename);
make_cleanup (free, filename);
/* FIXME, if writeable is set, open for read/write. */
scratch_chan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
scratch_chan = openp (getenv ("PATH"), 1, filename,
write_files? O_RDWR: O_RDONLY, 0,
&scratch_pathname);
if (scratch_chan < 0)
perror_with_name (filename);
@@ -131,7 +138,8 @@ exec_file_command (filename, from_tty)
}
#endif FIXME
if (build_section_table (exec_bfd, &exec_sections, &exec_sections_end))
if (build_section_table (exec_bfd, &exec_ops.sections,
&exec_ops.sections_end))
error ("Can't find the file sections in `%s': %s",
exec_bfd->filename, bfd_errmsg (bfd_error));
@@ -163,20 +171,24 @@ file_command (arg, from_tty)
}
/* Locate all mappable sections of a BFD file. */
/* Locate all mappable sections of a BFD file.
table_pp_char is a char * to get it through bfd_map_over_sections;
we cast it back to its proper type. */
void
add_to_section_table (abfd, asect, table_pp)
add_to_section_table (abfd, asect, table_pp_char)
bfd *abfd;
sec_ptr asect;
struct section_table **table_pp;
char *table_pp_char;
{
struct section_table **table_pp = (struct section_table **)table_pp_char;
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
/* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */
if (!(aflag & SEC_LOAD))
return;
(*table_pp)->bfd = abfd;
(*table_pp)->sec_ptr = asect;
(*table_pp)->addr = bfd_section_vma (abfd, asect);
(*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
@@ -197,7 +209,7 @@ build_section_table (some_bfd, start, end)
free (*start);
*start = (struct section_table *) xmalloc (count * sizeof (**start));
*end = *start;
bfd_map_over_sections (some_bfd, add_to_section_table, end);
bfd_map_over_sections (some_bfd, add_to_section_table, (char *)end);
if (*end > *start + count)
abort();
/* We could realloc the table, but it probably loses for most files. */
@@ -206,7 +218,7 @@ build_section_table (some_bfd, start, end)
/* Read or write the exec file.
Args are address within exec file, address within gdb address-space,
Args are address within a BFD file, address within gdb address-space,
length, and a flag indicating whether to read or write.
Result is a length:
@@ -223,13 +235,12 @@ build_section_table (some_bfd, start, end)
we just tail-call it with more arguments to select between them. */
int
xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
xfer_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
bfd *abfd;
struct section_table *sections, *sections_end;
struct target_ops *target;
{
boolean res;
struct section_table *p;
@@ -243,13 +254,13 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents;
nextsectaddr = memend;
for (p = sections; p < sections_end; p++)
for (p = target->sections; p < target->sections_end; p++)
{
if (p->addr <= memaddr)
if (p->endaddr >= memend)
{
/* Entire transfer is within this section. */
res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
return (res != false)? len: 0;
}
else if (p->endaddr <= memaddr)
@@ -261,7 +272,7 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
{
/* This section overlaps the transfer. Just do half. */
len = p->endaddr - memaddr;
res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
return (res != false)? len: 0;
}
else if (p->addr < nextsectaddr)
@@ -274,20 +285,6 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
return - (nextsectaddr - memaddr); /* Next boundary where we can help */
}
/* The function called by target_xfer_memory via our target_ops */
int
exec_xfer_memory (memaddr, myaddr, len, write)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
{
return xfer_memory (memaddr, myaddr, len, write,
exec_bfd, exec_sections, exec_sections_end);
}
#ifdef FIXME
#ifdef REG_STACK_SEGMENT
/* MOVE TO BFD... */
@@ -310,7 +307,7 @@ exec_files_info ()
printf ("\tExecutable file `%s'.\n", bfd_get_filename(exec_bfd));
for (p = exec_sections; p < exec_sections_end; p++)
for (p = exec_ops.sections; p < exec_ops.sections_end; p++)
printf("\texecutable from 0x%08x to 0x%08x is %s\n",
p->addr, p->endaddr,
bfd_section_name (exec_bfd, p->sec_ptr));
@@ -338,7 +335,7 @@ set_section_command (args, from_tty)
/* Parse out new virtual address */
secaddr = parse_and_eval_address (args);
for (p = exec_sections; p < exec_sections_end; p++) {
for (p = exec_ops.sections; p < exec_ops.sections_end; p++) {
if (!strncmp (secname, bfd_section_name (exec_bfd, p->sec_ptr), seclen)
&& bfd_section_name (exec_bfd, p->sec_ptr)[seclen] == '\0') {
offset = secaddr - p->addr;
@@ -363,16 +360,16 @@ Specify the filename of the executable file.",
child_attach, 0, 0, 0, /* attach, detach, resume, wait, */
0, 0, /* fetch_registers, store_registers, */
0, 0, 0, /* prepare_to_store, conv_to, conv_from, */
exec_xfer_memory, exec_files_info,
xfer_memory, exec_files_info,
0, 0, /* insert_breakpoint, remove_breakpoint, */
0, 0, 0, 0, 0, /* terminal stuff */
0, 0, /* kill, load */
add_syms_addr_command,
0, 0, /* call fn, lookup sym */
child_create_inferior,
0, /* mourn_inferior */
file_stratum, 0, /* next */
0, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */
0, 0, /* section pointers */
OPS_MAGIC, /* Always the last thing */
};
@@ -401,5 +398,11 @@ This can be used if the exec file does not contain section addresses,\n\
file itself are wrong. Each section must be changed separately. The\n\
``info files'' command lists all the sections and their addresses.");
add_show_from_set
(add_set_cmd ("write", class_support, var_boolean, (char *)&write_files,
"Set writing into executable and core files.",
&setlist),
&showlist);
add_target (&exec_ops);
}