]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/arm-symbian-tdep.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / arm-symbian-tdep.c
CommitLineData
78664fa3
PA
1/* ARM Symbian OS target support.
2
b811d2c2 3 Copyright (C) 2008-2020 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"
d55e5aa6 24#include "solib.h"
4de283e4 25#include "solib-target.h"
78664fa3 26#include "target.h"
4de283e4 27#include "elf-bfd.h"
78664fa3
PA
28
29/* If PC is in a DLL import stub, return the address of the `real'
30 function belonging to the stub. */
31
693be288 32static CORE_ADDR
78664fa3
PA
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
3e5d3a5a 41 if (!in_plt_section (pc))
78664fa3
PA
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{
78664fa3
PA
66 /* Shared library handling. */
67 set_gdbarch_skip_trampoline_code (gdbarch, arm_symbian_skip_trampoline_code);
68
08105857
PA
69 /* On this target, the toolchain outputs ELF files, with `sym' for
70 filename extension (e.g., `FOO.sym'); these are post-linker
71 processed into PE-ish DLLs (e.g., `FOO.dll'), and it's these that
72 are actually copied to and run on the target. Naturally, when
73 listing shared libraries, Symbian stubs report the DLL filenames.
74 Setting this makes it so that GDB automatically looks for the
75 corresponding ELF files on the host's filesystem. */
76 set_gdbarch_solib_symbols_extension (gdbarch, "sym");
77
ab38a727
PA
78 /* Canonical paths on this target look like `c:\sys\bin\bar.dll',
79 for example. */
80 set_gdbarch_has_dos_based_file_system (gdbarch, 1);
81
78664fa3
PA
82 set_solib_ops (gdbarch, &solib_target_so_ops);
83}
84
85/* Recognize Symbian object files. */
86
87static enum gdb_osabi
88arm_symbian_osabi_sniffer (bfd *abfd)
89{
22e048c9 90 Elf_Internal_Phdr *phdrs;
78664fa3
PA
91 long phdrs_size;
92 int num_phdrs, i;
93
94 /* Symbian executables are always shared objects (ET_DYN). */
95 if (elf_elfheader (abfd)->e_type == ET_EXEC)
96 return GDB_OSABI_UNKNOWN;
97
98 if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_NONE)
99 return GDB_OSABI_UNKNOWN;
100
101 /* Check for the ELF headers not being part of any PT_LOAD segment.
102 Symbian is the only GDB supported (or GNU binutils supported) ARM
103 target which uses a postlinker to flatten ELF files, dropping the
104 ELF dynamic info in the process. */
105 phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
106 if (phdrs_size == -1)
107 return GDB_OSABI_UNKNOWN;
108
224c3ddb 109 phdrs = (Elf_Internal_Phdr *) alloca (phdrs_size);
78664fa3
PA
110 num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
111 if (num_phdrs == -1)
112 return GDB_OSABI_UNKNOWN;
113
114 for (i = 0; i < num_phdrs; i++)
115 if (phdrs[i].p_type == PT_LOAD && phdrs[i].p_offset == 0)
116 return GDB_OSABI_UNKNOWN;
117
118 /* Looks like a Symbian binary. */
119 return GDB_OSABI_SYMBIAN;
120}
121
6c265988 122void _initialize_arm_symbian_tdep ();
78664fa3 123void
6c265988 124_initialize_arm_symbian_tdep ()
78664fa3
PA
125{
126 gdbarch_register_osabi_sniffer (bfd_arch_arm,
127 bfd_target_elf_flavour,
128 arm_symbian_osabi_sniffer);
129
130 gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_SYMBIAN,
131 arm_symbian_init_abi);
132}