From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1417 invoked by alias); 29 Jan 2008 05:26:20 -0000 Received: (qmail 1407 invoked by uid 22791); 29 Jan 2008 05:26:19 -0000 X-Spam-Check-By: sourceware.org Received: from ug-out-1314.google.com (HELO ug-out-1314.google.com) (66.249.92.168) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 29 Jan 2008 05:25:54 +0000 Received: by ug-out-1314.google.com with SMTP id h2so327271ugf.12 for ; Mon, 28 Jan 2008 21:25:51 -0800 (PST) Received: by 10.66.254.19 with SMTP id b19mr1030863ugi.7.1201584351377; Mon, 28 Jan 2008 21:25:51 -0800 (PST) Received: from ?192.168.0.101? ( [85.240.245.95]) by mx.google.com with ESMTPS id g9sm8401529gvc.4.2008.01.28.21.25.49 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 28 Jan 2008 21:25:49 -0800 (PST) Message-ID: <479EB897.5030603@portugalmail.pt> Date: Tue, 29 Jan 2008 05:35:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.8.1.9) Gecko/20071031 Thunderbird/2.0.0.9 Mnenhy/0.7.5.0 MIME-Version: 1.0 To: Pierre Muller , gdb-patches Subject: skip __main Content-Type: multipart/mixed; boundary="------------040709070309050606020609" 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-01/txt/msg00666.txt.bz2 This is a multi-part message in MIME format. --------------040709070309050606020609 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1033 Hi all, Pierre, Here's the much smaller patch I mentioned at gdb@. This version is about as small as it can get. First the prologue is analysed and skipped, then line info is used to get at the first line of user code in the function. If the function is called "main" (humm, I shall move that into the callback, as I believe the place where __main/__gccmain is emitted is configurable on the gcc side), call a gdbarch method that skips the __main call. Works OK as long as nothing is scheduled into before the __main call. That means that it should work OK at -O0, which is enough for fixing the runto_main problems in the testsuite. Then again, debugging code with .stabs debug info at anything but -O0 is not pleasant anyway. Last time I looked at the results, it uncovered other more serious problems, so it was a win just for that fact. I'm starting an overnight testrun on Cygwin, as the last time I did that was a couple of months back. Any comments? Suggestions for a better gdbarch callback name? -- Pedro Alves --------------040709070309050606020609 Content-Type: text/x-diff; name="skip_main.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="skip_main.diff" Content-length: 8790 2007-10-13 Pedro Alves * gdbarch.sh (gdbarch_skip___main_call): New. * gdbarch.h, gdbarch.c: Regenerate. * i386-tdep.h (i386_skip___main_call): Declare. * i386-tdep.c (i386_skip___main_call): New. * i386-cygwin-tdep.c (i386_cygwin_init_abi): Register i386_skip___main_call as gdbarch_skip___main_call gdbarch callback. * symtab.c (find_function_start_sal): When pc points at the "main" function, call gdbarch_skip___main_call. --- gdb/gdbarch.c | 33 +++++++++++++++++++++++++++++++++ gdb/gdbarch.h | 6 ++++++ gdb/gdbarch.sh | 1 + gdb/i386-cygwin-tdep.c | 2 ++ gdb/i386-tdep.c | 27 +++++++++++++++++++++++++++ gdb/i386-tdep.h | 1 + gdb/symtab.c | 15 +++++++++++++++ 7 files changed, 85 insertions(+) Index: src/gdb/i386-tdep.c =================================================================== --- src.orig/gdb/i386-tdep.c 2008-01-29 04:39:24.000000000 +0000 +++ src/gdb/i386-tdep.c 2008-01-29 04:39:40.000000000 +0000 @@ -949,6 +949,33 @@ i386_skip_prologue (struct gdbarch *gdba return pc; } +/* Check that the code pointed to by PC corresponds to a call to + __main, skip it if so. Return PC otherwise. */ + +CORE_ADDR +i386_skip___main_call (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_byte op; + + read_memory_nobpt (pc, &op, 1); + if (op == 0xe8) + { + gdb_byte buf[4]; + if (target_read_memory (pc + 1, buf, sizeof buf) == 0) + { + CORE_ADDR call_dest = pc + 5 + extract_unsigned_integer (buf, 4); + + struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest); + if (s != NULL + && SYMBOL_LINKAGE_NAME (s) != NULL + && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) + pc += 5; + } + } + + return pc; +} + /* This function is 64-bit safe. */ static CORE_ADDR Index: src/gdb/gdbarch.c =================================================================== --- src.orig/gdb/gdbarch.c 2008-01-29 04:39:16.000000000 +0000 +++ src/gdb/gdbarch.c 2008-01-29 04:39:40.000000000 +0000 @@ -184,6 +184,7 @@ struct gdbarch gdbarch_integer_to_address_ftype *integer_to_address; gdbarch_return_value_ftype *return_value; gdbarch_skip_prologue_ftype *skip_prologue; + gdbarch_skip___main_call_ftype *skip___main_call; gdbarch_inner_than_ftype *inner_than; gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc; gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address; @@ -306,6 +307,7 @@ struct gdbarch startup_gdbarch = 0, /* integer_to_address */ 0, /* return_value */ 0, /* skip_prologue */ + 0, /* skip___main_call */ 0, /* inner_than */ 0, /* breakpoint_from_pc */ 0, /* adjust_breakpoint_address */ @@ -542,6 +544,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of return_value, has predicate */ if (gdbarch->skip_prologue == 0) fprintf_unfiltered (log, "\n\tskip_prologue"); + /* Skip verify of skip___main_call, has predicate */ if (gdbarch->inner_than == 0) fprintf_unfiltered (log, "\n\tinner_than"); if (gdbarch->breakpoint_from_pc == 0) @@ -934,6 +937,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s "gdbarch_dump: single_step_through_delay = <0x%lx>\n", (long) gdbarch->single_step_through_delay); fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_skip___main_call_p() = %d\n", + gdbarch_skip___main_call_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: skip___main_call = <0x%lx>\n", + (long) gdbarch->skip___main_call); + fprintf_unfiltered (file, "gdbarch_dump: gdbarch_skip_permanent_breakpoint_p() = %d\n", gdbarch_skip_permanent_breakpoint_p (gdbarch)); fprintf_unfiltered (file, @@ -2075,6 +2084,30 @@ set_gdbarch_skip_prologue (struct gdbarc } int +gdbarch_skip___main_call_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->skip___main_call != NULL; +} + +CORE_ADDR +gdbarch_skip___main_call (struct gdbarch *gdbarch, CORE_ADDR ip) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->skip___main_call != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_skip___main_call called\n"); + return gdbarch->skip___main_call (gdbarch, ip); +} + +void +set_gdbarch_skip___main_call (struct gdbarch *gdbarch, + gdbarch_skip___main_call_ftype skip___main_call) +{ + gdbarch->skip___main_call = skip___main_call; +} + +int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs) { gdb_assert (gdbarch != NULL); Index: src/gdb/gdbarch.h =================================================================== --- src.orig/gdb/gdbarch.h 2008-01-29 04:39:16.000000000 +0000 +++ src/gdb/gdbarch.h 2008-01-29 04:39:40.000000000 +0000 @@ -374,6 +374,12 @@ typedef CORE_ADDR (gdbarch_skip_prologue extern CORE_ADDR gdbarch_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip); extern void set_gdbarch_skip_prologue (struct gdbarch *gdbarch, gdbarch_skip_prologue_ftype *skip_prologue); +extern int gdbarch_skip___main_call_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_skip___main_call_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip); +extern CORE_ADDR gdbarch_skip___main_call (struct gdbarch *gdbarch, CORE_ADDR ip); +extern void set_gdbarch_skip___main_call (struct gdbarch *gdbarch, gdbarch_skip___main_call_ftype *skip___main_call); + typedef int (gdbarch_inner_than_ftype) (CORE_ADDR lhs, CORE_ADDR rhs); extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs); extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than); Index: src/gdb/gdbarch.sh =================================================================== --- src.orig/gdb/gdbarch.sh 2008-01-29 04:39:16.000000000 +0000 +++ src/gdb/gdbarch.sh 2008-01-29 04:39:40.000000000 +0000 @@ -477,6 +477,7 @@ M:CORE_ADDR:integer_to_address:struct ty M:enum return_value_convention:return_value:struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf:valtype, regcache, readbuf, writebuf m:CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 +M:CORE_ADDR:skip___main_call:CORE_ADDR ip:ip f:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0 m:const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0: M:CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr Index: src/gdb/i386-cygwin-tdep.c =================================================================== --- src.orig/gdb/i386-cygwin-tdep.c 2008-01-29 04:39:18.000000000 +0000 +++ src/gdb/i386-cygwin-tdep.c 2008-01-29 04:39:40.000000000 +0000 @@ -227,6 +227,8 @@ i386_cygwin_init_abi (struct gdbarch_inf set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code); + set_gdbarch_skip___main_call (gdbarch, i386_skip___main_call); + tdep->struct_return = reg_struct_return; tdep->gregset_reg_offset = i386_win32_gregset_reg_offset; Index: src/gdb/i386-tdep.h =================================================================== --- src.orig/gdb/i386-tdep.h 2008-01-29 04:39:18.000000000 +0000 +++ src/gdb/i386-tdep.h 2008-01-29 04:39:40.000000000 +0000 @@ -166,6 +166,7 @@ extern struct type *i386_sse_type (struc /* Functions exported from i386-tdep.c. */ extern CORE_ADDR i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name); +extern CORE_ADDR i386_skip___main_call (struct gdbarch *gdbarch, CORE_ADDR pc); /* Return the name of register REGNUM. */ extern char const *i386_register_name (struct gdbarch * gdbarch, int regnum); Index: src/gdb/symtab.c =================================================================== --- src.orig/gdb/symtab.c 2008-01-29 04:39:16.000000000 +0000 +++ src/gdb/symtab.c 2008-01-29 04:39:40.000000000 +0000 @@ -2506,6 +2506,21 @@ find_function_start_sal (struct symbol * /* Recalculate the line number (might not be N+1). */ sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); } + + /* On targets with executable formats that don't have a concept of + constructors (ELF with .init has, PE doesn't), gcc emits a call + to `__main' in `main' between the prologue and before user + code. */ + if (funfirstline + && gdbarch_skip___main_call_p (current_gdbarch) + && SYMBOL_LINKAGE_NAME (sym) + && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0) + { + pc = gdbarch_skip___main_call (current_gdbarch, pc); + /* Recalculate the line number (might not be N+1). */ + sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); + } + sal.pc = pc; return sal; --------------040709070309050606020609--