* go32-nat.c (fetch_register): Call i387_supply_fsave instead of
[deliverable/binutils-gdb.git] / gdb / i386-interix-nat.c
CommitLineData
7a7adcdf
JB
1/* Native-dependent code for Interix running on i386's, for GDB.
2 Copyright 2002 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "defs.h"
21
22#include <sys/procfs.h>
23#include <inferior.h>
24#include <fcntl.h>
25
26#include <i386-tdep.h>
27#include "gdb_string.h"
28#include "gdbcore.h"
29#include "gregset.h"
30#include "regcache.h"
31
32typedef unsigned long greg_t;
33
34/* This is a duplicate of the table in i386-linux-nat.c. */
35
36static int regmap[] = {
37 EAX, ECX, EDX, EBX,
38 UESP, EBP, ESI, EDI,
39 EIP, EFL, CS, SS,
40 DS, ES, FS, GS,
41};
42
43/* Forward declarations. */
44extern void _initialize_core_interix (void);
45extern initialize_file_ftype _initialize_core_interix;
46
47/* Given a pointer to a general register set in /proc format (gregset_t *),
48 unpack the register contents and supply them as gdb's idea of the current
49 register values. */
50
51void
52supply_gregset (gregset_t *gregsetp)
53{
54 int regi;
55 greg_t *regp = (greg_t *) & gregsetp->gregs;
56
57 for (regi = 0; regi < I386_NUM_GREGS; regi++)
58 {
59 supply_register (regi, (char *) (regp + regmap[regi]));
60 }
61}
62
63/* Store GDB's value for REGNO in *GREGSETP. If REGNO is -1, do all
64 of them. */
65
66void
67fill_gregset (gregset_t *gregsetp, int regno)
68{
69 int regi;
70 greg_t *regp = (greg_t *) gregsetp->gregs;
71
72 for (regi = 0; regi < I386_NUM_GREGS; regi++)
73 if (regno == -1 || regi == regno)
74 regcache_collect (regi, (void *) (regp + regmap[regi]));
75}
76
77/* Fill GDB's register file with the floating-point register values in
78 *FPREGSETP. */
79
80void
81supply_fpregset (fpregset_t *fpregsetp)
82{
ed504bdf 83 i387_supply_fsave ((const char *) fpregsetp, -1);
7a7adcdf
JB
84}
85
86/* Given a pointer to a floating point register set in (fpregset_t *)
87 format, update all of the registers from gdb's idea of the current
88 floating point register set. */
89
90void
91fill_fpregset (fpregset_t *fpregsetp, int regno)
92{
93 i387_fill_fsave ((char *) fpregsetp, regno);
94}
95
96/* Read the values of either the general register set (WHICH equals 0)
97 or the floating point register set (WHICH equals 2) from the core
98 file data (pointed to by CORE_REG_SECT), and update gdb's idea of
99 their current values. The CORE_REG_SIZE parameter is compared to
100 the size of the gregset or fpgregset structures (as appropriate) to
101 validate the size of the structure from the core file. The
102 REG_ADDR parameter is ignored. */
103
104static void
105fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
106 CORE_ADDR reg_addr)
107{
108 gdb_gregset_t gregset;
109 gdb_fpregset_t fpregset;
110
111 if (which == 0)
112 {
113 if (core_reg_size != sizeof (gregset))
114 {
115 warning ("wrong size gregset struct in core file");
116 }
117 else
118 {
119 memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
120 supply_gregset (&gregset);
121 }
122 }
123 else if (which == 2)
124 {
125 if (core_reg_size != sizeof (fpregset))
126 {
127 warning ("wrong size fpregset struct in core file");
128 }
129 else
130 {
131 memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
132 supply_fpregset (&fpregset);
133 }
134 }
135}
136
137#include <setjmp.h>
138
139static struct core_fns interix_core_fns =
140{
141 bfd_target_coff_flavour, /* core_flavour (more or less) */
142 default_check_format, /* check_format */
143 default_core_sniffer, /* core_sniffer */
144 fetch_core_registers, /* core_read_registers */
145 NULL /* next */
146};
147
148void
149_initialize_core_interix (void)
150{
151 add_core_fns (&interix_core_fns);
152}
153
154/* We don't have a /proc/pid/file or /proc/pid/exe to read a link from,
155 so read it from the same place ps gets the name. */
156
157char *
158child_pid_to_exec_file (int pid)
159{
160 char *path;
161 char *buf;
162 int fd, c;
163 char *p;
164
165 xasprintf (&path, "/proc/%d/stat", pid);
166 buf = xcalloc (MAXPATHLEN + 1, sizeof (char));
167 make_cleanup (xfree, path);
168 make_cleanup (xfree, buf);
169
170 fd = open (path, O_RDONLY);
171
172 if (fd < 0)
173 return NULL;
174
175 /* Skip over "Argv0\t". */
176 lseek (fd, 6, SEEK_SET);
177
178 c = read (fd, buf, MAXPATHLEN);
179 close (fd);
180
181 if (c < 0)
182 return NULL;
183
184 buf[c] = '\0'; /* Ensure null termination. */
185 p = strchr (buf, '\n');
186 if (p != NULL)
187 *p = '\0';
188
189 return buf;
190}
This page took 0.097702 seconds and 4 git commands to generate.