* alpha-nat.c, alpha-tdep.c, config/alpha/alpha-osf1.mt,
authorPeter Schauer <Peter.Schauer@mytum.de>
Tue, 5 Oct 1993 19:25:43 +0000 (19:25 +0000)
committerPeter Schauer <Peter.Schauer@mytum.de>
Tue, 5 Oct 1993 19:25:43 +0000 (19:25 +0000)
  config/alpha/nm-alpha.h, config/alpha/tm-alpha.h, osfsolib.c:
New files.
* Makefile.in:  Add new files and dependencies.
* configure.in:  Add alpha target.
* config/alpha/alpha-osf1.mh (NATDEPFILES):  Add osfsolib.o
* config/alpha/alpha-osf1.mh (MH_CFLAGS):  Remove, we can handle
shared libraries now.
* config/alpha/xm-alpha.h:  Cleanup, get MAKEVA_* defines right.

gdb/config/alpha/.Sanitize
gdb/config/alpha/alpha-osf1.mt [new file with mode: 0644]
gdb/config/alpha/nm-alpha.h [new file with mode: 0644]
gdb/config/alpha/tm-alpha.h [new file with mode: 0644]
gdb/config/alpha/xm-alpha.h

index e66f10a4e13619820fc6b9be2e35097396ed8fd2..4f217092e14ff346656730945df845db4365a323 100644 (file)
@@ -22,6 +22,9 @@ Do-first:
 Things-to-keep:
 
 alpha-osf1.mh
+alpha-osf1.mt
+nm-alpha.h
+tm-alpha.h
 xm-alpha.h
 
 Things-to-lose:
