2c8cc0790218d2ae0dd784702d91a970d11e0854
[deliverable/binutils-gdb.git] / gdb / arm-linux-nat.c
1 /* GNU/Linux on ARM native support.
2 Copyright 1999, 2000 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,
19 Boston, MA 02111-1307, USA. */
20
21 #include "defs.h"
22 #include "inferior.h"
23 #include "gdbcore.h"
24 #include "gdb_string.h"
25
26 #include <sys/user.h>
27 #include <sys/ptrace.h>
28 #include <sys/utsname.h>
29
30 extern int arm_apcs_32;
31
32 #define typeNone 0x00
33 #define typeSingle 0x01
34 #define typeDouble 0x02
35 #define typeExtended 0x03
36 #define FPWORDS 28
37 #define CPSR_REGNUM 16
38
39 typedef union tagFPREG
40 {
41 unsigned int fSingle;
42 unsigned int fDouble[2];
43 unsigned int fExtended[3];
44 }
45 FPREG;
46
47 typedef struct tagFPA11
48 {
49 FPREG fpreg[8]; /* 8 floating point registers */
50 unsigned int fpsr; /* floating point status register */
51 unsigned int fpcr; /* floating point control register */
52 unsigned char fType[8]; /* type of floating point value held in
53 floating point registers. */
54 int initflag; /* NWFPE initialization flag. */
55 }
56 FPA11;
57
58 /* The following variables are used to determine the version of the
59 underlying Linux operating system. Examples:
60
61 Linux 2.0.35 Linux 2.2.12
62 os_version = 0x00020023 os_version = 0x0002020c
63 os_major = 2 os_major = 2
64 os_minor = 0 os_minor = 2
65 os_release = 35 os_release = 12
66
67 Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
68
69 These are initialized using get_linux_version() from
70 _initialize_arm_linux_nat(). */
71
72 static unsigned int os_version, os_major, os_minor, os_release;
73
74 static void
75 fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
76 {
77 unsigned int mem[3];
78
79 mem[0] = fpa11->fpreg[fn].fSingle;
80 mem[1] = 0;
81 mem[2] = 0;
82 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
83 }
84
85 static void
86 fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
87 {
88 unsigned int mem[3];
89
90 mem[0] = fpa11->fpreg[fn].fDouble[1];
91 mem[1] = fpa11->fpreg[fn].fDouble[0];
92 mem[2] = 0;
93 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
94 }
95
96 static void
97 fetch_nwfpe_none (unsigned int fn)
98 {
99 unsigned int mem[3] =
100 {0, 0, 0};
101
102 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
103 }
104
105 static void
106 fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
107 {
108 unsigned int mem[3];
109
110 mem[0] = fpa11->fpreg[fn].fExtended[0]; /* sign & exponent */
111 mem[1] = fpa11->fpreg[fn].fExtended[2]; /* ls bits */
112 mem[2] = fpa11->fpreg[fn].fExtended[1]; /* ms bits */
113 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
114 }
115
116 static void
117 store_nwfpe_single (unsigned int fn, FPA11 * fpa11)
118 {
119 unsigned int mem[3];
120
121 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
122 fpa11->fpreg[fn].fSingle = mem[0];
123 fpa11->fType[fn] = typeSingle;
124 }
125
126 static void
127 store_nwfpe_double (unsigned int fn, FPA11 * fpa11)
128 {
129 unsigned int mem[3];
130
131 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
132 fpa11->fpreg[fn].fDouble[1] = mem[0];
133 fpa11->fpreg[fn].fDouble[0] = mem[1];
134 fpa11->fType[fn] = typeDouble;
135 }
136
137 void
138 store_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
139 {
140 unsigned int mem[3];
141
142 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
143 fpa11->fpreg[fn].fExtended[0] = mem[0]; /* sign & exponent */
144 fpa11->fpreg[fn].fExtended[2] = mem[1]; /* ls bits */
145 fpa11->fpreg[fn].fExtended[1] = mem[2]; /* ms bits */
146 fpa11->fType[fn] = typeDouble;
147 }
148
149 /* Get the whole floating point state of the process and store the
150 floating point stack into registers[]. */
151
152 static void
153 fetch_fpregs (void)
154 {
155 int ret, regno;
156 FPA11 fp;
157
158 /* Read the floating point state. */
159 ret = ptrace (PT_GETFPREGS, inferior_pid, 0, &fp);
160 if (ret < 0)
161 {
162 warning ("Unable to fetch the floating point state.");
163 return;
164 }
165
166 /* Fetch fpsr. */
167 supply_register (FPS_REGNUM, (char *) &fp.fpsr);
168
169 /* Fetch the floating point registers. */
170 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
171 {
172 int fn = regno - F0_REGNUM;
173 unsigned int *p = (unsigned int *) &registers[REGISTER_BYTE (regno)];
174
175 switch (fp.fType[fn])
176 {
177 case typeSingle:
178 fetch_nwfpe_single (fn, &fp);
179 break;
180
181 case typeDouble:
182 fetch_nwfpe_double (fn, &fp);
183 break;
184
185 case typeExtended:
186 fetch_nwfpe_extended (fn, &fp);
187 break;
188
189 default:
190 fetch_nwfpe_none (fn);
191 }
192 }
193 }
194
195 /* Save the whole floating point state of the process using
196 the contents from registers[]. */
197
198 static void
199 store_fpregs (void)
200 {
201 int ret, regno;
202 FPA11 fp;
203
204 /* Store fpsr. */
205 if (register_valid[FPS_REGNUM])
206 read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
207
208 /* Store the floating point registers. */
209 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
210 {
211 if (register_valid[regno])
212 {
213 unsigned int fn = regno - F0_REGNUM;
214 switch (fp.fType[fn])
215 {
216 case typeSingle:
217 store_nwfpe_single (fn, &fp);
218 break;
219
220 case typeDouble:
221 store_nwfpe_double (fn, &fp);
222 break;
223
224 case typeExtended:
225 store_nwfpe_extended (fn, &fp);
226 break;
227 }
228 }
229 }
230
231 ret = ptrace (PTRACE_SETFPREGS, inferior_pid, 0, &fp);
232 if (ret < 0)
233 {
234 warning ("Unable to store floating point state.");
235 return;
236 }
237 }
238
239 /* Fetch all general registers of the process and store into
240 registers[]. */
241
242 static void
243 fetch_regs (void)
244 {
245 int ret, regno;
246 struct pt_regs regs;
247
248 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, &regs);
249 if (ret < 0)
250 {
251 warning ("Unable to fetch general registers.");
252 return;
253 }
254
255 for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
256 supply_register (regno, (char *) &regs.uregs[regno]);
257
258 if (arm_apcs_32)
259 supply_register (PS_REGNUM, (char *) &regs.uregs[CPSR_REGNUM]);
260 else
261 supply_register (PS_REGNUM, (char *) &regs.uregs[PC_REGNUM]);
262
263 regs.uregs[PC_REGNUM] = ADDR_BITS_REMOVE (regs.uregs[PC_REGNUM]);
264 supply_register (PC_REGNUM, (char *) &regs.uregs[PC_REGNUM]);
265 }
266
267 /* Store all general registers of the process from the values in
268 registers[]. */
269
270 static void
271 store_regs (void)
272 {
273 int ret, regno;
274 struct pt_regs regs;
275
276 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, &regs);
277 if (ret < 0)
278 {
279 warning ("Unable to fetch general registers.");
280 return;
281 }
282
283 for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++)
284 {
285 if (register_valid[regno])
286 read_register_gen (regno, (char *) &regs.uregs[regno]);
287 }
288
289 ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, &regs);
290
291 if (ret < 0)
292 {
293 warning ("Unable to store general registers.");
294 return;
295 }
296 }
297
298 /* Fetch registers from the child process. Fetch all registers if
299 regno == -1, otherwise fetch all general registers or all floating
300 point registers depending upon the value of regno. */
301
302 void
303 fetch_inferior_registers (int regno)
304 {
305 if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
306 fetch_regs ();
307
308 if (((regno >= F0_REGNUM) && (regno <= FPS_REGNUM)) || (regno == -1))
309 fetch_fpregs ();
310 }
311
312 /* Store registers back into the inferior. Store all registers if
313 regno == -1, otherwise store all general registers or all floating
314 point registers depending upon the value of regno. */
315
316 void
317 store_inferior_registers (int regno)
318 {
319 if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
320 store_regs ();
321
322 if (((regno >= F0_REGNUM) && (regno <= FPS_REGNUM)) || (regno == -1))
323 store_fpregs ();
324 }
325
326 #ifdef GET_LONGJMP_TARGET
327
328 /* Figure out where the longjmp will land. We expect that we have
329 just entered longjmp and haven't yet altered r0, r1, so the
330 arguments are still in the registers. (A1_REGNUM) points at the
331 jmp_buf structure from which we extract the pc (JB_PC) that we will
332 land at. The pc is copied into ADDR. This routine returns true on
333 success. */
334
335 #define LONGJMP_TARGET_SIZE sizeof(int)
336 #define JB_ELEMENT_SIZE sizeof(int)
337 #define JB_SL 18
338 #define JB_FP 19
339 #define JB_SP 20
340 #define JB_PC 21
341
342 int
343 arm_get_longjmp_target (CORE_ADDR * pc)
344 {
345 CORE_ADDR jb_addr;
346 char buf[LONGJMP_TARGET_SIZE];
347
348 jb_addr = read_register (A1_REGNUM);
349
350 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
351 LONGJMP_TARGET_SIZE))
352 return 0;
353
354 *pc = extract_address (buf, LONGJMP_TARGET_SIZE);
355 return 1;
356 }
357
358 #endif /* GET_LONGJMP_TARGET */
359
360 /*
361 Dynamic Linking on ARM Linux
362 ----------------------------
363
364 Note: PLT = procedure linkage table
365 GOT = global offset table
366
367 As much as possible, ELF dynamic linking defers the resolution of
368 jump/call addresses until the last minute. The technique used is
369 inspired by the i386 ELF design, and is based on the following
370 constraints.
371
372 1) The calling technique should not force a change in the assembly
373 code produced for apps; it MAY cause changes in the way assembly
374 code is produced for position independent code (i.e. shared
375 libraries).
376
377 2) The technique must be such that all executable areas must not be
378 modified; and any modified areas must not be executed.
379
380 To do this, there are three steps involved in a typical jump:
381
382 1) in the code
383 2) through the PLT
384 3) using a pointer from the GOT
385
386 When the executable or library is first loaded, each GOT entry is
387 initialized to point to the code which implements dynamic name
388 resolution and code finding. This is normally a function in the
389 program interpreter (on ARM Linux this is usually ld-linux.so.2,
390 but it does not have to be). On the first invocation, the function
391 is located and the GOT entry is replaced with the real function
392 address. Subsequent calls go through steps 1, 2 and 3 and end up
393 calling the real code.
394
395 1) In the code:
396
397 b function_call
398 bl function_call
399
400 This is typical ARM code using the 26 bit relative branch or branch
401 and link instructions. The target of the instruction
402 (function_call is usually the address of the function to be called.
403 In position independent code, the target of the instruction is
404 actually an entry in the PLT when calling functions in a shared
405 library. Note that this call is identical to a normal function
406 call, only the target differs.
407
408 2) In the PLT:
409
410 The PLT is a synthetic area, created by the linker. It exists in
411 both executables and libraries. It is an array of stubs, one per
412 imported function call. It looks like this:
413
414 PLT[0]:
415 str lr, [sp, #-4]! @push the return address (lr)
416 ldr lr, [pc, #16] @load from 6 words ahead
417 add lr, pc, lr @form an address for GOT[0]
418 ldr pc, [lr, #8]! @jump to the contents of that addr
419
420 The return address (lr) is pushed on the stack and used for
421 calculations. The load on the second line loads the lr with
422 &GOT[3] - . - 20. The addition on the third leaves:
423
424 lr = (&GOT[3] - . - 20) + (. + 8)
425 lr = (&GOT[3] - 12)
426 lr = &GOT[0]
427
428 On the fourth line, the pc and lr are both updated, so that:
429
430 pc = GOT[2]
431 lr = &GOT[0] + 8
432 = &GOT[2]
433
434 NOTE: PLT[0] borrows an offset .word from PLT[1]. This is a little
435 "tight", but allows us to keep all the PLT entries the same size.
436
437 PLT[n+1]:
438 ldr ip, [pc, #4] @load offset from gotoff
439 add ip, pc, ip @add the offset to the pc
440 ldr pc, [ip] @jump to that address
441 gotoff: .word GOT[n+3] - .
442
443 The load on the first line, gets an offset from the fourth word of
444 the PLT entry. The add on the second line makes ip = &GOT[n+3],
445 which contains either a pointer to PLT[0] (the fixup trampoline) or
446 a pointer to the actual code.
447
448 3) In the GOT:
449
450 The GOT contains helper pointers for both code (PLT) fixups and
451 data fixups. The first 3 entries of the GOT are special. The next
452 M entries (where M is the number of entries in the PLT) belong to
453 the PLT fixups. The next D (all remaining) entries belong to
454 various data fixups. The actual size of the GOT is 3 + M + D.
455
456 The GOT is also a synthetic area, created by the linker. It exists
457 in both executables and libraries. When the GOT is first
458 initialized , all the GOT entries relating to PLT fixups are
459 pointing to code back at PLT[0].
460
461 The special entries in the GOT are:
462
463 GOT[0] = linked list pointer used by the dynamic loader
464 GOT[1] = pointer to the reloc table for this module
465 GOT[2] = pointer to the fixup/resolver code
466
467 The first invocation of function call comes through and uses the
468 fixup/resolver code. On the entry to the fixup/resolver code:
469
470 ip = &GOT[n+3]
471 lr = &GOT[2]
472 stack[0] = return address (lr) of the function call
473 [r0, r1, r2, r3] are still the arguments to the function call
474
475 This is enough information for the fixup/resolver code to work
476 with. Before the fixup/resolver code returns, it actually calls
477 the requested function and repairs &GOT[n+3]. */
478
479 CORE_ADDR
480 arm_skip_solib_resolver (CORE_ADDR pc)
481 {
482 /* FIXME */
483 return 0;
484 }
485
486 int
487 arm_linux_register_u_addr (int blockend, int regnum)
488 {
489 return blockend + REGISTER_BYTE (regnum);
490 }
491
492 int
493 arm_linux_kernel_u_size (void)
494 {
495 return (sizeof (struct user));
496 }
497
498 /* Extract from an array REGBUF containing the (raw) register state
499 a function return value of type TYPE, and copy that, in virtual format,
500 into VALBUF. */
501
502 void
503 arm_linux_extract_return_value (struct type *type,
504 char regbuf[REGISTER_BYTES],
505 char *valbuf)
506 {
507 /* ScottB: This needs to be looked at to handle the different
508 floating point emulators on ARM Linux. Right now the code
509 assumes that fetch inferior registers does the right thing for
510 GDB. I suspect this won't handle NWFPE registers correctly, nor
511 will the default ARM version (arm_extract_return_value()). */
512
513 int regnum = (TYPE_CODE_FLT == TYPE_CODE (type)) ? F0_REGNUM : A1_REGNUM;
514 memcpy (valbuf, &regbuf[REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
515 }
516
517 static unsigned int
518 get_linux_version (unsigned int *vmajor,
519 unsigned int *vminor,
520 unsigned int *vrelease)
521 {
522 struct utsname info;
523 char *pmajor, *pminor, *prelease, *tail;
524
525 if (-1 == uname (&info))
526 {
527 warning ("Unable to determine Linux version.");
528 return -1;
529 }
530
531 pmajor = strtok (info.release, ".");
532 pminor = strtok (NULL, ".");
533 prelease = strtok (NULL, ".");
534
535 *vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
536 *vminor = (unsigned int) strtoul (pminor, &tail, 0);
537 *vrelease = (unsigned int) strtoul (prelease, &tail, 0);
538
539 return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
540 }
541
542 void
543 _initialize_arm_linux_nat (void)
544 {
545 os_version = get_linux_version (&os_major, &os_minor, &os_release);
546 }
This page took 0.041678 seconds and 4 git commands to generate.