* mn10300.igen (OP_F0F4): Need to load contents of register AN0
[platform/upstream/binutils.git] / gdb / mac-nat.c
1 /* Target-vector operations for controlling Mac applications, for GDB.
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Written by Stan Shebs.  Contributed by Cygnus Support.
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
9 the Free Software Foundation; either version 2 of the License, or
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 eve nthe 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
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* Note that because all the available Mac compilers are ANSI or very
22    close, and this is a native-only file, the code may be purely ANSI.  */
23
24 #include "defs.h"
25 #include "frame.h"              /* required by inferior.h */
26 #include "inferior.h"
27 #include "target.h"
28 #include "wait.h"
29 #include "gdbcore.h"
30 #include "command.h"
31 #include <signal.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34 #include "buildsym.h"
35 #include "gdb_string.h"
36 #include "gdbthread.h"
37 #include "gdbcmd.h"
38
39 #include <Processes.h>
40
41 /* We call the functions "child_..." rather than "mac_..." so no one
42    is tempted to try to link this with other native-only code.  */
43
44 /* Forward declaration */
45
46 extern struct target_ops child_ops;
47
48 static void child_stop PARAMS ((void));
49
50 static void
51 child_fetch_inferior_registers (int r)
52 {
53   if (r < 0)
54     {
55       for (r = 0; r < NUM_REGS; r++)
56         child_fetch_inferior_registers (r);
57     }
58   else
59     {
60       supply_register (r, 0);
61     }
62 }
63
64 static void
65 child_store_inferior_registers (int r)
66 {
67   if (r < 0)
68     {
69       for (r = 0; r < NUM_REGS; r++)
70         child_store_inferior_registers (r);
71     }
72   else
73     {
74       read_register_gen (r, 0);
75     }
76 }
77
78 static int
79 child_wait (int pid, struct target_waitstatus *ourstatus)
80 {
81 }
82
83 /* Attach to process PID, then initialize for debugging it.  */
84
85 static void
86 child_attach (args, from_tty)
87      char *args;
88      int from_tty;
89 {
90   ProcessSerialNumber psn;
91   ProcessInfoRec inforec;
92   Str31 name;
93   FSSpecPtr fsspec;
94   OSType code;
95   int pid;
96   char *exec_file;
97
98   if (!args)
99     error_no_arg ("process-id to attach");
100
101   pid = atoi (args);
102
103   psn.highLongOfPSN = 0;
104   psn.lowLongOfPSN = pid;
105
106   inforec.processInfoLength = sizeof(ProcessInfoRec);
107   inforec.processName = name;
108   inforec.processAppSpec = fsspec;
109
110   if (GetProcessInformation (&psn, &inforec) == noErr)
111     {
112       if (from_tty)
113         {
114           exec_file = (char *) get_exec_file (0);
115
116           if (exec_file)
117             printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
118                                target_pid_to_str (pid));
119           else
120             printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
121
122           gdb_flush (gdb_stdout);
123         }
124       /* Do we need to do anything special? */
125       attach_flag = 1;
126       inferior_pid = pid;
127       push_target (&child_ops);
128     }
129 }
130
131 static void
132 child_detach (args, from_tty)
133      char *args;
134      int from_tty;
135 {
136   char *exec_file;
137
138   if (from_tty)
139     {
140       exec_file = get_exec_file (0);
141       if (exec_file == 0)
142         exec_file = "";
143       printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
144                          target_pid_to_str (inferior_pid));
145       gdb_flush (gdb_stdout);
146     }
147   inferior_pid = 0;
148   unpush_target (&child_ops);
149 }
150
151 /* Print status information about what we're accessing.  */
152
153 static void
154 child_files_info (ignore)
155      struct target_ops *ignore;
156 {
157   printf_unfiltered ("\tUsing the running image of %s %s.\n",
158       attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
159 }
160
161 /* ARGSUSED */
162 static void
163 child_open (arg, from_tty)
164      char *arg;
165      int from_tty;
166 {
167   error ("Use the \"run\" command to start a Mac application.");
168 }
169
170 /* Start an inferior Mac program and sets inferior_pid to its pid.
171    EXEC_FILE is the file to run.
172    ALLARGS is a string containing the arguments to the program.
173    ENV is the environment vector to pass.  Errors reported with error().  */
174
175 static void
176 child_create_inferior (exec_file, allargs, env)
177      char *exec_file;
178      char *allargs;
179      char **env;
180 {
181   LaunchParamBlockRec launchparms;
182   FSSpec fsspec;
183   OSErr launch_err;
184
185   if (!exec_file)
186     {
187       error ("No executable specified, use `target exec'.\n");
188     }
189
190   launchparms.launchBlockID = extendedBlock;
191   launchparms.launchEPBLength = extendedBlockLen;
192   launchparms.launchFileFlags = 0;
193   launchparms.launchControlFlags = launchContinue | launchNoFileFlags;
194   fsspec.vRefNum = 0;
195   fsspec.parID = 0;
196   strcpy(fsspec.name + 1, exec_file);
197   fsspec.name[0] = strlen(exec_file);
198   launchparms.launchAppSpec = &fsspec;
199   launchparms.launchAppParameters = nil;
200
201   launch_err = LaunchApplication (&launchparms);
202
203   if (launch_err == 999 /*memFullErr*/)
204     {
205       error ("Not enough memory to launch %s\n", exec_file);
206     }
207   else if (launch_err != noErr)
208     {
209       error ("Error launching %s, code %d\n", exec_file, launch_err);
210     }
211
212   inferior_pid = launchparms.launchProcessSN.lowLongOfPSN;
213   /* FIXME be sure that high long of PSN is 0 */
214
215   push_target (&child_ops);
216   init_wait_for_inferior ();
217   clear_proceed_status ();
218
219 /*  proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);  */
220 }
221
222 static void
223 child_mourn_inferior ()
224 {
225   unpush_target (&child_ops);
226   generic_mourn_inferior ();
227 }
228
229 static void
230 child_stop ()
231 {
232 }
233
234 int
235 child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
236                  int write, struct target_ops *target)
237 {
238   int i;
239
240   for (i = 0; i < len; ++i)
241     {
242       if (write)
243         {
244           ((char *) memaddr)[i] = myaddr[i];
245         }
246       else
247         {
248           myaddr[i] = ((char *) memaddr)[i];
249         }
250     }
251   return len;
252 }
253
254 void
255 child_kill_inferior (void)
256 {
257 }
258
259 void
260 child_resume (int pid, int step, enum target_signal signal)
261 {
262 }
263
264 static void
265 child_prepare_to_store ()
266 {
267   /* Do nothing, since we can store individual regs */
268 }
269
270 static int
271 child_can_run ()
272 {
273   return 1;
274 }
275
276 static void
277 child_close ()
278 {
279 }
280
281 static void
282 info_proc (args, from_tty)
283      char *args;
284      int from_tty;
285 {
286   ProcessSerialNumber psn;
287   ProcessInfoRec inforec;
288   Str31 name;
289   FSSpecPtr fsspec;
290   OSType code;
291
292   /* Eventually use args, but not right now. */
293
294   psn.highLongOfPSN = 0;
295   psn.lowLongOfPSN = kNoProcess;
296
297   inforec.processInfoLength = sizeof(ProcessInfoRec);
298   inforec.processName = name;
299   inforec.processAppSpec = fsspec;
300
301   printf_filtered ("Process Name                     Sgnt Type    PSN   Loc Size FreeMem Time\n");
302
303   while (GetNextProcess (&psn) == noErr)
304     {
305       if (GetProcessInformation (&psn, &inforec) == noErr)
306         {
307           name[name[0] + 1] = '\0';
308           printf_filtered ("%-32.32s", name + 1);
309           code = inforec.processSignature;
310           printf_filtered (" %c%c%c%c",
311                            (code >> 24) & 0xff,
312                            (code >> 16) & 0xff,
313                            (code >>  8) & 0xff,
314                            (code >>  0) & 0xff);
315           code = inforec.processType;
316           printf_filtered (" %c%c%c%c",
317                            (code >> 24) & 0xff,
318                            (code >> 16) & 0xff,
319                            (code >>  8) & 0xff,
320                            (code >>  0) & 0xff);
321           if (psn.highLongOfPSN == 0)
322             printf_filtered (" %9d", psn.lowLongOfPSN);
323           else
324             printf_filtered (" %9d,%9d\n",
325                              psn.highLongOfPSN, psn.lowLongOfPSN);
326           printf_filtered (" 0x%x", inforec.processLocation);
327           printf_filtered (" %9d", inforec.processSize);
328           printf_filtered (" %9d", inforec.processFreeMem);
329           printf_filtered (" %9d", inforec.processActiveTime);
330           printf_filtered ("\n");
331         }
332     }
333 }
334
335 struct target_ops child_ops ;
336 static void init_child_ops(void)
337 {
338   child_ops.to_shortname =   "mac";             
339   child_ops.to_longname =   "MacOS application";
340   child_ops.to_doc    =  "MacOS application (started by the \"run\" command).";
341   child_ops.to_open   =  child_open; 
342   child_ops.to_close  =  child_close;
343   child_ops.to_attach =  child_attach;
344   child_ops.to_detach =  child_detach;
345   child_ops.to_resume =  child_resume;
346   child_ops.to_wait   =  child_wait;    
347   child_ops.to_fetch_registers  =   child_fetch_inferior_registers;
348   child_ops.to_store_registers  =   child_store_inferior_registers;
349   child_ops.to_prepare_to_store =   child_prepare_to_store;
350   child_ops.to_xfer_memory =   child_xfer_memory;               
351   child_ops.to_files_info  =   child_files_info;                
352   child_ops.to_insert_breakpoint =   memory_insert_breakpoint;  
353   child_ops.to_remove_breakpoint =   memory_remove_breakpoint;  
354   child_ops.to_terminal_init  =   0;                            
355   child_ops.to_terminal_inferior =   0;                         
356   child_ops.to_terminal_ours_for_output =  0;
357   child_ops.to_terminal_ours  =   0;                    
358   child_ops.to_terminal_info  =   0;                    
359   child_ops.to_kill  =   child_kill_inferior;   
360   child_ops.to_load  =   0;     
361   child_ops.to_lookup_symbol   = 0;                     
362   child_ops.to_create_inferior = child_create_inferior;
363   child_ops.to_mourn_inferior  = child_mourn_inferior;          
364   child_ops.to_can_run         = child_can_run;
365   child_ops.to_notice_signals =  0;      
366   child_ops.to_thread_alive  =   0;       
367   child_ops.to_stop  =   child_stop;      
368   child_ops.to_stratum =   process_stratum;
369   child_ops.DONT_USE =   0; 
370   child_ops.to_has_all_memory = 1; 
371   child_ops.to_has_memory     = 1; 
372   child_ops.to_has_stack      = 1; 
373   child_ops.to_has_registers  = 1; 
374   child_ops.to_has_execution  = 1; 
375   child_ops.to_sections       = 0; 
376   child_ops.to_sections_end   = 0; 
377   child_ops.to_magic =   OPS_MAGIC;
378 };
379
380 void
381 _initialize_mac_nat ()
382 {
383   init_child_ops() ;
384
385   add_info ("proc", info_proc,
386             "Show information about processes.");
387 }