diff options
author | Andreas Schwab <schwab@redhat.com> | 2009-08-24 10:15:51 +0200 |
---|---|---|
committer | Andreas Schwab <schwab@redhat.com> | 2009-08-24 10:15:51 +0200 |
commit | 255acd161cc2d7752a4e79234dcba5d929c3e0a4 (patch) | |
tree | 94c1d111cce2137ee948ff0e9d735f7a3643ef78 /sysdeps | |
parent | 593eff0f9e5bed517e0a8434507ee9f3f4d45b87 (diff) | |
parent | a0e25a886a9128b280b4c05bc9c6dd12377ea868 (diff) | |
download | glibc-255acd161cc2d7752a4e79234dcba5d929c3e0a4.tar.gz glibc-255acd161cc2d7752a4e79234dcba5d929c3e0a4.tar.xz glibc-255acd161cc2d7752a4e79234dcba5d929c3e0a4.zip |
Merge commit 'origin/master' into fedora/master
Conflicts: sysdeps/powerpc/powerpc64/____longjmp_chk.S sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/elf/backtracesyms.c | 71 | ||||
-rw-r--r-- | sysdeps/generic/elf/backtracesymsfd.c | 58 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/__longjmp-common.S | 15 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S | 15 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S (renamed from sysdeps/powerpc/powerpc32/____longjmp_chk.S) | 33 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S (renamed from sysdeps/powerpc/powerpc64/____longjmp_chk.S) | 30 |
6 files changed, 152 insertions, 70 deletions
diff --git a/sysdeps/generic/elf/backtracesyms.c b/sysdeps/generic/elf/backtracesyms.c index b31be6ac5d..319b207605 100644 --- a/sysdeps/generic/elf/backtracesyms.c +++ b/sysdeps/generic/elf/backtracesyms.c @@ -1,5 +1,5 @@ /* Return list with names for address in backtrace. - Copyright (C) 1998,1999,2000,2001,2003 Free Software Foundation, Inc. + Copyright (C) 1998,1999,2000,2001,2003,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -48,15 +48,22 @@ __backtrace_symbols (array, size) /* Fill in the information we can get from `dladdr'. */ for (cnt = 0; cnt < size; ++cnt) { - status[cnt] = _dl_addr (array[cnt], &info[cnt], NULL, NULL); + struct link_map *map; + status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL); if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0') - /* We have some info, compute the length of the string which will be - "<file-name>(<sym-name>) [+offset]. */ - total += (strlen (info[cnt].dli_fname ?: "") - + (info[cnt].dli_sname - ? strlen (info[cnt].dli_sname) + 3 + WORD_WIDTH + 3 - : 1) - + WORD_WIDTH + 5); + { + /* We have some info, compute the length of the string which will be + "<file-name>(<sym-name>+offset) [address]. */ + total += (strlen (info[cnt].dli_fname ?: "") + + strlen (info[cnt].dli_sname ?: "") + + 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5); + + /* The load bias is more useful to the user than the load + address. The use of these addresses is to calculate an + address in the ELF file, so its prelinked bias is not + something we want to subtract out. */ + info[cnt].dli_fbase = (void *) map->l_addr; + } else total += 5 + WORD_WIDTH; } @@ -71,25 +78,39 @@ __backtrace_symbols (array, size) { result[cnt] = last; - if (status[cnt] && info[cnt].dli_fname - && info[cnt].dli_fname[0] != '\0') + if (status[cnt] + && info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0') { - char buf[20]; + if (info[cnt].dli_sname == NULL) + /* We found no symbol name to use, so describe it as + relative to the file. */ + info[cnt].dli_saddr = info[cnt].dli_fbase; - if (array[cnt] >= (void *) info[cnt].dli_saddr) - sprintf (buf, "+%#lx", - (unsigned long)(array[cnt] - info[cnt].dli_saddr)); + if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0) + last += 1 + sprintf (last, "%s(%s) [%p]", + info[cnt].dli_fname ?: "", + info[cnt].dli_sname ?: "", + array[cnt]); else - sprintf (buf, "-%#lx", - (unsigned long)(info[cnt].dli_saddr - array[cnt])); - - last += 1 + sprintf (last, "%s%s%s%s%s[%p]", - info[cnt].dli_fname ?: "", - info[cnt].dli_sname ? "(" : "", - info[cnt].dli_sname ?: "", - info[cnt].dli_sname ? buf : "", - info[cnt].dli_sname ? ") " : " ", - array[cnt]); + { + char sign; + ptrdiff_t offset; + if (array[cnt] >= (void *) info[cnt].dli_saddr) + { + sign = '+'; + offset = array[cnt] - info[cnt].dli_saddr; + } + else + { + sign = '-'; + offset = info[cnt].dli_saddr - array[cnt]; + } + + last += 1 + sprintf (last, "%s(%s%c%#tx) [%p]", + info[cnt].dli_fname ?: "", + info[cnt].dli_sname ?: "", + sign, offset, array[cnt]); + } } else last += 1 + sprintf (last, "[%p]", array[cnt]); diff --git a/sysdeps/generic/elf/backtracesymsfd.c b/sysdeps/generic/elf/backtracesymsfd.c index 6754d145b0..f0ab71587f 100644 --- a/sysdeps/generic/elf/backtracesymsfd.c +++ b/sysdeps/generic/elf/backtracesymsfd.c @@ -1,5 +1,5 @@ /* Write formatted list with names for addresses in backtrace to a file. - Copyright (C) 1998, 2000, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 1998,2000,2003,2005,2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -46,47 +46,63 @@ __backtrace_symbols_fd (array, size, fd) { char buf[WORD_WIDTH]; Dl_info info; + struct link_map *map; size_t last = 0; - if (_dl_addr (array[cnt], &info, NULL, NULL) - && info.dli_fname && info.dli_fname[0] != '\0') + if (_dl_addr (array[cnt], &info, &map, NULL) + && info.dli_fname != NULL && info.dli_fname[0] != '\0') { /* Name of the file. */ iov[0].iov_base = (void *) info.dli_fname; iov[0].iov_len = strlen (info.dli_fname); last = 1; - /* Symbol name. */ - if (info.dli_sname != NULL) + if (info.dli_sname != NULL || map->l_addr != 0) { char buf2[WORD_WIDTH]; size_t diff; - iov[1].iov_base = (void *) "("; - iov[1].iov_len = 1; - iov[2].iov_base = (void *) info.dli_sname; - iov[2].iov_len = strlen (info.dli_sname); + iov[last].iov_base = (void *) "("; + iov[last].iov_len = 1; + ++last; + + if (info.dli_sname != NULL) + { + /* We have a symbol name. */ + iov[last].iov_base = (void *) info.dli_sname; + iov[last].iov_len = strlen (info.dli_sname); + ++last; + } + else + /* We have no symbol, so describe it as relative to the file. + The load bias is more useful to the user than the load + address. The use of these addresses is to calculate an + address in the ELF file, so its prelinked bias is not + something we want to subtract out. */ + info.dli_saddr = (void *) map->l_addr; if (array[cnt] >= (void *) info.dli_saddr) { - iov[3].iov_base = (void *) "+0x"; + iov[last].iov_base = (void *) "+0x"; diff = array[cnt] - info.dli_saddr; } else { - iov[3].iov_base = (void *) "-0x"; + iov[last].iov_base = (void *) "-0x"; diff = info.dli_saddr - array[cnt]; } - iov[3].iov_len = 3; - - iov[4].iov_base = _itoa_word ((unsigned long int) diff, - &buf2[WORD_WIDTH], 16, 0); - iov[4].iov_len = &buf2[WORD_WIDTH] - (char *) iov[4].iov_base; - - iov[5].iov_base = (void *) ")"; - iov[5].iov_len = 1; - - last = 6; + iov[last].iov_len = 3; + ++last; + + iov[last].iov_base = _itoa_word ((unsigned long int) diff, + &buf2[WORD_WIDTH], 16, 0); + iov[last].iov_len = (&buf2[WORD_WIDTH] + - (char *) iov[last].iov_base); + ++last; + + iov[last].iov_base = (void *) ")"; + iov[last].iov_len = 1; + ++last; } } diff --git a/sysdeps/powerpc/powerpc32/__longjmp-common.S b/sysdeps/powerpc/powerpc32/__longjmp-common.S index 7b1c017837..955161ef2b 100644 --- a/sysdeps/powerpc/powerpc32/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc32/__longjmp-common.S @@ -33,6 +33,13 @@ ENTRY (BP_SYM (__longjmp)) #if defined PTR_DEMANGLE || defined CHECK_SP lwz r24,(JB_GPR1*4)(r3) +# ifdef CHECK_SP +# ifdef PTR_DEMANGLE + PTR_DEMANGLE3 (r24, r24, r25) +# endif + CHECK_SP (r24) + mr r1,r24 +# endif #else lwz r1,(JB_GPR1*4)(r3) #endif @@ -45,17 +52,11 @@ ENTRY (BP_SYM (__longjmp)) lwz r19,((JB_GPRS+5)*4)(r3) lwz r20,((JB_GPRS+6)*4)(r3) #ifdef PTR_DEMANGLE -# ifdef CHECK_SP - PTR_DEMANGLE3 (r24, r24, r25) -# else +# ifndef CHECK_SP PTR_DEMANGLE3 (r1, r24, r25) # endif PTR_DEMANGLE2 (r0, r25) #endif -#ifdef CHECK_SP - CHECK_SP (r24) - mr r1,r24 -#endif mtlr r0 lwz r21,((JB_GPRS+7)*4)(r3) lwz r22,((JB_GPRS+8)*4)(r3) diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S index f105815b9c..04ed6da68b 100644 --- a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S @@ -116,6 +116,13 @@ L(no_vmx): #endif #if defined PTR_DEMANGLE || defined CHECK_SP lwz r24,(JB_GPR1*4)(r3) +# ifdef CHECK_SP +# ifdef PTR_DEMANGLE + PTR_DEMANGLE3 (r24, r24, r25) +# endif + CHECK_SP (r24) + mr r1,r24 +# endif #else lwz r1,(JB_GPR1*4)(r3) #endif @@ -135,17 +142,11 @@ L(no_vmx): lwz r20,((JB_GPRS+6)*4)(r3) lfd fp20,((JB_FPRS+6*2)*4)(r3) #ifdef PTR_DEMANGLE -# ifdef CHECK_SP - PTR_DEMANGLE3 (r24, r24, r25) -# else +# ifndef CHECK_SP PTR_DEMANGLE3 (r1, r24, r25) # endif PTR_DEMANGLE2 (r0, r25) #endif -#ifdef CHECK_SP - CHECK_SP (r24) - mr r1,r24 -#endif mtlr r0 lwz r21,((JB_GPRS+7)*4)(r3) lfd fp21,((JB_FPRS+7*2)*4)(r3) diff --git a/sysdeps/powerpc/powerpc32/____longjmp_chk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S index 128899a532..4cb968505d 100644 --- a/sysdeps/powerpc/powerpc32/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/____longjmp_chk.S @@ -19,7 +19,8 @@ #include <sysdep.h> #include <rtld-global-offsets.h> - .section .rodata.str1.1,"aMS",@progbits,1 + .section .rodata.str1.4,"aMS",@progbits,1 + .align 2 .LC0: .string "longjmp causes uninitialized stack frame" .text @@ -49,15 +50,35 @@ #define CHECK_SP(reg) \ cmplw reg, r1; \ bge+ .Lok; \ - cfi_remember_state; \ mflr r0; \ - stwu r1,-16(r1); \ - cfi_adjust_cfa_offset (16); \ - stw r0,20(r1); \ + stwu r1,-32(r1); \ + cfi_remember_state; \ + cfi_adjust_cfa_offset (32); \ + stw r0,36(r1); \ cfi_offset (lr, 4); \ + mr r31,r3; \ + mr r30,r4; \ + li r3,0; \ + addi r4,r1,8; \ + li r0,__NR_sigaltstack; \ + sc; \ + /* Without working sigaltstack we cannot perform the test. */ \ + bso .Lok2; \ + lwz r0,12(r1); \ + andi. r3,r0,1; \ + beq .Lfail; \ + lwz r0,16(r1); \ + lwz r3,8(r1); \ + add r3,r3,r0; \ + sub r3,r3,reg; \ + cmplw r3,r0; \ + bge+ .Lok2; \ +.Lfail: \ LOAD_ARG; \ bl HIDDEN_JUMPTARGET (__fortify_fail); \ - nop; \ +.Lok2: \ + mr r3,r31; \ + mr r4,r30; \ cfi_restore_state; \ .Lok: diff --git a/sysdeps/powerpc/powerpc64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S index f1b7d85e46..936ace5f69 100644 --- a/sysdeps/powerpc/powerpc64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S @@ -19,7 +19,8 @@ #include <sysdep.h> #include <rtld-global-offsets.h> - .section .rodata.str1.1,"aMS",@progbits,1 + .section .rodata.str1.8,"aMS",@progbits,1 + .align 3 .LC0: .string "longjmp causes uninitialized stack frame" .section .toc,"aw" @@ -32,15 +33,36 @@ #define CHECK_SP(reg) \ cmpld reg, r1; \ bge+ .Lok; \ - cfi_remember_state; \ mflr r0; \ std r0,16(r1); \ - stdu r1,-112(r1); \ - cfi_adjust_cfa_offset (112); \ + mr r31,r3; \ + mr r30,r4; \ + stdu r1,-144(r1); \ + cfi_remember_state; \ + cfi_adjust_cfa_offset (144); \ cfi_offset (lr, 16); \ + li r3,0; \ + addi r4,r1,112; \ + li r0,__NR_sigaltstack; \ + sc; \ + /* Without working sigaltstack we cannot perform the test. */ \ + bso .Lok2; \ + lwz r0,112+8(r1); \ + andi. r4,r0,1; \ + beq .Lfail; \ + ld r0,112+16(r1); \ + ld r4,112(r1); \ + add r4,r4,r0; \ + sub r3,r3,reg; \ + cmpld r3,r0; \ + bge+ .Lok2; \ +.Lfail: \ ld r3,.LC1@toc(2); \ bl HIDDEN_JUMPTARGET (__fortify_fail); \ nop; \ +.Lok2: \ + mr r3,r31; \ + mr r4,r30; \ cfi_restore_state; \ .Lok: |