]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/fbsd-nat.c
remove gdb_string.h
[thirdparty/binutils-gdb.git] / gdb / fbsd-nat.c
CommitLineData
578c1c03
MK
1/* Native-dependent code for FreeBSD.
2
28e7fd62 3 Copyright (C) 2002-2013 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"
2020b7ab 25#include "gdbthread.h"
578c1c03
MK
26
27#include "gdb_assert.h"
0e9f083f 28#include <string.h>
578c1c03 29#include <sys/types.h>
68b9939a
MK
30#include <sys/procfs.h>
31#include <sys/sysctl.h>
578c1c03
MK
32
33#include "elf-bfd.h"
34#include "fbsd-nat.h"
35
766062f6 36/* Return the name of a file that can be opened to get the symbols for
578c1c03
MK
37 the child process identified by PID. */
38
39char *
40fbsd_pid_to_exec_file (int pid)
41{
d8d2a3ee 42 size_t len = PATH_MAX;
68b9939a 43 char *buf = xcalloc (len, sizeof (char));
578c1c03 44 char *path;
578c1c03 45
68b9939a
MK
46#ifdef KERN_PROC_PATHNAME
47 int mib[4];
578c1c03 48
68b9939a
MK
49 mib[0] = CTL_KERN;
50 mib[1] = KERN_PROC;
51 mib[2] = KERN_PROC_PATHNAME;
52 mib[3] = pid;
53 if (sysctl (mib, 4, buf, &len, NULL, 0) == 0)
578c1c03 54 return buf;
68b9939a 55#endif
578c1c03 56
68b9939a 57 path = xstrprintf ("/proc/%d/file", pid);
d8d2a3ee 58 if (readlink (path, buf, PATH_MAX - 1) == -1)
68b9939a
MK
59 {
60 xfree (buf);
61 buf = NULL;
62 }
63
64 xfree (path);
65 return buf;
578c1c03
MK
66}
67
68static int
69fbsd_read_mapping (FILE *mapfile, unsigned long *start, unsigned long *end,
70 char *protection)
71{
72 /* FreeBSD 5.1-RELEASE uses a 256-byte buffer. */
73 char buf[256];
74 int resident, privateresident;
75 unsigned long obj;
76 int ret = EOF;
77
78 /* As of FreeBSD 5.0-RELEASE, the layout is described in
79 /usr/src/sys/fs/procfs/procfs_map.c. Somewhere in 5.1-CURRENT a
80 new column was added to the procfs map. Therefore we can't use
81 fscanf since we need to support older releases too. */
82 if (fgets (buf, sizeof buf, mapfile) != NULL)
83 ret = sscanf (buf, "%lx %lx %d %d %lx %s", start, end,
84 &resident, &privateresident, &obj, protection);
85
86 return (ret != 0 && ret != EOF);
87}
88
89/* Iterate over all the memory regions in the current inferior,
90 calling FUNC for each memory region. OBFD is passed as the last
91 argument to FUNC. */
92
93int
b8edc417 94fbsd_find_memory_regions (find_memory_region_ftype func, void *obfd)
578c1c03
MK
95{
96 pid_t pid = ptid_get_pid (inferior_ptid);
97 char *mapfilename;
98 FILE *mapfile;
99 unsigned long start, end, size;
100 char protection[4];
101 int read, write, exec;
7c8a8b04 102 struct cleanup *cleanup;
578c1c03
MK
103
104 mapfilename = xstrprintf ("/proc/%ld/map", (long) pid);
7c8a8b04 105 cleanup = make_cleanup (xfree, mapfilename);
578c1c03
MK
106 mapfile = fopen (mapfilename, "r");
107 if (mapfile == NULL)
8a3fe4f8 108 error (_("Couldn't open %s."), mapfilename);
7c8a8b04 109 make_cleanup_fclose (mapfile);
578c1c03
MK
110
111 if (info_verbose)
112 fprintf_filtered (gdb_stdout,
113 "Reading memory regions from %s\n", mapfilename);
114
115 /* Now iterate until end-of-file. */
116 while (fbsd_read_mapping (mapfile, &start, &end, &protection[0]))
117 {
118 size = end - start;
119
120 read = (strchr (protection, 'r') != 0);
121 write = (strchr (protection, 'w') != 0);
122 exec = (strchr (protection, 'x') != 0);
123
124 if (info_verbose)
125 {
126 fprintf_filtered (gdb_stdout,
5af949e3 127 "Save segment, %ld bytes at %s (%c%c%c)\n",
f5656ead 128 size, paddress (target_gdbarch (), start),
578c1c03
MK
129 read ? 'r' : '-',
130 write ? 'w' : '-',
131 exec ? 'x' : '-');
132 }
133
4f69f4c2
JK
134 /* Invoke the callback function to create the corefile segment.
135 Pass MODIFIED as true, we do not know the real modification state. */
136 func (start, size, read, write, exec, 1, obfd);
578c1c03
MK
137 }
138
7c8a8b04 139 do_cleanups (cleanup);
578c1c03
MK
140 return 0;
141}
142
2020b7ab
PA
143static int
144find_signalled_thread (struct thread_info *info, void *data)
145{
a493e3e2 146 if (info->suspend.stop_signal != GDB_SIGNAL_0
2020b7ab
PA
147 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
148 return 1;
149
150 return 0;
151}
152
2ea28649 153static enum gdb_signal
2020b7ab
PA
154find_stop_signal (void)
155{
156 struct thread_info *info =
157 iterate_over_threads (find_signalled_thread, NULL);
158
159 if (info)
16c381f0 160 return info->suspend.stop_signal;
2020b7ab 161 else
a493e3e2 162 return GDB_SIGNAL_0;
2020b7ab
PA
163}
164
578c1c03
MK
165/* Create appropriate note sections for a corefile, returning them in
166 allocated memory. */
167
168char *
169fbsd_make_corefile_notes (bfd *obfd, int *note_size)
170{
594f7785 171 const struct regcache *regcache = get_current_regcache ();
9970f04b 172 struct gdbarch *gdbarch = get_regcache_arch (regcache);
578c1c03
MK
173 gregset_t gregs;
174 fpregset_t fpregs;
175 char *note_data = NULL;
176 Elf_Internal_Ehdr *i_ehdrp;
177 const struct regset *regset;
178 size_t size;
179
180 /* Put a "FreeBSD" label in the ELF header. */
181 i_ehdrp = elf_elfheader (obfd);
182 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
183
184 gdb_assert (gdbarch_regset_from_core_section_p (gdbarch));
185
186 size = sizeof gregs;
187 regset = gdbarch_regset_from_core_section (gdbarch, ".reg", size);
188 gdb_assert (regset && regset->collect_regset);
189 regset->collect_regset (regset, regcache, -1, &gregs, size);
190
191 note_data = elfcore_write_prstatus (obfd, note_data, note_size,
192 ptid_get_pid (inferior_ptid),
2020b7ab 193 find_stop_signal (), &gregs);
578c1c03
MK
194
195 size = sizeof fpregs;
196 regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
197 gdb_assert (regset && regset->collect_regset);
198 regset->collect_regset (regset, regcache, -1, &fpregs, size);
199
200 note_data = elfcore_write_prfpreg (obfd, note_data, note_size,
201 &fpregs, sizeof (fpregs));
202
203 if (get_exec_file (0))
204 {
6d6c6b1f 205 const char *fname = lbasename (get_exec_file (0));
578c1c03
MK
206 char *psargs = xstrdup (fname);
207
208 if (get_inferior_args ())
3f1f6884
JK
209 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
210 (char *) NULL);
578c1c03
MK
211
212 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
213 fname, psargs);
214 }
215
216 make_cleanup (xfree, note_data);
217 return note_data;
218}