GDB (API)
/home/stan/gdb/src/gdb/arm-symbian-tdep.c
Go to the documentation of this file.
00001 /* ARM Symbian OS target support.
00002 
00003    Copyright (C) 2008-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "frame.h"
00022 #include "objfiles.h"
00023 #include "osabi.h"
00024 #include "solib.h"
00025 #include "solib-target.h"
00026 #include "target.h"
00027 #include "elf-bfd.h"
00028 
00029 /* If PC is in a DLL import stub, return the address of the `real'
00030    function belonging to the stub.  */
00031 
00032 static CORE_ADDR
00033 arm_symbian_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
00034 {
00035   struct gdbarch *gdbarch;
00036   enum bfd_endian byte_order;
00037   ULONGEST insn;
00038   CORE_ADDR dest;
00039   gdb_byte buf[4];
00040 
00041   if (!in_plt_section (pc))
00042     return 0;
00043 
00044   if (target_read_memory (pc, buf, 4) != 0)
00045     return 0;
00046 
00047   gdbarch = get_frame_arch (frame);
00048   byte_order = gdbarch_byte_order (gdbarch);
00049 
00050   /* ldr pc, [pc, #-4].  */
00051   insn = extract_unsigned_integer (buf, 4, byte_order);
00052   if (insn != 0xe51ff004)
00053     return 0;
00054 
00055   if (target_read_memory (pc + 4, buf, 4) != 0)
00056     return 0;
00057 
00058   dest = extract_unsigned_integer (buf, 4, byte_order);
00059   return gdbarch_addr_bits_remove (gdbarch, dest);
00060 }
00061 
00062 static void
00063 arm_symbian_init_abi (struct gdbarch_info info,
00064                       struct gdbarch *gdbarch)
00065 {
00066   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00067 
00068   /* Shared library handling.  */
00069   set_gdbarch_skip_trampoline_code (gdbarch, arm_symbian_skip_trampoline_code);
00070 
00071   /* On this target, the toolchain outputs ELF files, with `sym' for
00072      filename extension (e.g., `FOO.sym'); these are post-linker
00073      processed into PE-ish DLLs (e.g., `FOO.dll'), and it's these that
00074      are actually copied to and run on the target.  Naturally, when
00075      listing shared libraries, Symbian stubs report the DLL filenames.
00076      Setting this makes it so that GDB automatically looks for the
00077      corresponding ELF files on the host's filesystem.  */
00078   set_gdbarch_solib_symbols_extension (gdbarch, "sym");
00079 
00080   /* Canonical paths on this target look like `c:\sys\bin\bar.dll',
00081      for example.  */
00082   set_gdbarch_has_dos_based_file_system (gdbarch, 1);
00083 
00084   set_solib_ops (gdbarch, &solib_target_so_ops);
00085 }
00086 
00087 /* Recognize Symbian object files.  */
00088 
00089 static enum gdb_osabi
00090 arm_symbian_osabi_sniffer (bfd *abfd)
00091 {
00092   Elf_Internal_Phdr *phdrs;
00093   long phdrs_size;
00094   int num_phdrs, i;
00095 
00096   /* Symbian executables are always shared objects (ET_DYN).  */
00097   if (elf_elfheader (abfd)->e_type == ET_EXEC)
00098     return GDB_OSABI_UNKNOWN;
00099 
00100   if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_NONE)
00101     return GDB_OSABI_UNKNOWN;
00102 
00103   /* Check for the ELF headers not being part of any PT_LOAD segment.
00104      Symbian is the only GDB supported (or GNU binutils supported) ARM
00105      target which uses a postlinker to flatten ELF files, dropping the
00106      ELF dynamic info in the process.  */
00107   phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
00108   if (phdrs_size == -1)
00109     return GDB_OSABI_UNKNOWN;
00110 
00111   phdrs = alloca (phdrs_size);
00112   num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
00113   if (num_phdrs == -1)
00114     return GDB_OSABI_UNKNOWN;
00115 
00116   for (i = 0; i < num_phdrs; i++)
00117     if (phdrs[i].p_type == PT_LOAD && phdrs[i].p_offset == 0)
00118       return GDB_OSABI_UNKNOWN;
00119 
00120   /* Looks like a Symbian binary.  */
00121   return GDB_OSABI_SYMBIAN;
00122 }
00123 
00124 /* -Wmissing-prototypes */
00125 extern initialize_file_ftype _initialize_arm_symbian_tdep;
00126 
00127 void
00128 _initialize_arm_symbian_tdep (void)
00129 {
00130   gdbarch_register_osabi_sniffer (bfd_arch_arm,
00131                                   bfd_target_elf_flavour,
00132                                   arm_symbian_osabi_sniffer);
00133 
00134   gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_SYMBIAN,
00135                           arm_symbian_init_abi);
00136 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines