2001-12-06 21:42:23

by William Lee Irwin III

[permalink] [raw]
Subject: proc_pid_statm

It's unclear where the number 0x60000000 comes from. I believe it's
attempting to anticipate the layout of the process address space, in
particular the fact that ELF interpreters are mapped starting at
ELF_ET_DYN_BASE when formatted as dynamic shared objects, (and this
used to happen around 0x60000000 if I remember old ldd output), and in
many cases, all dynamic shared objects are mapped at still higher
addresses. Open-coding this number seems non-portable.

Could someone comment on this?


Cheers,
Bill


I think the author may have had this in mind (though this may still
report inaccurately on a few architectures):


--- linux-2.4.17-pre4-virgin/fs/proc/array.c Thu Oct 11 09:00:01 2001
+++ linux-2.4.17-pre4/fs/proc/array.c Thu Dec 6 13:36:33 2001
@@ -75,6 +75,7 @@
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/processor.h>
+#include <linux/elf.h>

/* Gcc optimizes away "strlen(x)" for constant x */
#define ADDBUF(buffer, string) \
@@ -491,14 +492,13 @@
share += shared;
dt += dirty;
size += total;
- if (vma->vm_flags & VM_EXECUTABLE)
- trs += pages; /* text */
- else if (vma->vm_flags & VM_GROWSDOWN)
- drs += pages; /* stack */
- else if (vma->vm_end > 0x60000000)
- lrs += pages; /* library */
- else
- drs += pages;
+ if (vma->vm_flags & VM_EXECUTABLE) {
+ if(vma->vm_end > ELF_ET_DYN_BASE)
+ lrs += pages; /* library */
+ else
+ trs += pages; /* text */
+ } else
+ drs += pages; /* stack and data */
vma = vma->vm_next;
}
up_read(&mm->mmap_sem);


2001-12-07 04:21:42

by BALBIR SINGH

[permalink] [raw]
Subject: Re: proc_pid_statm

I looked at ELF_ET_DYN_BASE and it is defined differently on
different architectures. For example on an i386, it is defined
to be 2GB which is 0x80000000.

On ia64 it is defined as (TASK_UNMAPPED_BASE + 0x1000000).

I would *dare* suggest that since all shared libraries are
mmapped, the correct value to compare against in your patch is
TASK_UNMAPPED_BASE.

On my i386, the ldd output and looking at /proc/<pid>/maps
justifies this.

ldd -d /bin/ls
libtermcap.so.2 => /lib/libtermcap.so.2 (0x4002d000)
libc.so.6 => /lib/i686/libc.so.6 (0x40031000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)


ld-linux.so.2 is loaded at TASK_UNMAPPED_BASE. Again, let me
remind you that I am speculating, so please correct me if u think
I am wrong.

Comments,
Balbir


William Lee Irwin III wrote:

>It's unclear where the number 0x60000000 comes from. I believe it's
>attempting to anticipate the layout of the process address space, in
>particular the fact that ELF interpreters are mapped starting at
>ELF_ET_DYN_BASE when formatted as dynamic shared objects, (and this
>used to happen around 0x60000000 if I remember old ldd output), and in
>many cases, all dynamic shared objects are mapped at still higher
>addresses. Open-coding this number seems non-portable.
>
>Could someone comment on this?
>
>
>Cheers,
>Bill
>
>
>I think the author may have had this in mind (though this may still
>report inaccurately on a few architectures):
>
>
>--- linux-2.4.17-pre4-virgin/fs/proc/array.c Thu Oct 11 09:00:01 2001
>+++ linux-2.4.17-pre4/fs/proc/array.c Thu Dec 6 13:36:33 2001
>@@ -75,6 +75,7 @@
> #include <asm/pgtable.h>
> #include <asm/io.h>
> #include <asm/processor.h>
>+#include <linux/elf.h>
>
> /* Gcc optimizes away "strlen(x)" for constant x */
> #define ADDBUF(buffer, string) \
>@@ -491,14 +492,13 @@
> share += shared;
> dt += dirty;
> size += total;
>- if (vma->vm_flags & VM_EXECUTABLE)
>- trs += pages; /* text */
>- else if (vma->vm_flags & VM_GROWSDOWN)
>- drs += pages; /* stack */
>- else if (vma->vm_end > 0x60000000)
>- lrs += pages; /* library */
>- else
>- drs += pages;
>+ if (vma->vm_flags & VM_EXECUTABLE) {
>+ if(vma->vm_end > ELF_ET_DYN_BASE)
>+ lrs += pages; /* library */
>+ else
>+ trs += pages; /* text */
>+ } else
>+ drs += pages; /* stack and data */
> vma = vma->vm_next;
> }
> up_read(&mm->mmap_sem);
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to [email protected]
>More majordomo info at http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at http://www.tux.org/lkml/
>



