This is the mail archive of the
mailing list for the binutils project.
Re: [Patch, avr] Place progmem.data from avr-libc above other progmem
- From: Senthil Kumar Selvaraj <senthil_kumar dot selvaraj at atmel dot com>
- To: Alan Modra <amodra at gmail dot com>
- Cc: Nick Clifton <nickc at redhat dot com>, <binutils at sourceware dot org>, "Denis Chertykov" <chertykov at gmail dot com>
- Date: Wed, 18 May 2016 14:09:03 +0530
- Subject: Re: [Patch, avr] Place progmem.data from avr-libc above other progmem
- Authentication-results: sourceware.org; auth=none
- References: <87oa8832kx dot fsf at atmel dot com> <fb734ee9-5592-716c-787d-4e9036863477 at redhat dot com> <87eg8z3j2l dot fsf at atmel dot com> <20160518081547 dot GO24091 at bubble dot grove dot modra dot org>
Alan Modra writes:
> On Wed, May 18, 2016 at 01:15:54PM +0530, Senthil Kumar Selvaraj wrote:
>> Nick Clifton writes:
>> > Hi Senthil,
>> >> avr-libc's vfprint handling uses a lookup table located in flash
>> >> if float format specifiers are involved. If user code also has
>> >> lots of flash data (in section .progmem.data), then
>> >> avr-libc's progmem data gets pushed beyond the 64 K word limit. The
>> >> avr-libc code doesn't expect this to happen and vfprintf stops working correctly.
>> > Doesn't this indicate a problem with the linker - in that it does not
>> > report to the user that the code is broken and that accesses above the 64k
>> > limit are being made without use of the memx address space modifier ?
>> Do you mean reloc processing should have detected the overflow? In
>> this case, the offending value is loaded into two 8 bit regs, using the
>> lo8 and hi8 modifiers, resulting in R_AVR_LO8_LDI_NEG and
>> R_AVR_HI8_LDI_NEG relocs. I guess if there was a single reloc that
>> handled the value, we could have detected overflow, AVR has only 8 bit
>> registers though, so I can't see a way to do this. Am I missing something?
> The problem of values being split over multiple insns is not one that
> should affect AVR since you use RELA relocs. The value ought to be
> available at each of the R_AVR_LO8_LDI_NEG and R_AVR_HI8_LDI_NEG
> relocs as the symbol value plus reloc addend.
Yes, but the > 64K symbol value itself is ok for each of those relocs - they
only write lower/next higher 8 bits of the value. The linker cannot
possibly know/tell that the value is big enough that it needs a extra
register load with a R_AVR_MS8_LDI reloc to load bits 24-31, can it?