* config/tc-xtensa.c (xtensa_mark_literal_pool_location): Remove
[deliverable/binutils-gdb.git] / gdb / i386-interix-nat.c
1 /* Native-dependent code for Interix running on i386's, for GDB.
2 Copyright 2002 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 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
32 typedef unsigned long greg_t;
33
34 /* This is a duplicate of the table in i386-linux-nat.c. */
35
36 static 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. */
44 extern void _initialize_core_interix (void);
45 extern 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
51 void
52 supply_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
66 void
67 fill_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
80 void
81 supply_fpregset (fpregset_t *fpregsetp)
82 {
83 i387_supply_fsave ((const char *) fpregsetp, -1);
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
90 void
91 fill_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
104 static void
105 fetch_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
139 static 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
148 void
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
157 char *
158 child_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.033988 seconds and 4 git commands to generate.