mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-03-03 06:58:15 +00:00

This change addresses a regression in gdb.dwarf2/dw2-skip-prologue.exp across MIPS16 multilibs: (gdb) file .../gdb.dwarf2/dw2-skip-prologue Reading symbols from .../gdb.d/gdb.dwarf2/dw2-skip-prologue...done. (gdb) delete breakpoints (gdb) info breakpoints No breakpoints or watchpoints. (gdb) break main warning: Breakpoint address adjusted from 0x00400725 to 0x00400721. Breakpoint 1 at 0x400721 (gdb) set remotetimeout 5 (gdb) kill The program is not being run. (gdb) [...] target remote ...:2345 Reading symbols from .../mips16/lib/ld.so.1...done. warning: Breakpoint address adjusted from 0x00400725 to 0x00400721. warning: Breakpoint address adjusted from 0x00400725 to 0x00400721. 0x2aaa8e81 in __start () from .../mips16/lib/ld.so.1 (gdb) continue Continuing. warning: Breakpoint address adjusted from 0x00400725 to 0x00400721. warning: Breakpoint 1 address previously adjusted from 0x00400725 to 0x00400721. Breakpoint 1, 0x00400721 in main () (gdb) break func Breakpoint 2 at 0x4006a1: func. (2 locations) (gdb) continue Continuing. warning: GDB can't find the start of the function at 0x4006dd. GDB is unable to find the start of the function at 0x4006dd and thus can't determine the size of that function's stack frame. This means that GDB may be unable to access that stack frame, or the frames below it. This problem is most likely caused by an invalid program counter or stack pointer. However, if you think GDB should simply search farther back from 0x4006dd for code which looks like the beginning of a function, you can increase the range of the search using the `set heuristic-fence-post' command. Program received signal SIGBUS, Bus error. 0x0040072b in main () (gdb) FAIL: gdb.dwarf2/dw2-skip-prologue.exp: continue to breakpoint: func -- notice the breakpoint adjustment messages that are already a bad sign. These happen when a breakpoint is requested in a branch delay slot and are not supposed to happen unless explicitly requested with an address pointing to a branch delay slot instruction. No symbol or line debug information is supposed to direct GDB to place a breakpoint in a delay slot. Here's how `main' looks like: 00400718 <main>: 400718: 64f5 save 40,ra,s0-s1 40071a: 1a00 01a8 jal 4006a0 <func> 40071e: 0104 addiu s1,sp,16 400720: 1a00 01b7 jal 4006dc <func+0x3c> 400724: 6702 move s0,v0 400726: e049 addu v0,s0,v0 400728: 65b9 move sp,s1 40072a: 6473 restore 24,ra,s0-s1 40072c: e8a0 jrc ra 40072e: 6500 nop -- so 0x400725 is the MIPS16 instruction address of the first MOVE instruction seen above, in a delay slot of the preceding JAL instruction indeed. This test case arranges for `main' to have no debug information so it is one of the heuristic prologue scanners, `mips16_scan_prologue' specifically in this case, that is responsible for finding the right location for the breakpoint to place. In this case the prologue really ends with the ADDIU instruction, reordered into the delay slot of the first JAL instruction. Of course we can't place the breakpoint for `main' after it as by doing so we'll let `func' to be called before hitting this breakpoint. So the breakpoint has to go at the JAL instruction instead, or 0x40071b. To make a general case out of it we must never consider any jump or branch instruction to be a part of a function's prologue. In the presence of a jump or branch at the beginning of a function the furthest instruction examined for the purpose of constructing frame information can be one in the delay slot of that jump or branch if present, and otherwise -- that is when the jump or branch is compact and has no delay slot -- the instruction immediately preceding the jump or branch. This change implements that approach across prologue scanners for the three instruction ISAs. In implementing it I have factored out code from the existing `*_instruction_has_delay_slot' handlers to be shared and a side effect for the microMIPS implementation is it now always fetches the second 16-bit halfword of 32-bit instructions even if it eventually is not going to be needed. I think it's an acceptable tradeoff for the purpose of code sharing. To make things more consistent I also carried logic from `micromips_scan_prologue' over to the other two scanners to accept (and ignore) a single non-prologue non-control transfer instruction reordered by the compiler into the prologue. While doing this I simplified the exit path from the scan loop such that `end_prologue_addr' is set only once. This made some concerns expressed in comments no longer applicable, although even before they were not valid. I have not fixed the logic around `load_immediate_bytes' in `mips32_scan_prologue' though, it remains broken, although I took care not to break it more. An approach similar to one taken for handling larger stack adjustments in `micromips_scan_prologue' will have to be eventually implemented here. For regression testing I used my usual choice of the mips-linux-gnu target and the following multilibs: -EB -EB -msoft-float -EB -mips16 -EB -mips16 -msoft-float -EB -mmicromips -EB -mmicromips -msoft-float -EB -mabi=n32 -EB -mabi=n32 -msoft-float -EB -mabi=64 -EB -mabi=64 -msoft-float and the -EL variants of same. That removed gdb.dwarf2/dw2-skip-prologue.exp failures across MIPS16 multilibs, the test log now shows: (gdb) file .../gdb.dwarf2/dw2-skip-prologue Reading symbols from .../gdb.d/gdb.dwarf2/dw2-skip-prologue...done. (gdb) delete breakpoints (gdb) info breakpoints No breakpoints or watchpoints. (gdb) break main Breakpoint 1 at 0x40071b (gdb) set remotetimeout 5 (gdb) kill The program is not being run. (gdb) [...] target remote ...:2345 Reading symbols from .../mips16/lib/ld.so.1...done. 0x2aaa8e81 in __start () from .../mips16/lib/ld.so.1 (gdb) continue Continuing. Breakpoint 1, 0x0040071b in main () (gdb) break func Breakpoint 2 at 0x4006a1: func. (2 locations) (gdb) continue Continuing. Breakpoint 2, func (param=0) at main.c:5 5 This program is free software; you can redistribute it and/or modify (gdb) PASS: gdb.dwarf2/dw2-skip-prologue.exp: continue to breakpoint: func -- so things look like intended. That also did regress, again across MIPS16 multilibs, another test case, gdb.base/step-symless.exp: (gdb) file .../gdb.d/gdb.base/step-symless Reading symbols from .../gdb.base/step-symless...done. (gdb) delete breakpoints (gdb) info breakpoints No breakpoints or watchpoints. (gdb) break main Breakpoint 1 at 0x4006d3 (gdb) set remotetimeout 5 (gdb) kill The program is not being run. (gdb) [...] target remote ...:2345 Reading symbols from .../mips16/lib/ld.so.1...done. 0x2aaa8e81 in __start () from .../mips16/lib/ld.so.1 (gdb) continue Continuing. Breakpoint 1, 0x004006d3 in main () (gdb) break symful Breakpoint 2 at 0x4006a5 (gdb) step Single stepping until exit from function main, which has no line number information. warning: GDB can't find the start of the function at 0x4006b9. GDB is unable to find the start of the function at 0x4006b9 and thus can't determine the size of that function's stack frame. This means that GDB may be unable to access that stack frame, or the frames below it. This problem is most likely caused by an invalid program counter or stack pointer. However, if you think GDB should simply search farther back from 0x4006b9 for code which looks like the beginning of a function, you can increase the range of the search using the `set heuristic-fence-post' command. 0x004006b9 in ?? () (gdb) FAIL: gdb.base/step-symless.exp: step -- but that is actually a good sign. Here `main', again, has no debug information and code involved looks like: 004006a0 <symful>: 4006a0: 6491 save 8,s1 4006a2: 673d move s1,sp 4006a4: b204 lw v0,4006b4 <symful+0x14> 4006a6: 9a40 lw v0,0(v0) 4006a8: 4261 addiu v1,v0,1 4006aa: b203 lw v0,4006b4 <symful+0x14> 4006ac: da60 sw v1,0(v0) 4006ae: 65b9 move sp,s1 4006b0: 6411 restore 8,s1 4006b2: e8a0 jrc ra 4006b4: 0041 addiu s0,sp,260 4006b6: 0860 la s0,400834 <__libc_start_main@mips16plt+0x54> 4006b8: 6491 save 8,s1 4006ba: 673d move s1,sp 4006bc: b204 lw v0,4006cc <symful+0x2c> 4006be: 9a40 lw v0,0(v0) 4006c0: 4261 addiu v1,v0,1 4006c2: b203 lw v0,4006cc <symful+0x2c> 4006c4: da60 sw v1,0(v0) 4006c6: 65b9 move sp,s1 4006c8: 6411 restore 8,s1 4006ca: e8a0 jrc ra 4006cc: 0041 addiu s0,sp,260 4006ce: 0860 la s0,40084c <__libc_start_main@mips16plt+0x6c> 004006d0 <main>: 4006d0: 64d4 save 32,ra,s1 4006d2: 1a00 01ae jal 4006b8 <symful+0x18> 4006d6: 0104 addiu s1,sp,16 4006d8: 1a00 01a8 jal 4006a0 <symful> 4006dc: 6500 nop 4006de: 6740 move v0,zero 4006e0: 65b9 move sp,s1 4006e2: 6452 restore 16,ra,s1 4006e4: e8a0 jrc ra 4006e6: 6500 nop 4006e8: 6500 nop 4006ea: 6500 nop 4006ec: 6500 nop 4006ee: 6500 nop -- and the original log: (gdb) file .../gdb.base/step-symless Reading symbols from .../gdb.base/step-symless...done. (gdb) delete breakpoints (gdb) info breakpoints No breakpoints or watchpoints. (gdb) break main warning: Breakpoint address adjusted from 0x004006dd to 0x004006d9. Breakpoint 1 at 0x4006d9 (gdb) set remotetimeout 5 (gdb) kill The program is not being run. (gdb) [...] target remote ...:2345 Reading symbols from .../mips16/lib/ld.so.1...done. warning: Breakpoint address adjusted from 0x004006dd to 0x004006d9. warning: Breakpoint address adjusted from 0x004006dd to 0x004006d9. 0x2aaa8e81 in __start () from .../mips16/lib/ld.so.1 (gdb) continue Continuing. warning: Breakpoint address adjusted from 0x004006dd to 0x004006d9. warning: Breakpoint 1 address previously adjusted from 0x004006dd to 0x004006d9. Breakpoint 1, 0x004006d9 in main () (gdb) break symful Breakpoint 2 at 0x4006a5 (gdb) step Single stepping until exit from function main, which has no line number information. Breakpoint 2, 0x004006a5 in symful () (gdb) PASS: gdb.base/step-symless.exp: step So the breakpoint at `main' was actually set at an instruction after the call to `symful+0x18' aka `symless' and the test only passed because single-stepping through `symless' wasn't actually done at all. With this change in place this test fails for MIPS16 multilibs consistently with all the other multilibs where it already failed in this manner previously. * mips-tdep.c (mips16_instruction_is_compact_branch): New function. (micromips_instruction_is_compact_branch): Likewise. (mips16_scan_prologue): Terminate scanning upon seeing a branch or a compact jump, reaching a jump delay slot, or seeing a second non-prologue instruction. (micromips_scan_prologue): Also terminate scanning upon seeing a compact branch or jump, or reaching a branch or jump delay slot. (mips32_scan_prologue): Terminate scanning upon reaching a branch or jump delay slot, or seeing a second non-prologue instruction. (mips32_instruction_has_delay_slot): Retain instruction examination code only, update arguments accordingly and move instruction fetch pieces to... (mips32_insn_at_pc_has_delay_slot): ... this new function. (micromips_instruction_has_delay_slot): Likewise and to... (micromips_insn_at_pc_has_delay_slot): ... this new function. (mips16_instruction_has_delay_slot): Likewise and to... (mips16_insn_at_pc_has_delay_slot): ... this new function. (mips_single_step_through_delay): Update accordingly. (mips_adjust_breakpoint_address): Likewise.
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.
Description
Languages
C
58.3%
Makefile
18.5%
Assembly
13.3%
C++
3.6%
Scheme
1.2%
Other
4.7%