@@ -24,14 +24,16 @@
# include "defs.h"
# include "gdbcore.h"
# include "regcache.h"
# include "regset.h"
# include "value.h"
# include "osabi.h"
# include "solib-svr4 .h"
# include "gdb_assert .h"
# include "gdb_string.h"
# include "nbsd-tdep.h"
# include "sh-tdep.h"
# include "shnbsd-tdep.h"
# include "solib-svr4.h"
/* Convert an r0-r15 register number into an offset into a ptrace
register structure. */
@@ -55,134 +57,150 @@ static const int regmap[] =
( 5 * 4 ) , /* r15 */
} ;
# define SIZEOF_STRUCT_REG (21 * 4)
/* Sizeof `struct reg' in <machine/reg.h>. */
# define SHNBSD_SIZEOF_GREGS (21 * 4)
void
shnbsd_supply_reg ( char * regs , int regno )
/* Supply register REGNUM from the buffer specified by GREGS and LEN
in the general-purpose register set REGSET to register cache
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
static void
shnbsd_supply_gregset ( const struct regset * regset ,
struct regcache * regcache ,
int regnum , const void * gregs , size_t len )
{
const gdb_byte * regs = gregs ;
int i ;
if ( regno = = PC_REGNUM | | regno = = - 1 )
regcache_raw_supply ( current_regcache , PC_REGNUM , regs + ( 0 * 4 ) ) ;
gdb_assert ( len > = SHNBSD_SIZEOF_GREGS ) ;
if ( regno = = SR _REGNUM | | regno = = - 1 )
regcache_raw_supply ( current_ regcache, SR _REGNUM, regs + ( 1 * 4 ) ) ;
if ( regnum = = PC _REGNUM | | regnum = = - 1 )
regcache_raw_supply ( regcache , PC _REGNUM, regs + ( 0 * 4 ) ) ;
if ( regno = = P R_REGNUM | | regno = = - 1 )
regcache_raw_supply ( current_ regcache, P R_REGNUM, regs + ( 2 * 4 ) ) ;
if ( regnum = = S R_REGNUM | | regnum = = - 1 )
regcache_raw_supply ( regcache , S R_REGNUM, regs + ( 1 * 4 ) ) ;
if ( regno = = MACH _REGNUM | | regno = = - 1 )
regcache_raw_supply ( current_ regcache, MACH _REGNUM, regs + ( 3 * 4 ) ) ;
if ( regnum = = PR _REGNUM | | regnum = = - 1 )
regcache_raw_supply ( regcache , PR _REGNUM, regs + ( 2 * 4 ) ) ;
if ( regno = = MACL _REGNUM | | regno = = - 1 )
regcache_raw_supply ( current_ regcache, MACL _REGNUM , regs + ( 4 * 4 ) ) ;
if ( regnum = = MACH _REGNUM | | regnum = = - 1 )
regcache_raw_supply ( regcache , MACH _REGNUM , regs + ( 3 * 4 ) ) ;
if ( ( regno > = R0_REGNUM & & regno < = ( R0_REGNUM + 15 ) ) | | regno = = - 1 )
if ( regnum = = MACL_REGNUM | | regnum = = - 1 )
regcache_raw_supply ( regcache , MACL_REGNUM , regs + ( 4 * 4 ) ) ;
for ( i = R0_REGNUM ; i < = ( R0_REGNUM + 15 ) ; i + + )
{
for ( i = R0_REGNUM ; i < = ( R0_REGNUM + 15 ) ; i + + )
if ( regno = = i | | regno = = - 1 )
regcache_raw_supply ( current_regcache , i ,
regs + regmap [ i - R0_REGNUM ] ) ;
i f ( regnum = = i | | regnum = = - 1 )
regcache_raw_supply ( regcache , i , regs + regmap [ i - R0_REGNUM ] ) ;
}
}
/* Collect register REGNUM in the general-purpose register set
REGSET. from register cache REGCACHE into the buffer specified by
GREGS and LEN. If REGNUM is -1, do this for all registers in
REGSET. */
static void
shnbsd_collect_gregset ( const struct regset * regset ,
const struct regcache * regcache ,
int regnum , void * gregs , size_t len )
{
gdb_byte * regs = gregs ;
int i ;
gdb_assert ( len > = SHNBSD_SIZEOF_GREGS ) ;
if ( regnum = = PC_REGNUM | | regnum = = - 1 )
regcache_raw_collect ( regcache , PC_REGNUM , regs + ( 0 * 4 ) ) ;
if ( regnum = = SR_REGNUM | | regnum = = - 1 )
regcache_raw_collect ( regcache , SR_REGNUM , regs + ( 1 * 4 ) ) ;
if ( regnum = = PR_REGNUM | | regnum = = - 1 )
regcache_raw_collect ( regcache , PR_REGNUM , regs + ( 2 * 4 ) ) ;
if ( regnum = = MACH_REGNUM | | regnum = = - 1 )
regcache_raw_collect ( regcache , MACH_REGNUM , regs + ( 3 * 4 ) ) ;
if ( regnum = = MACL_REGNUM | | regnum = = - 1 )
regcache_raw_collect ( regcache , MACL_REGNUM , regs + ( 4 * 4 ) ) ;
for ( i = R0_REGNUM ; i < = ( R0_REGNUM + 15 ) ; i + + )
{
if ( regnum = = i | | regnum = = - 1 )
regcache_raw_collect ( regcache , i , regs + regmap [ i - R0_REGNUM ] ) ;
}
}
/* SH register sets. */
static struct regset shnbsd_gregset =
{
NULL ,
shnbsd_supply_gregset ,
shnbsd_collect_gregset
} ;
/* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
const struct regset *
shnbsd_regset_from_core_section ( struct gdbarch * gdbarch ,
const char * sect_name , size_t sect_size )
{
if ( strcmp ( sect_name , " .reg " ) = = 0 & & sect_size > = SHNBSD_SIZEOF_GREGS )
return & shnbsd_gregset ;
return NULL ;
}
void
shnbsd_fill _reg ( char * regs , int regno )
shnbsd_supply _reg ( char * regs , int regnum )
{
int i ;
if ( regno = = PC_REGNUM | | regno = = - 1 )
regcache_raw_collect ( current_regcache , PC_REGNUM , regs + ( 0 * 4 ) ) ;
if ( regno = = SR_REGNUM | | regno = = - 1 )
regcache_raw_collect ( current_regcache , SR_REGNUM , regs + ( 1 * 4 ) ) ;
if ( regno = = PR_REGNUM | | regno = = - 1 )
regcache_raw_collect ( current_regcache , PR_REGNUM , regs + ( 2 * 4 ) ) ;
if ( regno = = MACH_REGNUM | | regno = = - 1 )
regcache_raw_collect ( current_regcache , MACH_REGNUM , regs + ( 3 * 4 ) ) ;
if ( regno = = MACL_REGNUM | | regno = = - 1 )
regcache_raw_collect ( current_regcache , MACL_REGNUM , regs + ( 4 * 4 ) ) ;
if ( ( regno > = R0_REGNUM & & regno < = ( R0_REGNUM + 15 ) ) | | regno = = - 1 )
{
for ( i = R0_REGNUM ; i < = ( R0_REGNUM + 15 ) ; i + + )
if ( regno = = i | | regno = = - 1 )
regcache_raw_collect ( current_regcache , i ,
regs + regmap [ i - R0_REGNUM ] ) ;
}
shnbsd_supply_gregset ( & shnbsd_gregset , current_regcache , regnum ,
regs , SHNBSD_SIZEOF_GREGS ) ;
}
static void
fetch_core_registers ( char * core_reg_sect , unsigned core_reg_size ,
int which , CORE_ADDR ignore )
void
shnbsd_fill_reg ( char * regs , int regnum )
{
/* We get everything from the .reg section. */
if ( which ! = 0 )
return ;
if ( core_reg_size < SIZEOF_STRUCT_REG )
{
warning ( _ ( " Wrong size register set in core file. " ) ) ;
return ;
}
/* Integer registers. */
shnbsd_supply_reg ( core_reg_sect , - 1 ) ;
shnbsd_collect_gregset ( & shnbsd_gregset , current_regcache , regnum ,
regs , SHNBSD_SIZEOF_GREGS ) ;
}
static void
fetch_elfcore_registers ( char * core_reg_sect , unsigned core_reg_size ,
int which , CORE_ADDR ignore )
{
switch ( which )
{
case 0 : /* Integer registers. */
if ( core_reg_size ! = SIZEOF_STRUCT_REG )
warning ( _ ( " Wrong size register set in core file. " ) ) ;
else
shnbsd_supply_reg ( core_reg_sect , - 1 ) ;
break ;
default :
/* Don't know what kind of register request this is; just ignore it. */
break ;
}
}
static struct core_fns shnbsd_core_fns =
{
bfd_target_unknown_flavour , /* core_flavour */
default_check_format , /* check_format */
default_core_sniffer , /* core_sniffer */
fetch_core_registers , /* core_read_registers */
NULL /* next */
} ;
static struct core_fns shnbsd_elfcore_fns =
{
bfd_target_elf_flavour , /* core_flavour */
default_check_format , /* check_format */
default_core_sniffer , /* core_sniffer */
fetch_elfcore_registers , /* core_read_registers */
NULL /* next */
} ;
static void
shnbsd_init_abi ( struct gdbarch_info info ,
struct gdbarch * gdbarch )
{
set_solib_svr4_fetch_link_map_offsets ( gdbarch ,
nbsd_ilp32_solib_svr4_fetch_link_map_offsets ) ;
set_gdbarch_regset_from_core_section
( gdbarch , shnbsd_regset_from_core_section ) ;
set_solib_svr4_fetch_link_map_offsets
( gdbarch , svr4_ilp32_fetch_link_map_offsets ) ;
}
/* OpenBSD uses uses the traditional NetBSD core file format, even for
ports that use ELF. */
# define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
static enum gdb_osabi
shnbsd_core_osabi_sniffer ( bfd * abfd )
{
if ( strcmp ( bfd_get_target ( abfd ) , " netbsd-core " ) = = 0 )
return GDB_OSABI_NETBSD_CORE ;
return GDB_OSABI_UNKNOWN ;
}
void
_initialize_shnbsd_tdep ( void )
{
deprecated_add_core_fns ( & shnbsd_core_fns ) ;
deprecated_add_core_fns ( & shnbsd_elfcore_fns ) ;
/* BFD doesn't set a flavour for NetBSD style a.out core files. */
gdbarch_register_osabi_sniffer ( bfd_arch_sh , bfd_target_unknown_flavour ,
shnbsd_core_osabi_sniffer ) ;
gdbarch_register_osabi ( bfd_arch_sh , 0 , GDB_OSABI_NETBSD_ELF ,
shnbsd_init_abi ) ;