binutils-gdb/gdb/gdbserver/linux-nios2-low.c
Adhemerval Zanella 754653a7c0 Sync proc_service definition with GLIBC
GLIBC BZ#20311 [1] proc_service.h install patch also remove 'const'
attributes from ps_get_thread_area and comment #15 discuss why to remove
the const attribute (basically since it a callback with the struct
ps_prochandle owned by the client it should be able to modify it if
it the case).

On default build this is not the issue and current g++ does not trigger
any issue with this mismatch declaration.  However, on some bootstrap
build configuration where gdbserver is build with gcc instead this
triggers:

error: conflicting types for 'ps_get_thread_area'

This patch fixes it by syncing the declaration with GLIBC.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=20311

gdb/ChangeLog:

2016-08-25  Adhemerval Zanella  <adhemerval.zanella@linaro.org>

	* aarch64-linux-nat.c (ps_get_thread_area): Remove const from
	struct ps_prochandle.
	* amd64-linux-nat.c (ps_get_thread_area): Likewise.
	* arm-linux-nat.c (ps_get_thread_area): Likewise.
	* gdb_proc_service.h (ps_get_thread_area): Likewise.
	* i386-linux-nat.c (ps_get_thread_area): Likewise.
	* m68klinux-nat.c (ps_get_thread_area): Likewise.
	* mips-linux-nat.c (ps_get_thread_area): Likewise.
	* nat/aarch64-linux.c (aarch64_ps_get_thread_area): Likewise.
	* nat/aarch64-linux.h (aarch64_ps_get_thread_area): Likewise.
	* xtensa-linux-nat.c (ps_get_thread_area): Likewise.

gdb/gdbserver/ChangeLog:

2016-08-25  Adhemerval Zanella  <adhemerval.zanella@linaro.org>

	PR server/20491
	* gdb_proc_service.h (ps_get_thread_area): Remove const from struct
	ps_prochandle.
	* linux-aarch64-low.c (ps_get_thread_area): Likewise.
	* linux-arm-low.c (ps_get_thread_area): Likewise.
	* linux-crisv32-low.c (ps_get_thread_area): Likewise.
	* linux-m68k-low.c (ps_get_thread_area): Likewise.
	* linux-mips-low.c (ps_get_thread_area): Likewise.
	* linux-nios2-low.c (ps_get_thread_area): Likewise.
	* linux-tic6x-low.c (ps_get_thread_area): Likewise.
	* linux-x86-low.c (ps_get_thread_area): Likewise.
	* linux-xtensa-low.c (ps_get_thread_area): Likewise.
2016-08-25 08:42:03 +01:00

260 lines
6.4 KiB
C

