GNU LD and ARM ELF spec disagree about meaning of p_vaddr field

Geoff Keating geoffk@geoffk.org
Tue Sep 24 16:41:00 GMT 2002


Nick Clifton <nickc@redhat.com> writes:

> Hi Guys,
> 
>   A recent posting by Adrian Bocaniciu to the bug binutils list has
>   raised an issue with GNU linker which may have important
>   repercussions for ARM Linux:
> 
>     http://sources.redhat.com/ml/bug-binutils/2002-q3/msg00388.html
> 
>   The problem is that GNU LD chooses to interpret the p_vaddr field of
>   the program header structure as being the run-time-memory-address
>   (or VMA in BFD terms) and the p_addr field as being the load-time-
>   memory-address (or LMA).  This is contrary to the ARM ELF spec.

No, this is correct.  The p_vaddr field is the address where the
segment should be while the program is running; the p_paddr field is
just some random information to help out the loader, often it is the
equivalent of p_vaddr in the loader's address space or the physical
address equivalent to p_vaddr..

>   The ELF spec is not exactly clear about the use of these fields:
> 
>     p_vaddr    This member gives the virtual address at which the
>                first byte of the segment resides in memory.
> 
>     p_paddr    On systems for which physical addressing is relevant, 
>                this member is reserved for the segment's physical
>                address. This member requires operating system specific  
>                information.
> 
>   It is not clear when the spec says "first byte of the segment
>   resides in memory" whether it means the address at the time that the
>   segment is loaded or at the time when the segment is connected to an
>   executing process.

The only time this distinction matters is when an object starts
executing before it has finished loading---it can't finish loading
before it can be executed, because "loading" is the name for the
process of moving it to the right place to be executed.

Normally, an object (like an OS kernel with bootstrap code at the
start) that starts executing before it has finished loading has
p_vaddr set to the final address it will be loaded into.

>   (Note - it is possible to glean such information from the section
>   headers, however the ELF spec allows the section headers to be
>   optional in executables, so loaders cannot rely upon them being
>   present).
> 
>   Anyway, the ARM ELF spec requires that the p_vaddr field be
>   interpreted as the load address not the execute address:
> 
>     p_vaddr    The virtual address at which the segment should be
>                loaded. This must be 0 modulo 4.

In this context, "loading" includes any VM management that may be
necessary.  For instance, on Linux the kernel will usually read any
given page into what it sees as some random page in the kernel's
address space, but to the actual process it will be mapped to the
location specified by p_vaddr.

"loading" also includes any copying that might be necessary.  For
instance, an image that is to be put in flash might first be read from
floppy into RAM, then copied into flash; the whole process is
"loading", not just the read from disk.

Adrian writes:

> This is especially annoying because the ARM debuggers
> use only the "VirtAddr" field and ignore the "PhysAddr"
> field, so that the files generated by arm-elf-ld are
> unusable.

I don't see why this would be annoying.  When the program is running,
the segment is being used, and you are debugging it, it _is_ at the
"VirtAddr" field, correct?

-- 
- Geoffrey Keating <geoffk@geoffk.org>



More information about the Binutils mailing list