This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: elf.c:3701: off += (m->sections[0]->vma - off) % bed->maxpagesize
- From: Ian Lance Taylor <ian at wasabisystems dot com>
- To: Andrew Cagney <cagney at gnu dot org>
- Cc: binutils at sources dot redhat dot com
- Date: 20 Jan 2004 22:44:58 -0500
- Subject: Re: elf.c:3701: off += (m->sections[0]->vma - off) % bed->maxpagesize
- References: <400DE42B.7020100@gnu.org>
Andrew Cagney <cagney@gnu.org> writes:
> From elf.c:
>
> 3701 off += (m->sections[0]->vma - off) % bed->maxpagesize;
> (gdb) print off
> $51 = 0x54
> (gdb) print m->sections[0]->vma
> $52 = 0x0
> (gdb) print bed->maxpagesize
> $53 = 0x10000
>
> ok:
>
> (gdb) ptype m->sections[0]->vma
> type = long unsigned int
> (gdb) ptype off
> type = long int
> (gdb) ptype bed->maxpagesize
> type = long unsigned int
> (gdb) print off + (m->sections[0]->vma - off) % bed->maxpagesize
> $50 = 0x10000
>
> broken:
>
> (gdb) ptype m->sections[0]->vma
> type = long unsigned int
> (gdb) ptype off
> type = long long int
> (gdb) ptype bed->maxpagesize
> type = long unsigned int
> (gdb) print off + (m->sections[0]->vma - off) % bed->maxpagesize
> $39 = 0x0
>
> I can make it work with:
>
> (gdb) print off + (m->sections[0]->vma - off) % (ufile_ptr)
> bed->maxpagesize
> $40 = 0x10000
>
> but is there a better way to write this expression? (that arithmetic
> strikes me as weird) and just how many others like this are lurking
> :-/ :-)?
We shouldn't be using % with a negative signed number. That's just
not good. We have to make sure either that the number is not
negative, or that the number has an unsigned type. When the types are
all the same size they wind up as unsigned. When file_ptr is a larger
signed type, the arithmetic winds up as signed long long, which is
wrong.
What we're trying to say here is something like ``increase OFF by the
least amount that will cause it to be equal to the VMA modulo the page
size.'' In other words, something like
vma_offset = m->sections[0]->vma % bed->maxpagesize;
off_offset = off % bed->maxpagesize;
off += vma_offset - off_offset;
if (vma_offset < off_offset)
off += bed->maxpagesize;
which can be collapsed to the above expression when using unsigned
arithmetic.
Probably easiest to just cast OFF to ufile_ptr.
I doubt there is much of this sort of arithmetic--though of course it
appears again 15 lines lower in the function.
Ian