libiberty/md5: fix strict alias warnings
[deliverable/binutils-gdb.git] / gdb / fbsd-nat.c
CommitLineData
578c1c03
MK
1/* Native-dependent code for FreeBSD.
2
0b302171 3 Copyright (C) 2002-2004, 2007-2012 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"
28#include "gdb_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{
68b9939a
MK
42 size_t len = MAXPATHLEN;
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
MK
57 path = xstrprintf ("/proc/%d/file", pid);
58 if (readlink (path, buf, MAXPATHLEN) == -1)
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
UW
127 "Save segment, %ld bytes at %s (%c%c%c)\n",
128 size, paddress (target_gdbarch, start),
578c1c03
MK
129 read ? 'r' : '-',
130 write ? 'w' : '-',
131 exec ? 'x' : '-');
132 }
133
394b0adb 134 /* Invoke the callback function to create the corefile segment. */
578c1c03
MK
135 func (start, size, read, write, exec, obfd);
136 }
137
7c8a8b04 138 do_cleanups (cleanup);
578c1c03
MK
139 return 0;
140}
141
2020b7ab
PA
142static int
143find_signalled_thread (struct thread_info *info, void *data)
144{
a493e3e2 145 if (info->suspend.stop_signal != GDB_SIGNAL_0
2020b7ab
PA
146 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
147 return 1;
148
149 return 0;
150}
151
2ea28649 152static enum gdb_signal
2020b7ab
PA
153find_stop_signal (void)
154{
155 struct thread_info *info =
156 iterate_over_threads (find_signalled_thread, NULL);
157
158 if (info)
16c381f0 159 return info->suspend.stop_signal;
2020b7ab 160 else
a493e3e2 161 return GDB_SIGNAL_0;
2020b7ab
PA
162}
163
578c1c03
MK
164/* Create appropriate note sections for a corefile, returning them in
165 allocated memory. */
166
167char *
168fbsd_make_corefile_notes (bfd *obfd, int *note_size)
169{
594f7785 170 const struct regcache *regcache = get_current_regcache ();
9970f04b 171 struct gdbarch *gdbarch = get_regcache_arch (regcache);
578c1c03
MK
172 gregset_t gregs;
173 fpregset_t fpregs;
174 char *note_data = NULL;
175 Elf_Internal_Ehdr *i_ehdrp;
176 const struct regset *regset;
177 size_t size;
178
179 /* Put a "FreeBSD" label in the ELF header. */
180 i_ehdrp = elf_elfheader (obfd);
181 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
182
183 gdb_assert (gdbarch_regset_from_core_section_p (gdbarch));
184
185 size = sizeof gregs;
186 regset = gdbarch_regset_from_core_section (gdbarch, ".reg", size);
187 gdb_assert (regset && regset->collect_regset);
188 regset->collect_regset (regset, regcache, -1, &gregs, size);
189
190 note_data = elfcore_write_prstatus (obfd, note_data, note_size,
191 ptid_get_pid (inferior_ptid),
2020b7ab 192 find_stop_signal (), &gregs);
578c1c03
MK
193
194 size = sizeof fpregs;
195 regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
196 gdb_assert (regset && regset->collect_regset);
197 regset->collect_regset (regset, regcache, -1, &fpregs, size);
198
199 note_data = elfcore_write_prfpreg (obfd, note_data, note_size,
200 &fpregs, sizeof (fpregs));
201
202 if (get_exec_file (0))
203 {
6d6c6b1f 204 const char *fname = lbasename (get_exec_file (0));
578c1c03
MK
205 char *psargs = xstrdup (fname);
206
207 if (get_inferior_args ())
3f1f6884
JK
208 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
209 (char *) NULL);
578c1c03
MK
210
211 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
212 fname, psargs);
213 }
214
215 make_cleanup (xfree, note_data);
216 return note_data;
217}
This page took 0.567391 seconds and 4 git commands to generate.