GDB (API)
/home/stan/gdb/src/gdb/hppabsd-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for HP PA-RISC BSD's.
00002 
00003    Copyright (C) 2004-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 "objfiles.h"
00022 #include "target.h"
00023 #include "value.h"
00024 
00025 #include "elf/common.h"
00026 
00027 #include "hppa-tdep.h"
00028 #include "hppabsd-tdep.h"
00029 #include "dwarf2-frame.h"
00030 #include "solib-svr4.h"
00031 
00032 static CORE_ADDR
00033 hppabsd_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
00034 {
00035   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00036   CORE_ADDR faddr = value_as_address (function);
00037   struct obj_section *faddr_sec;
00038   gdb_byte buf[4];
00039 
00040   /* Is this a plabel? If so, dereference it to get the Global Pointer
00041      value.  */
00042   if (faddr & 2)
00043     {
00044       if (target_read_memory ((faddr & ~3) + 4, buf, sizeof buf) == 0)
00045         return extract_unsigned_integer (buf, sizeof buf, byte_order);
00046     }
00047 
00048   /* If the address is in the .plt section, then the real function
00049      hasn't yet been fixed up by the linker so we cannot determine the
00050      Global Pointer for that function.  */
00051   if (in_plt_section (faddr))
00052     return 0;
00053 
00054   faddr_sec = find_pc_section (faddr);
00055   if (faddr_sec != NULL)
00056     {
00057       struct obj_section *sec;
00058 
00059       ALL_OBJFILE_OSECTIONS (faddr_sec->objfile, sec)
00060         {
00061           if (strcmp (sec->the_bfd_section->name, ".dynamic") == 0)
00062             break;
00063         }
00064 
00065       if (sec < faddr_sec->objfile->sections_end)
00066         {
00067           CORE_ADDR addr = obj_section_addr (sec);
00068           CORE_ADDR endaddr = obj_section_endaddr (sec);
00069 
00070           while (addr < endaddr)
00071             {
00072               gdb_byte buf[4];
00073               LONGEST tag;
00074 
00075               if (target_read_memory (addr, buf, sizeof buf) != 0)
00076                 break;
00077 
00078               tag = extract_signed_integer (buf, sizeof buf, byte_order);
00079               if (tag == DT_PLTGOT)
00080                 {
00081                   CORE_ADDR pltgot;
00082 
00083                   if (target_read_memory (addr + 4, buf, sizeof buf) != 0)
00084                     break;
00085 
00086                   /* The NetBSD/OpenBSD ld.so doesn't relocate DT_PLTGOT, so
00087                      we have to do it ourselves.  */
00088                   pltgot = extract_unsigned_integer (buf, sizeof buf,
00089                                                      byte_order);
00090                   pltgot += ANOFFSET (sec->objfile->section_offsets,
00091                                       SECT_OFF_TEXT (sec->objfile));
00092 
00093                   return pltgot;
00094                 }
00095 
00096               if (tag == DT_NULL)
00097                 break;
00098 
00099               addr += 8;
00100             }
00101         }
00102     }
00103 
00104   return 0;
00105 }
00106 
00107 
00108 static void
00109 hppabsd_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
00110                                struct dwarf2_frame_state_reg *reg,
00111                                struct frame_info *this_frame)
00112 {
00113   if (regnum == HPPA_PCOQ_HEAD_REGNUM)
00114     reg->how = DWARF2_FRAME_REG_RA;
00115   else if (regnum == HPPA_SP_REGNUM)
00116     reg->how = DWARF2_FRAME_REG_CFA;
00117 }
00118 
00119 void
00120 hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00121 {
00122   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00123 
00124   /* OpenBSD and NetBSD have a 64-bit 'long double'.  */
00125   set_gdbarch_long_double_bit (gdbarch, 64);
00126   set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
00127 
00128   /* OpenBSD and NetBSD use ELF.  */
00129   tdep->is_elf = 1;
00130   tdep->find_global_pointer = hppabsd_find_global_pointer;
00131   tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
00132   set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
00133 
00134   /* OpenBSD and NetBSD use SVR4-style shared libraries.  */
00135   set_solib_svr4_fetch_link_map_offsets
00136     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
00137 
00138   /* Hook in the DWARF CFI frame unwinder.  */
00139   dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg);
00140   dwarf2_append_unwinders (gdbarch);
00141 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines