From owner-svn-ports-all@freebsd.org Thu Jan 12 21:40:07 2017 Return-Path: Delivered-To: svn-ports-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9A2CDCACEC5; Thu, 12 Jan 2017 21:40:07 +0000 (UTC) (envelope-from olivier@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 62A941116; Thu, 12 Jan 2017 21:40:07 +0000 (UTC) (envelope-from olivier@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v0CLe63i079108; Thu, 12 Jan 2017 21:40:06 GMT (envelope-from olivier@FreeBSD.org) Received: (from olivier@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v0CLe6ki079103; Thu, 12 Jan 2017 21:40:06 GMT (envelope-from olivier@FreeBSD.org) Message-Id: <201701122140.v0CLe6ki079103@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: olivier set sender to olivier@FreeBSD.org using -f From: Olivier Cochard Date: Thu, 12 Jan 2017 21:40:06 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r431323 - in head/devel/gdb: . files files/kgdb X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Jan 2017 21:40:07 -0000 Author: olivier Date: Thu Jan 12 21:40:06 2017 New Revision: 431323 URL: https://svnweb.freebsd.org/changeset/ports/431323 Log: Add MIPS support and other fixes PR: 215938 - Main PR that merge all Submitted by: luca.pizzamiglio@gmail.com (maintainer) PR: 215783 - Add MIPS support Submitted by: jhb Sponsored by: DARPA / AFRL PR: 215868 - Fix build on powerpc architecture Reported by: Mark Millard PR: 212607 - Add a workaround to mitigate gdb hangs under some circumstances with multi-threaded applications (thanks to misc-freebsd-bugzilla@talk2dom.com) Reported by: tijl PR: 215578 - Fix build by removing option to use system readline Reported by: rozhuk.im@gmail.com Added: head/devel/gdb/files/commit-387360daf9 (contents, props changed) head/devel/gdb/files/commit-b268007c68 (contents, props changed) head/devel/gdb/files/kgdb/mipsfbsd-kern.c (contents, props changed) Deleted: head/devel/gdb/files/extrapatch-base-readline Modified: head/devel/gdb/Makefile head/devel/gdb/distinfo head/devel/gdb/files/extrapatch-kgdb head/devel/gdb/files/kgdb/ppcfbsd-kern.c head/devel/gdb/files/kgdb/sparc64fbsd-kern.c head/devel/gdb/files/patch-gdb-fbsd-nat.c Modified: head/devel/gdb/Makefile ============================================================================== --- head/devel/gdb/Makefile Thu Jan 12 21:34:38 2017 (r431322) +++ head/devel/gdb/Makefile Thu Jan 12 21:40:06 2017 (r431323) @@ -3,6 +3,7 @@ PORTNAME= gdb PORTVERSION= 7.12 +PORTREVISION= 1 CATEGORIES= devel MASTER_SITES= GNU @@ -30,32 +31,30 @@ CFLAGS:= ${CFLAGS:C/ +$//} # blanks at E CFLAGS+= -DRL_NO_COMPAT -Wno-unused-function -Wno-unused-variable EXCLUDE= dejagnu expect sim texinfo intl EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /} +EXTRA_PATCHES= ${FILESDIR}/commit-387360daf9 \ + ${FILESDIR}/commit-b268007c68 LIB_DEPENDS+= libexpat.so:textproc/expat2 VER= ${PORTVERSION:S/.//g} PLIST_SUB= VER=${VER} -ONLY_FOR_ARCHS= i386 amd64 powerpc powerpc64 armv6 # untested elsewhere, might work +ONLY_FOR_ARCHS= i386 amd64 powerpc powerpc64 armv6 mips # untested elsewhere, might work OPTIONS_DEFINE= DEBUG GDB_LINK GUILE KGDB PYTHON TUI OPTIONS_DEFAULT= GDB_LINK KGDB PYTHON TUI PORT_READLINE OPTIONS_SINGLE= READLINE -OPTIONS_SINGLE_READLINE= BASE_READLINE BUNDLED_READLINE PORT_READLINE +OPTIONS_SINGLE_READLINE= BUNDLED_READLINE PORT_READLINE GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink KGDB_DESC= Kernel Debugging Support -BASE_READLINE_DESC= from base system BUNDLED_READLINE_DESC= from gdb distfile PORT_READLINE_DESC= from devel/readline port TUI_DESC= Text User Interface enabled OPTIONS_SUB= yes -BASE_READLINE_USES= readline -BASE_READLINE_CFLAGS= -D_rl_echoing_p=readline_echoing_p -BASE_READLINE_EXTRA_PATCHES= ${FILESDIR}/extrapatch-base-readline BUNDLED_READLINE_CONFIGURE_OFF= --with-system-readline DEBUG_CFLAGS= -g GUILE_CONFIGURE_WITH= guile @@ -69,9 +68,6 @@ TUI_CONFIGURE_ENABLE= tui .include -# The option -Wno-extended-offsetof is supported by clang only -CFLAGS+= -Wno-extended-offsetof - .if ! ${PORT_OPTIONS:MBUNDLED_READLINE} EXCLUDE+= readline .endif @@ -80,6 +76,10 @@ EXCLUDE+= readline CONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL} .endif +.if ${ARCH} != "mips" +CFLAGS+= -Wno-extended-offsetof +.endif + post-patch: @${REINPLACE_CMD} -e 's|$$| [GDB v${PORTVERSION} for FreeBSD]|' \ ${WRKSRC}/gdb/version.in Modified: head/devel/gdb/distinfo ============================================================================== --- head/devel/gdb/distinfo Thu Jan 12 21:34:38 2017 (r431322) +++ head/devel/gdb/distinfo Thu Jan 12 21:40:06 2017 (r431323) @@ -1,3 +1,3 @@ -TIMESTAMP = 1480413713 +TIMESTAMP = 1483525133 SHA256 (gdb-7.12.tar.xz) = 834ff3c5948b30718343ea57b11cbc3235d7995c6a4f3a5cecec8c8114164f94 SIZE (gdb-7.12.tar.xz) = 19219556 Added: head/devel/gdb/files/commit-387360daf9 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/devel/gdb/files/commit-387360daf9 Thu Jan 12 21:40:06 2017 (r431323) @@ -0,0 +1,1360 @@ +commit 9978d70207d8a6bc7ff3c570814053c68e78b913 +Author: John Baldwin +Date: Wed Jan 4 09:41:58 2017 -0800 + + Add FreeBSD/mips architecture. + + This has been tested for the n64 and o32 ABIs. Signal frame unwinders for + both ABIs are provided. FreeBSD/mips requires custom linkmap offsets since + it contains an additional l_off member in 'struct link_map' that other + FreeBSD platforms do not have. Support for collecting and supplying + general purpose and floating point register sets are provided. Common + routines for working with native format register sets are exported for + use by the native target. + + gdb/ChangeLog: + + * Makefile.in (ALL_TARGET_OBS): Add mips-fbsd-tdep.o. + (ALLDEPFILES): Add mips-fbsd-tdep.c. + * NEWS: Mention new FreeBSD/mips target. + * configure.tgt: Add mips*-*-freebsd*. + * mips-fbsd-tdep.c: New file. + * mips-fbsd-tdep.h: New file. + + gdb/doc/ChangeLog: + + * gdb.texinfo (Contributors): Add SRI International and University + of Cambridge for FreeBSD/mips. + +diff --git gdb/Makefile.in gdb/Makefile.in +index 7b2df86878..300c2cb702 100644 +--- gdb/Makefile.in ++++ gdb/Makefile.in +@@ -685,6 +685,7 @@ ALL_TARGET_OBS = \ + m88k-tdep.o \ + mep-tdep.o \ + microblaze-tdep.o microblaze-linux-tdep.o \ ++ mips-fbsd-tdep.o \ + mips-linux-tdep.o mips-sde-tdep.o \ + mipsnbsd-tdep.o mips-tdep.o \ + mn10300-linux-tdep.o mn10300-tdep.o \ +@@ -1724,6 +1725,7 @@ ALLDEPFILES = \ + m88k-tdep.c m88kbsd-nat.c \ + microblaze-tdep.c microblaze-linux-tdep.c \ + mingw-hdep.c common/mingw-strerror.c \ ++ mips-fbsd-tdep.c \ + mips-linux-nat.c mips-linux-tdep.c \ + mips-sde-tdep.c \ + mips-tdep.c \ +diff --git gdb/configure.tgt gdb/configure.tgt +index 7f1aac3742..9ee9f7a799 100644 +--- gdb/configure.tgt ++++ gdb/configure.tgt +@@ -358,6 +358,11 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) + gdb_target_obs="mips-tdep.o mipsnbsd-tdep.o solib-svr4.o nbsd-tdep.o" + gdb_sim=../sim/mips/libsim.a + ;; ++mips*-*-freebsd*) ++ # Target: MIPS running FreeBSD ++ gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o solib-svr4.o fbsd-tdep.o" ++ gdb_sim=../sim/mips/libsim.a ++ ;; + mips64*-*-openbsd*) + # Target: OpenBSD/mips64 + gdb_target_obs="mips-tdep.o mips64obsd-tdep.o obsd-tdep.o solib-svr4.o" +diff --git gdb/doc/gdb.texinfo gdb/doc/gdb.texinfo +index 067a45b2de..179da5cdb3 100644 +--- gdb/doc/gdb.texinfo ++++ gdb/doc/gdb.texinfo +@@ -541,6 +541,11 @@ Steve Tjiang, John Newlin, and Scott Foehner. + Michael Eager and staff of Xilinx, Inc., contributed support for the + Xilinx MicroBlaze architecture. + ++Initial support for the FreeBSD/mips target and native configuration ++was developed by SRI International and the University of Cambridge ++Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 ++("CTSRD"), as part of the DARPA CRASH research programme. ++ + @node Sample Session + @chapter A Sample @value{GDBN} Session + +diff --git gdb/mips-fbsd-tdep.c gdb/mips-fbsd-tdep.c +new file mode 100644 +index 0000000000..733534ddac +--- /dev/null ++++ gdb/mips-fbsd-tdep.c +@@ -0,0 +1,560 @@ ++/* Target-dependent code for FreeBSD/mips. ++ ++ Copyright (C) 2017 Free Software Foundation, 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 . */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "regset.h" ++#include "trad-frame.h" ++#include "tramp-frame.h" ++ ++#include "fbsd-tdep.h" ++#include "mips-tdep.h" ++#include "mips-fbsd-tdep.h" ++ ++#include "solib-svr4.h" ++ ++/* Shorthand for some register numbers used below. */ ++#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM ++#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM ++#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32 ++ ++/* Core file support. */ ++ ++/* Number of registers in `struct reg' from . The ++ first 38 follow the standard MIPS layout. The 39th holds ++ IC_INT_REG on RM7K and RM9K processors. The 40th is a dummy for ++ padding. */ ++#define MIPS_FBSD_NUM_GREGS 40 ++ ++/* Number of registers in `struct fpreg' from . The ++ first 32 hold floating point registers. 33 holds the FSR. The ++ 34th is a dummy for padding. */ ++#define MIPS_FBSD_NUM_FPREGS 34 ++ ++/* Supply a single register. If the source register size matches the ++ size the regcache expects, this can use regcache_raw_supply(). If ++ they are different, this copies the source register into a buffer ++ that can be passed to regcache_raw_supply(). */ ++ ++static void ++mips_fbsd_supply_reg (struct regcache *regcache, int regnum, const void *addr, ++ size_t len) ++{ ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ ++ if (register_size (gdbarch, regnum) == len) ++ regcache_raw_supply (regcache, regnum, addr); ++ else ++ { ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ gdb_byte buf[MAX_REGISTER_SIZE]; ++ LONGEST val; ++ ++ val = extract_signed_integer ((const gdb_byte *) addr, len, byte_order); ++ store_signed_integer (buf, register_size (gdbarch, regnum), byte_order, ++ val); ++ regcache_raw_supply (regcache, regnum, buf); ++ } ++} ++ ++/* Collect a single register. If the destination register size ++ matches the size the regcache expects, this can use ++ regcache_raw_supply(). If they are different, this fetches the ++ register via regcache_raw_supply() into a buffer and then copies it ++ into the final destination. */ ++ ++static void ++mips_fbsd_collect_reg (const struct regcache *regcache, int regnum, void *addr, ++ size_t len) ++{ ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ ++ if (register_size (gdbarch, regnum) == len) ++ regcache_raw_collect (regcache, regnum, addr); ++ else ++ { ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ gdb_byte buf[MAX_REGISTER_SIZE]; ++ LONGEST val; ++ ++ regcache_raw_collect (regcache, regnum, buf); ++ val = extract_signed_integer (buf, register_size (gdbarch, regnum), ++ byte_order); ++ store_signed_integer ((gdb_byte *) addr, len, byte_order, val); ++ } ++} ++ ++/* Supply the floating-point registers stored in FPREGS to REGCACHE. ++ Each floating-point register in FPREGS is REGSIZE bytes in ++ length. */ ++ ++void ++mips_fbsd_supply_fpregs (struct regcache *regcache, int regnum, ++ const void *fpregs, size_t regsize) ++{ ++ const gdb_byte *regs = (const gdb_byte *) fpregs; ++ int i; ++ ++ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_supply_reg (regcache, i, ++ regs + (i - MIPS_FP0_REGNUM) * regsize, regsize); ++} ++ ++/* Supply the general-purpose registers stored in GREGS to REGCACHE. ++ Each general-purpose register in GREGS is REGSIZE bytes in ++ length. */ ++ ++void ++mips_fbsd_supply_gregs (struct regcache *regcache, int regnum, ++ const void *gregs, size_t regsize) ++{ ++ const gdb_byte *regs = (const gdb_byte *) gregs; ++ int i; ++ ++ for (i = 0; i <= MIPS_PC_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_supply_reg (regcache, i, regs + i * regsize, regsize); ++} ++ ++/* Collect the floating-point registers from REGCACHE and store them ++ in FPREGS. Each floating-point register in FPREGS is REGSIZE bytes ++ in length. */ ++ ++void ++mips_fbsd_collect_fpregs (const struct regcache *regcache, int regnum, ++ void *fpregs, size_t regsize) ++{ ++ gdb_byte *regs = (gdb_byte *) fpregs; ++ int i; ++ ++ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_collect_reg (regcache, i, ++ regs + (i - MIPS_FP0_REGNUM) * regsize, regsize); ++} ++ ++/* Collect the general-purpose registers from REGCACHE and store them ++ in GREGS. Each general-purpose register in GREGS is REGSIZE bytes ++ in length. */ ++ ++void ++mips_fbsd_collect_gregs (const struct regcache *regcache, int regnum, ++ void *gregs, size_t regsize) ++{ ++ gdb_byte *regs = (gdb_byte *) gregs; ++ int i; ++ ++ for (i = 0; i <= MIPS_PC_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_collect_reg (regcache, i, regs + i * regsize, regsize); ++} ++ ++/* Supply register REGNUM from the buffer specified by FPREGS and LEN ++ in the floating-point register set REGSET to register cache ++ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ ++ ++static void ++mips_fbsd_supply_fpregset (const struct regset *regset, ++ struct regcache *regcache, ++ int regnum, const void *fpregs, size_t len) ++{ ++ size_t regsize = mips_abi_regsize (get_regcache_arch (regcache)); ++ ++ gdb_assert (len >= MIPS_FBSD_NUM_FPREGS * regsize); ++ ++ mips_fbsd_supply_fpregs (regcache, regnum, fpregs, regsize); ++} ++ ++/* Collect register REGNUM from the register cache REGCACHE and store ++ it in the buffer specified by FPREGS and LEN in the floating-point ++ register set REGSET. If REGNUM is -1, do this for all registers in ++ REGSET. */ ++ ++static void ++mips_fbsd_collect_fpregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *fpregs, size_t len) ++{ ++ size_t regsize = mips_abi_regsize (get_regcache_arch (regcache)); ++ ++ gdb_assert (len >= MIPS_FBSD_NUM_FPREGS * regsize); ++ ++ mips_fbsd_collect_fpregs (regcache, regnum, fpregs, regsize); ++} ++ ++/* 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 ++mips_fbsd_supply_gregset (const struct regset *regset, ++ struct regcache *regcache, int regnum, ++ const void *gregs, size_t len) ++{ ++ size_t regsize = mips_abi_regsize (get_regcache_arch (regcache)); ++ ++ gdb_assert (len >= MIPS_FBSD_NUM_GREGS * regsize); ++ ++ mips_fbsd_supply_gregs (regcache, regnum, gregs, regsize); ++} ++ ++/* Collect register REGNUM from the register cache REGCACHE and store ++ it in the buffer specified by GREGS and LEN in the general-purpose ++ register set REGSET. If REGNUM is -1, do this for all registers in ++ REGSET. */ ++ ++static void ++mips_fbsd_collect_gregset (const struct regset *regset, ++ const struct regcache *regcache, ++ int regnum, void *gregs, size_t len) ++{ ++ size_t regsize = mips_abi_regsize (get_regcache_arch (regcache)); ++ ++ gdb_assert (len >= MIPS_FBSD_NUM_GREGS * regsize); ++ ++ mips_fbsd_collect_gregs (regcache, regnum, gregs, regsize); ++} ++ ++/* FreeBSD/mips register sets. */ ++ ++static const struct regset mips_fbsd_gregset = ++{ ++ NULL, ++ mips_fbsd_supply_gregset, ++ mips_fbsd_collect_gregset, ++}; ++ ++static const struct regset mips_fbsd_fpregset = ++{ ++ NULL, ++ mips_fbsd_supply_fpregset, ++ mips_fbsd_collect_fpregset, ++}; ++ ++/* Iterate over core file register note sections. */ ++ ++static void ++mips_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, ++ iterate_over_regset_sections_cb *cb, ++ void *cb_data, ++ const struct regcache *regcache) ++{ ++ size_t regsize = mips_abi_regsize (gdbarch); ++ ++ cb (".reg", MIPS_FBSD_NUM_GREGS * regsize, &mips_fbsd_gregset, ++ NULL, cb_data); ++ cb (".reg2", MIPS_FBSD_NUM_FPREGS * regsize, &mips_fbsd_fpregset, ++ NULL, cb_data); ++} ++ ++/* Signal trampoline support. */ ++ ++#define FBSD_SYS_sigreturn 417 ++ ++#define MIPS_INST_LI_V0_SIGRETURN 0x24020000 + FBSD_SYS_sigreturn ++#define MIPS_INST_SYSCALL 0x0000000c ++#define MIPS_INST_BREAK 0x0000000d ++ ++#define O32_SIGFRAME_UCONTEXT_OFFSET (16) ++#define O32_SIGSET_T_SIZE (16) ++ ++#define O32_UCONTEXT_ONSTACK (O32_SIGSET_T_SIZE) ++#define O32_UCONTEXT_PC (O32_UCONTEXT_ONSTACK + 4) ++#define O32_UCONTEXT_REGS (O32_UCONTEXT_PC + 4) ++#define O32_UCONTEXT_SR (O32_UCONTEXT_REGS + 4 * 32) ++#define O32_UCONTEXT_LO (O32_UCONTEXT_SR + 4) ++#define O32_UCONTEXT_HI (O32_UCONTEXT_LO + 4) ++#define O32_UCONTEXT_FPUSED (O32_UCONTEXT_HI + 4) ++#define O32_UCONTEXT_FPREGS (O32_UCONTEXT_FPUSED + 4) ++ ++#define O32_UCONTEXT_REG_SIZE 4 ++ ++static void ++mips_fbsd_sigframe_init (const struct tramp_frame *self, ++ struct frame_info *this_frame, ++ struct trad_frame_cache *cache, ++ CORE_ADDR func) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ CORE_ADDR sp, ucontext_addr, addr; ++ int regnum; ++ gdb_byte buf[4]; ++ ++ /* We find the appropriate instance of `ucontext_t' at a ++ fixed offset in the signal frame. */ ++ sp = get_frame_register_signed (this_frame, ++ MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch)); ++ ucontext_addr = sp + O32_SIGFRAME_UCONTEXT_OFFSET; ++ ++ /* PC. */ ++ regnum = mips_regnum (gdbarch)->pc; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + O32_UCONTEXT_PC); ++ ++ /* GPRs. */ ++ for (regnum = MIPS_ZERO_REGNUM, addr = ucontext_addr + O32_UCONTEXT_REGS; ++ regnum <= MIPS_RA_REGNUM; regnum++, addr += O32_UCONTEXT_REG_SIZE) ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ addr); ++ ++ regnum = MIPS_PS_REGNUM; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + O32_UCONTEXT_SR); ++ ++ /* HI and LO. */ ++ regnum = mips_regnum (gdbarch)->lo; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + O32_UCONTEXT_LO); ++ regnum = mips_regnum (gdbarch)->hi; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + O32_UCONTEXT_HI); ++ ++ if (target_read_memory (ucontext_addr + O32_UCONTEXT_FPUSED, buf, 4) == 0 && ++ extract_unsigned_integer (buf, 4, byte_order) != 0) ++ { ++ for (regnum = 0, addr = ucontext_addr + O32_UCONTEXT_FPREGS; ++ regnum < 32; regnum++, addr += O32_UCONTEXT_REG_SIZE) ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_fp0_regnum (gdbarch), ++ addr); ++ trad_frame_set_reg_addr (cache, mips_regnum (gdbarch)->fp_control_status, ++ addr); ++ } ++ ++ trad_frame_set_id (cache, frame_id_build (sp, func)); ++} ++ ++#define MIPS_INST_ADDIU_A0_SP_O32 (0x27a40000 \ ++ + O32_SIGFRAME_UCONTEXT_OFFSET) ++ ++static const struct tramp_frame mips_fbsd_sigframe = ++{ ++ SIGTRAMP_FRAME, ++ MIPS_INSN32_SIZE, ++ { ++ { MIPS_INST_ADDIU_A0_SP_O32, -1 }, /* addiu a0, sp, SIGF_UC */ ++ { MIPS_INST_LI_V0_SIGRETURN, -1 }, /* li v0, SYS_sigreturn */ ++ { MIPS_INST_SYSCALL, -1 }, /* syscall */ ++ { MIPS_INST_BREAK, -1 }, /* break */ ++ { TRAMP_SENTINEL_INSN, -1 } ++ }, ++ mips_fbsd_sigframe_init ++}; ++ ++#define N64_SIGFRAME_UCONTEXT_OFFSET (32) ++#define N64_SIGSET_T_SIZE (16) ++ ++#define N64_UCONTEXT_ONSTACK (N64_SIGSET_T_SIZE) ++#define N64_UCONTEXT_PC (N64_UCONTEXT_ONSTACK + 8) ++#define N64_UCONTEXT_REGS (N64_UCONTEXT_PC + 8) ++#define N64_UCONTEXT_SR (N64_UCONTEXT_REGS + 8 * 32) ++#define N64_UCONTEXT_LO (N64_UCONTEXT_SR + 8) ++#define N64_UCONTEXT_HI (N64_UCONTEXT_LO + 8) ++#define N64_UCONTEXT_FPUSED (N64_UCONTEXT_HI + 8) ++#define N64_UCONTEXT_FPREGS (N64_UCONTEXT_FPUSED + 8) ++ ++#define N64_UCONTEXT_REG_SIZE 8 ++ ++static void ++mips64_fbsd_sigframe_init (const struct tramp_frame *self, ++ struct frame_info *this_frame, ++ struct trad_frame_cache *cache, ++ CORE_ADDR func) ++{ ++ struct gdbarch *gdbarch = get_frame_arch (this_frame); ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ CORE_ADDR sp, ucontext_addr, addr; ++ int regnum; ++ gdb_byte buf[4]; ++ ++ /* We find the appropriate instance of `ucontext_t' at a ++ fixed offset in the signal frame. */ ++ sp = get_frame_register_signed (this_frame, ++ MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch)); ++ ucontext_addr = sp + N64_SIGFRAME_UCONTEXT_OFFSET; ++ ++ /* PC. */ ++ regnum = mips_regnum (gdbarch)->pc; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + N64_UCONTEXT_PC); ++ ++ /* GPRs. */ ++ for (regnum = MIPS_ZERO_REGNUM, addr = ucontext_addr + N64_UCONTEXT_REGS; ++ regnum <= MIPS_RA_REGNUM; regnum++, addr += N64_UCONTEXT_REG_SIZE) ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ addr); ++ ++ regnum = MIPS_PS_REGNUM; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + N64_UCONTEXT_SR); ++ ++ /* HI and LO. */ ++ regnum = mips_regnum (gdbarch)->lo; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + N64_UCONTEXT_LO); ++ regnum = mips_regnum (gdbarch)->hi; ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_num_regs (gdbarch), ++ ucontext_addr + N64_UCONTEXT_HI); ++ ++ if (target_read_memory (ucontext_addr + N64_UCONTEXT_FPUSED, buf, 4) == 0 && ++ extract_unsigned_integer (buf, 4, byte_order) != 0) ++ { ++ for (regnum = 0, addr = ucontext_addr + N64_UCONTEXT_FPREGS; ++ regnum < 32; regnum++, addr += N64_UCONTEXT_REG_SIZE) ++ trad_frame_set_reg_addr (cache, ++ regnum + gdbarch_fp0_regnum (gdbarch), ++ addr); ++ trad_frame_set_reg_addr (cache, mips_regnum (gdbarch)->fp_control_status, ++ addr); ++ } ++ ++ trad_frame_set_id (cache, frame_id_build (sp, func)); ++} ++ ++#define MIPS_INST_DADDIU_A0_SP_N64 (0x67a40000 \ ++ + N64_SIGFRAME_UCONTEXT_OFFSET) ++ ++static const struct tramp_frame mips64_fbsd_sigframe = ++{ ++ SIGTRAMP_FRAME, ++ MIPS_INSN32_SIZE, ++ { ++ { MIPS_INST_DADDIU_A0_SP_N64, -1 }, /* daddiu a0, sp, SIGF_UC */ ++ { MIPS_INST_LI_V0_SIGRETURN, -1 }, /* li v0, SYS_sigreturn */ ++ { MIPS_INST_SYSCALL, -1 }, /* syscall */ ++ { MIPS_INST_BREAK, -1 }, /* break */ ++ { TRAMP_SENTINEL_INSN, -1 } ++ }, ++ mips64_fbsd_sigframe_init ++}; ++ ++/* Shared library support. */ ++ ++/* FreeBSD/mips uses a slightly different `struct link_map' than the ++ other FreeBSD platforms as it includes an additional `l_off' ++ member. */ ++ ++static struct link_map_offsets * ++mips_fbsd_ilp32_fetch_link_map_offsets (void) ++{ ++ static struct link_map_offsets lmo; ++ static struct link_map_offsets *lmp = NULL; ++ ++ if (lmp == NULL) ++ { ++ lmp = &lmo; ++ ++ lmo.r_version_offset = 0; ++ lmo.r_version_size = 4; ++ lmo.r_map_offset = 4; ++ lmo.r_brk_offset = 8; ++ lmo.r_ldsomap_offset = -1; ++ ++ lmo.link_map_size = 24; ++ lmo.l_addr_offset = 0; ++ lmo.l_name_offset = 8; ++ lmo.l_ld_offset = 12; ++ lmo.l_next_offset = 16; ++ lmo.l_prev_offset = 20; ++ } ++ ++ return lmp; ++} ++ ++static struct link_map_offsets * ++mips_fbsd_lp64_fetch_link_map_offsets (void) ++{ ++ static struct link_map_offsets lmo; ++ static struct link_map_offsets *lmp = NULL; ++ ++ if (lmp == NULL) ++ { ++ lmp = &lmo; ++ ++ lmo.r_version_offset = 0; ++ lmo.r_version_size = 4; ++ lmo.r_map_offset = 8; ++ lmo.r_brk_offset = 16; ++ lmo.r_ldsomap_offset = -1; ++ ++ lmo.link_map_size = 48; ++ lmo.l_addr_offset = 0; ++ lmo.l_name_offset = 16; ++ lmo.l_ld_offset = 24; ++ lmo.l_next_offset = 32; ++ lmo.l_prev_offset = 40; ++ } ++ ++ return lmp; ++} ++ ++static void ++mips_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) ++{ ++ enum mips_abi abi = mips_abi (gdbarch); ++ ++ /* Generic FreeBSD support. */ ++ fbsd_init_abi (info, gdbarch); ++ ++ set_gdbarch_software_single_step (gdbarch, mips_software_single_step); ++ ++ switch (abi) ++ { ++ case MIPS_ABI_O32: ++ tramp_frame_prepend_unwinder (gdbarch, &mips_fbsd_sigframe); ++ break; ++ case MIPS_ABI_N32: ++ break; ++ case MIPS_ABI_N64: ++ tramp_frame_prepend_unwinder (gdbarch, &mips64_fbsd_sigframe); ++ break; ++ } ++ ++ set_gdbarch_iterate_over_regset_sections ++ (gdbarch, mips_fbsd_iterate_over_regset_sections); ++ ++ /* FreeBSD/mips has SVR4-style shared libraries. */ ++ set_solib_svr4_fetch_link_map_offsets ++ (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ? ++ mips_fbsd_ilp32_fetch_link_map_offsets : ++ mips_fbsd_lp64_fetch_link_map_offsets)); ++} ++ ++ ++/* Provide a prototype to silence -Wmissing-prototypes. */ ++void _initialize_mips_fbsd_tdep (void); ++ ++void ++_initialize_mips_fbsd_tdep (void) ++{ ++ gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_ELF, ++ mips_fbsd_init_abi); ++} +diff --git gdb/mips-fbsd-tdep.h gdb/mips-fbsd-tdep.h +new file mode 100644 +index 0000000000..8a197e6325 +--- /dev/null ++++ gdb/mips-fbsd-tdep.h +@@ -0,0 +1,28 @@ ++/* Common target dependent code for GDB on MIPS systems running FreeBSD. ++ ++ Copyright (C) 2017 Free Software Foundation, 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 . */ ++ ++#ifndef MIPS_FBSD_TDEP_H ++#define MIPS_FBSD_TDEP_H ++ ++void mips_fbsd_supply_fpregs (struct regcache *, int, const void *, size_t); ++void mips_fbsd_supply_gregs (struct regcache *, int, const void *, size_t); ++void mips_fbsd_collect_fpregs (const struct regcache *, int, void *, size_t); ++void mips_fbsd_collect_gregs (const struct regcache *, int, void *, size_t); ++ ++#endif /* MIPS_FBSD_TDEP_H */ +commit 9978d70207d8a6bc7ff3c570814053c68e78b913 +Author: John Baldwin +Date: Wed Jan 4 09:41:58 2017 -0800 + + Add FreeBSD/mips architecture. + + This has been tested for the n64 and o32 ABIs. Signal frame unwinders for + both ABIs are provided. FreeBSD/mips requires custom linkmap offsets since + it contains an additional l_off member in 'struct link_map' that other + FreeBSD platforms do not have. Support for collecting and supplying + general purpose and floating point register sets are provided. Common + routines for working with native format register sets are exported for + use by the native target. + + gdb/ChangeLog: + + * Makefile.in (ALL_TARGET_OBS): Add mips-fbsd-tdep.o. + (ALLDEPFILES): Add mips-fbsd-tdep.c. + * NEWS: Mention new FreeBSD/mips target. + * configure.tgt: Add mips*-*-freebsd*. + * mips-fbsd-tdep.c: New file. + * mips-fbsd-tdep.h: New file. + + gdb/doc/ChangeLog: + + * gdb.texinfo (Contributors): Add SRI International and University + of Cambridge for FreeBSD/mips. + +diff --git gdb/Makefile.in gdb/Makefile.in +index 7b2df86878..300c2cb702 100644 +--- gdb/Makefile.in ++++ gdb/Makefile.in +@@ -685,6 +685,7 @@ ALL_TARGET_OBS = \ + m88k-tdep.o \ + mep-tdep.o \ + microblaze-tdep.o microblaze-linux-tdep.o \ ++ mips-fbsd-tdep.o \ + mips-linux-tdep.o mips-sde-tdep.o \ + mipsnbsd-tdep.o mips-tdep.o \ + mn10300-linux-tdep.o mn10300-tdep.o \ +@@ -1724,6 +1725,7 @@ ALLDEPFILES = \ + m88k-tdep.c m88kbsd-nat.c \ + microblaze-tdep.c microblaze-linux-tdep.c \ + mingw-hdep.c common/mingw-strerror.c \ ++ mips-fbsd-tdep.c \ + mips-linux-nat.c mips-linux-tdep.c \ + mips-sde-tdep.c \ + mips-tdep.c \ +diff --git gdb/configure.tgt gdb/configure.tgt +index 7f1aac3742..9ee9f7a799 100644 +--- gdb/configure.tgt ++++ gdb/configure.tgt +@@ -358,6 +358,11 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) + gdb_target_obs="mips-tdep.o mipsnbsd-tdep.o solib-svr4.o nbsd-tdep.o" + gdb_sim=../sim/mips/libsim.a + ;; ++mips*-*-freebsd*) ++ # Target: MIPS running FreeBSD ++ gdb_target_obs="mips-tdep.o mips-fbsd-tdep.o solib-svr4.o fbsd-tdep.o" ++ gdb_sim=../sim/mips/libsim.a ++ ;; + mips64*-*-openbsd*) + # Target: OpenBSD/mips64 + gdb_target_obs="mips-tdep.o mips64obsd-tdep.o obsd-tdep.o solib-svr4.o" +diff --git gdb/doc/gdb.texinfo gdb/doc/gdb.texinfo +index 067a45b2de..179da5cdb3 100644 +--- gdb/doc/gdb.texinfo ++++ gdb/doc/gdb.texinfo +@@ -541,6 +541,11 @@ Steve Tjiang, John Newlin, and Scott Foehner. + Michael Eager and staff of Xilinx, Inc., contributed support for the + Xilinx MicroBlaze architecture. + ++Initial support for the FreeBSD/mips target and native configuration ++was developed by SRI International and the University of Cambridge ++Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 ++("CTSRD"), as part of the DARPA CRASH research programme. ++ + @node Sample Session + @chapter A Sample @value{GDBN} Session + +diff --git gdb/mips-fbsd-tdep.c gdb/mips-fbsd-tdep.c +new file mode 100644 +index 0000000000..733534ddac +--- /dev/null ++++ gdb/mips-fbsd-tdep.c +@@ -0,0 +1,560 @@ ++/* Target-dependent code for FreeBSD/mips. ++ ++ Copyright (C) 2017 Free Software Foundation, 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 . */ ++ ++#include "defs.h" ++#include "osabi.h" ++#include "regset.h" ++#include "trad-frame.h" ++#include "tramp-frame.h" ++ ++#include "fbsd-tdep.h" ++#include "mips-tdep.h" ++#include "mips-fbsd-tdep.h" ++ ++#include "solib-svr4.h" ++ ++/* Shorthand for some register numbers used below. */ ++#define MIPS_PC_REGNUM MIPS_EMBED_PC_REGNUM ++#define MIPS_FP0_REGNUM MIPS_EMBED_FP0_REGNUM ++#define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32 ++ ++/* Core file support. */ ++ ++/* Number of registers in `struct reg' from . The ++ first 38 follow the standard MIPS layout. The 39th holds ++ IC_INT_REG on RM7K and RM9K processors. The 40th is a dummy for ++ padding. */ ++#define MIPS_FBSD_NUM_GREGS 40 ++ ++/* Number of registers in `struct fpreg' from . The ++ first 32 hold floating point registers. 33 holds the FSR. The ++ 34th is a dummy for padding. */ ++#define MIPS_FBSD_NUM_FPREGS 34 ++ ++/* Supply a single register. If the source register size matches the ++ size the regcache expects, this can use regcache_raw_supply(). If ++ they are different, this copies the source register into a buffer ++ that can be passed to regcache_raw_supply(). */ ++ ++static void ++mips_fbsd_supply_reg (struct regcache *regcache, int regnum, const void *addr, ++ size_t len) ++{ ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ ++ if (register_size (gdbarch, regnum) == len) ++ regcache_raw_supply (regcache, regnum, addr); ++ else ++ { ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ gdb_byte buf[MAX_REGISTER_SIZE]; ++ LONGEST val; ++ ++ val = extract_signed_integer ((const gdb_byte *) addr, len, byte_order); ++ store_signed_integer (buf, register_size (gdbarch, regnum), byte_order, ++ val); ++ regcache_raw_supply (regcache, regnum, buf); ++ } ++} ++ ++/* Collect a single register. If the destination register size ++ matches the size the regcache expects, this can use ++ regcache_raw_supply(). If they are different, this fetches the ++ register via regcache_raw_supply() into a buffer and then copies it ++ into the final destination. */ ++ ++static void ++mips_fbsd_collect_reg (const struct regcache *regcache, int regnum, void *addr, ++ size_t len) ++{ ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ ++ if (register_size (gdbarch, regnum) == len) ++ regcache_raw_collect (regcache, regnum, addr); ++ else ++ { ++ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ++ gdb_byte buf[MAX_REGISTER_SIZE]; ++ LONGEST val; ++ ++ regcache_raw_collect (regcache, regnum, buf); ++ val = extract_signed_integer (buf, register_size (gdbarch, regnum), ++ byte_order); ++ store_signed_integer ((gdb_byte *) addr, len, byte_order, val); ++ } ++} ++ ++/* Supply the floating-point registers stored in FPREGS to REGCACHE. ++ Each floating-point register in FPREGS is REGSIZE bytes in ++ length. */ ++ ++void ++mips_fbsd_supply_fpregs (struct regcache *regcache, int regnum, ++ const void *fpregs, size_t regsize) ++{ ++ const gdb_byte *regs = (const gdb_byte *) fpregs; ++ int i; ++ ++ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_supply_reg (regcache, i, ++ regs + (i - MIPS_FP0_REGNUM) * regsize, regsize); ++} ++ ++/* Supply the general-purpose registers stored in GREGS to REGCACHE. ++ Each general-purpose register in GREGS is REGSIZE bytes in ++ length. */ ++ ++void ++mips_fbsd_supply_gregs (struct regcache *regcache, int regnum, ++ const void *gregs, size_t regsize) ++{ ++ const gdb_byte *regs = (const gdb_byte *) gregs; ++ int i; ++ ++ for (i = 0; i <= MIPS_PC_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_supply_reg (regcache, i, regs + i * regsize, regsize); ++} ++ ++/* Collect the floating-point registers from REGCACHE and store them ++ in FPREGS. Each floating-point register in FPREGS is REGSIZE bytes ++ in length. */ ++ ++void ++mips_fbsd_collect_fpregs (const struct regcache *regcache, int regnum, ++ void *fpregs, size_t regsize) ++{ ++ gdb_byte *regs = (gdb_byte *) fpregs; ++ int i; ++ ++ for (i = MIPS_FP0_REGNUM; i <= MIPS_FSR_REGNUM; i++) ++ if (regnum == i || regnum == -1) ++ mips_fbsd_collect_reg (regcache, i, ++ regs + (i - MIPS_FP0_REGNUM) * regsize, regsize); ++} ++ ++/* Collect the general-purpose registers from REGCACHE and store them ++ in GREGS. Each general-purpose register in GREGS is REGSIZE bytes ++ in length. */ ++ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***