--- /dev/null
+/* Target dependent code for ARC arhitecture, for GDB.
+
+ Copyright 2005-2016 Free Software Foundation, Inc.
+ Contributed by Synopsys Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* GDB header files. */
+#include "defs.h"
+#include "arch-utils.h"
+#include "disasm.h"
+#include "dwarf2-frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "trad-frame.h"
+
+/* ARC header files. */
+#include "opcode/arc.h"
+#include "arc-tdep.h"
+
+/* Standard headers. */
+#include <algorithm>
+
+/* Default target descriptions. */
+#include "features/arc-v2.c"
+#include "features/arc-arcompact.c"
+
+/* The frame unwind cache for the ARC. Current structure is a stub, because
+ it should be filled in during the prologue analysis. */
+
+struct arc_frame_cache
+{
+ /* The stack pointer at the time this frame was created; i.e. the caller's
+ stack pointer when this function was called. It is used to identify this
+ frame. */
+ CORE_ADDR prev_sp;
+
+ /* Store addresses for registers saved in prologue. */
+ struct trad_frame_saved_reg *saved_regs;
+};
+
+/* Global debug flag. */
+
+int arc_debug;
+
+/* XML target description features. */
+
+static const char core_v2_feature_name[] = "org.gnu.gdb.arc.core.v2";
+static const char
+ core_reduced_v2_feature_name[] = "org.gnu.gdb.arc.core-reduced.v2";
+static const char
+ core_arcompact_feature_name[] = "org.gnu.gdb.arc.core.arcompact";
+static const char aux_minimal_feature_name[] = "org.gnu.gdb.arc.aux-minimal";
+
+/* XML target description known registers. */
+
+static const char *const core_v2_register_names[] = {
+ "r0", "r1", "r2", "r3",
+ "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23",
+ "r24", "r25", "gp", "fp",
+ "sp", "ilink", "r30", "blink",
+ "r32", "r33", "r34", "r35",
+ "r36", "r37", "r38", "r39",
+ "r40", "r41", "r42", "r43",
+ "r44", "r45", "r46", "r47",
+ "r48", "r49", "r50", "r51",
+ "r52", "r53", "r54", "r55",
+ "r56", "r57", "accl", "acch",
+ "lp_count", "pcl",
+};
+
+static const char *const aux_minimal_register_names[] = {
+ "pc", "status32",
+};
+
+static const char *const core_arcompact_register_names[] = {
+ "r0", "r1", "r2", "r3",
+ "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23",
+ "r24", "r25", "gp", "fp",
+ "sp", "ilink1", "ilink2", "blink",
+ "r32", "r33", "r34", "r35",
+ "r36", "r37", "r38", "r39",
+ "r40", "r41", "r42", "r43",
+ "r44", "r45", "r46", "r47",
+ "r48", "r49", "r50", "r51",
+ "r52", "r53", "r54", "r55",
+ "r56", "r57", "r58", "r59",
+ "lp_count", "pcl",
+};
+
+/* Implement the "write_pc" gdbarch method.
+
+ In ARC PC register is a normal register so in most cases setting PC value
+ is a straightforward process: debugger just writes PC value. However it
+ gets trickier in case when current instruction is an instruction in delay
+ slot. In this case CPU will execute instruction at current PC value, then
+ will set PC to the current value of BTA register; also current instruction
+ cannot be branch/jump and some of the other instruction types. Thus if
+ debugger would try to just change PC value in this case, this instruction
+ will get executed, but then core will "jump" to the original branch target.
+
+ Whether current instruction is a delay-slot instruction or not is indicated
+ by DE bit in STATUS32 register indicates if current instruction is a delay
+ slot instruction. This bit is writable by debug host, which allows debug
+ host to prevent core from jumping after the delay slot instruction. It
+ also works in another direction: setting this bit will make core to treat
+ any current instructions as a delay slot instruction and to set PC to the
+ current value of BTA register.
+
+ To workaround issues with changing PC register while in delay slot
+ instruction, debugger should check for the STATUS32.DE bit and reset it if
+ it is set. No other change is required in this function. Most common
+ case, where this function might be required is calling inferior functions
+ from debugger. Generic GDB logic handles this pretty well: current values
+ of registers are stored, value of PC is changed (that is the job of this
+ function), and after inferior function is executed, GDB restores all
+ registers, include BTA and STATUS32, which also means that core is returned
+ to its original state of being halted on delay slot instructions.
+
+ This method is useless for ARC 600, because it doesn't have externally
+ exposed BTA register. In the case of ARC 600 it is impossible to restore
+ core to its state in all occasions thus core should never be halted (from
+ the perspective of debugger host) in the delay slot. */
+
+static void
+arc_write_pc (struct regcache *regcache, CORE_ADDR new_pc)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+ if (arc_debug)
+ debug_printf ("arc: Writing PC, new value=%s\n",
+ paddress (gdbarch, new_pc));
+
+ regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch),
+ new_pc);
+
+ ULONGEST status32;
+ regcache_cooked_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
+ &status32);
+
+ /* Mask for DE bit is 0x40. */
+ if (status32 & 0x40)
+ {
+ if (arc_debug)
+ {
+ debug_printf ("arc: Changing PC while in delay slot. Will "
+ "reset STATUS32.DE bit to zero. Value of STATUS32 "
+ "register is 0x%s\n",
+ phex (status32, ARC_REGISTER_SIZE));
+ }
+
+ /* Reset bit and write to the cache. */
+ status32 &= ~0x40;
+ regcache_cooked_write_unsigned (regcache, gdbarch_ps_regnum (gdbarch),
+ status32);
+ }
+}
+
+/* Implement the "virtual_frame_pointer" gdbarch method.
+
+ According to ABI the FP (r27) is used to point to the middle of the current
+ stack frame, just below the saved FP and before local variables, register
+ spill area and outgoing args. However for optimization levels above O2 and
+ in any case in leaf functions, the frame pointer is usually not set at all.
+ The exception being when handling nested functions.
+
+ We use this function to return a "virtual" frame pointer, marking the start
+ of the current stack frame as a register-offset pair. If the FP is not
+ being used, then it should return SP, with an offset of the frame size.
+
+ The current implementation doesn't actually know the frame size, nor
+ whether the FP is actually being used, so for now we just return SP and an
+ offset of zero. This is no worse than other architectures, but is needed
+ to avoid assertion failures.
+
+ TODO: Can we determine the frame size to get a correct offset?
+
+ PC is a program counter where we need the virtual FP. REG_PTR is the base
+ register used for the virtual FP. OFFSET_PTR is the offset used for the
+ virtual FP. */
+
+static void
+arc_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
+ int *reg_ptr, LONGEST *offset_ptr)
+{
+ *reg_ptr = gdbarch_sp_regnum (gdbarch);
+ *offset_ptr = 0;
+}
+
+/* Implement the "dummy_id" gdbarch method.
+
+ Tear down a dummy frame created by arc_push_dummy_call (). This data has
+ to be constructed manually from the data in our hand. The stack pointer
+ and program counter can be obtained from the frame info. */
+
+static struct frame_id
+arc_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+ return frame_id_build (get_frame_sp (this_frame),
+ get_frame_pc (this_frame));
+}
+
+/* Implement the "push_dummy_call" gdbarch method.
+
+ Stack Frame Layout
+
+ This shows the layout of the stack frame for the general case of a
+ function call; a given function might not have a variable number of
+ arguments or local variables, or might not save any registers, so it would
+ not have the corresponding frame areas. Additionally, a leaf function
+ (i.e. one which calls no other functions) does not need to save the
+ contents of the BLINK register (which holds its return address), and a
+ function might not have a frame pointer.
+
+ The stack grows downward, so SP points below FP in memory; SP always
+ points to the last used word on the stack, not the first one.
+
+ | | |
+ | arg word N | | caller's
+ | : | | frame
+ | arg word 10 | |
+ | arg word 9 | |
+ old SP ---> +-----------------------+ --+
+ | | |
+ | callee-saved | |
+ | registers | |
+ | including fp, blink | |
+ | | | callee's
+ new FP ---> +-----------------------+ | frame
+ | | |
+ | local | |
+ | variables | |
+ | | |
+ | register | |
+ | spill area | |
+ | | |
+ | outgoing args | |
+ | | |
+ new SP ---> +-----------------------+ --+
+ | |
+ | unused |
+ | |
+ |
+ |
+ V
+ downwards
+
+ The list of arguments to be passed to a function is considered to be a
+ sequence of _N_ words (as though all the parameters were stored in order in
+ memory with each parameter occupying an integral number of words). Words
+ 1..8 are passed in registers 0..7; if the function has more than 8 words of
+ arguments then words 9..@em N are passed on the stack in the caller's frame.
+
+ If the function has a variable number of arguments, e.g. it has a form such
+ as `function (p1, p2, ...);' and _P_ words are required to hold the values
+ of the named parameters (which are passed in registers 0..@em P -1), then
+ the remaining 8 - _P_ words passed in registers _P_..7 are spilled into the
+ top of the frame so that the anonymous parameter words occupy a continuous
+ region.
+
+ Any arguments are already in target byte order. We just need to store
+ them!
+
+ BP_ADDR is the return address where breakpoint must be placed. NARGS is
+ the number of arguments to the function. ARGS is the arguments values (in
+ target byte order). SP is the Current value of SP register. STRUCT_RETURN
+ is TRUE if structures are returned by the function. STRUCT_ADDR is the
+ hidden address for returning a struct. Returns SP of a new frame. */
+
+static CORE_ADDR
+arc_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+ struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+ struct value **args, CORE_ADDR sp, int struct_return,
+ CORE_ADDR struct_addr)
+{
+ if (arc_debug)
+ debug_printf ("arc: push_dummy_call (nargs = %d)\n", nargs);
+
+ int arg_reg = ARC_FIRST_ARG_REGNUM;
+
+ /* Push the return address. */
+ regcache_cooked_write_unsigned (regcache, ARC_BLINK_REGNUM, bp_addr);
+
+ /* Are we returning a value using a structure return instead of a normal
+ value return? If so, struct_addr is the address of the reserved space for
+ the return structure to be written on the stack, and that address is
+ passed to that function as a hidden first argument. */
+ if (struct_return)
+ {
+ /* Pass the return address in the first argument register. */
+ regcache_cooked_write_unsigned (regcache, arg_reg, struct_addr);
+
+ if (arc_debug)
+ debug_printf ("arc: struct return address %s passed in R%d",
+ print_core_address (gdbarch, struct_addr), arg_reg);
+
+ arg_reg++;
+ }
+
+ if (nargs > 0)
+ {
+ unsigned int total_space = 0;
+
+ /* How much space do the arguments occupy in total? Must round each
+ argument's size up to an integral number of words. */
+ for (int i = 0; i < nargs; i++)
+ {
+ unsigned int len = TYPE_LENGTH (value_type (args[i]));
+ unsigned int space = align_up (len, 4);
+
+ total_space += space;
+
+ if (arc_debug)
+ debug_printf ("arc: arg %d: %u bytes -> %u\n", i, len, space);
+ }
+
+ /* Allocate a buffer to hold a memory image of the arguments. */
+ gdb_byte *memory_image = XCNEWVEC (gdb_byte, total_space);
+
+ /* Now copy all of the arguments into the buffer, correctly aligned. */
+ gdb_byte *data = memory_image;
+ for (int i = 0; i < nargs; i++)
+ {
+ unsigned int len = TYPE_LENGTH (value_type (args[i]));
+ unsigned int space = align_up (len, 4);
+
+ memcpy (data, value_contents (args[i]), (size_t) len);
+ if (arc_debug)
+ debug_printf ("arc: copying arg %d, val 0x%08x, len %d to mem\n",
+ i, *((int *) value_contents (args[i])), len);
+
+ data += space;
+ }
+
+ /* Now load as much as possible of the memory image into registers. */
+ data = memory_image;
+ while (arg_reg <= ARC_LAST_ARG_REGNUM)
+ {
+ if (arc_debug)
+ debug_printf ("arc: passing 0x%02x%02x%02x%02x in register R%d\n",
+ data[0], data[1], data[2], data[3], arg_reg);
+
+ /* Note we don't use write_unsigned here, since that would convert
+ the byte order, but we are already in the correct byte order. */
+ regcache_cooked_write (regcache, arg_reg, data);
+
+ data += ARC_REGISTER_SIZE;
+ total_space -= ARC_REGISTER_SIZE;
+
+ /* All the data is now in registers. */
+ if (total_space == 0)
+ break;
+
+ arg_reg++;
+ }
+
+ /* If there is any data left, push it onto the stack (in a single write
+ operation). */
+ if (total_space > 0)
+ {
+ if (arc_debug)
+ debug_printf ("arc: passing %d bytes on stack\n", total_space);
+
+ sp -= total_space;
+ write_memory (sp, data, (int) total_space);
+ }
+
+ xfree (memory_image);
+ }
+
+ /* Finally, update the SP register. */
+ regcache_cooked_write_unsigned (regcache, gdbarch_sp_regnum (gdbarch), sp);
+
+ return sp;
+}
+
+/* Implement the "push_dummy_code" gdbarch method.
+
+ We don't actually push any code. We just identify where a breakpoint can
+ be inserted to which we are can return and the resume address where we
+ should be called.
+
+ ARC does not necessarily have an executable stack, so we can't put the
+ return breakpoint there. Instead we put it at the entry point of the
+ function. This means the SP is unchanged.
+
+ SP is a current stack pointer FUNADDR is an address of the function to be
+ called. ARGS is arguments to pass. NARGS is a number of args to pass.
+ VALUE_TYPE is a type of value returned. REAL_PC is a resume address when
+ the function is called. BP_ADDR is an address where breakpoint should be
+ set. Returns the updated stack pointer. */
+
+static CORE_ADDR
+arc_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr,
+ struct value **args, int nargs, struct type *value_type,
+ CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
+ struct regcache *regcache)
+{
+ *real_pc = funaddr;
+ *bp_addr = entry_point_address ();
+ return sp;
+}
+
+/* Implement the "cannot_fetch_register" gdbarch method. */
+
+static int
+arc_cannot_fetch_register (struct gdbarch *gdbarch, int regnum)
+{
+ /* Assume that register is readable if it is unknown. */
+ return FALSE;
+}
+
+/* Implement the "cannot_store_register" gdbarch method. */
+
+static int
+arc_cannot_store_register (struct gdbarch *gdbarch, int regnum)
+{
+ /* Assume that register is writable if it is unknown. */
+ switch (regnum)
+ {
+ case ARC_PCL_REGNUM:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/* Get the return value of a function from the registers/memory used to
+ return it, according to the convention used by the ABI - 4-bytes values are
+ in the R0, while 8-byte values are in the R0-R1.
+
+ TODO: This implementation ignores the case of "complex double", where
+ according to ABI, value is returned in the R0-R3 registers.
+
+ TYPE is a returned value's type. VALBUF is a buffer for the returned
+ value. */
+
+static void
+arc_extract_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, gdb_byte *valbuf)
+{
+ unsigned int len = TYPE_LENGTH (type);
+
+ if (arc_debug)
+ debug_printf ("arc: extract_return_value\n");
+
+ if (len <= ARC_REGISTER_SIZE)
+ {
+ ULONGEST val;
+
+ /* Get the return value from one register. */
+ regcache_cooked_read_unsigned (regcache, ARC_R0_REGNUM, &val);
+ store_unsigned_integer (valbuf, (int) len,
+ gdbarch_byte_order (gdbarch), val);
+
+ if (arc_debug)
+ debug_printf ("arc: returning 0x%s\n", phex (val, ARC_REGISTER_SIZE));
+ }
+ else if (len <= ARC_REGISTER_SIZE * 2)
+ {
+ ULONGEST low, high;
+
+ /* Get the return value from two registers. */
+ regcache_cooked_read_unsigned (regcache, ARC_R0_REGNUM, &low);
+ regcache_cooked_read_unsigned (regcache, ARC_R1_REGNUM, &high);
+
+ store_unsigned_integer (valbuf, ARC_REGISTER_SIZE,
+ gdbarch_byte_order (gdbarch), low);
+ store_unsigned_integer (valbuf + ARC_REGISTER_SIZE,
+ (int) len - ARC_REGISTER_SIZE,
+ gdbarch_byte_order (gdbarch), high);
+
+ if (arc_debug)
+ debug_printf ("arc: returning 0x%s%s\n",
+ phex (high, ARC_REGISTER_SIZE),
+ phex (low, ARC_REGISTER_SIZE));
+ }
+ else
+ error (_("arc: extract_return_value: type length %u too large"), len);
+}
+
+
+/* Store the return value of a function into the registers/memory used to
+ return it, according to the convention used by the ABI.
+
+ TODO: This implementation ignores the case of "complex double", where
+ according to ABI, value is returned in the R0-R3 registers.
+
+ TYPE is a returned value's type. VALBUF is a buffer with the value to
+ return. */
+
+static void
+arc_store_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, const gdb_byte *valbuf)
+{
+ unsigned int len = TYPE_LENGTH (type);
+
+ if (arc_debug)
+ debug_printf ("arc: store_return_value\n");
+
+ if (len <= ARC_REGISTER_SIZE)
+ {
+ ULONGEST val;
+
+ /* Put the return value into one register. */
+ val = extract_unsigned_integer (valbuf, (int) len,
+ gdbarch_byte_order (gdbarch));
+ regcache_cooked_write_unsigned (regcache, ARC_R0_REGNUM, val);
+
+ if (arc_debug)
+ debug_printf ("arc: storing 0x%s\n", phex (val, ARC_REGISTER_SIZE));
+ }
+ else if (len <= ARC_REGISTER_SIZE * 2)
+ {
+ ULONGEST low, high;
+
+ /* Put the return value into two registers. */
+ low = extract_unsigned_integer (valbuf, ARC_REGISTER_SIZE,
+ gdbarch_byte_order (gdbarch));
+ high = extract_unsigned_integer (valbuf + ARC_REGISTER_SIZE,
+ (int) len - ARC_REGISTER_SIZE,
+ gdbarch_byte_order (gdbarch));
+
+ regcache_cooked_write_unsigned (regcache, ARC_R0_REGNUM, low);
+ regcache_cooked_write_unsigned (regcache, ARC_R1_REGNUM, high);
+
+ if (arc_debug)
+ debug_printf ("arc: storing 0x%s%s\n",
+ phex (high, ARC_REGISTER_SIZE),
+ phex (low, ARC_REGISTER_SIZE));
+ }
+ else
+ error (_("arc_store_return_value: type length too large."));
+}
+
+/* Implement the "return_value" gdbarch method. */
+
+static enum return_value_convention
+arc_return_value (struct gdbarch *gdbarch, struct value *function,
+ struct type *valtype, struct regcache *regcache,
+ gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+ /* If the return type is a struct, or a union, or would occupy more than two
+ registers, the ABI uses the "struct return convention": the calling
+ function passes a hidden first parameter to the callee (in R0). That
+ parameter is the address at which the value being returned should be
+ stored. Otherwise, the result is returned in registers. */
+ int is_struct_return = (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+ || TYPE_CODE (valtype) == TYPE_CODE_UNION
+ || TYPE_LENGTH (valtype) > 2 * ARC_REGISTER_SIZE);
+
+ if (arc_debug)
+ debug_printf ("arc: return_value (readbuf = %p, writebuf = %p)\n",
+ readbuf, writebuf);
+
+ if (writebuf != NULL)
+ {
+ /* Case 1. GDB should not ask us to set a struct return value: it
+ should know the struct return location and write the value there
+ itself. */
+ gdb_assert (!is_struct_return);
+ arc_store_return_value (gdbarch, valtype, regcache, writebuf);
+ }
+ else if (readbuf != NULL)
+ {
+ /* Case 2. GDB should not ask us to get a struct return value: it
+ should know the struct return location and read the value from there
+ itself. */
+ gdb_assert (!is_struct_return);
+ arc_extract_return_value (gdbarch, valtype, regcache, readbuf);
+ }
+
+ return (is_struct_return
+ ? RETURN_VALUE_STRUCT_CONVENTION
+ : RETURN_VALUE_REGISTER_CONVENTION);
+}
+
+/* Return the base address of the frame. For ARC, the base address is the
+ frame pointer. */
+
+static CORE_ADDR
+arc_frame_base_address (struct frame_info *this_frame, void **prologue_cache)
+{
+ return (CORE_ADDR) get_frame_register_unsigned (this_frame, ARC_FP_REGNUM);
+}
+
+/* Implement the "skip_prologue" gdbarch method.
+
+ Skip the prologue for the function at PC. This is done by checking from
+ the line information read from the DWARF, if possible; otherwise, we scan
+ the function prologue to find its end. */
+
+static CORE_ADDR
+arc_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ if (arc_debug)
+ debug_printf ("arc: skip_prologue\n");
+
+ CORE_ADDR func_addr;
+ const char *func_name;
+
+ /* See what the symbol table says. */
+ if (find_pc_partial_function (pc, &func_name, &func_addr, NULL))
+ {
+ /* Found a function. */
+ CORE_ADDR postprologue_pc
+ = skip_prologue_using_sal (gdbarch, func_addr);
+
+ if (postprologue_pc != 0)
+ return std::max (pc, postprologue_pc);
+ }
+
+ /* No prologue info in symbol table, have to analyze prologue. */
+
+ /* Find an upper limit on the function prologue using the debug
+ information. If the debug information could not be used to provide that
+ bound, then pass 0 and arc_scan_prologue will estimate value itself. */
+ CORE_ADDR limit_pc = skip_prologue_using_sal (gdbarch, pc);
+ /* We don't have a proper analyze_prologue function yet, but its result
+ should be returned here. Currently GDB will just stop at the first
+ instruction of function if debug information doesn't have prologue info;
+ and if there is a debug info about prologue - this code path will not be
+ taken at all. */
+ return (limit_pc == 0 ? pc : limit_pc);
+}
+
+/* Implement the "print_insn" gdbarch method.
+
+ arc_get_disassembler () may return different functions depending on bfd
+ type, so it is not possible to pass print_insn directly to
+ set_gdbarch_print_insn (). Instead this wrapper function is used. It also
+ may be used by other functions to get disassemble_info for address. It is
+ important to note, that those print_insn from opcodes always print
+ instruction to the stream specified in the INFO. If this is not desired,
+ then either `print_insn` function in INFO should be set to some function
+ that will not print, or `stream` should be different from standard
+ gdb_stdlog. */
+
+static int
+arc_delayed_print_insn (bfd_vma addr, struct disassemble_info *info)
+{
+ int (*print_insn) (bfd_vma, struct disassemble_info *);
+ /* exec_bfd may be null, if GDB is run without a target BFD file. Opcodes
+ will handle NULL value gracefully. */
+ print_insn = arc_get_disassembler (exec_bfd);
+ gdb_assert (print_insn != NULL);
+ return print_insn (addr, info);
+}
+
+/* Baremetal breakpoint instructions.
+
+ ARC supports both big- and little-endian. However, instructions for
+ little-endian processors are encoded in the middle-endian: half-words are
+ in big-endian, while bytes inside the half-words are in little-endian; data
+ is represented in the "normal" little-endian. Big-endian processors treat
+ data and code identically.
+
+ Assuming the number 0x01020304, it will be presented this way:
+
+ Address : N N+1 N+2 N+3
+ little-endian : 0x04 0x03 0x02 0x01
+ big-endian : 0x01 0x02 0x03 0x04
+ ARC middle-endian : 0x02 0x01 0x04 0x03
+ */
+
+static const gdb_byte arc_brk_s_be[] = { 0x7f, 0xff };
+static const gdb_byte arc_brk_s_le[] = { 0xff, 0x7f };
+static const gdb_byte arc_brk_be[] = { 0x25, 0x6f, 0x00, 0x3f };
+static const gdb_byte arc_brk_le[] = { 0x6f, 0x25, 0x3f, 0x00 };
+
+/* Implement the "breakpoint_from_pc" gdbarch method.
+
+ For ARC ELF, breakpoint uses the 16-bit BRK_S instruction, which is 0x7fff
+ (little endian) or 0xff7f (big endian). We used to insert BRK_S even
+ instead of 32-bit instructions, which works mostly ok, unless breakpoint is
+ inserted into delay slot instruction. In this case if branch is taken
+ BLINK value will be set to address of instruction after delay slot, however
+ if we replaced 32-bit instruction in delay slot with 16-bit long BRK_S,
+ then BLINK value will have an invalid value - it will point to the address
+ after the BRK_S (which was there at the moment of branch execution) while
+ it should point to the address after the 32-bit long instruction. To avoid
+ such issues this function disassembles instruction at target location and
+ evaluates it value.
+
+ ARC 600 supports only 16-bit BRK_S.
+
+ NB: Baremetal GDB uses BRK[_S], while user-space GDB uses TRAP_S. BRK[_S]
+ is much better because it doesn't commit unlike TRAP_S, so it can be set in
+ delay slots; however it cannot be used in user-mode, hence usage of TRAP_S
+ in GDB for user-space.
+
+ PCPTR is a pointer to the PC where we want to place a breakpoint. LENPTR
+ is a number of bytes used by the breakpoint. Returns the byte sequence of
+ a breakpoint instruction. */
+
+static const gdb_byte *
+arc_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
+ int *lenptr)
+{
+ size_t length_with_limm = gdb_insn_length (gdbarch, *pcptr);
+
+ /* Replace 16-bit instruction with BRK_S, replace 32-bit instructions with
+ BRK. LIMM is part of instruction length, so it can be either 4 or 8
+ bytes for 32-bit instructions. */
+ if ((length_with_limm == 4 || length_with_limm == 8)
+ && !arc_mach_is_arc600 (gdbarch))
+ {
+ *lenptr = sizeof (arc_brk_le);
+ return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ ? arc_brk_be
+ : arc_brk_le);
+ }
+ else
+ {
+ *lenptr = sizeof (arc_brk_s_le);
+ return ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ ? arc_brk_s_be
+ : arc_brk_s_le);
+ }
+}
+
+/* Implement the "unwind_pc" gdbarch method. */
+
+static CORE_ADDR
+arc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ int pc_regnum = gdbarch_pc_regnum (gdbarch);
+ CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, pc_regnum);
+
+ if (arc_debug)
+ debug_printf ("arc: unwind PC: %s\n", paddress (gdbarch, pc));
+
+ return pc;
+}
+
+/* Implement the "unwind_sp" gdbarch method. */
+
+static CORE_ADDR
+arc_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ int sp_regnum = gdbarch_sp_regnum (gdbarch);
+ CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, sp_regnum);
+
+ if (arc_debug)
+ debug_printf ("arc: unwind SP: %s\n", paddress (gdbarch, sp));
+
+ return sp;
+}
+
+/* Implement the "frame_align" gdbarch method. */
+
+static CORE_ADDR
+arc_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+ return align_down (sp, 4);
+}
+
+/* Frame unwinder for normal frames. */
+
+static struct arc_frame_cache *
+arc_make_frame_cache (struct frame_info *this_frame)
+{
+ if (arc_debug)
+ debug_printf ("arc: frame_cache\n");
+
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+
+ CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
+ CORE_ADDR prev_pc = get_frame_pc (this_frame);
+
+ CORE_ADDR entrypoint, prologue_end;
+ if (find_pc_partial_function (block_addr, NULL, &entrypoint, &prologue_end))
+ {
+ struct symtab_and_line sal = find_pc_line (entrypoint, 0);
+ if (sal.line == 0)
+ /* No line info so use current PC. */
+ prologue_end = prev_pc;
+ else if (sal.end < prologue_end)
+ /* The next line begins after the function end. */
+ prologue_end = sal.end;
+
+ prologue_end = std::min (prologue_end, prev_pc);
+ }
+ else
+ {
+ entrypoint = get_frame_register_unsigned (this_frame,
+ gdbarch_pc_regnum (gdbarch));
+ prologue_end = 0;
+ }
+
+ /* Allocate new frame cache instance and space for saved register info.
+ * FRAME_OBSTACK_ZALLOC will initialize fields to zeroes. */
+ struct arc_frame_cache *cache
+ = FRAME_OBSTACK_ZALLOC (struct arc_frame_cache);
+ cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+ /* Should call analyze_prologue here, when it will be implemented. */
+
+ return cache;
+}
+
+/* Implement the "this_id" frame_unwind method. */
+
+static void
+arc_frame_this_id (struct frame_info *this_frame, void **this_cache,
+ struct frame_id *this_id)
+{
+ if (arc_debug)
+ debug_printf ("arc: frame_this_id\n");
+
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+
+ if (*this_cache == NULL)
+ *this_cache = arc_make_frame_cache (this_frame);
+ struct arc_frame_cache *cache = (struct arc_frame_cache *) (*this_cache);
+
+ CORE_ADDR stack_addr = cache->prev_sp;
+
+ /* There are 4 possible situation which decide how frame_id->code_addr is
+ evaluated:
+
+ 1) Function is compiled with option -g. Then frame_id will be created
+ in dwarf_* function and not in this function. NB: even if target
+ binary is compiled with -g, some std functions like __start and _init
+ are not, so they still will follow one of the following choices.
+
+ 2) Function is compiled without -g and binary hasn't been stripped in
+ any way. In this case GDB still has enough information to evaluate
+ frame code_addr properly. This case is covered by call to
+ get_frame_func ().
+
+ 3) Binary has been striped with option -g (strip debug symbols). In
+ this case there is still enough symbols for get_frame_func () to work
+ properly, so this case is also covered by it.
+
+ 4) Binary has been striped with option -s (strip all symbols). In this
+ case GDB cannot get function start address properly, so we return current
+ PC value instead.
+ */
+ CORE_ADDR code_addr = get_frame_func (this_frame);
+ if (code_addr == 0)
+ code_addr = get_frame_register_unsigned (this_frame,
+ gdbarch_pc_regnum (gdbarch));
+
+ *this_id = frame_id_build (stack_addr, code_addr);
+}
+
+/* Implement the "prev_register" frame_unwind method. */
+
+static struct value *
+arc_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ if (arc_debug)
+ debug_printf ("arc: frame_prev_register (regnum = %d)\n", regnum);
+
+ if (*this_cache == NULL)
+ *this_cache = arc_make_frame_cache (this_frame);
+ struct arc_frame_cache *cache = (struct arc_frame_cache *) (*this_cache);
+
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+
+ /* If we are asked to unwind the PC, then we need to return BLINK instead:
+ the saved value of PC points into this frame's function's prologue, not
+ the next frame's function's resume location. */
+ if (regnum == gdbarch_pc_regnum (gdbarch))
+ regnum = ARC_BLINK_REGNUM;
+
+ /* SP is a special case - we should return prev_sp, because
+ trad_frame_get_prev_register will return _current_ SP value.
+ Alternatively we could have stored cache->prev_sp in the cache->saved
+ regs, but here we follow the lead of AArch64, ARM and Xtensa and will
+ leave that logic in this function, instead of prologue analyzers. That I
+ think is a bit more clear as `saved_regs` should contain saved regs, not
+ computable.
+
+ Because value has been computed, "got_constant" should be used, so that
+ returned value will be a "not_lval" - immutable. */
+
+ if (regnum == gdbarch_sp_regnum (gdbarch))
+ return frame_unwind_got_constant (this_frame, regnum, cache->prev_sp);
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
+}
+
+/* Implement the "init_reg" dwarf2_frame method. */
+
+static void
+arc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
+ struct dwarf2_frame_state_reg *reg,
+ struct frame_info *info)
+{
+ if (regnum == gdbarch_pc_regnum (gdbarch))
+ /* The return address column. */
+ reg->how = DWARF2_FRAME_REG_RA;
+ else if (regnum == gdbarch_sp_regnum (gdbarch))
+ /* The call frame address. */
+ reg->how = DWARF2_FRAME_REG_CFA;
+}
+
+/* Structure defining the ARC ordinary frame unwind functions. Since we are
+ the fallback unwinder, we use the default frame sniffer, which always
+ accepts the frame. */
+
+static const struct frame_unwind arc_frame_unwind = {
+ NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
+ arc_frame_this_id,
+ arc_frame_prev_register,
+ NULL,
+ default_frame_sniffer,
+ NULL,
+ NULL
+};
+
+
+static const struct frame_base arc_normal_base = {
+ &arc_frame_unwind,
+ arc_frame_base_address,
+ arc_frame_base_address,
+ arc_frame_base_address
+};
+
+/* Initialize target description for the ARC.
+
+ Returns TRUE if input tdesc was valid and in this case it will assign TDESC
+ and TDESC_DATA output parameters. */
+
+static int
+arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
+ struct tdesc_arch_data **tdesc_data)
+{
+ if (arc_debug)
+ debug_printf ("arc: Target description initialization.\n");
+
+ const struct target_desc *tdesc_loc = info.target_desc;
+
+ /* Depending on whether this is ARCompact or ARCv2 we will assign
+ different default registers sets (which will differ in exactly two core
+ registers). GDB will also refuse to accept register feature from invalid
+ ISA - v2 features can be used only with v2 ARChitecture. We read
+ bfd_arch_info, which looks like to be a safe bet here, as it looks like it
+ is always initialized even when we don't pass any elf file to GDB at all
+ (it uses default arch in this case). Also GDB will call this function
+ multiple times, and if XML target description file contains architecture
+ specifications, then GDB will set this architecture to info.bfd_arch_info,
+ overriding value from ELF file if they are different. That means that,
+ where matters, this value is always our best guess on what CPU we are
+ debugging. It has been noted that architecture specified in tdesc file
+ has higher precedence over ELF and even "set architecture" - that is,
+ using "set architecture" command will have no effect when tdesc has "arch"
+ tag. */
+ /* Cannot use arc_mach_is_arcv2 (), because gdbarch is not created yet. */
+ const int is_arcv2 = (info.bfd_arch_info->mach == bfd_mach_arc_arcv2);
+ int is_reduced_rf;
+ const char *const *core_regs;
+ const char *core_feature_name;
+
+ /* If target doesn't provide a description - use default one. */
+ if (!tdesc_has_registers (tdesc_loc))
+ {
+ if (is_arcv2)
+ {
+ tdesc_loc = tdesc_arc_v2;
+ if (arc_debug)
+ debug_printf ("arc: Using default register set for ARC v2.\n");
+ }
+ else
+ {
+ tdesc_loc = tdesc_arc_arcompact;
+ if (arc_debug)
+ debug_printf ("arc: Using default register set for ARCompact.\n");
+ }
+ }
+ else
+ {
+ if (arc_debug)
+ debug_printf ("arc: Using provided register set.\n");
+ }
+ gdb_assert (tdesc_loc != NULL);
+
+ /* Now we can search for base registers. Core registers can be either full
+ or reduced. Summary:
+
+ - core.v2 + aux-minimal
+ - core-reduced.v2 + aux-minimal
+ - core.arcompact + aux-minimal
+
+ NB: It is entirely feasible to have ARCompact with reduced core regs, but
+ we ignore that because GCC doesn't support that and at the same time
+ ARCompact is considered obsolete, so there is not much reason to support
+ that. */
+ const struct tdesc_feature *feature
+ = tdesc_find_feature (tdesc_loc, core_v2_feature_name);
+ if (feature != NULL)
+ {
+ /* Confirm that register and architecture match, to prevent accidents in
+ some situations. This code will trigger an error if:
+
+ 1. XML tdesc doesn't specify arch explicitly, registers are for arch
+ X, but ELF specifies arch Y.
+
+ 2. XML tdesc specifies arch X, but contains registers for arch Y.
+
+ It will not protect from case where XML or ELF specify arch X,
+ registers are for the same arch X, but the real target is arch Y. To
+ detect this case we need to check IDENTITY register. */
+ if (!is_arcv2)
+ {
+ arc_print (_("Error: ARC v2 target description supplied for "
+ "non-ARCv2 target.\n"));
+ return FALSE;
+ }
+
+ is_reduced_rf = FALSE;
+ core_feature_name = core_v2_feature_name;
+ core_regs = core_v2_register_names;
+ }
+ else
+ {
+ feature = tdesc_find_feature (tdesc_loc, core_reduced_v2_feature_name);
+ if (feature != NULL)
+ {
+ if (!is_arcv2)
+ {
+ arc_print (_("Error: ARC v2 target description supplied for "
+ "non-ARCv2 target.\n"));
+ return FALSE;
+ }
+
+ is_reduced_rf = TRUE;
+ core_feature_name = core_reduced_v2_feature_name;
+ core_regs = core_v2_register_names;
+ }
+ else
+ {
+ feature = tdesc_find_feature (tdesc_loc,
+ core_arcompact_feature_name);
+ if (feature != NULL)
+ {
+ if (is_arcv2)
+ {
+ arc_print (_("Error: ARCompact target description supplied "
+ "for non-ARCompact target.\n"));
+ return FALSE;
+ }
+
+ is_reduced_rf = FALSE;
+ core_feature_name = core_arcompact_feature_name;
+ core_regs = core_arcompact_register_names;
+ }
+ else
+ {
+ arc_print (_("Error: Couldn't find core register feature in "
+ "supplied target description."));
+ return FALSE;
+ }
+ }
+ }
+
+ struct tdesc_arch_data *tdesc_data_loc = tdesc_data_alloc ();
+
+ gdb_assert (feature != NULL);
+ int valid_p = 1;
+
+ for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
+ {
+ /* If rf16, then skip extra registers. */
+ if (is_reduced_rf && ((i >= ARC_R4_REGNUM && i <= ARC_R9_REGNUM)
+ || (i >= ARC_R16_REGNUM && i <= ARC_R25_REGNUM)))
+ continue;
+
+ valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i,
+ core_regs[i]);
+
+ /* - Ignore errors in extension registers - they are optional.
+ - Ignore missing ILINK because it doesn't make sense for Linux.
+ - Ignore missing ILINK2 when architecture is ARCompact, because it
+ doesn't make sense for Linux targets.
+
+ In theory those optional registers should be in separate features, but
+ that would create numerous but tiny features, which looks like an
+ overengineering of a rather simple task. */
+ if (!valid_p && (i <= ARC_SP_REGNUM || i == ARC_BLINK_REGNUM
+ || i == ARC_LP_COUNT_REGNUM || i == ARC_PCL_REGNUM
+ || (i == ARC_R30_REGNUM && is_arcv2)))
+ {
+ arc_print (_("Error: Cannot find required register `%s' in "
+ "feature `%s'.\n"), core_regs[i], core_feature_name);
+ tdesc_data_cleanup (tdesc_data_loc);
+ return FALSE;
+ }
+ }
+
+ /* Mandatory AUX registeres are intentionally few and are common between
+ ARCompact and ARC v2, so same code can be used for both. */
+ feature = tdesc_find_feature (tdesc_loc, aux_minimal_feature_name);
+ if (feature == NULL)
+ {
+ arc_print (_("Error: Cannot find required feature `%s' in supplied "
+ "target description.\n"), aux_minimal_feature_name);
+ tdesc_data_cleanup (tdesc_data_loc);
+ return FALSE;
+ }
+
+ for (int i = ARC_FIRST_AUX_REGNUM; i <= ARC_LAST_AUX_REGNUM; i++)
+ {
+ const char *name = aux_minimal_register_names[i - ARC_FIRST_AUX_REGNUM];
+ valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i, name);
+ if (!valid_p)
+ {
+ arc_print (_("Error: Cannot find required register `%s' "
+ "in feature `%s'.\n"),
+ name, tdesc_feature_name (feature));
+ tdesc_data_cleanup (tdesc_data_loc);
+ return FALSE;
+ }
+ }
+
+ *tdesc = tdesc_loc;
+ *tdesc_data = tdesc_data_loc;
+
+ return TRUE;
+}
+
+/* Implement the "init" gdbarch method. */
+
+static struct gdbarch *
+arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+ const struct target_desc *tdesc;
+ struct tdesc_arch_data *tdesc_data;
+
+ if (arc_debug)
+ debug_printf ("arc: Architecture initialization.\n");
+
+ if (!arc_tdesc_init (info, &tdesc, &tdesc_data))
+ return NULL;
+
+ struct gdbarch *gdbarch = gdbarch_alloc (&info, NULL);
+
+ /* Data types. */
+ set_gdbarch_short_bit (gdbarch, 16);
+ set_gdbarch_int_bit (gdbarch, 32);
+ set_gdbarch_long_bit (gdbarch, 32);
+ set_gdbarch_long_long_bit (gdbarch, 64);
+ set_gdbarch_long_long_align_bit (gdbarch, 32);
+ set_gdbarch_float_bit (gdbarch, 32);
+ set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
+ set_gdbarch_double_bit (gdbarch, 64);
+ set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
+ set_gdbarch_ptr_bit (gdbarch, 32);
+ set_gdbarch_addr_bit (gdbarch, 32);
+ set_gdbarch_char_signed (gdbarch, 0);
+
+ set_gdbarch_write_pc (gdbarch, arc_write_pc);
+
+ set_gdbarch_virtual_frame_pointer (gdbarch, arc_virtual_frame_pointer);
+
+ /* tdesc_use_registers expects gdbarch_num_regs to return number of registers
+ parsed by gdbarch_init, and then it will add all of the remaining
+ registers and will increase number of registers. */
+ set_gdbarch_num_regs (gdbarch, ARC_LAST_REGNUM + 1);
+ set_gdbarch_num_pseudo_regs (gdbarch, 0);
+ set_gdbarch_sp_regnum (gdbarch, ARC_SP_REGNUM);
+ set_gdbarch_pc_regnum (gdbarch, ARC_PC_REGNUM);
+ set_gdbarch_ps_regnum (gdbarch, ARC_STATUS32_REGNUM);
+ set_gdbarch_fp0_regnum (gdbarch, -1); /* No FPU registers. */
+
+ set_gdbarch_dummy_id (gdbarch, arc_dummy_id);
+ set_gdbarch_push_dummy_call (gdbarch, arc_push_dummy_call);
+ set_gdbarch_push_dummy_code (gdbarch, arc_push_dummy_code);
+
+ set_gdbarch_cannot_fetch_register (gdbarch, arc_cannot_fetch_register);
+ set_gdbarch_cannot_store_register (gdbarch, arc_cannot_store_register);
+
+ set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+
+ set_gdbarch_return_value (gdbarch, arc_return_value);
+
+ set_gdbarch_skip_prologue (gdbarch, arc_skip_prologue);
+ set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+ set_gdbarch_breakpoint_from_pc (gdbarch, arc_breakpoint_from_pc);
+
+ /* On ARC 600 BRK_S instruction advances PC, unlike other ARC cores. */
+ if (!arc_mach_is_arc600 (gdbarch))
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ else
+ set_gdbarch_decr_pc_after_break (gdbarch, 2);
+
+ set_gdbarch_unwind_pc (gdbarch, arc_unwind_pc);
+ set_gdbarch_unwind_sp (gdbarch, arc_unwind_sp);
+
+ set_gdbarch_frame_align (gdbarch, arc_frame_align);
+
+ set_gdbarch_print_insn (gdbarch, arc_delayed_print_insn);
+
+ set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
+
+ /* "nonsteppable" watchpoint means that watchpoint triggers before
+ instruction is committed, therefore it is required to remove watchpoint
+ to step though instruction that triggers it. ARC watchpoints trigger
+ only after instruction is committed, thus there is no need to remove
+ them. In fact on ARC watchpoint for memory writes may trigger with more
+ significant delay, like one or two instructions, depending on type of
+ memory where write is performed (CCM or external) and next instruction
+ after the memory write. */
+ set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 0);
+
+ /* This doesn't include possible long-immediate value. */
+ set_gdbarch_max_insn_length (gdbarch, 4);
+
+ /* Frame unwinders and sniffers. */
+ dwarf2_frame_set_init_reg (gdbarch, arc_dwarf2_frame_init_reg);
+ dwarf2_append_unwinders (gdbarch);
+ frame_unwind_append_unwinder (gdbarch, &arc_frame_unwind);
+ frame_base_set_default (gdbarch, &arc_normal_base);
+
+ /* Setup stuff specific to a particular environment (baremetal or Linux).
+ It can override functions set earlier. */
+ gdbarch_init_osabi (info, gdbarch);
+
+ tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+
+ return gdbarch;
+}
+
+/* Implement the "dump_tdep" gdbarch method. */
+
+static void
+arc_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
+{
+ /* Empty for now. */
+}
+
+/* Suppress warning from -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_arc_tdep;
+
+void
+_initialize_arc_tdep (void)
+{
+ gdbarch_register (bfd_arch_arc, arc_gdbarch_init, arc_dump_tdep);
+
+ initialize_tdesc_arc_v2 ();
+ initialize_tdesc_arc_arcompact ();
+
+ /* Register ARC-specific commands with gdb. */
+
+ /* Debug internals for ARC GDB. */
+ add_setshow_zinteger_cmd ("arc", class_maintenance,
+ &arc_debug,
+ _("Set ARC specific debugging."),
+ _("Show ARC specific debugging."),
+ _("Non-zero enables ARC specific debugging."),
+ NULL, NULL, &setdebuglist, &showdebuglist);
+}