From 74cb5b6093708f2368253cedf65b555c165ed558 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Mon, 10 Jul 2000 13:51:45 +0000 Subject: [PATCH] 2000-07-10 Maciej W. Rozycki * sysdeps/mips/dl-machine.h (elf_machine_runtime_link_map): Verify that gpreg really points to the GOT section of the calling object. Scan all PT_LOAD segments of objects for stub_pc, instead of only checking a start address of first one. Fix typos. * sysdeps/mips/mips64/dl-machine.h (elf_machine_runtime_link_map): Likewise. * sysdeps/mips/dl-machine.h (__dl_runtime_resolve): Fix a typo. --- sysdeps/mips/dl-machine.h | 64 ++++++++++++++++++++++------------------ sysdeps/mips/mips64/dl-machine.h | 61 +++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h index f08afa9..e1b9163 100644 --- a/sysdeps/mips/dl-machine.h +++ b/sysdeps/mips/dl-machine.h @@ -141,9 +141,9 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) extern int _dl_mips_gnu_objects; /* got[1] is reserved to keep its link map address for the shared - object generated by gnu linker. If all are such object, we can - find link map from current GPREG simply. If not so, get link map - for callers object containing STUB_PC. */ + object generated by the gnu linker. If all are such objects, we + can find the link map from current GPREG simply. If not so, get + the link map for caller's object containing STUB_PC. */ if (_dl_mips_gnu_objects) { @@ -153,45 +153,51 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) g1 = ((ElfW(Word) *) got)[1]; if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0) - return (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK); + { + struct link_map *l = + (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK); + ElfW(Addr) base, limit; + const ElfW(Phdr) *p = l->l_phdr; + ElfW(Half) this, nent = l->l_phnum; + + /* For the common case of a stub being called from the containing + object, STUB_PC will point to somewhere within the object that + is described by the link map fetched via got[1]. Otherwise we + have to scan all maps. */ + for (this = 0; this < nent; this++) + { + if (p[this].p_type == PT_LOAD) + { + base = p[this].p_vaddr + l->l_addr; + limit = base + p[this].p_memsz; + if (stub_pc >= base && stub_pc < limit) + return l; + } + } + } } { struct link_map *l = _dl_loaded; - struct link_map *ret = 0; - ElfW(Addr) candidate = 0; while (l) { - ElfW(Addr) base = 0; + ElfW(Addr) base, limit; const ElfW(Phdr) *p = l->l_phdr; ElfW(Half) this, nent = l->l_phnum; - /* Get the base. */ - for (this = 0; this < nent; this++) - if (p[this].p_type == PT_LOAD) - { - base = p[this].p_vaddr + l->l_addr; - break; - } - if (! base) - { - l = l->l_next; - continue; - } - - /* Find closest link base addr. */ - if ((base < stub_pc) && (candidate < base)) + for (this = 0; this < nent; ++this) { - candidate = base; - ret = l; + if (p[this].p_type == PT_LOAD) + { + base = p[this].p_vaddr + l->l_addr; + limit = base + p[this].p_memsz; + if (stub_pc >= base && stub_pc < limit) + return l; + } } l = l->l_next; } - if (candidate && ret && (candidate < stub_pc)) - return ret; - else if (!candidate) - return _dl_loaded; } _dl_signal_error (0, NULL, "cannot find runtime link map"); @@ -208,7 +214,7 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) Other architectures call fixup from dl-runtime.c in _dl_runtime_resolve. MIPS instead calls __dl_runtime_resolve. We have to use our own version because of the way the got section is - treaded on MIPS (we've also got ELF_MACHINE_PLT defined). */ + treated on MIPS (we've also got ELF_MACHINE_PLT defined). */ #define ELF_MACHINE_RUNTIME_TRAMPOLINE \ /* The flag _dl_mips_gnu_objects is set if all dynamic objects are \ diff --git a/sysdeps/mips/mips64/dl-machine.h b/sysdeps/mips/mips64/dl-machine.h index c2f2f6e..024476b 100644 --- a/sysdeps/mips/mips64/dl-machine.h +++ b/sysdeps/mips/mips64/dl-machine.h @@ -252,9 +252,9 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) extern int _dl_mips_gnu_objects; /* got[1] is reserved to keep its link map address for the shared - object generated by gnu linker. If all are such object, we can - find link map from current GPREG simply. If not so, get link map - for callers object containing STUB_PC. */ + object generated by the gnu linker. If all are such objects, we + can find the link map from current GPREG simply. If not so, get + the link map for caller's object containing STUB_PC. */ if (_dl_mips_gnu_objects) { @@ -264,45 +264,52 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc) g1 = ((ElfW(Word) *) got)[1]; if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0) - return (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK); + { + struct link_map *l = + (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK); + ElfW(Addr) base, limit; + const ElfW(Phdr) *p = l->l_phdr; + ElfW(Half) this, nent = l->l_phnum; + + /* For the common case of a stub being called from the containing + object, STUB_PC will point to somewhere within the object that + is described by the link map fetched via got[1]. Otherwise we + have to scan all maps. */ + for (this = 0; this < nent; this++) + { + if (p[this].p_type == PT_LOAD) + { + base = p[this].p_vaddr + l->l_addr; + limit = base + p[this].p_memsz; + if (stub_pc >= base && stub_pc < limit) + return l; + } + this++; + } + } } { struct link_map *l = _dl_loaded; - struct link_map *ret = 0; - ElfW(Addr) candidate = 0; while (l) { - ElfW(Addr) base = 0; + ElfW(Addr) base, limit; const ElfW(Phdr) *p = l->l_phdr; ElfW(Half) this, nent = l->l_phnum; - /* Get the base. */ for (this = 0; this < nent; this++) - if (p[this].p_type == PT_LOAD) - { - base = p[this].p_vaddr + l->l_addr; - break; - } - if (! base) - { - l = l->l_next; - continue; - } - - /* Find closest link base addr. */ - if ((base < stub_pc) && (candidate < base)) { - candidate = base; - ret = l; + if (p[this].p_type == PT_LOAD) + { + base = p[this].p_vaddr + l->l_addr; + limit = base + p[this].p_memsz; + if (stub_pc >= base && stub_pc < limit) + return l; + } } l = l->l_next; } - if (candidate && ret && (candidate < stub_pc)) - return ret; - else if (!candidate) - return _dl_loaded; } _dl_signal_error (0, NULL, "cannot find runtime link map"); -- 2.7.4