Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dgollub
gdb
infcall.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File infcall.diff of Package gdb
From nobody Fri Mar 28 10:36:27 2008 From: "Ulrich Weigand" <uweigand@de.ibm.com> Subject: [rfc] Fix inferior calls during interrupted system calls on PowerPC To: gdb-patches@sourceware.org Date: Thu, 27 Mar 2008 20:33:51 +0100 (CET) Hello, PowerPC still suffers from a problem that was fixed on other platforms a while ago: if GDB wants to perform an inferior call while the inferior is blocked in an (interrupted) system call, the Linux kernel gets confused. With recent kernel versions (>= 2.6.23 I think), it is possible to correctly handle this situation using a similar approach to what is currently done on i386: there, GDB informs the kernel that it wants to do an inferior call by writing to the "special" ORIG_EAX register -- this causes the kernel to not attempt to "restart" the system call. After the inferior call is finished, the original contents of ORIG_EAX are restored. On PowerPC, the same mechanism is possible, except that there are two registers that need to be restored, ORIG_R3 and TRAP. When initiating an inferior call, only TRAP has to be reset. The patch below implements this by adding two new registers, ORIG_R3 and TRAP to the PowerPC Linux register sets. As these are only available on Linux, I've added two new XML features powerpc-linux32 and powerpc-linux64 that include these new registers. Native code in ppc-linux-nat.c will register that it supports those by returning the appropriate feature from ppc_linux_read_description. Similarly, the new ppc_linux_core_read_description routine will handle Linux core files. gdbserver is switched to always use powerpc-linux32/64 instead of powerpc-32/64. This still leaves the new registers out on any non-AltiVec platforms. I guess for powerpc-e500 we could create a similar powerpc-linuxe500 feature, if this is required. I'm not sure how to handle the default (non-AltiVec, non-SPE) case which does not yet use XML. Simply adding registers to the .dat files is probably not a good idea as it might break old GDBs that connect to the new gdbserver ... Any suggestion how we should handle that? Any other comments on this approach are welcome ... Note that the patch below assumes that the AltiVec auto-detection patch is already applied. Tested on powerpc-linux and powerpc64-linux, both natively and using a local gdbserver. Fixes all interrupt.exp failures. Bye, Ulrich ChangeLog: * ppc-tdep.h (struct ppc_reg_offsets): New members orig_r3_offset and trap_offset. (struct gdbarch_tdep): New members ppc_orig_r3_regnum and ppc_trap_regnum. (PPC_ORIG_R3_REGNUM, PPC_TRAP_REGNUM): New enum members. (tdesc_powerpc_linux32, tdesc_powerpc_linux64): Declare. * rs6000-tdep.c: Include features/rs6000/powerpc-linux32.c and features/rs6000/powerpc-linux64.c. (ppc_greg_offset): Handle orig_r3 and trap. (ppc_supply_gregset, ppu_collect_gregset): Likewise. (rs6000_gdbarch_init): Handle org.gnu.gdb.power.linux feature. Set up ppc_orig_r3_regnum and ppc_trap_regnum tdep entries. (_initialize_rs6000_tdep): Call initialize_tdesc_powerpc_linux32 and initialize_tdesc_powerpc_linux64 * ppc-linux-tdep.c (ppc32_linux_reg_offsets): Initialize orig_r3_offset and trap_offset fields. (ppc64_linux_reg_offsets): Likewise. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install them. * ppcnbsd-tdep.c (_initialize_ppcnbsd_tdep): Initialize ppcnbsd_reg_offsets.orig_r3_offset and ppcnbsd_reg_offsets.trap_offset. * ppcobsd-tdep.c (_initialize_ppcobsd_tdep): Initialize ppcobsd_reg_offsets.orig_r3_offset and ppcobsd_reg_offsets.trap_offset. * rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Initialize orig_r3_offset and trap_offset fields. (rs6000_aix64_reg_offsets): Likewise. * ppc-linux-nat.c (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap. (fetch_ppc_registers, store_ppc_registers, store_register): Likewise. (ppc_linux_read_description): Return tdesc_powerpc_linux32 or tdesc_powerpc_linux64 as appropriate. diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux32.c gdb-head/gdb/features/rs6000/powerpc-linux32.c --- gdb-orig/gdb/features/rs6000/powerpc-linux32.c 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux32.c 2008-03-27 00:05:36.394145047 +0100 @@ -0,0 +1,168 @@ +/* THIS FILE IS GENERATED. Original: powerpc-linux32.xml */ + +#include "defs.h" +#include "gdbtypes.h" +#include "target-descriptions.h" + +struct target_desc *tdesc_powerpc_linux32; +static void +initialize_tdesc_powerpc_linux32 (void) +{ + struct target_desc *result = allocate_target_description (); + struct tdesc_feature *feature; + struct type *field_type, *type; + + set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common")); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); + tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr"); + tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); + tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); + tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + field_type = tdesc_named_type (feature, "ieee_single"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4f"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int32"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4i32"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int16"); + type = init_vector_type (field_type, 8); + TYPE_NAME (type) = xstrdup ("v8i16"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int8"); + type = init_vector_type (field_type, 16); + TYPE_NAME (type) = xstrdup ("v16i8"); + tdesc_record_type (feature, type); + + type = init_composite_type (NULL, TYPE_CODE_UNION); + TYPE_NAME (type) = xstrdup ("vec128"); + field_type = tdesc_named_type (feature, "uint128"); + append_composite_type_field (type, xstrdup ("uint128"), field_type); + field_type = tdesc_named_type (feature, "v4f"); + append_composite_type_field (type, xstrdup ("v4_float"), field_type); + field_type = tdesc_named_type (feature, "v4i32"); + append_composite_type_field (type, xstrdup ("v4_int32"), field_type); + field_type = tdesc_named_type (feature, "v8i16"); + append_composite_type_field (type, xstrdup ("v8_int16"), field_type); + field_type = tdesc_named_type (feature, "v16i8"); + append_composite_type_field (type, xstrdup ("v16_int8"), field_type); + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + tdesc_record_type (feature, type); + + tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); + tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); + + tdesc_powerpc_linux32 = result; +} diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux32.xml gdb-head/gdb/features/rs6000/powerpc-linux32.xml --- gdb-orig/gdb/features/rs6000/powerpc-linux32.xml 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux32.xml 2008-03-27 00:05:36.397144616 +0100 @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!-- PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only + view of the PowerPC. Includes Linux-only special "registers". --> + +<!DOCTYPE target SYSTEM "gdb-target.dtd"> +<target> + <architecture>powerpc:common</architecture> + <xi:include href="power-core.xml"/> + <xi:include href="power-fpu.xml"/> + <feature name="org.gnu.gdb.power.linux"> + <reg name="orig_r3" bitsize="32"/> + <reg name="trap" bitsize="32"/> + </feature> + <xi:include href="power-altivec.xml"/> +</target> diff -urNp gdb-orig/gdb/features/rs6000/powerpc-linux64.c gdb-head/gdb/features/rs6000/powerpc-linux64.c --- gdb-orig/gdb/features/rs6000/powerpc-linux64.c 1970-01-01 01:00:00.000000000 +0100 +++ gdb-head/gdb/features/rs6000/powerpc-linux64.c 2008-03-27 00:05:36.403143754 +0100 @@ -0,0 +1,168 @@ +/* THIS FILE IS GENERATED. Original: powerpc-linux64.xml */ + +#include "defs.h" +#include "gdbtypes.h" +#include "target-descriptions.h" + +struct target_desc *tdesc_powerpc_linux64; +static void +initialize_tdesc_powerpc_linux64 (void) +{ + struct target_desc *result = allocate_target_description (); + struct tdesc_feature *feature; + struct type *field_type, *type; + + set_tdesc_architecture (result, bfd_scan_arch ("powerpc:common64")); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.core"); + tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32"); + tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr"); + tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64"); + tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.fpu"); + tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double"); + tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux"); + tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int"); + + feature = tdesc_create_feature (result, "org.gnu.gdb.power.altivec"); + field_type = tdesc_named_type (feature, "ieee_single"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4f"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int32"); + type = init_vector_type (field_type, 4); + TYPE_NAME (type) = xstrdup ("v4i32"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int16"); + type = init_vector_type (field_type, 8); + TYPE_NAME (type) = xstrdup ("v8i16"); + tdesc_record_type (feature, type); + + field_type = tdesc_named_type (feature, "int8"); + type = init_vector_type (field_type, 16); + TYPE_NAME (type) = xstrdup ("v16i8"); + tdesc_record_type (feature, type); + + type = init_composite_type (NULL, TYPE_CODE_UNION); + TYPE_NAME (type) = xstrdup ("vec128"); + field_type = tdesc_named_type (feature, "uint128"); + append_composite_type_field (type, xstrdup ("uint128"), field_type); + field_type = tdesc_named_type (feature, "v4f"); + append_composite_type_field (type, xstrdup ("v4_float"), field_type); + field_type = tdesc_named_type (feature, "v4i32"); + append_composite_type_field (type, xstrdup ("v4_int32"), field_type); + field_type = tdesc_named_type (feature, "v8i16"); + append_composite_type_field (type, xstrdup ("v8_int16"), field_type); + field_type = tdesc_named_type (feature, "v16i8"); + append_composite_type_field (type, xstrdup ("v16_int8"), field_type); + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + tdesc_record_type (feature, type); + + tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128"); + tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int"); + tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int"); + + tdesc_powerpc_linux64 = result; +} diff -urNp gdb-orig/gdb/ppc-linux-nat.c gdb-head/gdb/ppc-linux-nat.c --- gdb-orig/gdb/ppc-linux-nat.c 2008-03-27 00:52:46.050416072 +0100 +++ gdb-head/gdb/ppc-linux-nat.c 2008-03-27 00:05:36.427140307 +0100 @@ -43,6 +43,14 @@ #include "gregset.h" #include "ppc-tdep.h" +/* This sometimes isn't defined. */ +#ifndef PT_ORIG_R3 +#define PT_ORIG_R3 34 +#endif +#ifndef PT_TRAP +#define PT_TRAP 40 +#endif + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a configure time check. Some older glibc's (for instance 2.2.1) don't have a specific powerpc version of ptrace.h, and fall back on @@ -200,6 +208,10 @@ ppc_register_u_addr (struct gdbarch *gdb #endif if (regno == tdep->ppc_ps_regnum) u_addr = PT_MSR * wordsize; + if (regno == tdep->ppc_orig_r3_regnum) + u_addr = PT_ORIG_R3 * wordsize; + if (regno == tdep->ppc_trap_regnum) + u_addr = PT_TRAP * wordsize; if (tdep->ppc_fpscr_regnum >= 0 && regno == tdep->ppc_fpscr_regnum) { @@ -476,6 +488,10 @@ fetch_ppc_registers (struct regcache *re fetch_register (regcache, tid, tdep->ppc_xer_regnum); if (tdep->ppc_mq_regnum != -1) fetch_register (regcache, tid, tdep->ppc_mq_regnum); + if (tdep->ppc_orig_r3_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_orig_r3_regnum); + if (tdep->ppc_trap_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_trap_regnum); if (tdep->ppc_fpscr_regnum != -1) fetch_register (regcache, tid, tdep->ppc_fpscr_regnum); if (have_ptrace_getvrregs) @@ -676,9 +692,12 @@ store_register (const struct regcache *r regaddr += sizeof (long); if (errno == EIO - && regno == tdep->ppc_fpscr_regnum) + && (regno == tdep->ppc_fpscr_regnum + || regno == tdep->ppc_orig_r3_regnum + || regno == tdep->ppc_trap_regnum)) { - /* Some older kernel versions don't allow fpscr to be written. */ + /* Some older kernel versions don't allow fpscr, orig_r3 + or trap to be written. */ continue; } @@ -763,6 +782,10 @@ store_ppc_registers (const struct regcac store_register (regcache, tid, tdep->ppc_xer_regnum); if (tdep->ppc_mq_regnum != -1) store_register (regcache, tid, tdep->ppc_mq_regnum); + if (tdep->ppc_orig_r3_regnum != -1) + store_register (regcache, tid, tdep->ppc_orig_r3_regnum); + if (tdep->ppc_trap_regnum != -1) + store_register (regcache, tid, tdep->ppc_trap_regnum); if (tdep->ppc_fpscr_regnum != -1) store_register (regcache, tid, tdep->ppc_fpscr_regnum); if (have_ptrace_getvrregs) @@ -964,16 +987,31 @@ ppc_linux_read_description (struct targe return tdesc_powerpc_e500; else { - /* EIO means that the PTRACE_GETEVRREGS request isn't supported. */ - if (errno == EIO) - return NULL; - else - /* Anything else needs to be reported. */ + /* EIO means that the PTRACE_GETEVRREGS request isn't supported. + Anything else needs to be reported. */ + if (errno != EIO) perror_with_name (_("Unable to fetch SPE registers")); } } - return NULL; + /* Check for 64-bit inferior process. This is the case when the host is + 64-bit, and in addition the top bit of the MSR register is set. */ +#ifdef __powerpc64__ + { + long msr; + + int tid = TIDGET (inferior_ptid); + if (tid == 0) + tid = PIDGET (inferior_ptid); + + errno = 0; + msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0); + if (errno == 0 && msr < 0) + return tdesc_powerpc_linux64; + } +#endif + + return tdesc_powerpc_linux32; } void _initialize_ppc_linux_nat (void); diff -urNp gdb-orig/gdb/ppc-linux-tdep.c gdb-head/gdb/ppc-linux-tdep.c --- gdb-orig/gdb/ppc-linux-tdep.c 2008-03-27 00:52:46.093409899 +0100 +++ gdb-head/gdb/ppc-linux-tdep.c 2008-03-27 00:05:36.471133987 +0100 @@ -656,7 +656,11 @@ static const struct ppc_reg_offsets ppc3 /* AltiVec registers. */ /* .vr0_offset = */ 0, /* .vscr_offset = */ 512 + 12, - /* .vrsave_offset = */ 528 + /* .vrsave_offset = */ 528, + + /* Linux-specific registers. */ + /* .orig_r3_offset = */ 136, + /* .trap_offset = */ 160 }; static const struct ppc_reg_offsets ppc64_linux_reg_offsets = @@ -681,7 +685,11 @@ static const struct ppc_reg_offsets ppc6 /* AltiVec registers. */ /* .vr0_offset = */ 0, /* .vscr_offset = */ 512 + 12, - /* .vrsave_offset = */ 528 + /* .vrsave_offset = */ 528, + + /* Linux-specific registers. */ + /* .orig_r3_offset = */ 272, + /* .trap_offset = */ 320 }; static const struct regset ppc32_linux_gregset = { @@ -895,6 +903,50 @@ static struct tramp_frame ppc64_linux_si ppc64_linux_sighandler_cache_init }; + +static void +ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch), pc); + + /* Set special TRAP register to -1 to prevent the kernel from + messing with the PC we just installed, if we happen to be + within an interrupted system call that the kernel wants to + restart. + + Note that after we return from the dummy call, the TRAP and + ORIG_R3 registers will be automatically restored, and the + kernel continues to restart the system call at this point. */ + regcache_cooked_write_unsigned (regcache, tdep->ppc_trap_regnum, -1); +} + + +static const struct target_desc * +ppc_linux_core_read_description (struct gdbarch *gdbarch, + struct target_ops *target, + bfd *abfd) +{ + asection *section = bfd_get_section_by_name (abfd, ".reg"); + if (! section) + return NULL; + + switch (bfd_section_size (abfd, section)) + { + case 48 * 4: + return tdesc_powerpc_linux32; + + case 48 * 8: + return tdesc_powerpc_linux64; + + default: + return NULL; + } +} + + static void ppc_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) @@ -914,6 +966,9 @@ ppc_linux_init_abi (struct gdbarch_info set_gdbarch_convert_from_func_ptr_addr (gdbarch, ppc_linux_convert_from_func_ptr_addr); + /* Handle inferior calls during interrupted system calls. */ + set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc); + if (tdep->wordsize == 4) { /* Until November 2001, gcc did not comply with the 32 bit SysV @@ -951,6 +1006,7 @@ ppc_linux_init_abi (struct gdbarch_info tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame); } set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section); + set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description); /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, diff -urNp gdb-orig/gdb/ppcnbsd-tdep.c gdb-head/gdb/ppcnbsd-tdep.c --- gdb-orig/gdb/ppcnbsd-tdep.c 2008-03-27 00:52:46.098409181 +0100 +++ gdb-head/gdb/ppcnbsd-tdep.c 2008-03-27 00:05:36.513127954 +0100 @@ -231,5 +231,9 @@ _initialize_ppcnbsd_tdep (void) ppcnbsd_reg_offsets.vr0_offset = 0; ppcnbsd_reg_offsets.vrsave_offset = 512; ppcnbsd_reg_offsets.vscr_offset = 524; + + /* Linux-specific registers. */ + ppcnbsd_reg_offsets.orig_r3_offset = -1; + ppcnbsd_reg_offsets.trap_offset = -1; } } diff -urNp gdb-orig/gdb/ppcobsd-tdep.c gdb-head/gdb/ppcobsd-tdep.c --- gdb-orig/gdb/ppcobsd-tdep.c 2008-03-27 00:52:46.102408607 +0100 +++ gdb-head/gdb/ppcobsd-tdep.c 2008-03-27 00:05:36.517127379 +0100 @@ -325,6 +325,10 @@ _initialize_ppcobsd_tdep (void) ppcobsd_reg_offsets.vr0_offset = 0; ppcobsd_reg_offsets.vscr_offset = 512; ppcobsd_reg_offsets.vrsave_offset = 520; + + /* Linux-specific registers. */ + ppcobsd_reg_offsets.orig_r3_offset = -1; + ppcobsd_reg_offsets.trap_offset = -1; } if (ppcobsd_fpreg_offsets.fpscr_offset == 0) diff -urNp gdb-orig/gdb/ppc-tdep.h gdb-head/gdb/ppc-tdep.h --- gdb-orig/gdb/ppc-tdep.h 2008-03-27 00:52:46.107407889 +0100 +++ gdb-head/gdb/ppc-tdep.h 2008-03-27 00:05:36.522126661 +0100 @@ -102,6 +102,10 @@ struct ppc_reg_offsets int vr0_offset; int vscr_offset; int vrsave_offset; + + /* Linux-specific registers. Size in gpr_size. */ + int orig_r3_offset; + int trap_offset; }; /* Supply register REGNUM in the general-purpose register set REGSET @@ -194,6 +198,10 @@ struct gdbarch_tdep /* Multiplier-Quotient Register (older POWER architectures only). */ int ppc_mq_regnum; + /* Linux-specific registers. */ + int ppc_orig_r3_regnum; /* GPR3 at syscall entry. */ + int ppc_trap_regnum; /* Syscall trap code. */ + /* Altivec registers. */ int ppc_vr0_regnum; /* First AltiVec register */ int ppc_vrsave_regnum; /* Last AltiVec register */ @@ -255,6 +263,8 @@ enum { PPC_VR0_REGNUM = 106, PPC_VSCR_REGNUM = 138, PPC_VRSAVE_REGNUM = 139, + PPC_ORIG_R3_REGNUM = 140, + PPC_TRAP_REGNUM = 141, PPC_NUM_REGS }; @@ -265,6 +275,8 @@ enum { /* Estimate for the maximum number of instrctions in a function epilogue. */ #define PPC_MAX_EPILOGUE_INSTRUCTIONS 52 +extern struct target_desc *tdesc_powerpc_linux32; +extern struct target_desc *tdesc_powerpc_linux64; extern struct target_desc *tdesc_powerpc_e500; #endif /* ppc-tdep.h */ diff -urNp gdb-orig/gdb/rs6000-aix-tdep.c gdb-head/gdb/rs6000-aix-tdep.c --- gdb-orig/gdb/rs6000-aix-tdep.c 2008-03-27 00:52:46.126405161 +0100 +++ gdb-head/gdb/rs6000-aix-tdep.c 2008-03-27 00:05:52.840308201 +0100 @@ -52,7 +52,11 @@ static struct ppc_reg_offsets rs6000_aix /* AltiVec registers. */ -1, /* vr0_offset */ -1, /* vscr_offset */ - -1 /* vrsave_offset */ + -1, /* vrsave_offset */ + + /* Linux-specific registers. */ + -1, /* orig_r3_offset */ + -1 /* trap_offset */ }; static struct ppc_reg_offsets rs6000_aix64_reg_offsets = @@ -77,7 +81,11 @@ static struct ppc_reg_offsets rs6000_aix /* AltiVec registers. */ -1, /* vr0_offset */ -1, /* vscr_offset */ - -1 /* vrsave_offset */ + -1, /* vrsave_offset */ + + /* Linux-specific registers. */ + -1, /* orig_r3_offset */ + -1 /* trap_offset */ }; diff -urNp gdb-orig/gdb/rs6000-tdep.c gdb-head/gdb/rs6000-tdep.c --- gdb-orig/gdb/rs6000-tdep.c 2008-03-27 00:52:46.138403438 +0100 +++ gdb-head/gdb/rs6000-tdep.c 2008-03-27 00:05:52.852306477 +0100 @@ -64,6 +64,7 @@ #include "rs6000-tdep.h" #include "features/rs6000/powerpc-32.c" +#include "features/rs6000/powerpc-linux32.c" #include "features/rs6000/powerpc-403.c" #include "features/rs6000/powerpc-403gc.c" #include "features/rs6000/powerpc-505.c" @@ -72,6 +73,7 @@ #include "features/rs6000/powerpc-603.c" #include "features/rs6000/powerpc-604.c" #include "features/rs6000/powerpc-64.c" +#include "features/rs6000/powerpc-linux64.c" #include "features/rs6000/powerpc-7400.c" #include "features/rs6000/powerpc-750.c" #include "features/rs6000/powerpc-860.c" @@ -448,6 +450,12 @@ ppc_greg_offset (struct gdbarch *gdbarch if (regnum == tdep->ppc_ctr_regnum) return offsets->ctr_offset; + if (regnum == tdep->ppc_orig_r3_regnum) + return offsets->orig_r3_offset; + + if (regnum == tdep->ppc_trap_regnum) + return offsets->trap_offset; + *regsize = offsets->xr_size; if (regnum == tdep->ppc_cr_regnum) return offsets->cr_offset; @@ -526,6 +534,10 @@ ppc_supply_gregset (const struct regset gregs, offsets->lr_offset, gpr_size); ppc_supply_reg (regcache, tdep->ppc_ctr_regnum, gregs, offsets->ctr_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_orig_r3_regnum, + gregs, offsets->orig_r3_offset, gpr_size); + ppc_supply_reg (regcache, tdep->ppc_trap_regnum, + gregs, offsets->trap_offset, gpr_size); ppc_supply_reg (regcache, tdep->ppc_cr_regnum, gregs, offsets->cr_offset, offsets->xr_size); ppc_supply_reg (regcache, tdep->ppc_xer_regnum, @@ -654,6 +666,10 @@ ppc_collect_gregset (const struct regset gregs, offsets->lr_offset, gpr_size); ppc_collect_reg (regcache, tdep->ppc_ctr_regnum, gregs, offsets->ctr_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_orig_r3_regnum, + gregs, offsets->orig_r3_offset, gpr_size); + ppc_collect_reg (regcache, tdep->ppc_trap_regnum, + gregs, offsets->trap_offset, gpr_size); ppc_collect_reg (regcache, tdep->ppc_cr_regnum, gregs, offsets->cr_offset, offsets->xr_size); ppc_collect_reg (regcache, tdep->ppc_xer_regnum, @@ -3267,6 +3283,7 @@ rs6000_gdbarch_init (struct gdbarch_info int soft_float; enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global; int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0; + int have_linux_regs = 0; int tdesc_wordsize = -1; const struct target_desc *tdesc = info.target_desc; struct tdesc_arch_data *tdesc_data = NULL; @@ -3415,6 +3432,26 @@ rs6000_gdbarch_init (struct gdbarch_info wordsize = tdesc_wordsize; feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.power.linux"); + if (feature != NULL) + { + valid_p = 1; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_ORIG_R3_REGNUM, "orig_r3"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + PPC_TRAP_REGNUM, "trap"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + have_linux_regs = 1; + } + else + have_linux_regs = 0; + + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.power.fpu"); if (feature != NULL) { @@ -3657,6 +3694,9 @@ rs6000_gdbarch_init (struct gdbarch_info tdep->ppc_xer_regnum = PPC_XER_REGNUM; tdep->ppc_mq_regnum = have_mq ? PPC_MQ_REGNUM : -1; + tdep->ppc_orig_r3_regnum = have_linux_regs ? PPC_ORIG_R3_REGNUM : -1; + tdep->ppc_trap_regnum = have_linux_regs ? PPC_TRAP_REGNUM : -1; + tdep->ppc_fp0_regnum = have_fpu ? PPC_F0_REGNUM : -1; tdep->ppc_fpscr_regnum = have_fpu ? PPC_FPSCR_REGNUM : -1; tdep->ppc_vr0_regnum = have_altivec ? PPC_VR0_REGNUM : -1; @@ -3923,6 +3963,7 @@ _initialize_rs6000_tdep (void) /* Initialize the standard target descriptions. */ initialize_tdesc_powerpc_32 (); + initialize_tdesc_powerpc_linux32 (); initialize_tdesc_powerpc_403 (); initialize_tdesc_powerpc_403gc (); initialize_tdesc_powerpc_505 (); @@ -3931,6 +3972,7 @@ _initialize_rs6000_tdep (void) initialize_tdesc_powerpc_603 (); initialize_tdesc_powerpc_604 (); initialize_tdesc_powerpc_64 (); + initialize_tdesc_powerpc_linux64 (); initialize_tdesc_powerpc_7400 (); initialize_tdesc_powerpc_750 (); initialize_tdesc_powerpc_860 (); -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor