From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3082 invoked by alias); 11 Jun 2003 07:45:37 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 3051 invoked from network); 11 Jun 2003 07:45:37 -0000 Received: from unknown (HELO zenia.home) (12.223.225.216) by sources.redhat.com with SMTP; 11 Jun 2003 07:45:37 -0000 Received: by zenia.home (Postfix, from userid 5433) id D1BB920FE6; Wed, 11 Jun 2003 02:46:48 -0500 (EST) To: "Theodore A. Roth" Cc: gdb@sources.redhat.com Subject: Function addresses on the AVR From: Jim Blandy Date: Wed, 11 Jun 2003 07:45:00 -0000 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-06/txt/msg00178.txt.bz2 Hey there. I've been looking at uses of CONVERT_FROM_FUNC_PTR_ADDR with an eye towards fixing up some related stuff, and I noticed two things about avr-tdep.c: - It provides a function for CONVERT_FROM_FUNC_PTR_ADDR that multiplies the address by two, and - There's a comment saying: ... The problem manifests itself when trying to set a breakpoint in a function which resides in the upper half of the instruction space and thus requires a 17-bit address. ... Both of these things caught my eye, and made me wonder if there weren't a way to help the AVR port work better, and incidentally remove your use of CONVERT_FROM_FUNC_PTR_ADDR altogether. >From looking at the AVR manual, I gather that code addresses are 16 bits wide, and refer to 16-bit words in the program memory. So the architecture can address 64k words (128k bytes), of code. Instructions are always 16 or 32 bits long, so the processor never addresses them by byte at all. So as far as the processor is concerned, code addresses are 16 bit long. Is that right? But GDB and the rest of the GNU toolchain all want to use byte addresses for everything, so in the unified address space you use for linking, your program memory appears as 128k bytes at addresses 0x0 through 0x1ffff. Whatever SRAM the system has appears at 0x800000 in this unified address space; a pointer value of 0x0 refers to the byte at 0x800000 in the unified space. Is that right? I'll bet C programs represent data pointers as byte addresses, but pointers to a functions as word addresses --- 16-bit values you could load directly into the PC. And I'll bet return addresses on the stack are also just 16-bit values. So this means that the toolchain is using 17-bit byte addresses, while the running program is using 16-bit word addresses. Right? If so, I think this is exactly the program that POINTER_TO_ADDRESS and ADDRESS_TO_POINTER are supposed to solve. They're described in more detail in gdb/doc/gdbint.texinfo, in the section called "Pointers Are Not Always Addresses"; that even uses a Harvard architecture as an example. You're using them to add and remove the upper "prefix" bits, which is partly what they're for, but they're also supposed to handle converting between the word addresses that appear in the running program, and the byte addresses that GDB uses to actually read and write instruction memory. The general idea is that CORE_ADDR values should always be byte addresses, and if the processor's natural form for function pointers and return addresses on the stack is not a byte address, then POINTER_TO_ADDRESS converts the natural form to byte addresses, and ADDRESS_TO_POINTER converts byte addresses to the natural form. In other words, POINTER_TO_ADDRESS should shift the value left one bit when the type is a pointer to function or method --- turning the word address into a byte address --- and ADDRESS_TO_POINTER should shift the value right one bit when the type is right --- turning the byte address back into a word address. If you change your methods to do this, and dedicate the full range 0x0 -- 0x1ffff for byte-addressed program memory (which I'll bet is what gas, ld, and the binutils are doing already), and then get rid of the definition of CONVERT_FROM_FUNC_PTR_ADDR, then I think a bunch of stuff should start to work better.