This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
Patch: ldd and ld-2.0.7.so (fwd)
- To: libc-alpha@cygnus.com
- Subject: Patch: ldd and ld-2.0.7.so (fwd)
- From: Wes Morgan <by-tor@by-tor.tacorp.net>
- Date: Tue, 27 Oct 1998 13:53:12 -0500 (EST)
For those of you who don't necessarily follow the linux-kernel mailing
list and have had trouble with 2.0.99 and some of the newer linux 2.1
kernels, this patch seems to work for me.
--
+--------------------------+----------------------------------------+
| by-tor@by-tor.tacorp.net | UNIX _is_ user-friendly. It's just not |
| By-Tor@EfNet | ignorant-friendly and idiot-friendly. |
+--------------------------+----------------------------------------+
---------- Forwarded message ----------
Date: Tue, 27 Oct 1998 16:31:26 +0100
From: ralf@uni-koblenz.de
To: torvalds@transmeta.com
Cc: Ralf Wierzbicki <rafal@boa1.cas.McMaster.CA>,
Kernel Mailing List <linux-kernel@vger.rutgers.edu>
Subject: Patch: ldd and ld-2.0.7.so
On Sat, Oct 24, 1998 at 04:02:00AM -0400, Ralf Wierzbicki wrote:
> The dynamic loader (2.0.7) coredumps in linux 2.1.126 with a segmentation
> fault. I checked in 2.1.125 and ldd works fine, the problem occurs
> only in 2.1.126 when trying to run ld-2.0.7 --verify (ldd).
The problem was in my fix to binfmt_elf to handle certain address
combinations, certain executables linked to addresses != 0 would have
dumped core. This is (for the sake of tradition ...) the case on MIPS.
The fix has a bug which crashes ET_DYN executables like ld-2.0.7.so on
certain architectures like Intel where addresses are just right. The
appended patch fixes this. The patch looks quite a bit bigger than it
actually is since I used the occassion to rewrite and reformat the code
in question a bit so it is less heavily indented. The actuall functional
fix is a two liner or so. Tested on Intel and MIPS. Linus, please include
the appended fix.
Ralf
--- linux-2.1.126.orig/fs/binfmt_elf.c Tue Oct 27 04:41:35 1998
+++ linux-2.1.126/fs/binfmt_elf.c Tue Oct 27 13:15:35 1998
@@ -608,7 +608,7 @@
base, as well as whatever program they might try to exec. This
is because the brk will follow the loader, and is not movable. */
- load_bias = (elf_ex.e_type == ET_DYN ? ELF_ET_DYN_BASE : 0);
+ load_bias = ELF_PAGESTART(elf_ex.e_type==ET_DYN ? ELF_ET_DYN_BASE : 0);
/* Now we do a little grungy work by mmaping the ELF image into
the correct location in memory. At this point, we assume that
@@ -618,51 +618,50 @@
old_fs = get_fs();
set_fs(get_ds());
for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
- if (elf_ppnt->p_type == PT_LOAD) {
- int elf_prot = 0, elf_flags;
- unsigned long vaddr;
-
- if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
- if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
- if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
-
- elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
-
- vaddr = elf_ppnt->p_vaddr;
- if (elf_ex.e_type == ET_EXEC || load_addr_set) {
- elf_flags |= MAP_FIXED;
- }
+ int elf_prot = 0, elf_flags;
+ unsigned long vaddr;
+
+ if (elf_ppnt->p_type != PT_LOAD)
+ continue;
+
+ if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
+ if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
+ if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
+
+ elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
+
+ vaddr = elf_ppnt->p_vaddr;
+ if (elf_ex.e_type == ET_EXEC || load_addr_set) {
+ elf_flags |= MAP_FIXED;
+ }
- error = do_mmap(file,
- ELF_PAGESTART(load_bias + vaddr),
- (elf_ppnt->p_filesz +
- ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
- elf_prot, elf_flags,
- (elf_ppnt->p_offset -
- ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
-
- if (!load_addr_set) {
- load_addr_set = 1;
- load_addr = (elf_ppnt->p_vaddr -
- elf_ppnt->p_offset);
- if (elf_ex.e_type == ET_DYN) {
- load_bias = error - ELF_PAGESTART(load_bias + vaddr);
- load_addr += error;
- }
+ error = do_mmap(file, ELF_PAGESTART(load_bias + vaddr),
+ (elf_ppnt->p_filesz +
+ ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
+ elf_prot, elf_flags, (elf_ppnt->p_offset -
+ ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
+
+ if (!load_addr_set) {
+ load_addr_set = 1;
+ load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
+ if (elf_ex.e_type == ET_DYN) {
+ load_bias += error -
+ ELF_PAGESTART(load_bias + vaddr);
+ load_addr += error;
}
- k = elf_ppnt->p_vaddr;
- if (k < start_code) start_code = k;
- k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
- if (k > elf_bss)
- elf_bss = k;
- if ((elf_ppnt->p_flags & PF_X) && end_code < k)
- end_code = k;
- if (end_data < k)
- end_data = k;
- k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
- if (k > elf_brk)
- elf_brk = k;
}
+ k = elf_ppnt->p_vaddr;
+ if (k < start_code) start_code = k;
+ k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
+ if (k > elf_bss)
+ elf_bss = k;
+ if ((elf_ppnt->p_flags & PF_X) && end_code < k)
+ end_code = k;
+ if (end_data < k)
+ end_data = k;
+ k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
+ if (k > elf_brk)
+ elf_brk = k;
}
set_fs(old_fs);
fput(file); /* all done with the file */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/