/* GNU/Linux/Nios II specific low level interface, for the remote server for
GDB.
Copyright (C) 2008-2016 Free Software Foundation, Inc.
Contributed by Mentor Graphics, 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 "server.h"
#include "linux-low.h"
#include "elf/common.h"
#include "nat/gdb_ptrace.h"
#include <endian.h>
#include "gdb_proc_service.h"
#include <asm/ptrace.h>
#ifndef PTRACE_GET_THREAD_AREA
#define PTRACE_GET_THREAD_AREA 25
#endif
/* The following definition must agree with the number of registers
defined in "struct user_regs" in GLIBC
(sysdeps/unix/sysv/linux/nios2/sys/user.h), and also with
NIOS2_NUM_REGS in GDB proper. */
#define nios2_num_regs 49
/* Defined in auto-generated file nios2-linux.c. */
void init_registers_nios2_linux (void);
extern const struct target_desc *tdesc_nios2_linux;
/* This union is used to convert between int and byte buffer
representations of register contents. */
union nios2_register
{
unsigned char buf[4];
int reg32;
};
/* Return the ptrace ``address'' of register REGNO. */
static int nios2_regmap[] = {
-1, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48,
0
};
/* Implement the arch_setup linux_target_ops method. */
static void
nios2_arch_setup (void)
{
current_process ()->tdesc = tdesc_nios2_linux;
}
/* Implement the cannot_fetch_register linux_target_ops method. */
static int
nios2_cannot_fetch_register (int regno)
{
if (nios2_regmap[regno] == -1)
return 1;
return 0;
}
/* Implement the cannot_store_register linux_target_ops method. */
static int
nios2_cannot_store_register (int regno)
{
if (nios2_regmap[regno] == -1)
return 1;
return 0;
}
/* Breakpoint support. Also see comments on nios2_breakpoint_from_pc
in nios2-tdep.c. */
#if defined(__nios2_arch__) && __nios2_arch__ == 2
#define NIOS2_BREAKPOINT 0xb7fd0020
#define CDX_BREAKPOINT 0xd7c9
#else
#define NIOS2_BREAKPOINT 0x003b6ffa
#endif
/* We only register the 4-byte breakpoint, even on R2 targets which also
support 2-byte breakpoints. Since there is no supports_z_point_type
function provided, gdbserver never inserts software breakpoints itself
and instead relies on GDB to insert the breakpoint of the correct length
via a memory write. */
static const unsigned int nios2_breakpoint = NIOS2_BREAKPOINT;
#define nios2_breakpoint_len 4
/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
static const gdb_byte *
nios2_sw_breakpoint_from_kind (int kind, int *size)
{
*size = nios2_breakpoint_len;
return (const gdb_byte *) &nios2_breakpoint;
}
/* Implement the breakpoint_at linux_target_ops method. */
static int
nios2_breakpoint_at (CORE_ADDR where)
{
unsigned int insn;
/* For R2, first check for the 2-byte CDX trap.n breakpoint encoding. */
#if defined(__nios2_arch__) && __nios2_arch__ == 2
(*the_target->read_memory) (where, (unsigned char *) &insn, 2);
if (insn == CDX_BREAKPOINT)
return 1;
#endif
(*the_target->read_memory) (where, (unsigned char *) &insn, 4);
if (insn == nios2_breakpoint)
return 1;
return 0;
}
/* Fetch the thread-local storage pointer for libthread_db. */
ps_err_e
ps_get_thread_area (struct ps_prochandle *ph,
lwpid_t lwpid, int idx, void **base)
{
if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
return PS_ERR;
/* IDX is the bias from the thread pointer to the beginning of the
thread descriptor. It has to be subtracted due to implementation
quirks in libthread_db. */
*base = (void *) ((char *) *base - idx);
return PS_OK;
}
/* Helper functions to collect/supply a single register REGNO. */
static void
nios2_collect_register (struct regcache *regcache, int regno,
union nios2_register *reg)
{
union nios2_register tmp_reg;
collect_register (regcache, regno, &tmp_reg.reg32);
reg->reg32 = tmp_reg.reg32;
}
static void
nios2_supply_register (struct regcache *regcache, int regno,
const union nios2_register *reg)
{
supply_register (regcache, regno, reg->buf);
}
/* We have only a single register set on Nios II. */
static void
nios2_fill_gregset (struct regcache *regcache, void *buf)
{
union nios2_register *regset = (union nios2_register *) buf;
int i;
for (i = 1; i < nios2_num_regs; i++)
nios2_collect_register (regcache, i, regset + i);
}
static void
nios2_store_gregset (struct regcache *regcache, const void *buf)
{
const union nios2_register *regset = (union nios2_register *) buf;
int i;
for (i = 0; i < nios2_num_regs; i++)
nios2_supply_register (regcache, i, regset + i);
}
static struct regset_info nios2_regsets[] =
{
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
nios2_num_regs * 4, GENERAL_REGS,
nios2_fill_gregset, nios2_store_gregset },
NULL_REGSET
};
static struct regsets_info nios2_regsets_info =
{
nios2_regsets, /* regsets */
0, /* num_regsets */
NULL, /* disabled_regsets */
};
static struct usrregs_info nios2_usrregs_info =
{
nios2_num_regs,
nios2_regmap,
};
static struct regs_info regs_info =
{
NULL, /* regset_bitmap */
&nios2_usrregs_info,
&nios2_regsets_info
};
static const struct regs_info *
nios2_regs_info (void)
{
return &regs_info;
}
struct linux_target_ops the_low_target =
{
nios2_arch_setup,
nios2_regs_info,
nios2_cannot_fetch_register,
nios2_cannot_store_register,
NULL,
linux_get_pc_32bit,
linux_set_pc_32bit,
NULL, /* breakpoint_kind_from_pc */
nios2_sw_breakpoint_from_kind,
NULL, /* get_next_pcs */
0,
nios2_breakpoint_at,
};
void
initialize_low_arch (void)
{
init_registers_nios2_linux ();
initialize_regsets_info (&nios2_regsets_info);
}