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: [patch] Fix bfd_elf_bfd_from_remote_memory() loadbase


> On Fri, Aug 10, 2007 at 05:15:46PM +0200, Jan Kratochvil wrote:
> > I believe a simple rule "just the first PT_LOAD segment" implemented in my
> > patch should be enough.
> 
> No.  Please fix this properly as per the ELF gABI.

Sorry, reading your citation from the spec did not help me have any idea
what you think "fix this properly" means in this context.

The situation is that we have some phdrs, and we know an address that is
the lowest virtual address corresponding to file offset 0.  The task at
hand is to calculate the base address from that knowledge.

In a correct object per the spec, "PT_LOAD with lower p_vaddr" is the
same as "PT_LOAD with lower index".  Ergo, the first PT_LOAD with
(p_offset & -maxpage) == 0 is the one whose (p_vaddr & -maxpage)
describes the lowest-addresse mapping of file offset 0.  Ergo, the
difference between this and the known address we started with is the
base address we are looking for.  

The file itself doesn't tell you what "maxpage" is, but p_align is
supposed to match it.  You can't presume the actual memory addresses
used will be so aligned (it's the maximum page size, not the minimum).
However, in a correct ELF object's phdrs, each p_vaddr and p_offset
must be congruent to that alignment.  So (p_offset & -p_align) == 0 is
enough to tell you that the system could have mapped that segment such
that (p_vaddr & -p_align) came from file offset 0.  From there, it's a
mild assumption of normal practice to guess that the first (thus
lowest-addressed) such segment is the (first) one actually mapped from
offset 0.  Technically, a valid object could have:

	PT_LOAD p_vaddr=0x201000 p_offset=0x1000 p_align=0x200000
	PT_LOAD p_vaddr=0x400000 p_offset=0	 p_align=0x200000

If mapped with an actual page size of 0x1000, then the assumption is
wrong.  So to answer the general question "does this PT_LOAD segment
include file offset 0 in memory", you need to know the actual page
size.  bfd_elf_bfd_from_remote_memory doesn't know this.  (The
debugger might know it by some external means.  While there is no
detailed specification for ET_CORE files, the de facto standard is
that p_align in core file PT_LOAD segments gives the actual page size.
For live debugging, there are OS-specific ways to find out.)

However, for the task at hand you are starting from an address that is
a priori both the lowest address mapped and the one mapped at offset 0.  
So the assumption is completely safe for this purpose.

Jan's change to includes only segments with p_offset==0 is incorrect.
In practice today, those are the phdrs we see.  But they could very
well be p_vaddr=0x123 p_offset=0x123 instead.

Jan's change to use only the first segment that maps file offset 0 is
correct.  The old change to ignore segments without PF_R was incorrect
for the general case, though handled the only real-world case where the
function was used on phdrs of which more than one maps file offset 0
(the Linux/IA64 vDSO, whose first such mapping has PF_R).

Jan's new comment explaining the PF_R check is incorrect.  It may once
have been the case in Linux that the debugger was unable to read memory
mapped without read permission, but that has certainly not been true
recently.  I think this check may have been introduced solely as a
heuristic to handle the ia64 vDSO.  This is IMO much better addressed
by correcting the base address calculation to use the first PT_LOAD
mapping file offset 0 rather than the last, as Jan's change does.



Thanks,
Roland


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