Support fusion for ELFv2 stubs
[deliverable/binutils-gdb.git] / gdb / fbsd-nat.c
CommitLineData
578c1c03
MK
1/* Native-dependent code for FreeBSD.
2
ecd75fc8 3 Copyright (C) 2002-2014 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 *
8dd27370 40fbsd_pid_to_exec_file (struct target_ops *self, int pid)
578c1c03 41{
b4ab256d
HZ
42 ssize_t len = PATH_MAX;
43 static char buf[PATH_MAX];
44 char name[PATH_MAX];
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
b4ab256d
HZ
57 xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid);
58 len = readlink (name, buf, PATH_MAX - 1);
59 if (len != -1)
68b9939a 60 {
b4ab256d
HZ
61 buf[len] = '\0';
62 return buf;
68b9939a
MK
63 }
64
b4ab256d 65 return NULL;
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
2e73927c
TT
94fbsd_find_memory_regions (struct target_ops *self,
95 find_memory_region_ftype func, void *obfd)
578c1c03
MK
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;
7c8a8b04 103 struct cleanup *cleanup;
578c1c03
MK
104
105 mapfilename = xstrprintf ("/proc/%ld/map", (long) pid);
7c8a8b04 106 cleanup = make_cleanup (xfree, mapfilename);
578c1c03
MK
107 mapfile = fopen (mapfilename, "r");
108 if (mapfile == NULL)
8a3fe4f8 109 error (_("Couldn't open %s."), mapfilename);
7c8a8b04 110 make_cleanup_fclose (mapfile);
578c1c03
MK
111
112 if (info_verbose)
113 fprintf_filtered (gdb_stdout,
114 "Reading memory regions from %s\n", mapfilename);
115
116 /* Now iterate until end-of-file. */
117 while (fbsd_read_mapping (mapfile, &start, &end, &protection[0]))
118 {
119 size = end - start;
120
121 read = (strchr (protection, 'r') != 0);
122 write = (strchr (protection, 'w') != 0);
123 exec = (strchr (protection, 'x') != 0);
124
125 if (info_verbose)
126 {
127 fprintf_filtered (gdb_stdout,
5af949e3 128 "Save segment, %ld bytes at %s (%c%c%c)\n",
f5656ead 129 size, paddress (target_gdbarch (), start),
578c1c03
MK
130 read ? 'r' : '-',
131 write ? 'w' : '-',
132 exec ? 'x' : '-');
133 }
134
4f69f4c2
JK
135 /* Invoke the callback function to create the corefile segment.
136 Pass MODIFIED as true, we do not know the real modification state. */
137 func (start, size, read, write, exec, 1, obfd);
578c1c03
MK
138 }
139
7c8a8b04 140 do_cleanups (cleanup);
578c1c03
MK
141 return 0;
142}
143
2020b7ab
PA
144static int
145find_signalled_thread (struct thread_info *info, void *data)
146{
a493e3e2 147 if (info->suspend.stop_signal != GDB_SIGNAL_0
2020b7ab
PA
148 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
149 return 1;
150
151 return 0;
152}
153
2ea28649 154static enum gdb_signal
2020b7ab
PA
155find_stop_signal (void)
156{
157 struct thread_info *info =
158 iterate_over_threads (find_signalled_thread, NULL);
159
160 if (info)
16c381f0 161 return info->suspend.stop_signal;
2020b7ab 162 else
a493e3e2 163 return GDB_SIGNAL_0;
2020b7ab
PA
164}
165
578c1c03
MK
166/* Create appropriate note sections for a corefile, returning them in
167 allocated memory. */
168
169char *
fc6691b2 170fbsd_make_corefile_notes (struct target_ops *self, bfd *obfd, int *note_size)
578c1c03 171{
594f7785 172 const struct regcache *regcache = get_current_regcache ();
9970f04b 173 struct gdbarch *gdbarch = get_regcache_arch (regcache);
578c1c03
MK
174 gregset_t gregs;
175 fpregset_t fpregs;
176 char *note_data = NULL;
177 Elf_Internal_Ehdr *i_ehdrp;
178 const struct regset *regset;
179 size_t size;
180
181 /* Put a "FreeBSD" label in the ELF header. */
182 i_ehdrp = elf_elfheader (obfd);
183 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
184
185 gdb_assert (gdbarch_regset_from_core_section_p (gdbarch));
186
187 size = sizeof gregs;
188 regset = gdbarch_regset_from_core_section (gdbarch, ".reg", size);
189 gdb_assert (regset && regset->collect_regset);
190 regset->collect_regset (regset, regcache, -1, &gregs, size);
191
192 note_data = elfcore_write_prstatus (obfd, note_data, note_size,
193 ptid_get_pid (inferior_ptid),
2020b7ab 194 find_stop_signal (), &gregs);
578c1c03
MK
195
196 size = sizeof fpregs;
197 regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", size);
198 gdb_assert (regset && regset->collect_regset);
199 regset->collect_regset (regset, regcache, -1, &fpregs, size);
200
201 note_data = elfcore_write_prfpreg (obfd, note_data, note_size,
202 &fpregs, sizeof (fpregs));
203
204 if (get_exec_file (0))
205 {
6d6c6b1f 206 const char *fname = lbasename (get_exec_file (0));
578c1c03
MK
207 char *psargs = xstrdup (fname);
208
209 if (get_inferior_args ())
3f1f6884
JK
210 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
211 (char *) NULL);
578c1c03
MK
212
213 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
214 fname, psargs);
215 }
216
217 make_cleanup (xfree, note_data);
218 return note_data;
219}
This page took 0.789609 seconds and 4 git commands to generate.