diff --git a/gdb/config/alpha/alpha-osf1.mt b/gdb/config/alpha/alpha-osf1.mt
new file mode 100644 (file)
index 0000000..6f5d02b
--- /dev/null
@@ -0,0 +1,8 @@
+# Target: Little-endian Alpha
+TDEPFILES= alpha-tdep.o exec.o
+TM_FILE= tm-alpha.h
+#
+# Can't define this in tm.h because defs.h uses it before including tm.h
+# FIXME: Needs to be at least 64-bits (LONGEST for e.g. 386 x alpha), but
+# CORE_ADDR is typedef'd before LONGEST is defined.
+MT_CFLAGS = -DCORE_ADDR_TYPE="unsigned long"
diff --git a/gdb/config/alpha/nm-alpha.h b/gdb/config/alpha/nm-alpha.h
new file mode 100644 (file)
index 0000000..0a6e5de
--- /dev/null
@@ -0,0 +1,48 @@
+/* Native definitions for alpha running OSF/1.
+   Copyright (C) 1993 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 2 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, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Figure out where the longjmp will land.  We expect that we have just entered
+   longjmp and haven't yet setup the stack frame, so the args are still in the
+   argument regs.  A0_REGNUM points at the jmp_buf structure from which we
+   extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
+   This routine returns true on success */
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+extern int
+get_longjmp_target PARAMS ((CORE_ADDR *));
+
+/* ptrace register ``addresses'' are absolute.  */
+
+#define U_REGS_OFFSET 0
+
+/* FIXME: Shouldn't the default definition in inferior.h be int* ? */
+
+#define PTRACE_ARG3_TYPE int*
+
+/* ptrace transfers longs, the ptrace man page is lying.  */
+
+#define PTRACE_XFER_TYPE long
+
+/* The alpha does not step over a breakpoint, the manpage is lying again.  */
+
+#define CANNOT_STEP_BREAKPOINT
+
+/* Support for shared libraries.  */
+
+#include "solib.h"
diff --git a/gdb/config/alpha/tm-alpha.h b/gdb/config/alpha/tm-alpha.h
new file mode 100644 (file)
index 0000000..b6cdcbf
--- /dev/null
@@ -0,0 +1,403 @@
+/* Definitions to make GDB run on an Alpha box under OSF1.
+   Copyright 1993 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 2 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, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "bfd.h"
+#include "coff/sym.h"          /* Needed for PDR below.  */
+#include "coff/symconst.h"
+
+#if !defined (TARGET_BYTE_ORDER)
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+/* Redefine some target bit sizes from the default.  */
+
+#undef TARGET_LONG_BIT
+#define TARGET_LONG_BIT 64
+#undef TARGET_LONG_LONG_BIT
+#define TARGET_LONG_LONG_BIT 64
+#undef TARGET_PTR_BIT
+#define TARGET_PTR_BIT 64
+
+/* Floating point is IEEE compliant */
+#define IEEE_FLOAT
+
+/* Number of traps that happen between exec'ing the shell 
+ * to run an inferior, and when we finally get to 
+ * the inferior code.  This is 2 on most implementations.
+ */
+#define START_INFERIOR_TRAPS_EXPECTED 3
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)      pc = alpha_skip_prologue(pc, 0)
+extern CORE_ADDR alpha_skip_prologue PARAMS ((CORE_ADDR addr, int lenient));
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame)     alpha_saved_pc_after_call(frame)
+#ifdef __STDC__
+struct frame_info;
+#endif
+extern CORE_ADDR
+alpha_saved_pc_after_call PARAMS ((struct frame_info *));
+
+/* Are we currently handling a signal ?  */
+
+#define IN_SIGTRAMP(pc, name)  ((name) && STREQ ("__sigtramp", (name)))
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+#define BREAKPOINT {0x80, 0, 0, 0} /* call_pal bpt */
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#define DECR_PC_AFTER_BREAK 4
+
+/* Nonzero if instruction at PC is a return instruction.
+   "ret $zero,($ra),1" on alpha. */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 4) == 0x6bfa8001)
+
+/* Return 1 if P points to an invalid floating point value. */
+
+#define INVALID_FLOAT(p,l) 0
+
+/* Say how long (all) registers are.
+   This is unused for the alpha, but the define is necessary.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 66
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+#define REGISTER_NAMES         \
+    {  "v0",   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6", \
+       "t7",   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "fp", \
+       "a0",   "a1",   "a2",   "a3",   "a4",   "a5",   "t8",   "t9", \
+       "t10",  "t11",  "ra",   "t12",  "at",   "gp",   "sp",   "zero", \
+       "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7", \
+       "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15", \
+       "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",\
+       "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",\
+       "pc",   "vfp",                                          \
+    }
+
+/* Register numbers of various important registers.
+   Note that most of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and FP_REGNUM is a "phony" register number which is too large
+   to be an actual register number as far as the user is concerned
+   but serves to get the desired value when passed to read_register.  */
+
+#define V0_REGNUM 0            /* Function integer return value */
+#define GCC_FP_REGNUM 15       /* Used by gcc as frame register */
+#define A0_REGNUM 16           /* Loc of first arg during a subr call */
+#define T12_REGNUM 27          /* Contains start addr of current proc */
+#define SP_REGNUM 30           /* Contains address of top of stack */
+#define RA_REGNUM 26           /* Contains return address value */
+#define ZERO_REGNUM 31         /* Read-only register, always 0 */
+#define FP0_REGNUM 32           /* Floating point register 0 */
+#define FPA0_REGNUM 48          /* First float arg during a subr call */
+#define PC_REGNUM 64           /* Contains program counter */
+#define FP_REGNUM 65           /* Virtual frame pointer */
+
+#define CANNOT_FETCH_REGISTER(regno) \
+  ((regno) == FP_REGNUM || (regno) == ZERO_REGNUM)
+#define CANNOT_STORE_REGISTER(regno) \
+  ((regno) == FP_REGNUM || (regno) == ZERO_REGNUM)
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (NUM_REGS * 8)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N) * 8)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  On Alphas, all regs are 8 bytes.  */
+
+#define REGISTER_RAW_SIZE(N) 8
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On Alphas, all regs are 8 bytes.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) 8
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) 0
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO)    \
+  memcpy ((TO), (FROM), 8);
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO)        \
+  memcpy ((TO), (FROM), 8);
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+
+#define REGISTER_VIRTUAL_TYPE(N) \
+       (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32)  \
+        ? builtin_type_double : builtin_type_long) \
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  Handled by alpha_push_arguments.  */
+
+#define STORE_STRUCT_RETURN(addr, sp)  /**/
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  alpha_extract_return_value(TYPE, REGBUF, VALBUF)
+#ifdef __STDC__
+struct type;
+#endif
+extern void
+alpha_extract_return_value PARAMS ((struct type *, char *, char *));
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  alpha_store_return_value(TYPE, VALBUF)
+extern void
+alpha_store_return_value PARAMS ((struct type *, char *));
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+/* The address is passed in a0 upon entry to the function, but when
+   the function exits, the compiler has copied the value to v0.  This
+   convention is specified by the System V ABI, so I think we can rely
+   on it.  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
+  (extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
+                   REGISTER_RAW_SIZE (V0_REGNUM)))
+
+/* Structures are returned by ref in extra arg0 */
+#define USE_STRUCT_CONVENTION(gcc_p, type)     1
+
+\f
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer. */
+
+#define FRAME_CHAIN(thisframe) (FRAME_ADDR)alpha_frame_chain(thisframe)
+extern CORE_ADDR
+alpha_frame_chain PARAMS ((struct frame_info *));
+
+/* Define other aspects of the stack frame.  */
+
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+/* We handle this differently for alpha, and maybe we should not */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS)  {(FRAMELESS) = 0;}
+
+/* Saved Pc.  */
+
+#define FRAME_SAVED_PC(FRAME)  (alpha_frame_saved_pc(FRAME))
+extern CORE_ADDR
+alpha_frame_saved_pc PARAMS ((struct frame_info *));
+
+/* The offsets for the arguments and locals are  off a virtual pointer
+   to the argument transfer area. The argument transfer area is immediately
+   below the virtual frame pointer, its size is in localoff from the PDR.  */
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame - (fi)->localoff)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame - (fi)->localoff)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(num, fi)        ((num) = -1)
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 0
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(fi, frame_saved_regs) ( \
+  (frame_saved_regs) = *(fi)->saved_regs, \
+  (frame_saved_regs).regs[SP_REGNUM] = (fi)->frame)
+
+\f
+/* Things needed for making the inferior call functions.  */
+
+#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+    sp = alpha_push_arguments(nargs, args, sp, struct_return, struct_addr)
+#ifdef __STDC__
+struct value;
+#endif
+extern CORE_ADDR
+alpha_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int, CORE_ADDR));
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME       alpha_push_dummy_frame()
+extern void
+alpha_push_dummy_frame PARAMS ((void));
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME              alpha_pop_frame()
+extern void
+alpha_pop_frame PARAMS ((void));
+
+/* Alpha OSF/1 inhibits execution of code on the stack.
+   But there is no need for a dummy on the alpha. PUSH_ARGUMENTS
+   takes care of all argument handling and bp_call_dummy takes care
+   of stopping the dummy.  */
+
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+
+/* We need a fake CALL_DUMMY definition to enable the proper
+   call_function_by_hand and to avoid zero length array warnings
+   in valops.c  */
+   
+#define CALL_DUMMY {\
+ 0x80,                         /* call_pal bpt */                      \
+}
+
+#define CALL_DUMMY_START_OFFSET (0)
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.
+   We only have to set RA_REGNUM to the dummy breakpoint address
+   and T12_REGNUM (the `procedure value register') to the function address.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)    \
+{                                                                      \
+  CORE_ADDR bp_address = entry_point_address ();                       \
+  if (bp_address == 0)                                                 \
+    error ("no place to put call");                                    \
+  write_register (RA_REGNUM, bp_address);                              \
+  write_register (T12_REGNUM, fun);                                    \
+}
+
+/* There's a mess in stack frame creation.  See comments in blockframe.c
+   near reference to INIT_FRAME_PC_FIRST.  */
+
+#define        INIT_FRAME_PC(fromleaf, prev) /* nada */
+
+#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
+  (prev)->pc = ((fromleaf) ? SAVED_PC_AFTER_CALL ((prev)->next) : \
+             (prev)->next ? FRAME_SAVED_PC ((prev)->next) : read_pc ());
+
+/* Special symbol found in blocks associated with routines.  We can hang
+   alpha_extra_func_info_t's off of this.  */
+
+#define MIPS_EFI_SYMBOL_NAME "__GDB_EFI_INFO__"
+
+/* Specific information about a procedure.
+   This overlays the ALPHA's PDR records, 
+   alpharead.c (ab)uses this to save memory */
+
+typedef struct alpha_extra_func_info {
+       long    numargs;        /* number of args to procedure (was iopt) */
+       PDR     pdr;            /* Procedure descriptor record */
+} *alpha_extra_func_info_t;
+
+/* Define the extra_func_info that mipsread.c needs.
+   FIXME: We should define our own PDR interface, perhaps in a separate
+   header file. This would get rid of the <bfd.h> inclusion in all sources
+   and would abstract the mips/alpha interface from ecoff.  */
+#define mips_extra_func_info alpha_extra_func_info
+#define mips_extra_func_info_t alpha_extra_func_info_t
+
+#define EXTRA_FRAME_INFO \
+  int localoff; \
+  alpha_extra_func_info_t proc_desc; \
+  struct frame_saved_regs *saved_regs;
+
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci)
+extern void
+init_extra_frame_info PARAMS ((struct frame_info *));
+
+#define        PRINT_EXTRA_FRAME_INFO(fi) \
+  { \
+    if (fi && fi->proc_desc && fi->proc_desc->pdr.framereg < NUM_REGS) \
+      printf_filtered (" frame pointer is at %s+%d\n", \
+                       reg_names[fi->proc_desc->pdr.framereg], \
+                                 fi->proc_desc->pdr.frameoffset); \
+  }
+
+/* It takes two values to specify a frame on the ALPHA.  Sigh.
+
+   In fact, at the moment, the *PC* is the primary value that sets up
+   a frame.  The PC is looked up to see what function it's in; symbol
+   information from that function tells us which register is the frame
+   pointer base, and what offset from there is the "virtual frame pointer".
+   (This is usually an offset from SP.)  FIXME -- this should be cleaned
+   up so that the primary value is the SP, and the PC is used to disambiguate
+   multiple functions with the same SP that are at different stack levels. */
+
+#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv)
+/* FIXME:  Depends on equivalence between FRAME and "struct frame_info *",
+   and equivalence between CORE_ADDR and FRAME_ADDR. */
+extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *));
index 0fa519906a9c3212a6282502ea85736ddbd13191..5edc862c602f083f327ca06915592d22fd659c98 100644 (file)
@@ -1,5 +1,5 @@
-/* Definitions to make GDB run on an Alpha box under OSF 1.
-   Copyright (C) 1992 Free Software Foundation, Inc.
+/* Host definitions for GDB running on an alpha under OSF/1
+   Copyright (C) 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -21,29 +21,46 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define HOST_BYTE_ORDER LITTLE_ENDIAN
 #endif
 
-/* Get rid of any system-imposed stack limit if possible */
-
+/* Get rid of any system-imposed stack limit if possible.  */
 #define        SET_STACK_LIMIT_HUGE
 
-#define        MEM_FNS_DECLARED
-
-#if ! defined (__STDC__) && ! defined (offsetof)
-# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-#endif
-
-/*#define MALLOC_INCOMPATIBLE*/
-
-extern void free PARAMS ((void *));
-
+/* The alpha has no siginterrupt routine.  */
 #define NO_SIGINTERRUPT
 
-#define KERNEL_U_ADDR 0
+/* The alpha stores the first six float parameters below the va_list.
+   We make no distinction and store the first six parameters below
+   and above the va_list.  */
+#define VA_FLOAT_ARGS_SIZE (6*8)
+#define MAKEVA_SIZE(nargs, max_arg_size) \
+  return sizeof (makeva_list) + nargs * max_arg_size + VA_FLOAT_ARGS_SIZE;
+#define MAKEVA_START(list) \
+  list->argindex = VA_FLOAT_ARGS_SIZE;
+#define MAKEVA_ARG(list, argaddr, argsize)                               \
+{                                                                        \
+  memcpy (&list->aligner.arg_bytes[list->argindex], argaddr, argsize);   \
+  if ((list->argindex - VA_FLOAT_ARGS_SIZE) < VA_FLOAT_ARGS_SIZE)        \
+    memcpy (&list->aligner.arg_bytes[list->argindex - VA_FLOAT_ARGS_SIZE],\
+           argaddr, argsize);                                            \
+  list->argindex += argsize;                                             \
+}
+#ifdef __GNUC__                                                        
+#define MAKEVA_END(list)                                       \
+{                                                              \
+  va_list ret;                                                 \
+  ret.__base = &(list)->aligner.arg_bytes[VA_FLOAT_ARGS_SIZE]; \
+  ret.__offset = 0;                                            \
+  return ret;                                                  \
+}
+#else
+#define MAKEVA_END(list)                                       \
+{                                                              \
+  va_list ret;                                                 \
+  ret.a0 = &(list)->aligner.arg_bytes[VA_FLOAT_ARGS_SIZE];     \
+  ret.offset = 0;                                              \
+  return ret;                                                  \
+}
+#endif
 
+/* HAVE_SGTTY also works, but we have termios, so use it.  */
 
-#define MAKEVA_END(list)               \
-{                                      \
-  va_list ret;                         \
-  ret.a0 = (char *)(list)->aligner.arg_bytes;  \
-  ret.offset = (list)->argindex;       \
-  return ret;                          \
-}
+#define HAVE_TERMIOS