oops - omitted from previous delta
[deliverable/binutils-gdb.git] / gdb / fbsd-nat.c
CommitLineData
578c1c03
MK
1/* Native-dependent code for FreeBSD.
2
9b254dd1 3 Copyright (C) 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
578c1c03
MK
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
578c1c03
MK
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
578c1c03
MK
19
20#include "defs.h"
21#include "gdbcore.h"
22#include "inferior.h"
23#include "regcache.h"
24#include "regset.h"
25
26#include "gdb_assert.h"
27#include "gdb_string.h"
578c1c03 28#include <sys/types.h>
68b9939a
MK
29#include <sys/procfs.h>
30#include <sys/sysctl.h>
578c1c03
MK
31
32#include "elf-bfd.h"
33#include "fbsd-nat.h"
34
35/* Return a the name of file that can be opened to get the symbols for
36 the child process identified by PID. */
37
38char *
39fbsd_pid_to_exec_file (int pid)
40{
68b9939a
MK
41 size_t len = MAXPATHLEN;
42 char *buf = xcalloc (len, sizeof (char));
578c1c03 43 char *path;
578c1c03 44
68b9939a
MK
45#ifdef KERN_PROC_PATHNAME
46 int mib[4];
578c1c03 47
68b9939a
MK
48 mib[0] = CTL_KERN;
49 mib[1] = KERN_PROC;
50 mib[2] = KERN_PROC_PATHNAME;
51 mib[3] = pid;
52 if (sysctl (mib, 4, buf, &len, NULL, 0) == 0)
578c1c03 53 return buf;
68b9939a 54#endif
578c1c03 55
68b9939a
MK
56 path = xstrprintf ("/proc/%d/file", pid);
57 if (readlink (path, buf, MAXPATHLEN) == -1)
58 {
59 xfree (buf);
60 buf = NULL;
61 }
62
63 xfree (path);
64 return buf;
578c1c03
MK
65}
66
67static int
68fbsd_read_mapping (FILE *mapfile, unsigned long *start, unsigned long *end,
69 char *protection)
70{
71 /* FreeBSD 5.1-RELEASE uses a 256-byte buffer. */
72 char buf[256];
73 int resident, privateresident;
74 unsigned long obj;
75 int ret = EOF;
76
77 /* As of FreeBSD 5.0-RELEASE, the layout is described in
78 /usr/src/sys/fs/procfs/procfs_map.c. Somewhere in 5.1-CURRENT a
79 new column was added to the procfs map. Therefore we can't use
80 fscanf since we need to support older releases too. */
81 if (fgets (buf, sizeof buf, mapfile) != NULL)
82 ret = sscanf (buf, "%lx %lx %d %d %lx %s", start, end,
83 &resident, &privateresident, &obj, protection);
84
85 return (ret != 0 && ret != EOF);
86}
87
88/* Iterate over all the memory regions in the current inferior,
89 calling FUNC for each memory region. OBFD is passed as the last
90 argument to FUNC. */
91
92int
93fbsd_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
94 int, int, int, void *),
95 void *obfd)
96{
97 pid_t pid = ptid_get_pid (inferior_ptid);
98 char *mapfilename;
99 FILE *mapfile;
100 unsigned long start, end, size;
101 char protection[4];
102 int read, write, exec;
103
104 mapfilename = xstrprintf ("/proc/%ld/map", (long) pid);
105 mapfile = fopen (mapfilename, "r");
106 if (mapfile == NULL)
8a3fe4f8 107 error (_("Couldn't open %s."), mapfilename);
578c1c03
MK
108
109 if (info_verbose)
110 fprintf_filtered (gdb_stdout,
111 "Reading memory regions from %s\n", mapfilename);
112
113 /* Now iterate until end-of-file. */
114 while (fbsd_read_mapping (mapfile, &start, &end, &protection[0]))
115 {
116 size = end - start;
117
118 read = (strchr (protection, 'r') != 0);
119 write = (strchr (protection, 'w') != 0);
120 exec = (strchr (protection, 'x') != 0);
121
122 if (info_verbose)
123 {
124 fprintf_filtered (gdb_stdout,
125 "Save segment, %ld bytes at 0x%s (%c%c%c)\n",
126 size, paddr_nz (start),
127 read ? 'r' : '-',
128 write ? 'w' : '-',
129 exec ? 'x' : '-');
130 }
131
132 /* Invoke the callback function to create the corefile segment. */
133 func (start, size, read, write, exec, obfd);
134 }
135
136 fclose (mapfile);
137 return 0;
138}
139
140/* Create appropriate note sections for a corefile, returning them in
141 allocated memory. */
142
143char *
144fbsd_make_corefile_notes (bfd *obfd, int *note_size)
145{
594f7785 146 const struct regcache *regcache = get_current_regcache ();
9970f04b 147 struct gdbarch *gdbarch = get_regcache_arch (regcache);
578c1c03
MK
148 gregset_t gregs;
149 fpregset_t fpregs;
150 char *note_data = NULL;
151 Elf_Internal_Ehdr *i_ehdrp;
152 const struct regset *regset;
153 size_t size;
154
155 /* Put a "FreeBSD" label in the ELF header. */
156 i_ehdrp = elf_elfheader (obfd);
157 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
158
159 gdb_assert (gdbarch_regset_from_core_section_p (gdbarch));
160
161 size = sizeof gregs;
162 regset = gdbarch_regset_from_core_section (gdbarch, ".reg", size);
163 gdb_assert (regset && regset->collect_regset);
164 regset->collect_regset (regset, regcache, -1, &gregs, size);
165
166 note_data = elfcore_write_prstatus (obfd, note_data, note_size,
167 ptid_get_pid (inferior_ptid),
168 stop_signal, &gregs);
169
170 size = sizeof fpregs;
171 regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
172 gdb_assert (regset && regset->collect_regset);
173 regset->collect_regset (regset, regcache, -1, &fpregs, size);
174
175 note_data = elfcore_write_prfpreg (obfd, note_data, note_size,
176 &fpregs, sizeof (fpregs));
177
178 if (get_exec_file (0))
179 {
180 char *fname = strrchr (get_exec_file (0), '/') + 1;
181 char *psargs = xstrdup (fname);
182
183 if (get_inferior_args ())
184 psargs = reconcat (psargs, psargs, " ", get_inferior_args (), NULL);
185
186 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
187 fname, psargs);
188 }
189
190 make_cleanup (xfree, note_data);
191 return note_data;
192}
This page took 0.382021 seconds and 4 git commands to generate.