binutils-gdb/gdb/arm-symbian-tdep.c
Maciej W. Rozycki 3e5d3a5aaf * objfiles.h (pc_in_section): New prototype.
(in_plt_section): Remove name argument, replace prototype with
	static inline function.
	* mips-tdep.h: Include "objfiles.h".
	(in_mips_stubs_section): New function.
	* hppa-tdep.h (gdbarch_tdep): Remove name argument of
	in_solib_call_trampoline member.
	(hppa_in_solib_call_trampoline): Remove name argument.
	* objfiles.c (pc_in_section): New function.
	(in_plt_section): Remove function.
	* mips-linux-tdep.c: Include "objfiles.h".
	(mips_linux_in_dynsym_stub): Call in_mips_stubs_section.  Remove
	name argument.  Return 1 rather than the low 16-bit halfword of
	any instruction examined.
	(mips_linux_in_dynsym_resolve_code): Update
	mips_linux_in_dynsym_stub call accordingly.
	* mips-tdep.c (mips_stub_frame_sniffer): Use in_mips_stubs_section
	rather than an equivalent hand-coded sequence.
	* hppa-hpux-tdep.c (in_opd_section): Remove function.
	(hppa32_hpux_in_solib_call_trampoline): Remove name argument.
	(hppa64_hpux_in_solib_call_trampoline): Likewise.
	(hppa64_hpux_find_global_pointer): Use pc_in_section rather than
	in_opd_section.
	* hppa-tdep.c (hppa_stub_unwind_sniffer): Remove name argument
	on call to tdep->in_solib_call_trampoline.
	(hppa_in_solib_call_trampoline): Remove name argument, update
	according to in_plt_section change.
	(hppa_skip_trampoline_code): Update according to in_plt_section
	change.
	* aarch64-tdep.c (aarch64_stub_unwind_sniffer): Likewise.
	* arm-symbian-tdep.c (arm_symbian_skip_trampoline_code):
	Likewise.
	* arm-tdep.c (arm_stub_unwind_sniffer): Likewise.
	* hppa-linux-tdep.c (hppa_linux_find_global_pointer): Likewise.
	* hppabsd-tdep.c (hppabsd_find_global_pointer): Likewise.
	* nios2-tdep.c (nios2_stub_frame_sniffer): Likewise.
	* nto-tdep.c (nto_relocate_section_addresses): Likewise.
	* s390-tdep.c (s390_stub_frame_sniffer): Likewise.
	* sh-tdep.c (sh_stub_unwind_sniffer): Likewise.
	* solib-dsbt.c (dsbt_in_dynsym_resolve_code): Likewise.
	* solib-frv.c (frv_in_dynsym_resolve_code): Likewise.
	* solib-svr4.c (svr4_in_dynsym_resolve_code): Likewise.
	* solib-target.c (solib_target_in_dynsym_resolve_code): Likewise.
	* sparc-tdep.c (sparc_analyze_prologue): Likewise.
	* tic6x-tdep.c (tic6x_stub_unwind_sniffer): Likewise.
2013-06-24 22:18:32 +00:00

137 lines
4.1 KiB
C

/* ARM Symbian OS target support.
Copyright (C) 2008-2013 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "frame.h"
#include "objfiles.h"
#include "osabi.h"
#include "solib.h"
#include "solib-target.h"
#include "target.h"
#include "elf-bfd.h"
/* If PC is in a DLL import stub, return the address of the `real'
function belonging to the stub. */
static CORE_ADDR
arm_symbian_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
struct gdbarch *gdbarch;
enum bfd_endian byte_order;
ULONGEST insn;
CORE_ADDR dest;
gdb_byte buf[4];
if (!in_plt_section (pc))
return 0;
if (target_read_memory (pc, buf, 4) != 0)
return 0;
gdbarch = get_frame_arch (frame);
byte_order = gdbarch_byte_order (gdbarch);
/* ldr pc, [pc, #-4]. */
insn = extract_unsigned_integer (buf, 4, byte_order);
if (insn != 0xe51ff004)
return 0;
if (target_read_memory (pc + 4, buf, 4) != 0)
return 0;
dest = extract_unsigned_integer (buf, 4, byte_order);
return gdbarch_addr_bits_remove (gdbarch, dest);
}
static void
arm_symbian_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, arm_symbian_skip_trampoline_code);
/* On this target, the toolchain outputs ELF files, with `sym' for
filename extension (e.g., `FOO.sym'); these are post-linker
processed into PE-ish DLLs (e.g., `FOO.dll'), and it's these that
are actually copied to and run on the target. Naturally, when
listing shared libraries, Symbian stubs report the DLL filenames.
Setting this makes it so that GDB automatically looks for the
corresponding ELF files on the host's filesystem. */
set_gdbarch_solib_symbols_extension (gdbarch, "sym");
/* Canonical paths on this target look like `c:\sys\bin\bar.dll',
for example. */
set_gdbarch_has_dos_based_file_system (gdbarch, 1);
set_solib_ops (gdbarch, &solib_target_so_ops);
}
/* Recognize Symbian object files. */
static enum gdb_osabi
arm_symbian_osabi_sniffer (bfd *abfd)
{
Elf_Internal_Phdr *phdrs;
long phdrs_size;
int num_phdrs, i;
/* Symbian executables are always shared objects (ET_DYN). */
if (elf_elfheader (abfd)->e_type == ET_EXEC)
return GDB_OSABI_UNKNOWN;
if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_NONE)
return GDB_OSABI_UNKNOWN;
/* Check for the ELF headers not being part of any PT_LOAD segment.
Symbian is the only GDB supported (or GNU binutils supported) ARM
target which uses a postlinker to flatten ELF files, dropping the
ELF dynamic info in the process. */
phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
if (phdrs_size == -1)
return GDB_OSABI_UNKNOWN;
phdrs = alloca (phdrs_size);
num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
if (num_phdrs == -1)
return GDB_OSABI_UNKNOWN;
for (i = 0; i < num_phdrs; i++)
if (phdrs[i].p_type == PT_LOAD && phdrs[i].p_offset == 0)
return GDB_OSABI_UNKNOWN;
/* Looks like a Symbian binary. */
return GDB_OSABI_SYMBIAN;
}
/* -Wmissing-prototypes */
extern initialize_file_ftype _initialize_arm_symbian_tdep;
void
_initialize_arm_symbian_tdep (void)
{
gdbarch_register_osabi_sniffer (bfd_arch_arm,
bfd_target_elf_flavour,
arm_symbian_osabi_sniffer);
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_SYMBIAN,
arm_symbian_init_abi);
}