From a2b08ee54130cf3a74655856e6ca6c29874a9df2 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 27 Sep 1997 00:21:42 +0000 Subject: Update. 1997-09-27 01:14 Ulrich Drepper * Makeconfig (extra-objs): Depend in before-compile. * configure.in: Locate Perl and substitute with complete path. * config.make.in: Add PERL for substitution. * elf/Makefile (routines): Add dl-addr. * elf/dladdr.c: Move the real code into ... * elf/dl-addr.c: New file. * elf/link.h: Add prototype for _dl_addr. * elf/dladdr.c (dladdr): Change address argument to be const. * elf/dlfcn.h: Likewise. * locale/C_name.c: Add _nl_POSIX_name. * locale/localeinfo.h: Add declaration of _nl_POSIX_name. * locale/findlocale.c (_nl_find_locale): Use _nl_POSIX_name. (_nl_remove_locale): Free name of data set. * locale/setlocale.c (clever_copy): Remove. (new_composite_name): Use _nl_C_name and _nl_POSIX_name in compare. (setname): Only remove old name when it is for category LC_ALL. Change malloc, free, realloc, and memalign hooks for glibc to take another parameter indicating the location of the caller. * malloc/malloc.c: Change hook functions and variables. * malloc/malloc.h: Likewise. * malloc/mcheck.c: Likewise. Make sure later hooked function also get the original caller address. * malloc/mtrace.c: Likewise. (tr_where): If no information in _mtrace_file is given use the information about the caller. * malloc/Makefile (distribute): Replace mtrace.awk by mtrace.pl. Add rules to install mtrace.pl after rewriting. * malloc/mtrace.pl: New file. Based on the old AWK script but with extended functionality. * malloc/mtrace.awk: Removed. * po/fr.po: New version. * string/Makefile: Do use builtins for tester.c and inl-tester.c. * string/tester.c: Rewrite. Split in many small functions to not exceed gcc's limits. * sysdeps/unix/sysv/linux/syscalls.list: Add prctl. 1997-09-25 Andreas Schwab * string/bits/string2.h (__stpcpy_small): Don't use casts as lvalues. 1997-09-26 Andreas Jaeger * manual/time.texi (Formatting Date and Time): Clarify explanation of strftime flags a bit. Suggested by Robert Bihlmeyer . 1997-09-25 00:13 David S. Miller * sysdeps/libm-ieee754/s_exp2f.c: Protect _GNU_SOURCE definition. Fix typo, it is FLT_MANT_DIG. 1997-09-24 18:52 H.J. Lu * math/atest-exp2.c: Include instead of . 1997-08-27 08:10 H.J. Lu * libio/libio.h, libio/libioP.h: Support libio in libstdc++. * libio/libio.h (_IO_peekc): Defined as _IO_peekc_unlocked if _IO_MTSAFE_IO is undefined. 1997-09-24 23:27 Richard Henderson * elf/dl-runtime.c (fixup): Don't go through elf_machine_relplt, but lookup the value of the target symbol ourselves and call the new elf_machine_fixup_plt. This kills the ELF_FIXUP_RETURN_VALUE hack. (profile_fixup): Likewise, but don't fix up the plt. * elf/rtld.c (_dl_main): ELF_MACHINE_RELOC_NOPLT renamed _JMP_SLOT. * sysdeps/alpha/dl-machine.h (ELF_MACHINE_RELOC_NOPLT): Renamed. (elf_alpha_fix_plt): Renamed elf_machine_fixup_plt. * sysdeps/i386/dl-machine.h (elf_machine_relplt): Killed. (ELF_MACHINE_JMP_SLOT): Renamed. (elf_machine_fixup_plt): New function. * sysdeps/m68k/dl-machine.h: Likewise. * sysdeps/powerpc/dl-machine.h: Likewise. (elf_machine_rela): Moved JMP_SLOT fixup out to elf_machine_fixup_plt. * sysdeps/sparc/sparc32/dl-machine.h: Likewise. * sysdeps/sparc/sparc64/dl-machine.h: Likewise. * sysdeps/stub/dl-machine.h: Update, sorta. * sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Do profiling. (TRAMPOLINE_TEMPLATE): From the carcas of _RUNTIME_TRAMPOLINE, do both normal and profile code. (elf_machine_rela): Handle r_addend for .got and .plt too. --- sysdeps/powerpc/dl-machine.h | 134 +++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 67 deletions(-) (limited to 'sysdeps/powerpc') diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h index 70a3f20b31..beabc1d4ff 100644 --- a/sysdeps/powerpc/dl-machine.h +++ b/sysdeps/powerpc/dl-machine.h @@ -197,8 +197,7 @@ _dl_runtime_resolve: # ...unwind the stack frame, and jump to the PLT entry we updated. addi 1,1,48 bctr -0: - .size _dl_runtime_resolve,0b-_dl_runtime_resolve + .size _dl_runtime_resolve,.-_dl_runtime_resolve .align 2 .globl _dl_prof_resolve @@ -395,10 +394,6 @@ static ElfW(Addr) _dl_preferred_address = 1 _dl_preferred_address = mapstart; \ } ) -/* We require the address of the PLT entry returned from fixup, not - the first word of the PLT entry. */ -#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result)) - /* Nonzero iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ #define elf_machine_lookup_noexec_p(type) ((type) == R_PPC_COPY) @@ -413,7 +408,7 @@ static ElfW(Addr) _dl_preferred_address = 1 (type) == R_PPC_JMP_SLOT) /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ -#define ELF_MACHINE_RELOC_NOPLT R_PPC_JMP_SLOT +#define ELF_MACHINE_JMP_SLOT R_PPC_JMP_SLOT /* Nonzero iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. */ @@ -554,6 +549,70 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc) /* elf_machine_runtime_setup handles this. */ } +static inline void +elf_machine_fixup_plt(struct link_map *map, const Elf32_Rela *reloc, + Elf32_Addr *reloc_addr, Elf32_Addr finaladdr) +{ + Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr; + if (delta << 6 >> 6 == delta) + *reloc_addr = OPCODE_B (delta); + else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000) + *reloc_addr = OPCODE_BA (finaladdr); + else + { + Elf32_Word *plt; + Elf32_Word index; + + plt = (Elf32_Word *)((char *)map->l_addr + + map->l_info[DT_PLTGOT]->d_un.d_val); + index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2; + if (index >= PLT_DOUBLE_SIZE) + { + /* Slots greater than or equal to 2^13 have 4 words available + instead of two. */ + /* FIXME: There are some possible race conditions in this code, + when called from 'fixup'. + + 1) Suppose that a lazy PLT entry is executing, a context switch + between threads (or a signal) occurs, and the new thread or + signal handler calls the same lazy PLT entry. Then the PLT entry + would be changed while it's being run, which will cause a segfault + (almost always). + + 2) Suppose the reverse: that a lazy PLT entry is being updated, + a context switch occurs, and the new code calls the lazy PLT + entry that is being updated. Then the half-fixed PLT entry will + be executed, which will also almost always cause a segfault. + + These problems don't happen with the 2-word entries, because + only one of the two instructions are changed when a lazy entry + is retargeted at the actual PLT entry; the li instruction stays + the same (we have to update it anyway, because we might not be + updating a lazy PLT entry). */ + + reloc_addr[0] = OPCODE_LI (11, finaladdr); + reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16); + reloc_addr[2] = OPCODE_MTCTR (11); + reloc_addr[3] = OPCODE_BCTR (); + } + else + { + Elf32_Word num_plt_entries; + + num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val + / sizeof(Elf32_Rela)); + + plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr; + reloc_addr[0] = OPCODE_LI (11, index*4); + reloc_addr[1] = OPCODE_B (-(4*(index*2 + + 1 + - PLT_LONGBRANCH_ENTRY_WORDS + + PLT_INITIAL_ENTRY_WORDS))); + } + } + MODIFIED_CODE (reloc_addr); +} + #endif /* dl_machine_h */ #ifdef RESOLVE @@ -674,66 +733,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, } else if (rinfo == R_PPC_JMP_SLOT) { - Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr; - if (delta << 6 >> 6 == delta) - *reloc_addr = OPCODE_B (delta); - else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000) - *reloc_addr = OPCODE_BA (finaladdr); - else - { - Elf32_Word *plt; - Elf32_Word index; - - plt = (Elf32_Word *)((char *)map->l_addr - + map->l_info[DT_PLTGOT]->d_un.d_val); - index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2; - if (index >= PLT_DOUBLE_SIZE) - { - /* Slots greater than or equal to 2^13 have 4 words available - instead of two. */ - /* FIXME: There are some possible race conditions in this code, - when called from 'fixup'. - - 1) Suppose that a lazy PLT entry is executing, a - context switch between threads (or a signal) occurs, - and the new thread or signal handler calls the same - lazy PLT entry. Then the PLT entry would be changed - while it's being run, which will cause a segfault - (almost always). - - 2) Suppose the reverse: that a lazy PLT entry is - being updated, a context switch occurs, and the new - code calls the lazy PLT entry that is being updated. - Then the half-fixed PLT entry will be executed, which - will also almost always cause a segfault. - - These problems don't happen with the 2-word entries, because - only one of the two instructions are changed when a lazy - entry is retargeted at the actual PLT entry; the li - instruction stays the same (we have to update it anyway, - because we might not be updating a lazy PLT entry). */ - reloc_addr[0] = OPCODE_LI (11, finaladdr); - reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16); - reloc_addr[2] = OPCODE_MTCTR (11); - reloc_addr[3] = OPCODE_BCTR (); - } - else - { - Elf32_Word num_plt_entries; - - num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val - / sizeof(Elf32_Rela)); - - plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr; - reloc_addr[0] = OPCODE_LI (11, index*4); - reloc_addr[1] = - OPCODE_B (-(4*(index*2 - + 1 - - PLT_LONGBRANCH_ENTRY_WORDS - + PLT_INITIAL_ENTRY_WORDS))); - } - } - MODIFIED_CODE (reloc_addr); + elf_machine_fixup_plt (map, reloc, reloc_addr, finalvalue); } else { -- cgit v1.2.3