Attachments:
InterScan_Disclaimer.txt (855.00 B)

2001-12-07 04:58:12

by William Lee Irwin III

[permalink] [raw]
Subject: Re: proc_pid_statm

On Fri, Dec 07, 2001 at 09:38:35AM +0530, BALBIR SINGH wrote:
> I looked at ELF_ET_DYN_BASE and it is defined differently on
> different architectures. For example on an i386, it is defined
> to be 2GB which is 0x80000000.
> On ia64 it is defined as (TASK_UNMAPPED_BASE + 0x1000000).
> I would *dare* suggest that since all shared libraries are
> mmapped, the correct value to compare against in your patch is
> TASK_UNMAPPED_BASE.

Well, it should be different. My analysis was that the libraries
were loaded above the ELF interpreter. I believe your assessment
is more accurate.

On Fri, Dec 07, 2001 at 09:38:35AM +0530, BALBIR SINGH wrote:
> On my i386, the ldd output and looking at /proc/<pid>/maps
> justifies this.
>
> ldd -d /bin/ls
> libtermcap.so.2 => /lib/libtermcap.so.2 (0x4002d000)
> libc.so.6 => /lib/i686/libc.so.6 (0x40031000)
> /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
>
>
> ld-linux.so.2 is loaded at TASK_UNMAPPED_BASE. Again, let me
> remind you that I am speculating, so please correct me if u think
> I am wrong.

TASK_UNMAPPED_BASE is what the m68k tree uses as well. I'll roll a
fresh version of the patch using that instead.

Oddly, on i386 the following definitions are used:

include/asm-i386/processor.h:273:#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
include/asm-i386/elf.h:58:#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)

so only one of us can be correct here, and it appears to be you:

include/asm-i386/processor.h:268:#define TASK_SIZE (PAGE_OFFSET)

and 3*0x40000000 == 0xC0000000 == PAGE_OFFSET

Cheers,
Bill

2001-12-07 05:00:32

by William Lee Irwin III

[permalink] [raw]
Subject: Re: proc_pid_statm

On Fri, Dec 07, 2001 at 09:38:35AM +0530, BALBIR SINGH wrote:
> I looked at ELF_ET_DYN_BASE and it is defined differently on
> different architectures. For example on an i386, it is defined
> to be 2GB which is 0x80000000.

The corrected patch follows:


--- linux-2.4.17-pre4-virgin/fs/proc/array.c Thu Oct 11 09:00:01 2001
+++ linux-2.4.17-pre4/fs/proc/array.c Thu Dec 6 20:58:36 2001
@@ -491,14 +491,13 @@
share += shared;
dt += dirty;
size += total;
- if (vma->vm_flags & VM_EXECUTABLE)
- trs += pages; /* text */
- else if (vma->vm_flags & VM_GROWSDOWN)
- drs += pages; /* stack */
- else if (vma->vm_end > 0x60000000)
- lrs += pages; /* library */
- else
- drs += pages;
+ if (vma->vm_flags & VM_EXECUTABLE) {
+ if(vma->vm_end > TASK_UNMAPPED_BASE)
+ lrs += pages; /* library */
+ else
+ trs += pages; /* text */
+ } else
+ drs += pages; /* stack and data */
vma = vma->vm_next;
}
up_read(&mm->mmap_sem);