From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27794 invoked by alias); 24 Jul 2007 17:35:35 -0000 Received: (qmail 27783 invoked by uid 22791); 24 Jul 2007 17:35:34 -0000 X-Spam-Check-By: sourceware.org Received: from dmz.mips-uk.com (HELO dmz.mips-uk.com) (194.74.144.194) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 24 Jul 2007 17:35:32 +0000 Received: from internal-mx1 ([192.168.192.240] helo=ukservices1.mips.com) by dmz.mips-uk.com with esmtp (Exim 3.35 #1 (Debian)) id 1IDOID-0005Cj-00; Tue, 24 Jul 2007 18:35:29 +0100 Received: from perivale.mips.com ([192.168.192.200]) by ukservices1.mips.com with esmtp (Exim 3.36 #1 (Debian)) id 1IDOHF-0006nc-00; Tue, 24 Jul 2007 18:34:29 +0100 Received: from macro (helo=localhost) by perivale.mips.com with local-esmtp (Exim 4.63) (envelope-from ) id 1IDOHF-0003Nu-Ec; Tue, 24 Jul 2007 18:34:29 +0100 Date: Tue, 24 Jul 2007 20:13:00 -0000 From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Nigel Stephens , Chris Dearman , "Maciej W. Rozycki" Subject: Use the address mask with addresses for SREC, etc. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-MIPS-Technologies-UK-MailScanner: Found to be clean X-MIPS-Technologies-UK-MailScanner-From: macro@mips.com 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: 2007-07/txt/msg00256.txt.bz2 Hello, Some binary formats, such as SREC, only support 32-bit addresses and do not sign-extend them properly for targets that require it. This causes a problem with the MIPS target when KSEG addresses are used as they have bit 31 set which should be propagated through the high 32 bits to suit 64-bit BFD. It is seen with the gdb.base/dump.exp set of tests. Here is a change that fixes the problem. It has been successfully tested for mipsisa32-sde-elf, with the mips-sim-sde32/-EB, mips-sim-sde32/-mips16/-EB, mips-sim-sde32/-EL and mips-sim-sde32/-mips16/-EL target boards, removing all the 15 failures like below seen there: (gdb) file intarr1.srec Load new symbol table from ".../gdb/testsuite.mips-sim-sde32.-EL/intarr1.srec"? (y or n) y Reading symbols from .../gdb/testsuite.mips-sim-sde32.-EL/intarr1.srec...done. (gdb) print intarray Cannot access memory at address 0x800220a8 (gdb) PASS: gdb.base/dump.exp: reload array as value, srec; capture intarray FAIL: gdb.base/dump.exp: reload array as value, srec; value restored ok 2007-07-24 Nigel Stephens Chris Dearman Maciej W. Rozycki * cli/cli-dump.c (restore_section_callback): Use the address mask when comparing addresses. * exec.c (xfer_memory): Likewise. OK to apply? Maciej 12100-3.diff Index: binutils-quilt/src/gdb/exec.c =================================================================== --- binutils-quilt.orig/src/gdb/exec.c 2007-07-23 18:59:51.000000000 +0100 +++ binutils-quilt/src/gdb/exec.c 2007-07-23 19:00:23.000000000 +0100 @@ -463,6 +463,8 @@ struct section_table *p; CORE_ADDR nextsectaddr, memend; asection *section = NULL; + int addr_bit = gdbarch_addr_bit (current_gdbarch); + CORE_ADDR addr_mask; if (len <= 0) internal_error (__FILE__, __LINE__, _("failed internal consistency check")); @@ -474,30 +476,46 @@ memaddr = overlay_mapped_address (memaddr, section); } + /* Only match address bits which are significant + for the current architecture. */ + if (addr_bit < sizeof (CORE_ADDR) * HOST_CHAR_BIT) + { + addr_mask = ((CORE_ADDR)1 << addr_bit) - 1; + memaddr &= addr_mask; + } + else + addr_mask = ~(CORE_ADDR)0; + memend = memaddr + len; nextsectaddr = memend; for (p = target->to_sections; p < target->to_sections_end; p++) { + CORE_ADDR p_addr; + if (overlay_debugging && section && p->the_bfd_section && strcmp (section->name, p->the_bfd_section->name) != 0) continue; /* not the section we need */ - if (memaddr >= p->addr) + + p_addr = p->addr & addr_mask; + if (memaddr >= p_addr) { - if (memend <= p->endaddr) + CORE_ADDR p_endaddr = p->endaddr & addr_mask; + + if (memend <= p_endaddr) { /* Entire transfer is within this section. */ if (write) res = bfd_set_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + myaddr, memaddr - p_addr, len); else res = bfd_get_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + myaddr, memaddr - p_addr, len); return (res != 0) ? len : 0; } - else if (memaddr >= p->endaddr) + else if (memaddr >= p_endaddr) { /* This section ends before the transfer starts. */ continue; @@ -505,20 +523,20 @@ else { /* This section overlaps the transfer. Just do half. */ - len = p->endaddr - memaddr; + len = p_endaddr - memaddr; if (write) res = bfd_set_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + myaddr, memaddr - p_addr, len); else res = bfd_get_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + myaddr, memaddr - p_addr, len); return (res != 0) ? len : 0; } } else - nextsectaddr = min (nextsectaddr, p->addr); + nextsectaddr = min (nextsectaddr, p_addr); } if (nextsectaddr >= memend) Index: binutils-quilt/src/gdb/cli/cli-dump.c =================================================================== --- binutils-quilt.orig/src/gdb/cli/cli-dump.c 2007-07-23 18:59:51.000000000 +0100 +++ binutils-quilt/src/gdb/cli/cli-dump.c 2007-07-23 19:00:34.000000000 +0100 @@ -462,6 +462,8 @@ bfd_vma sec_end = sec_start + size; bfd_size_type sec_offset = 0; bfd_size_type sec_load_count = size; + int addr_bit = gdbarch_addr_bit (current_gdbarch); + CORE_ADDR addr_mask; struct cleanup *old_chain; gdb_byte *buf; int ret; @@ -470,9 +472,17 @@ if (!(bfd_get_section_flags (ibfd, isec) & SEC_LOAD)) return; - /* Does the section overlap with the desired restore range? */ - if (sec_end <= data->load_start - || (data->load_end > 0 && sec_start >= data->load_end)) + /* Only match address bits which are significant + for the current architecture. */ + if (addr_bit < sizeof (CORE_ADDR) * HOST_CHAR_BIT) + addr_mask = ((CORE_ADDR) 1 << addr_bit) - 1; + else + addr_mask = ~(CORE_ADDR) 0; + + /* Does the section overlap with the desired restore range? */ + if (sec_end <= (data->load_start & addr_mask) + || ((data->load_end & addr_mask) > 0 + && sec_start >= (data->load_end & addr_mask))) { /* No, no useable data in this section. */ printf_filtered (_("skipping section %s...\n"), @@ -483,11 +493,11 @@ /* Compare section address range with user-requested address range (if any). Compute where the actual transfer should start and end. */ - if (sec_start < data->load_start) + if (sec_start < (data->load_start & addr_mask)) sec_offset = data->load_start - sec_start; /* Size of a partial transfer: */ sec_load_count -= sec_offset; - if (data->load_end > 0 && sec_end > data->load_end) + if (data->load_end > 0 && sec_end > (data->load_end & addr_mask)) sec_load_count -= sec_end - data->load_end; /* Get the data. */