1 /* GNU/Linux on ARM native support.
2 Copyright 1999, 2000 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
24 #include "gdb_string.h"
27 #include <sys/ptrace.h>
28 #include <sys/utsname.h>
30 extern int arm_apcs_32;
33 #define typeSingle 0x01
34 #define typeDouble 0x02
35 #define typeExtended 0x03
37 #define CPSR_REGNUM 16
39 typedef union tagFPREG
42 unsigned int fDouble[2];
43 unsigned int fExtended[3];
47 typedef struct tagFPA11
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. */
58 /* The following variables are used to determine the version of the
59 underlying Linux operating system. Examples:
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
67 Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
69 These are initialized using get_linux_version() from
70 _initialize_arm_linux_nat(). */
72 static unsigned int os_version, os_major, os_minor, os_release;
75 fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
79 mem[0] = fpa11->fpreg[fn].fSingle;
82 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
86 fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
90 mem[0] = fpa11->fpreg[fn].fDouble[1];
91 mem[1] = fpa11->fpreg[fn].fDouble[0];
93 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
97 fetch_nwfpe_none (unsigned int fn)
102 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
106 fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
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]);
117 store_nwfpe_single (unsigned int fn, FPA11 * fpa11)
121 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
122 fpa11->fpreg[fn].fSingle = mem[0];
123 fpa11->fType[fn] = typeSingle;
127 store_nwfpe_double (unsigned int fn, FPA11 * fpa11)
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;
138 store_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
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;
149 /* Get the whole floating point state of the process and store the
150 floating point stack into registers[]. */
158 /* Read the floating point state. */
159 ret = ptrace (PT_GETFPREGS, inferior_pid, 0, &fp);
162 warning ("Unable to fetch the floating point state.");
167 supply_register (FPS_REGNUM, (char *) &fp.fpsr);
169 /* Fetch the floating point registers. */
170 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
172 int fn = regno - F0_REGNUM;
174 switch (fp.fType[fn])
177 fetch_nwfpe_single (fn, &fp);
181 fetch_nwfpe_double (fn, &fp);
185 fetch_nwfpe_extended (fn, &fp);
189 fetch_nwfpe_none (fn);
194 /* Save the whole floating point state of the process using
195 the contents from registers[]. */
204 if (register_valid[FPS_REGNUM])
205 read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
207 /* Store the floating point registers. */
208 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
210 if (register_valid[regno])
212 unsigned int fn = regno - F0_REGNUM;
213 switch (fp.fType[fn])
216 store_nwfpe_single (fn, &fp);
220 store_nwfpe_double (fn, &fp);
224 store_nwfpe_extended (fn, &fp);
230 ret = ptrace (PTRACE_SETFPREGS, inferior_pid, 0, &fp);
233 warning ("Unable to store floating point state.");
238 /* Fetch all general registers of the process and store into
247 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, ®s);
250 warning ("Unable to fetch general registers.");
254 for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
255 supply_register (regno, (char *) ®s.uregs[regno]);
258 supply_register (PS_REGNUM, (char *) ®s.uregs[CPSR_REGNUM]);
260 supply_register (PS_REGNUM, (char *) ®s.uregs[PC_REGNUM]);
262 regs.uregs[PC_REGNUM] = ADDR_BITS_REMOVE (regs.uregs[PC_REGNUM]);
263 supply_register (PC_REGNUM, (char *) ®s.uregs[PC_REGNUM]);
266 /* Store all general registers of the process from the values in
275 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, ®s);
278 warning ("Unable to fetch general registers.");
282 for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++)
284 if (register_valid[regno])
285 read_register_gen (regno, (char *) ®s.uregs[regno]);
288 ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, ®s);
292 warning ("Unable to store general registers.");
297 /* Fetch registers from the child process. Fetch all registers if
298 regno == -1, otherwise fetch all general registers or all floating
299 point registers depending upon the value of regno. */
302 fetch_inferior_registers (int regno)
304 if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
307 if (((regno >= F0_REGNUM) && (regno <= FPS_REGNUM)) || (regno == -1))
311 /* Store registers back into the inferior. Store all registers if
312 regno == -1, otherwise store all general registers or all floating
313 point registers depending upon the value of regno. */
316 store_inferior_registers (int regno)
318 if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
321 if (((regno >= F0_REGNUM) && (regno <= FPS_REGNUM)) || (regno == -1))
326 Dynamic Linking on ARM Linux
327 ----------------------------
329 Note: PLT = procedure linkage table
330 GOT = global offset table
332 As much as possible, ELF dynamic linking defers the resolution of
333 jump/call addresses until the last minute. The technique used is
334 inspired by the i386 ELF design, and is based on the following
337 1) The calling technique should not force a change in the assembly
338 code produced for apps; it MAY cause changes in the way assembly
339 code is produced for position independent code (i.e. shared
342 2) The technique must be such that all executable areas must not be
343 modified; and any modified areas must not be executed.
345 To do this, there are three steps involved in a typical jump:
349 3) using a pointer from the GOT
351 When the executable or library is first loaded, each GOT entry is
352 initialized to point to the code which implements dynamic name
353 resolution and code finding. This is normally a function in the
354 program interpreter (on ARM Linux this is usually ld-linux.so.2,
355 but it does not have to be). On the first invocation, the function
356 is located and the GOT entry is replaced with the real function
357 address. Subsequent calls go through steps 1, 2 and 3 and end up
358 calling the real code.
365 This is typical ARM code using the 26 bit relative branch or branch
366 and link instructions. The target of the instruction
367 (function_call is usually the address of the function to be called.
368 In position independent code, the target of the instruction is
369 actually an entry in the PLT when calling functions in a shared
370 library. Note that this call is identical to a normal function
371 call, only the target differs.
375 The PLT is a synthetic area, created by the linker. It exists in
376 both executables and libraries. It is an array of stubs, one per
377 imported function call. It looks like this:
380 str lr, [sp, #-4]! @push the return address (lr)
381 ldr lr, [pc, #16] @load from 6 words ahead
382 add lr, pc, lr @form an address for GOT[0]
383 ldr pc, [lr, #8]! @jump to the contents of that addr
385 The return address (lr) is pushed on the stack and used for
386 calculations. The load on the second line loads the lr with
387 &GOT[3] - . - 20. The addition on the third leaves:
389 lr = (&GOT[3] - . - 20) + (. + 8)
393 On the fourth line, the pc and lr are both updated, so that:
399 NOTE: PLT[0] borrows an offset .word from PLT[1]. This is a little
400 "tight", but allows us to keep all the PLT entries the same size.
403 ldr ip, [pc, #4] @load offset from gotoff
404 add ip, pc, ip @add the offset to the pc
405 ldr pc, [ip] @jump to that address
406 gotoff: .word GOT[n+3] - .
408 The load on the first line, gets an offset from the fourth word of
409 the PLT entry. The add on the second line makes ip = &GOT[n+3],
410 which contains either a pointer to PLT[0] (the fixup trampoline) or
411 a pointer to the actual code.
415 The GOT contains helper pointers for both code (PLT) fixups and
416 data fixups. The first 3 entries of the GOT are special. The next
417 M entries (where M is the number of entries in the PLT) belong to
418 the PLT fixups. The next D (all remaining) entries belong to
419 various data fixups. The actual size of the GOT is 3 + M + D.
421 The GOT is also a synthetic area, created by the linker. It exists
422 in both executables and libraries. When the GOT is first
423 initialized , all the GOT entries relating to PLT fixups are
424 pointing to code back at PLT[0].
426 The special entries in the GOT are:
428 GOT[0] = linked list pointer used by the dynamic loader
429 GOT[1] = pointer to the reloc table for this module
430 GOT[2] = pointer to the fixup/resolver code
432 The first invocation of function call comes through and uses the
433 fixup/resolver code. On the entry to the fixup/resolver code:
437 stack[0] = return address (lr) of the function call
438 [r0, r1, r2, r3] are still the arguments to the function call
440 This is enough information for the fixup/resolver code to work
441 with. Before the fixup/resolver code returns, it actually calls
442 the requested function and repairs &GOT[n+3]. */
445 arm_skip_solib_resolver (CORE_ADDR pc)
452 arm_linux_register_u_addr (int blockend, int regnum)
454 return blockend + REGISTER_BYTE (regnum);
458 arm_linux_kernel_u_size (void)
460 return (sizeof (struct user));
464 get_linux_version (unsigned int *vmajor,
465 unsigned int *vminor,
466 unsigned int *vrelease)
469 char *pmajor, *pminor, *prelease, *tail;
471 if (-1 == uname (&info))
473 warning ("Unable to determine Linux version.");
477 pmajor = strtok (info.release, ".");
478 pminor = strtok (NULL, ".");
479 prelease = strtok (NULL, ".");
481 *vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
482 *vminor = (unsigned int) strtoul (pminor, &tail, 0);
483 *vrelease = (unsigned int) strtoul (prelease, &tail, 0);
485 return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
489 _initialize_arm_linux_nat (void)
491 os_version = get_linux_version (&os_major, &os_minor, &os_release);