From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20708 invoked by alias); 14 Nov 2008 23:14:34 -0000 Received: (qmail 20624 invoked by uid 22791); 14 Nov 2008 23:14:33 -0000 X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 14 Nov 2008 23:13:56 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id mAENDtBV023402 for ; Fri, 14 Nov 2008 18:13:55 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id mAENDsXr000603 for ; Fri, 14 Nov 2008 18:13:54 -0500 Received: from mesquite.lan (vpn-12-57.rdu.redhat.com [10.11.12.57]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id mAENDruJ015204 for ; Fri, 14 Nov 2008 18:13:54 -0500 Date: Sat, 15 Nov 2008 18:40:00 -0000 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: [RFC] FRV: Skip call to __main in main() Message-ID: <20081114161353.3495cc1e@mesquite.lan> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-11/txt/msg00380.txt.bz2 For frv-elf (and perhaps other frv targets too), GCC now emits a call to __main() in the prologue of main(). The patch below adds code to test for this call and to skip over it so that placing a breakpoint in main() will correctly cause the breakpoint to be placed on the first statement instead of in the prologue. I submitted a similar patch for PPC a while back and was asked to fix the hard-coded constants. However, the convention in frv-tdep.c seems to be to use hard-coded constants preceded by a comment block showing how the constant was derived. I chose to follow that convention in this patch. Comments? * frv-tdep.c (frv_skip_main_prologue): New function. (frv_gdbarch_init): Register frv_skip_main_prologue. Index: frv-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/frv-tdep.c,v retrieving revision 1.122 diff -u -p -r1.122 frv-tdep.c --- frv-tdep.c 11 Sep 2008 14:23:15 -0000 1.122 +++ frv-tdep.c 14 Nov 2008 22:40:25 -0000 @@ -999,6 +999,85 @@ frv_skip_prologue (struct gdbarch *gdbar } +/* Examine the instruction pointed to by PC. If it corresponds to + a call to __main, return the address of the next instruction. + Otherwise, return PC. */ + +static CORE_ADDR +frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_byte buf[4]; + unsigned long op; + CORE_ADDR orig_pc = pc; + + if (target_read_memory (pc, buf, 4)) + return pc; + op = extract_unsigned_integer (buf, 4); + + /* In PIC code, GR15 may be loaded from some offset off of FP prior + to the call instruction. + + Skip over this instruction if present. It won't be present in + non-PIC code, and even in PIC code, it might not be present. + (This is due to the fact that GR15, the FDPIC register, already + contains the correct value.) + + The general form of the LDI is given first, followed by the + specific instruction with the GRi and GRk filled in as FP and + GR15. + + ldi @(GRi, d12), GRk + P KKKKKK 0110010 IIIIII SSSSSSSSSSSS = 0x00c80000 + 0 000000 1111111 000000 000000000000 = 0x01fc0000 + . . . . . . . . + ldi @(FP, d12), GR15 + P KKKKKK 0110010 IIIIII SSSSSSSSSSSS = 0x1ec82000 + 0 001111 1111111 000010 000000000000 = 0x7ffff000 + . . . . . . . . */ + + if ((op & 0x7ffff000) == 0x1ec82000) + { + pc += 4; + if (target_read_memory (pc, buf, 4)) + return orig_pc; + op = extract_unsigned_integer (buf, 4); + } + + /* The format of an FRV CALL instruction is as follows: + + call label24 + P HHHHHH 0001111 LLLLLLLLLLLLLLLLLL = 0x003c0000 + 0 000000 1111111 000000000000000000 = 0x01fc0000 + . . . . . . . . + + where label24 is constructed by concatenating the H bits with the + L bits. The call target is PC + (4 * sign_ext(label24)). */ + + if ((op & 0x01fc0000) == 0x003c0000) + { + LONGEST displ; + CORE_ADDR call_dest; + struct minimal_symbol *s; + + displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff); + if ((displ & 0x00800000) != 0) + displ |= ~((LONGEST) 0x00ffffff); + + call_dest = pc + 4 * displ; + s = lookup_minimal_symbol_by_pc (call_dest); + + if (s != NULL + && SYMBOL_LINKAGE_NAME (s) != NULL + && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) + { + pc += 4; + return pc; + } + } + return orig_pc; +} + + static struct frv_unwind_cache * frv_frame_unwind_cache (struct frame_info *this_frame, void **this_prologue_cache) @@ -1501,6 +1580,7 @@ frv_gdbarch_init (struct gdbarch_info in set_gdbarch_pseudo_register_write (gdbarch, frv_pseudo_register_write); set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue); + set_gdbarch_skip_main_prologue (gdbarch, frv_skip_main_prologue); set_gdbarch_breakpoint_from_pc (gdbarch, frv_breakpoint_from_pc); set_gdbarch_adjust_breakpoint_address (gdbarch, frv_adjust_breakpoint_address);