This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ARM ELF p_paddr is not put to zero


On Wed, Jun 22, 2011 at 9:43 PM, Ian Lance Taylor <iant@google.com> wrote:
> Drasko DRASKOVIC <drasko.draskovic@gmail.com> writes:
>
>>> That is the default behaviour for the GNU tools, so that it is possible
>>> to represent a load address separate from the virtual address.
>> What do you exactly mean by this default behaviour ? To put p_paddr =
>> p_vaddr ? In which situations ?
>
> Conceptually, every section has a virtual address (the address where the
> section should live when the program is run) and a load address (the
> address where the section should be loaded). ?On a virtual memory
> machine these are normally the same. ?On a device without virtual memory
> and with ROM, it is often useful to load the initialized data section at
> one address (in ROM) but to run with the data at another address (in
> RAM). ?Given that, it becomes useful to use some mechanism for
> representing both the load address and the virtual address in a linked
> executable. ?The GNU tools normally store the load address in the
> p_paddr field and the virtual address in the p_vaddr field.

Hi Ian,
thanks for clarifications. I think that p_vaddr can be affected with
by --entry flag and  explicit address, as it sound logical to me that
it is set to this value. Is this correct ? Does this flag however also
affects p_paddr at the same time ?

How do we specify p_paddr (I am talking about ROM and noMMU devices)?
I.e. how do we tell at which address binary should be loaded ? Is this
done only via linker script or there are some command line options
with which we can define lma ?

Third question is - what happens if we do not define load address at
all, just provide address at we want to link, i.e. address of the
first symbol (if this does not affect p_paddr just p_vaddr) ? How does
ld manage this internally - would it equalize p_paddr to p_vaddr
during the process and spit out binary with p_paddr = p_vaddr ?

>>> ?So most
>>> likely this unusual ARM ELF requirement has simply not been implemented.
>>
>> Would that say that GNU ld is ARM EABI (ABI v. 2.0, published after
>> December 2003), but *not* OABI (ABI v. 1.0, prior to December 2003)
>> compliant, because of p_paddr != 0 ?
>
> It is certainly true that GNU ld strives to be EABI compliant.

Yes, and this makes a lot of sense - rather than strive for 10 years
old proprietary vendor standard.

Let me explain in a little more details why I am asking the questions
from above.

I got interested into this subject by working on OpenOCD
(http://openocd.berlios.de/web/), which currently discovers ELF image
load address by reading elf->segments[i].p_paddr. As this is low-level
JTAG debugger, it looks quite fine and consistent with you said before
p_paddr is lma for noMMU, ROM and similar embedded stuff.

However, I run recently into an ARM ELF that looked like this :

Program Headers:
 Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
 LOAD           0x000074 0x00008000 0x00000000 0xe1f18 0xe1f18 RWE 0x1
 LOAD           0x0e1f8c 0x0060f028 0x00000000 0x1103f 0x1103f RWE 0x1

and normally, OpenOCD was trying to put it to address 0x0, which is
wrong. And it's wrong because ARM OEBI obviously demands p_paddr to be
zero.

However, GDB could cope with it and load ELF normally. So I started
digging in BFD code and discovered something like this in elf.c :
if ((flags & SEC_ALLOC) != 0)
   {
     Elf_Internal_Phdr *phdr;
     unsigned int i, nload;

     /* Some ELF linkers produce binaries with all the program header
        p_paddr fields zero.  If we have such a binary with more than
        one PT_LOAD header, then leave the section lma equal to vma
        so that we don't create sections with overlapping lma.  */
     phdr = elf_tdata (abfd)->phdr;
     for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
       if (phdr->p_paddr != 0)
         break;
       else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
         ++nload;
     if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
       return TRUE;

I have send a patch to OpenOCD that mimics this solution in order to
be more robust and GDB consistent, but I just wanted to double-check
on the list here how these flags are handled in GNU ld, and that is
why I posted above questions.

Here are some interesting posts, just for the reference :
http://lists.gnu.org/archive/html/bug-gnu-utils/2002-02/msg00098.html
http://cygwin.com/ml/binutils/2002-09/msg00516.html
http://lists.gnu.org/archive/html/bug-gnu-utils/2002-08/msg00319.html
http://blackfin.uclinux.org/gf/project/u-boot/tracker/?action=TrackerItemEdit&tracker_item_id=642
http://lists.gnu.org/archive/html/bug-gnu-utils/2002-08/msg00324.html

Thanks and best regards,
Drasko


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]