gdb/
[deliverable/binutils-gdb.git] / gdb / arm-symbian-tdep.c
CommitLineData
78664fa3
PA
1/* ARM Symbian OS target support.
2
0b302171 3 Copyright (C) 2008-2012 Free Software Foundation, Inc.
78664fa3
PA
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 3 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 even the 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, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "frame.h"
22#include "objfiles.h"
23#include "osabi.h"
24#include "solib.h"
25#include "solib-target.h"
26#include "target.h"
27#include "elf-bfd.h"
28
29/* If PC is in a DLL import stub, return the address of the `real'
30 function belonging to the stub. */
31
32CORE_ADDR
33arm_symbian_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
34{
35 struct gdbarch *gdbarch;
36 enum bfd_endian byte_order;
37 ULONGEST insn;
38 CORE_ADDR dest;
39 gdb_byte buf[4];
40
41 if (!in_plt_section (pc, NULL))
42 return 0;
43
44 if (target_read_memory (pc, buf, 4) != 0)
45 return 0;
46
47 gdbarch = get_frame_arch (frame);
48 byte_order = gdbarch_byte_order (gdbarch);
49
50 /* ldr pc, [pc, #-4]. */
51 insn = extract_unsigned_integer (buf, 4, byte_order);
52 if (insn != 0xe51ff004)
53 return 0;
54
55 if (target_read_memory (pc + 4, buf, 4) != 0)
56 return 0;
57
58 dest = extract_unsigned_integer (buf, 4, byte_order);
59 return gdbarch_addr_bits_remove (gdbarch, dest);
60}
61
62static void
63arm_symbian_init_abi (struct gdbarch_info info,
64 struct gdbarch *gdbarch)
65{
66 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
67
68 /* Shared library handling. */
69 set_gdbarch_skip_trampoline_code (gdbarch, arm_symbian_skip_trampoline_code);
70
08105857
PA
71 /* On this target, the toolchain outputs ELF files, with `sym' for
72 filename extension (e.g., `FOO.sym'); these are post-linker
73 processed into PE-ish DLLs (e.g., `FOO.dll'), and it's these that
74 are actually copied to and run on the target. Naturally, when
75 listing shared libraries, Symbian stubs report the DLL filenames.
76 Setting this makes it so that GDB automatically looks for the
77 corresponding ELF files on the host's filesystem. */
78 set_gdbarch_solib_symbols_extension (gdbarch, "sym");
79
ab38a727
PA
80 /* Canonical paths on this target look like `c:\sys\bin\bar.dll',
81 for example. */
82 set_gdbarch_has_dos_based_file_system (gdbarch, 1);
83
78664fa3
PA
84 set_solib_ops (gdbarch, &solib_target_so_ops);
85}
86
87/* Recognize Symbian object files. */
88
89static enum gdb_osabi
90arm_symbian_osabi_sniffer (bfd *abfd)
91{
92 Elf_Internal_Phdr *phdrs, **segments;
93 long phdrs_size;
94 int num_phdrs, i;
95
96 /* Symbian executables are always shared objects (ET_DYN). */
97 if (elf_elfheader (abfd)->e_type == ET_EXEC)
98 return GDB_OSABI_UNKNOWN;
99
100 if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_NONE)
101 return GDB_OSABI_UNKNOWN;
102
103 /* Check for the ELF headers not being part of any PT_LOAD segment.
104 Symbian is the only GDB supported (or GNU binutils supported) ARM
105 target which uses a postlinker to flatten ELF files, dropping the
106 ELF dynamic info in the process. */
107 phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
108 if (phdrs_size == -1)
109 return GDB_OSABI_UNKNOWN;
110
111 phdrs = alloca (phdrs_size);
112 num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
113 if (num_phdrs == -1)
114 return GDB_OSABI_UNKNOWN;
115
116 for (i = 0; i < num_phdrs; i++)
117 if (phdrs[i].p_type == PT_LOAD && phdrs[i].p_offset == 0)
118 return GDB_OSABI_UNKNOWN;
119
120 /* Looks like a Symbian binary. */
121 return GDB_OSABI_SYMBIAN;
122}
123
124void
125_initialize_arm_symbian_tdep (void)
126{
127 gdbarch_register_osabi_sniffer (bfd_arch_arm,
128 bfd_target_elf_flavour,
129 arm_symbian_osabi_sniffer);
130
131 gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_SYMBIAN,
132 arm_symbian_init_abi);
133}
This page took 0.158103 seconds and 4 git commands to generate.