1699b0f92Schristos /* Motorola m68k target-dependent support for GNU/Linux. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 1996-2023 Free Software Foundation, Inc. 4699b0f92Schristos 5699b0f92Schristos This file is part of GDB. 6699b0f92Schristos 7699b0f92Schristos This program is free software; you can redistribute it and/or modify 8699b0f92Schristos it under the terms of the GNU General Public License as published by 9699b0f92Schristos the Free Software Foundation; either version 3 of the License, or 10699b0f92Schristos (at your option) any later version. 11699b0f92Schristos 12699b0f92Schristos This program is distributed in the hope that it will be useful, 13699b0f92Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14699b0f92Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15699b0f92Schristos GNU General Public License for more details. 16699b0f92Schristos 17699b0f92Schristos You should have received a copy of the GNU General Public License 18699b0f92Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19699b0f92Schristos 20699b0f92Schristos #include "defs.h" 21699b0f92Schristos #include "gdbcore.h" 22699b0f92Schristos #include "frame.h" 23699b0f92Schristos #include "target.h" 24699b0f92Schristos #include "gdbtypes.h" 25699b0f92Schristos #include "osabi.h" 26699b0f92Schristos #include "regcache.h" 27699b0f92Schristos #include "objfiles.h" 28699b0f92Schristos #include "symtab.h" 29699b0f92Schristos #include "m68k-tdep.h" 30699b0f92Schristos #include "trad-frame.h" 31699b0f92Schristos #include "frame-unwind.h" 32699b0f92Schristos #include "glibc-tdep.h" 33699b0f92Schristos #include "solib-svr4.h" 34699b0f92Schristos #include "auxv.h" 357f2ac410Schristos #include "observable.h" 36699b0f92Schristos #include "elf/common.h" 37699b0f92Schristos #include "linux-tdep.h" 38699b0f92Schristos #include "regset.h" 39699b0f92Schristos 40699b0f92Schristos /* Offsets (in target ints) into jmp_buf. */ 41699b0f92Schristos 42699b0f92Schristos #define M68K_LINUX_JB_ELEMENT_SIZE 4 43699b0f92Schristos #define M68K_LINUX_JB_PC 7 44699b0f92Schristos 45699b0f92Schristos /* Check whether insn1 and insn2 are parts of a signal trampoline. */ 46699b0f92Schristos 47699b0f92Schristos #define IS_SIGTRAMP(insn1, insn2) \ 48699b0f92Schristos (/* addaw #20,sp; moveq #119,d0; trap #0 */ \ 49699b0f92Schristos (insn1 == 0xdefc0014 && insn2 == 0x70774e40) \ 50699b0f92Schristos /* moveq #119,d0; trap #0 */ \ 51699b0f92Schristos || insn1 == 0x70774e40) 52699b0f92Schristos 53699b0f92Schristos #define IS_RT_SIGTRAMP(insn1, insn2) \ 54699b0f92Schristos (/* movel #173,d0; trap #0 */ \ 55699b0f92Schristos (insn1 == 0x203c0000 && insn2 == 0x00ad4e40) \ 56699b0f92Schristos /* moveq #82,d0; notb d0; trap #0 */ \ 57699b0f92Schristos || (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40)) 58699b0f92Schristos 59699b0f92Schristos /* Return non-zero if THIS_FRAME corresponds to a signal trampoline. For 60699b0f92Schristos the sake of m68k_linux_get_sigtramp_info we also distinguish between 61699b0f92Schristos non-RT and RT signal trampolines. */ 62699b0f92Schristos 63699b0f92Schristos static int 64*6881a400Schristos m68k_linux_pc_in_sigtramp (frame_info_ptr this_frame) 65699b0f92Schristos { 66699b0f92Schristos struct gdbarch *gdbarch = get_frame_arch (this_frame); 67699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 68699b0f92Schristos gdb_byte buf[12]; 69699b0f92Schristos unsigned long insn0, insn1, insn2; 70699b0f92Schristos CORE_ADDR pc = get_frame_pc (this_frame); 71699b0f92Schristos 72*6881a400Schristos if (!safe_frame_unwind_memory (this_frame, pc - 4, {buf, sizeof (buf)})) 73699b0f92Schristos return 0; 74699b0f92Schristos insn1 = extract_unsigned_integer (buf + 4, 4, byte_order); 75699b0f92Schristos insn2 = extract_unsigned_integer (buf + 8, 4, byte_order); 76699b0f92Schristos if (IS_SIGTRAMP (insn1, insn2)) 77699b0f92Schristos return 1; 78699b0f92Schristos if (IS_RT_SIGTRAMP (insn1, insn2)) 79699b0f92Schristos return 2; 80699b0f92Schristos 81699b0f92Schristos insn0 = extract_unsigned_integer (buf, 4, byte_order); 82699b0f92Schristos if (IS_SIGTRAMP (insn0, insn1)) 83699b0f92Schristos return 1; 84699b0f92Schristos if (IS_RT_SIGTRAMP (insn0, insn1)) 85699b0f92Schristos return 2; 86699b0f92Schristos 87699b0f92Schristos insn0 = ((insn0 << 16) & 0xffffffff) | (insn1 >> 16); 88699b0f92Schristos insn1 = ((insn1 << 16) & 0xffffffff) | (insn2 >> 16); 89699b0f92Schristos if (IS_SIGTRAMP (insn0, insn1)) 90699b0f92Schristos return 1; 91699b0f92Schristos if (IS_RT_SIGTRAMP (insn0, insn1)) 92699b0f92Schristos return 2; 93699b0f92Schristos 94699b0f92Schristos return 0; 95699b0f92Schristos } 96699b0f92Schristos 97699b0f92Schristos /* From <asm/sigcontext.h>. */ 98699b0f92Schristos static int m68k_linux_sigcontext_reg_offset[M68K_NUM_REGS] = 99699b0f92Schristos { 100699b0f92Schristos 2 * 4, /* %d0 */ 101699b0f92Schristos 3 * 4, /* %d1 */ 102699b0f92Schristos -1, /* %d2 */ 103699b0f92Schristos -1, /* %d3 */ 104699b0f92Schristos -1, /* %d4 */ 105699b0f92Schristos -1, /* %d5 */ 106699b0f92Schristos -1, /* %d6 */ 107699b0f92Schristos -1, /* %d7 */ 108699b0f92Schristos 4 * 4, /* %a0 */ 109699b0f92Schristos 5 * 4, /* %a1 */ 110699b0f92Schristos -1, /* %a2 */ 111699b0f92Schristos -1, /* %a3 */ 112699b0f92Schristos -1, /* %a4 */ 113699b0f92Schristos -1, /* %a5 */ 114699b0f92Schristos -1, /* %fp */ 115699b0f92Schristos 1 * 4, /* %sp */ 116699b0f92Schristos 6 * 4, /* %sr */ 117699b0f92Schristos 6 * 4 + 2, /* %pc */ 118699b0f92Schristos 8 * 4, /* %fp0 */ 119699b0f92Schristos 11 * 4, /* %fp1 */ 120699b0f92Schristos -1, /* %fp2 */ 121699b0f92Schristos -1, /* %fp3 */ 122699b0f92Schristos -1, /* %fp4 */ 123699b0f92Schristos -1, /* %fp5 */ 124699b0f92Schristos -1, /* %fp6 */ 125699b0f92Schristos -1, /* %fp7 */ 126699b0f92Schristos 14 * 4, /* %fpcr */ 127699b0f92Schristos 15 * 4, /* %fpsr */ 128699b0f92Schristos 16 * 4 /* %fpiaddr */ 129699b0f92Schristos }; 130699b0f92Schristos 131699b0f92Schristos static int m68k_uclinux_sigcontext_reg_offset[M68K_NUM_REGS] = 132699b0f92Schristos { 133699b0f92Schristos 2 * 4, /* %d0 */ 134699b0f92Schristos 3 * 4, /* %d1 */ 135699b0f92Schristos -1, /* %d2 */ 136699b0f92Schristos -1, /* %d3 */ 137699b0f92Schristos -1, /* %d4 */ 138699b0f92Schristos -1, /* %d5 */ 139699b0f92Schristos -1, /* %d6 */ 140699b0f92Schristos -1, /* %d7 */ 141699b0f92Schristos 4 * 4, /* %a0 */ 142699b0f92Schristos 5 * 4, /* %a1 */ 143699b0f92Schristos -1, /* %a2 */ 144699b0f92Schristos -1, /* %a3 */ 145699b0f92Schristos -1, /* %a4 */ 146699b0f92Schristos 6 * 4, /* %a5 */ 147699b0f92Schristos -1, /* %fp */ 148699b0f92Schristos 1 * 4, /* %sp */ 149699b0f92Schristos 7 * 4, /* %sr */ 150699b0f92Schristos 7 * 4 + 2, /* %pc */ 151699b0f92Schristos -1, /* %fp0 */ 152699b0f92Schristos -1, /* %fp1 */ 153699b0f92Schristos -1, /* %fp2 */ 154699b0f92Schristos -1, /* %fp3 */ 155699b0f92Schristos -1, /* %fp4 */ 156699b0f92Schristos -1, /* %fp5 */ 157699b0f92Schristos -1, /* %fp6 */ 158699b0f92Schristos -1, /* %fp7 */ 159699b0f92Schristos -1, /* %fpcr */ 160699b0f92Schristos -1, /* %fpsr */ 161699b0f92Schristos -1 /* %fpiaddr */ 162699b0f92Schristos }; 163699b0f92Schristos 164699b0f92Schristos /* From <asm/ucontext.h>. */ 165699b0f92Schristos static int m68k_linux_ucontext_reg_offset[M68K_NUM_REGS] = 166699b0f92Schristos { 167699b0f92Schristos 6 * 4, /* %d0 */ 168699b0f92Schristos 7 * 4, /* %d1 */ 169699b0f92Schristos 8 * 4, /* %d2 */ 170699b0f92Schristos 9 * 4, /* %d3 */ 171699b0f92Schristos 10 * 4, /* %d4 */ 172699b0f92Schristos 11 * 4, /* %d5 */ 173699b0f92Schristos 12 * 4, /* %d6 */ 174699b0f92Schristos 13 * 4, /* %d7 */ 175699b0f92Schristos 14 * 4, /* %a0 */ 176699b0f92Schristos 15 * 4, /* %a1 */ 177699b0f92Schristos 16 * 4, /* %a2 */ 178699b0f92Schristos 17 * 4, /* %a3 */ 179699b0f92Schristos 18 * 4, /* %a4 */ 180699b0f92Schristos 19 * 4, /* %a5 */ 181699b0f92Schristos 20 * 4, /* %fp */ 182699b0f92Schristos 21 * 4, /* %sp */ 183699b0f92Schristos 23 * 4, /* %sr */ 184699b0f92Schristos 22 * 4, /* %pc */ 185699b0f92Schristos 27 * 4, /* %fp0 */ 186699b0f92Schristos 30 * 4, /* %fp1 */ 187699b0f92Schristos 33 * 4, /* %fp2 */ 188699b0f92Schristos 36 * 4, /* %fp3 */ 189699b0f92Schristos 39 * 4, /* %fp4 */ 190699b0f92Schristos 42 * 4, /* %fp5 */ 191699b0f92Schristos 45 * 4, /* %fp6 */ 192699b0f92Schristos 48 * 4, /* %fp7 */ 193699b0f92Schristos 24 * 4, /* %fpcr */ 194699b0f92Schristos 25 * 4, /* %fpsr */ 195699b0f92Schristos 26 * 4 /* %fpiaddr */ 196699b0f92Schristos }; 197699b0f92Schristos 198699b0f92Schristos 199699b0f92Schristos /* Get info about saved registers in sigtramp. */ 200699b0f92Schristos 201699b0f92Schristos struct m68k_linux_sigtramp_info 202699b0f92Schristos { 203699b0f92Schristos /* Address of sigcontext. */ 204699b0f92Schristos CORE_ADDR sigcontext_addr; 205699b0f92Schristos 206699b0f92Schristos /* Offset of registers in `struct sigcontext'. */ 207699b0f92Schristos int *sc_reg_offset; 208699b0f92Schristos }; 209699b0f92Schristos 210699b0f92Schristos /* Nonzero if running on uClinux. */ 211699b0f92Schristos static int target_is_uclinux; 212699b0f92Schristos 213699b0f92Schristos static void 214*6881a400Schristos m68k_linux_inferior_created (inferior *inf) 215699b0f92Schristos { 216699b0f92Schristos /* Record that we will need to re-evaluate whether we are running on a 217699b0f92Schristos uClinux or normal GNU/Linux target (see m68k_linux_get_sigtramp_info). */ 218699b0f92Schristos target_is_uclinux = -1; 219699b0f92Schristos } 220699b0f92Schristos 221699b0f92Schristos static struct m68k_linux_sigtramp_info 222*6881a400Schristos m68k_linux_get_sigtramp_info (frame_info_ptr this_frame) 223699b0f92Schristos { 224699b0f92Schristos struct gdbarch *gdbarch = get_frame_arch (this_frame); 225699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 226699b0f92Schristos CORE_ADDR sp; 227699b0f92Schristos struct m68k_linux_sigtramp_info info; 228699b0f92Schristos 229699b0f92Schristos /* Determine whether we are running on a uClinux or normal GNU/Linux 230699b0f92Schristos target so we can use the correct sigcontext layouts. */ 231699b0f92Schristos if (target_is_uclinux == -1) 232699b0f92Schristos target_is_uclinux = linux_is_uclinux (); 233699b0f92Schristos 234699b0f92Schristos sp = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM); 235699b0f92Schristos 236699b0f92Schristos /* Get sigcontext address, it is the third parameter on the stack. */ 237699b0f92Schristos info.sigcontext_addr = read_memory_unsigned_integer (sp + 8, 4, byte_order); 238699b0f92Schristos 239699b0f92Schristos if (m68k_linux_pc_in_sigtramp (this_frame) == 2) 240699b0f92Schristos info.sc_reg_offset = m68k_linux_ucontext_reg_offset; 241699b0f92Schristos else 242699b0f92Schristos info.sc_reg_offset = (target_is_uclinux 243699b0f92Schristos ? m68k_uclinux_sigcontext_reg_offset 244699b0f92Schristos : m68k_linux_sigcontext_reg_offset); 245699b0f92Schristos return info; 246699b0f92Schristos } 247699b0f92Schristos 248699b0f92Schristos /* Signal trampolines. */ 249699b0f92Schristos 250699b0f92Schristos static struct trad_frame_cache * 251*6881a400Schristos m68k_linux_sigtramp_frame_cache (frame_info_ptr this_frame, 252699b0f92Schristos void **this_cache) 253699b0f92Schristos { 254699b0f92Schristos struct frame_id this_id; 255699b0f92Schristos struct trad_frame_cache *cache; 256699b0f92Schristos struct gdbarch *gdbarch = get_frame_arch (this_frame); 257699b0f92Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 258699b0f92Schristos struct m68k_linux_sigtramp_info info; 259699b0f92Schristos gdb_byte buf[4]; 260699b0f92Schristos int i; 261699b0f92Schristos 262699b0f92Schristos if (*this_cache) 263699b0f92Schristos return (struct trad_frame_cache *) *this_cache; 264699b0f92Schristos 265699b0f92Schristos cache = trad_frame_cache_zalloc (this_frame); 266699b0f92Schristos 267699b0f92Schristos /* FIXME: cagney/2004-05-01: This is is long standing broken code. 268699b0f92Schristos The frame ID's code address should be the start-address of the 269699b0f92Schristos signal trampoline and not the current PC within that 270699b0f92Schristos trampoline. */ 271699b0f92Schristos get_frame_register (this_frame, M68K_SP_REGNUM, buf); 272699b0f92Schristos /* See the end of m68k_push_dummy_call. */ 273699b0f92Schristos this_id = frame_id_build (extract_unsigned_integer (buf, 4, byte_order) 274699b0f92Schristos - 4 + 8, get_frame_pc (this_frame)); 275699b0f92Schristos trad_frame_set_id (cache, this_id); 276699b0f92Schristos 277699b0f92Schristos info = m68k_linux_get_sigtramp_info (this_frame); 278699b0f92Schristos 279699b0f92Schristos for (i = 0; i < M68K_NUM_REGS; i++) 280699b0f92Schristos if (info.sc_reg_offset[i] != -1) 281699b0f92Schristos trad_frame_set_reg_addr (cache, i, 282699b0f92Schristos info.sigcontext_addr + info.sc_reg_offset[i]); 283699b0f92Schristos 284699b0f92Schristos *this_cache = cache; 285699b0f92Schristos return cache; 286699b0f92Schristos } 287699b0f92Schristos 288699b0f92Schristos static void 289*6881a400Schristos m68k_linux_sigtramp_frame_this_id (frame_info_ptr this_frame, 290699b0f92Schristos void **this_cache, 291699b0f92Schristos struct frame_id *this_id) 292699b0f92Schristos { 293699b0f92Schristos struct trad_frame_cache *cache = 294699b0f92Schristos m68k_linux_sigtramp_frame_cache (this_frame, this_cache); 295699b0f92Schristos trad_frame_get_id (cache, this_id); 296699b0f92Schristos } 297699b0f92Schristos 298699b0f92Schristos static struct value * 299*6881a400Schristos m68k_linux_sigtramp_frame_prev_register (frame_info_ptr this_frame, 300699b0f92Schristos void **this_cache, 301699b0f92Schristos int regnum) 302699b0f92Schristos { 303699b0f92Schristos /* Make sure we've initialized the cache. */ 304699b0f92Schristos struct trad_frame_cache *cache = 305699b0f92Schristos m68k_linux_sigtramp_frame_cache (this_frame, this_cache); 306699b0f92Schristos return trad_frame_get_register (cache, this_frame, regnum); 307699b0f92Schristos } 308699b0f92Schristos 309699b0f92Schristos static int 310699b0f92Schristos m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, 311*6881a400Schristos frame_info_ptr this_frame, 312699b0f92Schristos void **this_prologue_cache) 313699b0f92Schristos { 314699b0f92Schristos return m68k_linux_pc_in_sigtramp (this_frame); 315699b0f92Schristos } 316699b0f92Schristos 317699b0f92Schristos static const struct frame_unwind m68k_linux_sigtramp_frame_unwind = 318699b0f92Schristos { 319*6881a400Schristos "m68k linux sigtramp", 320699b0f92Schristos SIGTRAMP_FRAME, 321699b0f92Schristos default_frame_unwind_stop_reason, 322699b0f92Schristos m68k_linux_sigtramp_frame_this_id, 323699b0f92Schristos m68k_linux_sigtramp_frame_prev_register, 324699b0f92Schristos NULL, 325699b0f92Schristos m68k_linux_sigtramp_frame_sniffer 326699b0f92Schristos }; 327699b0f92Schristos 328699b0f92Schristos /* Register maps for supply/collect regset functions. */ 329699b0f92Schristos 330699b0f92Schristos static const struct regcache_map_entry m68k_linux_gregmap[] = 331699b0f92Schristos { 332699b0f92Schristos { 7, M68K_D1_REGNUM, 4 }, /* d1 ... d7 */ 333699b0f92Schristos { 7, M68K_A0_REGNUM, 4 }, /* a0 ... a6 */ 334699b0f92Schristos { 1, M68K_D0_REGNUM, 4 }, 335699b0f92Schristos { 1, M68K_SP_REGNUM, 4 }, 336699b0f92Schristos { 1, REGCACHE_MAP_SKIP, 4 }, /* orig_d0 (skip) */ 337699b0f92Schristos { 1, M68K_PS_REGNUM, 4 }, 338699b0f92Schristos { 1, M68K_PC_REGNUM, 4 }, 339699b0f92Schristos /* Ignore 16-bit fields 'fmtvec' and '__fill'. */ 340699b0f92Schristos { 0 } 341699b0f92Schristos }; 342699b0f92Schristos 343699b0f92Schristos #define M68K_LINUX_GREGS_SIZE (20 * 4) 344699b0f92Schristos 345699b0f92Schristos static const struct regcache_map_entry m68k_linux_fpregmap[] = 346699b0f92Schristos { 347699b0f92Schristos { 8, M68K_FP0_REGNUM, 12 }, /* fp0 ... fp7 */ 348699b0f92Schristos { 1, M68K_FPC_REGNUM, 4 }, 349699b0f92Schristos { 1, M68K_FPS_REGNUM, 4 }, 350699b0f92Schristos { 1, M68K_FPI_REGNUM, 4 }, 351699b0f92Schristos { 0 } 352699b0f92Schristos }; 353699b0f92Schristos 354699b0f92Schristos #define M68K_LINUX_FPREGS_SIZE (27 * 4) 355699b0f92Schristos 356699b0f92Schristos /* Register sets. */ 357699b0f92Schristos 358699b0f92Schristos static const struct regset m68k_linux_gregset = 359699b0f92Schristos { 360699b0f92Schristos m68k_linux_gregmap, 361699b0f92Schristos regcache_supply_regset, regcache_collect_regset 362699b0f92Schristos }; 363699b0f92Schristos 364699b0f92Schristos static const struct regset m68k_linux_fpregset = 365699b0f92Schristos { 366699b0f92Schristos m68k_linux_fpregmap, 367699b0f92Schristos regcache_supply_regset, regcache_collect_regset 368699b0f92Schristos }; 369699b0f92Schristos 370699b0f92Schristos /* Iterate over core file register note sections. */ 371699b0f92Schristos 372699b0f92Schristos static void 373699b0f92Schristos m68k_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, 374699b0f92Schristos iterate_over_regset_sections_cb *cb, 375699b0f92Schristos void *cb_data, 376699b0f92Schristos const struct regcache *regcache) 377699b0f92Schristos { 3787f2ac410Schristos cb (".reg", M68K_LINUX_GREGS_SIZE, M68K_LINUX_GREGS_SIZE, &m68k_linux_gregset, 3797f2ac410Schristos NULL, cb_data); 3807f2ac410Schristos cb (".reg2", M68K_LINUX_FPREGS_SIZE, M68K_LINUX_FPREGS_SIZE, 3817f2ac410Schristos &m68k_linux_fpregset, NULL, cb_data); 382699b0f92Schristos } 383699b0f92Schristos 384699b0f92Schristos static void 385699b0f92Schristos m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 386699b0f92Schristos { 387*6881a400Schristos m68k_gdbarch_tdep *tdep = gdbarch_tdep<m68k_gdbarch_tdep> (gdbarch); 388699b0f92Schristos 389*6881a400Schristos linux_init_abi (info, gdbarch, 0); 390699b0f92Schristos 391699b0f92Schristos tdep->jb_pc = M68K_LINUX_JB_PC; 392699b0f92Schristos tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE; 393699b0f92Schristos 394699b0f92Schristos /* GNU/Linux uses a calling convention that's similar to SVR4. It 395699b0f92Schristos returns integer values in %d0/%d1, pointer values in %a0 and 396699b0f92Schristos floating values in %fp0, just like SVR4, but uses %a1 to pass the 397699b0f92Schristos address to store a structure value. It also returns small 398699b0f92Schristos structures in registers instead of memory. */ 399699b0f92Schristos m68k_svr4_init_abi (info, gdbarch); 400699b0f92Schristos tdep->struct_value_regnum = M68K_A1_REGNUM; 401699b0f92Schristos tdep->struct_return = reg_struct_return; 402699b0f92Schristos 403699b0f92Schristos set_gdbarch_decr_pc_after_break (gdbarch, 2); 404699b0f92Schristos 405699b0f92Schristos frame_unwind_append_unwinder (gdbarch, &m68k_linux_sigtramp_frame_unwind); 406699b0f92Schristos 407699b0f92Schristos /* Shared library handling. */ 408699b0f92Schristos 409699b0f92Schristos /* GNU/Linux uses SVR4-style shared libraries. */ 410699b0f92Schristos set_solib_svr4_fetch_link_map_offsets (gdbarch, 411*6881a400Schristos linux_ilp32_fetch_link_map_offsets); 412699b0f92Schristos 413699b0f92Schristos /* GNU/Linux uses the dynamic linker included in the GNU C Library. */ 414699b0f92Schristos set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); 415699b0f92Schristos 416699b0f92Schristos set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 417699b0f92Schristos 418699b0f92Schristos /* Core file support. */ 419699b0f92Schristos set_gdbarch_iterate_over_regset_sections 420699b0f92Schristos (gdbarch, m68k_linux_iterate_over_regset_sections); 421699b0f92Schristos 422699b0f92Schristos /* Enable TLS support. */ 423699b0f92Schristos set_gdbarch_fetch_tls_load_module_address (gdbarch, 424699b0f92Schristos svr4_fetch_objfile_link_map); 425699b0f92Schristos } 426699b0f92Schristos 4277d62b00eSchristos void _initialize_m68k_linux_tdep (); 428699b0f92Schristos void 4297d62b00eSchristos _initialize_m68k_linux_tdep () 430699b0f92Schristos { 431699b0f92Schristos gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_LINUX, 432699b0f92Schristos m68k_linux_init_abi); 433*6881a400Schristos gdb::observers::inferior_created.attach (m68k_linux_inferior_created, 434*6881a400Schristos "m68k-linux-tdep"); 435699b0f92Schristos } 436