GDB (API)
|
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 }