1 /* Target-dependent code for the LoongArch architecture, for GDB.
3 Copyright (C) 2022 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "arch-utils.h"
22 #include "dwarf2/frame.h"
24 #include "frame-unwind.h"
26 #include "loongarch-tdep.h"
28 #include "target-descriptions.h"
29 #include "trad-frame.h"
30 #include "user-regs.h"
32 /* Fetch the instruction at PC. */
35 loongarch_fetch_instruction (CORE_ADDR pc
)
37 size_t insn_len
= loongarch_insn_length (0);
38 gdb_byte buf
[insn_len
];
41 err
= target_read_memory (pc
, buf
, insn_len
);
43 memory_error (TARGET_XFER_E_IO
, pc
);
45 return extract_unsigned_integer (buf
, insn_len
, BFD_ENDIAN_LITTLE
);
48 /* Return TRUE if INSN is a branch instruction, otherwise return FALSE. */
51 loongarch_insn_is_branch (insn_t insn
)
53 if ((insn
& 0xfc000000) == 0x4c000000 /* jirl rd, rj, offs16 */
54 || (insn
& 0xfc000000) == 0x50000000 /* b offs26 */
55 || (insn
& 0xfc000000) == 0x54000000 /* bl offs26 */
56 || (insn
& 0xfc000000) == 0x58000000 /* beq rj, rd, offs16 */
57 || (insn
& 0xfc000000) == 0x5c000000 /* bne rj, rd, offs16 */
58 || (insn
& 0xfc000000) == 0x60000000 /* blt rj, rd, offs16 */
59 || (insn
& 0xfc000000) == 0x64000000 /* bge rj, rd, offs16 */
60 || (insn
& 0xfc000000) == 0x68000000 /* bltu rj, rd, offs16 */
61 || (insn
& 0xfc000000) == 0x6c000000 /* bgeu rj, rd, offs16 */
62 || (insn
& 0xfc000000) == 0x40000000 /* beqz rj, offs21 */
63 || (insn
& 0xfc000000) == 0x44000000) /* bnez rj, offs21 */
68 /* Analyze the function prologue from START_PC to LIMIT_PC.
69 Return the address of the first instruction past the prologue. */
72 loongarch_scan_prologue (struct gdbarch
*gdbarch
, CORE_ADDR start_pc
,
73 CORE_ADDR limit_pc
, struct frame_info
*this_frame
,
74 struct trad_frame_cache
*this_cache
)
76 CORE_ADDR cur_pc
= start_pc
, prologue_end
= 0;
77 loongarch_gdbarch_tdep
*tdep
= (loongarch_gdbarch_tdep
*) gdbarch_tdep (gdbarch
);
78 auto regs
= tdep
->regs
;
79 int32_t sp
= regs
.r
+ 3;
80 int32_t fp
= regs
.r
+ 22;
81 int32_t reg_value
[32] = {0};
82 int32_t reg_used
[32] = {1, 0};
84 while (cur_pc
< limit_pc
)
86 insn_t insn
= loongarch_fetch_instruction (cur_pc
);
87 size_t insn_len
= loongarch_insn_length (insn
);
88 int32_t rd
= loongarch_decode_imm ("0:5", insn
, 0);
89 int32_t rj
= loongarch_decode_imm ("5:5", insn
, 0);
90 int32_t rk
= loongarch_decode_imm ("10:5", insn
, 0);
91 int32_t si12
= loongarch_decode_imm ("10:12", insn
, 1);
92 int32_t si20
= loongarch_decode_imm ("5:20", insn
, 1);
94 if ((insn
& 0xffc00000) == 0x02c00000 /* addi.d sp,sp,si12 */
95 && rd
== sp
&& rj
== sp
&& si12
< 0)
97 prologue_end
= cur_pc
+ insn_len
;
99 else if ((insn
& 0xffc00000) == 0x02c00000 /* addi.d fp,sp,si12 */
100 && rd
== fp
&& rj
== sp
&& si12
> 0)
102 prologue_end
= cur_pc
+ insn_len
;
104 else if ((insn
& 0xffc00000) == 0x29c00000 /* st.d rd,sp,si12 */
107 prologue_end
= cur_pc
+ insn_len
;
109 else if ((insn
& 0xff000000) == 0x27000000 /* stptr.d rd,sp,si14 */
112 prologue_end
= cur_pc
+ insn_len
;
114 else if ((insn
& 0xfe000000) == 0x14000000) /* lu12i.w rd,si20 */
116 reg_value
[rd
] = si20
<< 12;
119 else if ((insn
& 0xffc00000) == 0x03800000) /* ori rd,rj,si12 */
123 reg_value
[rd
] = reg_value
[rj
] | (si12
& 0xfff);
127 else if ((insn
& 0xffff8000) == 0x00108000 /* add.d sp,sp,rk */
128 && rd
== sp
&& rj
== sp
)
130 if (reg_used
[rk
] == 1 && reg_value
[rk
] < 0)
132 prologue_end
= cur_pc
+ insn_len
;
136 else if (loongarch_insn_is_branch (insn
))
144 if (prologue_end
== 0)
145 prologue_end
= cur_pc
;
150 /* Implement the loongarch_skip_prologue gdbarch method. */
153 loongarch_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR pc
)
157 /* See if we can determine the end of the prologue via the symbol table.
158 If so, then return either PC, or the PC after the prologue, whichever
160 if (find_pc_partial_function (pc
, nullptr, &func_addr
, nullptr))
162 CORE_ADDR post_prologue_pc
163 = skip_prologue_using_sal (gdbarch
, func_addr
);
164 if (post_prologue_pc
!= 0)
165 return std::max (pc
, post_prologue_pc
);
168 /* Can't determine prologue from the symbol table, need to examine
171 /* Find an upper limit on the function prologue using the debug
172 information. If the debug information could not be used to provide
173 that bound, then use an arbitrary large number as the upper bound. */
174 CORE_ADDR limit_pc
= skip_prologue_using_sal (gdbarch
, pc
);
176 limit_pc
= pc
+ 100; /* Arbitrary large number. */
178 return loongarch_scan_prologue (gdbarch
, pc
, limit_pc
, nullptr, nullptr);
181 /* Adjust the address downward (direction of stack growth) so that it
182 is correctly aligned for a new stack frame. */
185 loongarch_frame_align (struct gdbarch
*gdbarch
, CORE_ADDR addr
)
187 return align_down (addr
, 16);
190 /* Generate, or return the cached frame cache for LoongArch frame unwinder. */
192 static struct trad_frame_cache
*
193 loongarch_frame_cache (struct frame_info
*this_frame
, void **this_cache
)
195 struct gdbarch
*gdbarch
= get_frame_arch (this_frame
);
196 struct trad_frame_cache
*cache
;
199 if (*this_cache
!= nullptr)
200 return (struct trad_frame_cache
*) *this_cache
;
202 cache
= trad_frame_cache_zalloc (this_frame
);
205 loongarch_gdbarch_tdep
*tdep
= (loongarch_gdbarch_tdep
*) gdbarch_tdep (gdbarch
);
206 trad_frame_set_reg_realreg (cache
, gdbarch_pc_regnum (gdbarch
), tdep
->regs
.ra
);
208 pc
= get_frame_address_in_block (this_frame
);
209 trad_frame_set_id (cache
, frame_id_build_unavailable_stack (pc
));
214 /* Implement the this_id callback for LoongArch frame unwinder. */
217 loongarch_frame_this_id (struct frame_info
*this_frame
, void **prologue_cache
,
218 struct frame_id
*this_id
)
220 struct trad_frame_cache
*info
;
222 info
= loongarch_frame_cache (this_frame
, prologue_cache
);
223 trad_frame_get_id (info
, this_id
);
226 /* Implement the prev_register callback for LoongArch frame unwinder. */
228 static struct value
*
229 loongarch_frame_prev_register (struct frame_info
*this_frame
,
230 void **prologue_cache
, int regnum
)
232 struct trad_frame_cache
*info
;
234 info
= loongarch_frame_cache (this_frame
, prologue_cache
);
235 return trad_frame_get_register (info
, this_frame
, regnum
);
238 static const struct frame_unwind loongarch_frame_unwind
= {
239 "loongarch prologue",
240 /*.type =*/NORMAL_FRAME
,
241 /*.stop_reason =*/default_frame_unwind_stop_reason
,
242 /*.this_id =*/loongarch_frame_this_id
,
243 /*.prev_register =*/loongarch_frame_prev_register
,
244 /*.unwind_data =*/nullptr,
245 /*.sniffer =*/default_frame_sniffer
,
246 /*.dealloc_cache =*/nullptr,
247 /*.prev_arch =*/nullptr,
250 /* Implement the "dwarf2_reg_to_regnum" gdbarch method. */
253 loongarch_dwarf2_reg_to_regnum (struct gdbarch
*gdbarch
, int num
)
255 loongarch_gdbarch_tdep
*tdep
= (loongarch_gdbarch_tdep
*) gdbarch_tdep (gdbarch
);
256 auto regs
= tdep
->regs
;
258 if (0 <= num
&& num
< 32)
264 static constexpr gdb_byte loongarch_default_breakpoint
[] = {0x05, 0x00, 0x2a, 0x00};
265 typedef BP_MANIPULATION (loongarch_default_breakpoint
) loongarch_breakpoint
;
267 /* Extract a set of required target features out of ABFD. If ABFD is nullptr
268 then a LOONGARCH_GDBARCH_FEATURES is returned in its default state. */
270 static struct loongarch_gdbarch_features
271 loongarch_features_from_bfd (const bfd
*abfd
)
273 struct loongarch_gdbarch_features features
;
275 /* Now try to improve on the defaults by looking at the binary we are
276 going to execute. We assume the user knows what they are doing and
277 that the target will match the binary. Remember, this code path is
278 only used at all if the target hasn't given us a description, so this
279 is really a last ditched effort to do something sane before giving
281 if (abfd
!= nullptr && bfd_get_flavour (abfd
) == bfd_target_elf_flavour
)
283 unsigned char eclass
= elf_elfheader (abfd
)->e_ident
[EI_CLASS
];
285 if (eclass
== ELFCLASS32
)
287 else if (eclass
== ELFCLASS64
)
290 internal_error (__FILE__
, __LINE__
,
291 _("unknown ELF header class %d"), eclass
);
297 /* Find a suitable default target description. Use the contents of INFO,
298 specifically the bfd object being executed, to guide the selection of a
299 suitable default target description. */
301 static const struct target_desc
*
302 loongarch_find_default_target_description (const struct gdbarch_info info
)
304 /* Extract desired feature set from INFO. */
305 struct loongarch_gdbarch_features features
306 = loongarch_features_from_bfd (info
.abfd
);
308 /* If the XLEN field is still 0 then we got nothing useful from INFO.BFD,
309 maybe there was no bfd object. In this case we fall back to a minimal
310 useful target with no floating point, the x-register size is selected
311 based on the architecture from INFO. */
312 if (features
.xlen
== 0)
313 features
.xlen
= info
.bfd_arch_info
->bits_per_address
== 32 ? 4 : 8;
315 /* Now build a target description based on the feature set. */
316 return loongarch_lookup_target_description (features
);
319 /* Initialize the current architecture based on INFO */
321 static struct gdbarch
*
322 loongarch_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
324 const struct target_desc
*tdesc
= info
.target_desc
;
326 /* Ensure we always have a target description. */
327 if (!tdesc_has_registers (tdesc
))
328 tdesc
= loongarch_find_default_target_description (info
);
330 const struct tdesc_feature
*feature_cpu
331 = tdesc_find_feature (tdesc
, "org.gnu.gdb.loongarch.base");
332 if (feature_cpu
== nullptr)
335 int xlen_bitsize
= tdesc_register_bitsize (feature_cpu
, "pc");
336 struct loongarch_gdbarch_features features
;
337 features
.xlen
= (xlen_bitsize
/ 8);
340 tdesc_arch_data_up tdesc_data
= tdesc_data_alloc ();
341 loongarch_gdbarch_tdep
*tdep
= new loongarch_gdbarch_tdep
;
342 tdep
->regs
.r
= regnum
;
344 /* Validate the description provides the mandatory base registers
345 and allocate their numbers. */
347 for (int i
= 0; i
< 32; i
++)
348 valid_p
&= tdesc_numbered_register (feature_cpu
, tdesc_data
.get (), regnum
++,
349 loongarch_r_normal_name
[i
] + 1);
350 valid_p
&= tdesc_numbered_register (feature_cpu
, tdesc_data
.get (),
351 tdep
->regs
.pc
= regnum
++, "pc");
352 valid_p
&= tdesc_numbered_register (feature_cpu
, tdesc_data
.get (),
353 tdep
->regs
.badv
= regnum
++, "badv");
357 /* LoongArch code is always little-endian. */
358 info
.byte_order_for_code
= BFD_ENDIAN_LITTLE
;
360 /* Have a look at what the supplied (if any) bfd object requires of the
361 target, then check that this matches with what the target is
363 struct loongarch_gdbarch_features abi_features
364 = loongarch_features_from_bfd (info
.abfd
);
366 /* If the ABI_FEATURES xlen is 0 then this indicates we got no useful abi
367 features from the INFO object. In this case we just treat the
368 hardware features as defining the abi. */
369 if (abi_features
.xlen
== 0)
370 abi_features
= features
;
372 /* Find a candidate among the list of pre-declared architectures. */
373 for (arches
= gdbarch_list_lookup_by_info (arches
, &info
);
375 arches
= gdbarch_list_lookup_by_info (arches
->next
, &info
))
377 /* Check that the feature set of the ARCHES matches the feature set
378 we are looking for. If it doesn't then we can't reuse this
380 loongarch_gdbarch_tdep
*candidate_tdep
381 = (loongarch_gdbarch_tdep
*) gdbarch_tdep (arches
->gdbarch
);
383 if (candidate_tdep
->abi_features
!= abi_features
)
389 if (arches
!= nullptr)
390 return arches
->gdbarch
;
392 /* None found, so create a new architecture from the information provided. */
393 struct gdbarch
*gdbarch
= gdbarch_alloc (&info
, tdep
);
394 tdep
->abi_features
= abi_features
;
396 /* Target data types. */
397 set_gdbarch_short_bit (gdbarch
, 16);
398 set_gdbarch_int_bit (gdbarch
, 32);
399 set_gdbarch_long_bit (gdbarch
, info
.bfd_arch_info
->bits_per_address
);
400 set_gdbarch_long_long_bit (gdbarch
, 64);
401 set_gdbarch_float_bit (gdbarch
, 32);
402 set_gdbarch_double_bit (gdbarch
, 64);
403 set_gdbarch_long_double_bit (gdbarch
, 128);
404 set_gdbarch_long_double_format (gdbarch
, floatformats_ieee_quad
);
405 set_gdbarch_ptr_bit (gdbarch
, info
.bfd_arch_info
->bits_per_address
);
406 set_gdbarch_char_signed (gdbarch
, 0);
408 info
.target_desc
= tdesc
;
409 info
.tdesc_data
= tdesc_data
.get ();
411 /* Information about registers. */
412 tdep
->regs
.ra
= tdep
->regs
.r
+ 1;
413 tdep
->regs
.sp
= tdep
->regs
.r
+ 3;
414 set_gdbarch_num_regs (gdbarch
, regnum
);
415 set_gdbarch_sp_regnum (gdbarch
, tdep
->regs
.sp
);
416 set_gdbarch_pc_regnum (gdbarch
, tdep
->regs
.pc
);
418 /* Finalise the target description registers. */
419 tdesc_use_registers (gdbarch
, tdesc
, std::move (tdesc_data
));
421 /* Advance PC across function entry code. */
422 set_gdbarch_skip_prologue (gdbarch
, loongarch_skip_prologue
);
424 /* Stack grows downward. */
425 set_gdbarch_inner_than (gdbarch
, core_addr_lessthan
);
428 set_gdbarch_frame_align (gdbarch
, loongarch_frame_align
);
430 /* Breakpoint manipulation. */
431 set_gdbarch_breakpoint_kind_from_pc (gdbarch
, loongarch_breakpoint::kind_from_pc
);
432 set_gdbarch_sw_breakpoint_from_kind (gdbarch
, loongarch_breakpoint::bp_from_kind
);
434 /* Frame unwinders. Use DWARF debug info if available, otherwise use our own unwinder. */
435 set_gdbarch_dwarf2_reg_to_regnum (gdbarch
, loongarch_dwarf2_reg_to_regnum
);
436 dwarf2_append_unwinders (gdbarch
);
437 frame_unwind_append_unwinder (gdbarch
, &loongarch_frame_unwind
);
439 /* Hook in OS ABI-specific overrides, if they have been registered. */
440 gdbarch_init_osabi (info
, gdbarch
);
445 void _initialize_loongarch_tdep ();
447 _initialize_loongarch_tdep ()
449 gdbarch_register (bfd_arch_loongarch
, loongarch_gdbarch_init
, nullptr);