This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[rfc] anti-plt patch for division routines
- From: Richard Henderson <rth at twiddle dot net>
- To: libc-alpha at sources dot redhat dot com
- Date: Mon, 24 Jan 2005 13:08:08 -0800
- Subject: [rfc] anti-plt patch for division routines
Not a patch that should be applied as-is, but looking for comments.
Rather than use a DYNAMIC table entry, I thought a PT_NOTE entry
would be just as easy, and would work with all existing toolchains.
Of the things that Aren't Quite Right include,
(1) abi-note.S ought not be changed. The correct place for this
new note seems to be crti.o, since that's included in both
executables and shared libraries. I stuck it here for now
because that's what's included when the testsuite is run.
We do not link against csu/crt[in].o, which is arguably a bug.
(2) You probably don't like the generic Makerules change, though
that should be completely harmless for other systems. I'm not
sure how to approach making such a change genercially...
(3) Ought to add ".type foo,@funcnoplt" to the assembler and whatnot.
Leaving these routines marked as @object seems nasty. That would
need toolchain changes, and thus configury hacking.
(4) Numbering of ELF_NOTE_ALPHA_DIVNOPLT. A possibility that just
ocurred to me for namespace nicities is (EM_FOO << 16 | number).
Which sorta fits with the one number that we've already got.
Alternately, I could use "GNUALPHA" or something as the note name,
but that's not a convenient 4 byte scalar...
(5) Setting DF_1_NOW is a rather large sledgehammer and might easily
break applications that rely on lazy binding to work (because they
have undefined symbols or somesuch). Another possibility is to set
a bit in the link_map (surely I can find one unused that wouldn't
impact other targets), and check each symbol in elf_machine_lazy_rel
by name for the 8 division routines, and somehow force them to be
fixed up then.
Thoughts?
r~
* Makerules (shlib.lds): Position .note.alpha.divnoplt.
* csu/abi-note.S: Move...
* sysdeps/generic/abi-note.S: ... here.
* elf/elf.h (ELF_NOTE_ALPHA_DIVNOPLT): New.
* sysdeps/alpha/div_libc.h (DIV_FUNC_TYPE, PROTECTED): New.
* sysdeps/alpha/divl.S, sysdeps/alpha/divq.S, sysdeps/alpha/divqu.S,
sysdeps/alpha/reml.S, sysdeps/alpha/remq.S, sysdeps/alpha/remqu.S:
Use them.
* sysdeps/alpha/dl-trampoline.S: Don't save anything but C
argument registers.
* sysdeps/alpha/elf/initfini.c: Add .note.alpha.divnoplt.
* sysdeps/alpha/abi-note.S: New.
linuxthreads/
* sysdeps/alpha/elf/pt-initfini.c: Add .note.alpha.divnoplt.
nptl/
* sysdeps/alpha/elf/pt-initfini.c: Add .note.alpha.divnoplt.
Index: Makerules
===================================================================
RCS file: /cvs/glibc/libc/Makerules,v
retrieving revision 1.425
diff -c -p -d -r1.425 Makerules
*** Makerules 15 Dec 2004 18:52:39 -0000 1.425
--- Makerules 24 Jan 2005 20:43:22 -0000
*************** $(common-objpfx)shlib.lds: $(common-objp
*** 486,492 ****
-Wl,--verbose 2>&1 | \
sed > $@T \
-e '/^=========/,/^=========/!d;/^=========/d' \
! -e 's/^.*\.hash[ ]*:.*$$/ .note.ABI-tag : { *(.note.ABI-tag) } &/' \
-e 's/^.*\*(\.dynbss).*$$/& \
PROVIDE(__start___libc_freeres_ptrs = .); \
*(__libc_freeres_ptrs) \
--- 486,492 ----
-Wl,--verbose 2>&1 | \
sed > $@T \
-e '/^=========/,/^=========/!d;/^=========/d' \
! -e 's/^.*\.hash[ ]*:.*$$/ .note.ABI-tag : { *(.note.ABI-tag) } .note.alpha.divnoplt : { *(.note.alpha.divnoplt) } &/' \
-e 's/^.*\*(\.dynbss).*$$/& \
PROVIDE(__start___libc_freeres_ptrs = .); \
*(__libc_freeres_ptrs) \
Index: csu/abi-note.S
===================================================================
RCS file: csu/abi-note.S
diff -N csu/abi-note.S
*** csu/abi-note.S 10 Dec 2002 05:09:56 -0000 1.7
--- /dev/null 1 Jan 1970 00:00:00 -0000
***************
*** 1,73 ****
- /* Special .init and .fini section support.
- Copyright (C) 1997, 2001, 2002 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- In addition to the permissions in the GNU Lesser General Public
- License, the Free Software Foundation gives you unlimited
- permission to link the compiled version of this file with other
- programs, and to distribute those programs without any restriction
- coming from the use of this file. (The Lesser General Public
- License restrictions do apply in other respects; for example, they
- cover modification of the file, and distribution when not linked
- into another program.)
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
- /* Define an ELF note identifying the operating-system ABI that the
- executable was created for. The ELF note information identifies a
- particular OS or coordinated development effort within which the
- ELF header's e_machine value plus (for dynamically linked programs)
- the PT_INTERP dynamic linker name and DT_NEEDED shared library
- names fully identify the runtime environment required by an
- executable.
-
- The general format of ELF notes is as follows.
- Offsets and lengths are bytes or (parenthetical references) to the
- values in other fields.
-
- offset length contents
- 0 4 length of name
- 4 4 length of data
- 8 4 note type
- 12 (0) vendor name
- - null-terminated ASCII string, padded to 4-byte alignment
- 12+(0) (4) note data,
-
- The GNU project and cooperating development efforts (including the
- Linux community) use note type 1 and a vendor name string of "GNU"
- for a note descriptor that indicates ABI requirements. The note data
- is four 32-bit words. The first of these is an operating system
- number (0=Linux, 1=Hurd, 2=Solaris, ...) and the remaining three
- identify the earliest release of that OS that supports this ABI.
- See abi-tags (top level) for details. */
-
- #include <config.h>
- #include <abi-tag.h> /* OS-specific ABI tag value */
-
- /* The linker (GNU ld 2.8 and later) recognizes an allocated section whose
- name begins with `.note' and creates a PT_NOTE program header entry
- pointing at it. */
-
- .section ".note.ABI-tag", "a"
- .p2align 2
- .long 1f - 0f /* name length */
- .long 3f - 2f /* data length */
- .long 1 /* note type */
- 0: .asciz "GNU" /* vendor name */
- 1: .p2align 2
- 2: .long __ABI_TAG_OS /* note data: the ABI tag */
- .long __ABI_TAG_VERSION
- 3: .p2align 2 /* pad out section */
--- 0 ----
Index: elf/elf.h
===================================================================
RCS file: /cvs/glibc/libc/elf/elf.h,v
retrieving revision 1.143
diff -c -p -d -r1.143 elf.h
*** elf/elf.h 12 Nov 2004 21:51:33 -0000 1.143
--- elf/elf.h 24 Jan 2005 20:43:23 -0000
*************** typedef struct
*** 1012,1017 ****
--- 1012,1019 ----
*/
#define ELF_NOTE_ABI 1
+ #define ELF_NOTE_ALPHA_DIVNOPLT 0x10001
+
/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI
note section entry. */
#define ELF_NOTE_OS_LINUX 0
Index: linuxthreads/sysdeps/alpha/elf/pt-initfini.c
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/alpha/elf/pt-initfini.c,v
retrieving revision 1.4
diff -c -p -d -r1.4 pt-initfini.c
*** linuxthreads/sysdeps/alpha/elf/pt-initfini.c 10 Dec 2003 05:46:41 -0000 1.4
--- linuxthreads/sysdeps/alpha/elf/pt-initfini.c 24 Jan 2005 20:43:24 -0000
*************** _init: \n\
*** 55,60 ****
--- 55,69 ----
jsr $26, __pthread_initialize_minimal \n\
ldq $29, 8($30) \n\
.align 3 \n\
+ .section .note.alpha.divnoplt, \"a\", @note \n\
+ .p2align 2 \n\
+ .long 1f-0f /* name length */ \n\
+ .long 3f-2f /* data length */ \n\
+ .long 0x10001 /* note type */ \n\
+ 0: .asciz \"GNU\" /* vendor name */ \n\
+ 1: .p2align 2 \n\
+ 2: .long 0 /* note data unused */ \n\
+ 3: .p2align 2 \n\
/*@_init_PROLOG_ENDS*/ \n\
\n\
/*@_init_EPILOG_BEGINS*/ \n\
Index: nptl/sysdeps/alpha/elf/pt-initfini.c
===================================================================
RCS file: /cvs/glibc/libc/nptl/sysdeps/alpha/elf/pt-initfini.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 pt-initfini.c
*** nptl/sysdeps/alpha/elf/pt-initfini.c 8 Jul 2003 03:41:53 -0000 1.2
--- nptl/sysdeps/alpha/elf/pt-initfini.c 24 Jan 2005 20:43:25 -0000
*************** _init: \n\
*** 54,59 ****
--- 54,68 ----
stq $29, 8($30) \n\
bsr $26, __pthread_initialize_minimal_internal !samegp \n\
.align 3 \n\
+ .section .note.alpha.divnoplt, \"a\", @note \n\
+ .p2align 2 \n\
+ .long 1f-0f /* name length */ \n\
+ .long 3f-2f /* data length */ \n\
+ .long 0x10001 /* note type */ \n\
+ 0: .asciz \"GNU\" /* vendor name */ \n\
+ 1: .p2align 2 \n\
+ 2: .long 0 /* note data unused */ \n\
+ 3: .p2align 2 \n\
/*@_init_PROLOG_ENDS*/ \n\
\n\
/*@_init_EPILOG_BEGINS*/ \n\
Index: sysdeps/alpha/abi-note.S
===================================================================
RCS file: sysdeps/alpha/abi-note.S
diff -N sysdeps/alpha/abi-note.S
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- sysdeps/alpha/abi-note.S 24 Jan 2005 20:43:26 -0000
***************
*** 0 ****
--- 1,43 ----
+ /* Special .init and .fini section support.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ /* Add the generic ABI note. */
+ #include <sysdeps/generic/abi-note.S>
+
+ /* Indicate that the module has been linked against a libc that prevents
+ the creation of a PLT for the special linkage division routines. */
+
+ .section .note.alpha.divnoplt, "a", @note
+ .p2align 2
+ .long 1f-0f /* name length */
+ .long 3f-2f /* data length */
+ .long 0x10001 /* note type */
+ 0: .asciz "GNU" /* vendor name */
+ 1: .p2align 2
+ 2: .long 0 /* note data unused */
+ 3: .p2align 2
Index: sysdeps/alpha/div_libc.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/div_libc.h,v
retrieving revision 1.4
diff -c -p -d -r1.4 div_libc.h
*** sysdeps/alpha/div_libc.h 6 Sep 2004 02:01:35 -0000 1.4
--- sysdeps/alpha/div_libc.h 24 Jan 2005 20:43:26 -0000
***************
*** 26,31 ****
--- 26,45 ----
# include <machine/pal.h>
#endif
+ /* We don't use @function because we don't want the linker to create a plt
+ for this symbol. Detect support for @funcnoplt. */
+ #define DIV_FUNC_TYPE @object
+
+ /* We can't play symbol renaming games with the division routines, because
+ that symbol is embedded explicitly into the compiler. Normal caveats
+ against using protected visibility do not apply, since we prevent the
+ creation of plt entries in the first place. */
+ #ifdef PIC
+ #define PROTECTED(x) .protected x
+ #else
+ #define PROTECTED(x)
+ #endif
+
/* These are not normal C functions. Argument registers are t10 and t11;
the result goes in t12; the return address is in t9. Only t12 and AT
may be clobbered. */
Index: sysdeps/alpha/divl.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/divl.S,v
retrieving revision 1.8
diff -c -p -d -r1.8 divl.S
*** sysdeps/alpha/divl.S 6 Sep 2004 02:01:35 -0000 1.8
--- sysdeps/alpha/divl.S 24 Jan 2005 20:43:26 -0000
***************
*** 36,42 ****
.text
.align 4
.globl __divl
! .type __divl, @function
.usepv __divl, no
cfi_startproc
--- 36,43 ----
.text
.align 4
.globl __divl
! PROTECTED (__divl)
! .type __divl, DIV_FUNC_TYPE
.usepv __divl, no
cfi_startproc
Index: sysdeps/alpha/divq.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/divq.S,v
retrieving revision 1.9
diff -c -p -d -r1.9 divq.S
*** sysdeps/alpha/divq.S 6 Sep 2004 02:01:35 -0000 1.9
--- sysdeps/alpha/divq.S 24 Jan 2005 20:43:27 -0000
***************
*** 43,49 ****
.text
.align 4
.globl __divq
! .type __divq, @function
.usepv __divq, no
cfi_startproc
--- 43,50 ----
.text
.align 4
.globl __divq
! PROTECTED (__divq)
! .type __divq, DIV_FUNC_TYPE
.usepv __divq, no
cfi_startproc
Index: sysdeps/alpha/divqu.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/divqu.S,v
retrieving revision 1.8
diff -c -p -d -r1.8 divqu.S
*** sysdeps/alpha/divqu.S 6 Sep 2004 02:01:35 -0000 1.8
--- sysdeps/alpha/divqu.S 24 Jan 2005 20:43:27 -0000
***************
*** 43,49 ****
.text
.align 4
.globl __divqu
! .type __divqu, @function
.usepv __divqu, no
cfi_startproc
--- 43,50 ----
.text
.align 4
.globl __divqu
! PROTECTED (__divqu)
! .type __divqu, DIV_FUNC_TYPE
.usepv __divqu, no
cfi_startproc
Index: sysdeps/alpha/dl-machine.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/dl-machine.h,v
retrieving revision 1.79
diff -c -p -d -r1.79 dl-machine.h
*** sysdeps/alpha/dl-machine.h 23 Jan 2005 08:02:34 -0000 1.79
--- sysdeps/alpha/dl-machine.h 24 Jan 2005 20:43:27 -0000
*************** elf_machine_runtime_setup (struct link_m
*** 152,157 ****
--- 152,179 ----
++rela;
}
}
+
+ /* Look for a PT_NOTE section with ELF_NOTE_ALPHA_DIVNOPLT. If not
+ present, then we'll need to suppress lazy binding for this module. */
+ {
+ Elf64_Phdr *phdr = l->l_phdr;
+ Elf64_Half i, phnum = l->l_phnum;
+
+ for (i = 0; i < phnum; ++i)
+ if (phdr->p_type == PT_NOTE)
+ {
+ Elf64_Nhdr *nhdr = phdr->p_vaddr;
+ if (nhdr->n_type == ELF_NOTE_ALPHA_DIVNOPLT
+ && nhdr->n_namesz == 4
+ /* ??? Would be nice if gcc would optimize this memcmp
+ on strict-alignment machines when alignment known. */
+ && *(unsigned int *)(nhdr + 1) == 'G'+('N'<<8)|('U'<<16))
+ goto found_divnoplt;
+ }
+ l->l_flags_1 |= DF_1_NOW;
+ found_divnoplt:
+ ;
+ }
}
return lazy;
Index: sysdeps/alpha/dl-trampoline.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/dl-trampoline.S,v
retrieving revision 1.1
diff -c -p -d -r1.1 dl-trampoline.S
*** sysdeps/alpha/dl-trampoline.S 23 Jan 2005 08:02:35 -0000 1.1
--- sysdeps/alpha/dl-trampoline.S 24 Jan 2005 20:43:27 -0000
***************
*** 21,86 ****
.set noat
.globl _dl_runtime_resolve
.ent _dl_runtime_resolve
!
! #undef FRAMESIZE
! #define FRAMESIZE 44*8
_dl_runtime_resolve:
lda $30, -FRAMESIZE($30)
.frame $30, FRAMESIZE, $26
! /* Preserve all registers that C normally doesn't. */
stq $26, 0*8($30)
! stq $0, 1*8($30)
! stq $1, 2*8($30)
! stq $2, 3*8($30)
! stq $3, 4*8($30)
! stq $4, 5*8($30)
! stq $5, 6*8($30)
! stq $6, 7*8($30)
! stq $7, 8*8($30)
! stq $8, 9*8($30)
! stq $16, 10*8($30)
! stq $17, 11*8($30)
! stq $18, 12*8($30)
! stq $19, 13*8($30)
! stq $20, 14*8($30)
! stq $21, 15*8($30)
! stq $22, 16*8($30)
! stq $23, 17*8($30)
! stq $24, 18*8($30)
! stq $25, 19*8($30)
! stq $29, 20*8($30)
! stt $f0, 21*8($30)
! stt $f1, 22*8($30)
! stt $f10, 23*8($30)
! stt $f11, 24*8($30)
! stt $f12, 25*8($30)
! stt $f13, 26*8($30)
! stt $f14, 27*8($30)
! stt $f15, 28*8($30)
! stt $f16, 29*8($30)
! stt $f17, 30*8($30)
! stt $f18, 31*8($30)
! stt $f19, 32*8($30)
! stt $f20, 33*8($30)
! stt $f21, 34*8($30)
! stt $f22, 35*8($30)
! stt $f23, 36*8($30)
! stt $f24, 37*8($30)
! stt $f25, 38*8($30)
! stt $f26, 39*8($30)
! stt $f27, 40*8($30)
! stt $f28, 41*8($30)
! stt $f29, 42*8($30)
! stt $f30, 43*8($30)
! .mask 0x27ff01ff, -FRAMESIZE
! .fmask 0xfffffc03, -FRAMESIZE+21*8
/* Set up our GP. */
br $29, .+4
! ldgp $29, 0($29)
! .prologue 0
/* Set up the arguments for _dl_fixup:
$16 = link_map out of plt0
$17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
--- 21,57 ----
.set noat
+ #undef FRAMESIZE
+ #define FRAMESIZE 14*8
+
.globl _dl_runtime_resolve
.ent _dl_runtime_resolve
! .align 4
_dl_runtime_resolve:
lda $30, -FRAMESIZE($30)
.frame $30, FRAMESIZE, $26
! /* Preserve C argument registers. */
stq $26, 0*8($30)
! stq $16, 1*8($30)
! stq $17, 2*8($30)
! stq $18, 3*8($30)
! stq $19, 4*8($30)
! stq $20, 5*8($30)
! stq $21, 6*8($30)
! stt $f16, 7*8($30)
! stt $f17, 8*8($30)
! stt $f18, 9*8($30)
! stt $f19, 10*8($30)
! stt $f20, 11*8($30)
! stt $f21, 12*8($30)
! .mask 0x04000000, -FRAMESIZE
! .prologue 0
!
/* Set up our GP. */
br $29, .+4
! ldah $29, 0($29) !gpdisp!1
!
/* Set up the arguments for _dl_fixup:
$16 = link_map out of plt0
$17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24
*************** _dl_runtime_resolve:
*** 89,232 ****
subq $28, $27, $17
ldq $16, 8($27)
subq $17, 20, $17
mov $26, $18
addq $17, $17, $17
bsr $26, _dl_fixup !samegp
/* Move the destination address into position. */
mov $0, $27
! /* Restore program registers. */
ldq $26, 0*8($30)
! ldq $0, 1*8($30)
! ldq $1, 2*8($30)
! ldq $2, 3*8($30)
! ldq $3, 4*8($30)
! ldq $4, 5*8($30)
! ldq $5, 6*8($30)
! ldq $6, 7*8($30)
! ldq $7, 8*8($30)
! ldq $8, 9*8($30)
! ldq $16, 10*8($30)
! ldq $17, 11*8($30)
! ldq $18, 12*8($30)
! ldq $19, 13*8($30)
! ldq $20, 14*8($30)
! ldq $21, 15*8($30)
! ldq $22, 16*8($30)
! ldq $23, 17*8($30)
! ldq $24, 18*8($30)
! ldq $25, 19*8($30)
! ldq $29, 20*8($30)
! ldt $f0, 21*8($30)
! ldt $f1, 22*8($30)
! ldt $f10, 23*8($30)
! ldt $f11, 24*8($30)
! ldt $f12, 25*8($30)
! ldt $f13, 26*8($30)
! ldt $f14, 27*8($30)
! ldt $f15, 28*8($30)
! ldt $f16, 29*8($30)
! ldt $f17, 30*8($30)
! ldt $f18, 31*8($30)
! ldt $f19, 32*8($30)
! ldt $f20, 33*8($30)
! ldt $f21, 34*8($30)
! ldt $f22, 35*8($30)
! ldt $f23, 36*8($30)
! ldt $f24, 37*8($30)
! ldt $f25, 38*8($30)
! ldt $f26, 39*8($30)
! ldt $f27, 40*8($30)
! ldt $f28, 41*8($30)
! ldt $f29, 42*8($30)
! ldt $f30, 43*8($30)
/* Flush the Icache after having modified the .plt code. */
imb
/* Clean up and turn control to the destination */
lda $30, FRAMESIZE($30)
jmp $31, ($27)
.end _dl_runtime_resolve
.globl _dl_runtime_profile
.usepv _dl_runtime_profile, no
.type _dl_runtime_profile, @function
/* We save the registers in a different order than desired by
.mask/.fmask, so we have to use explicit cfi directives. */
cfi_startproc
- .macro savei regno, offset
- stq $\regno, \offset($30)
- cfi_rel_offset(\regno, \offset)
- .endm
-
- .macro savef regno, offset
- stt $f\regno, \offset($30)
- cfi_rel_offset(\regno+32, \offset)
- .endm
-
- #undef FRAMESIZE
- #define FRAMESIZE 50*8
-
_dl_runtime_profile:
lda $30, -FRAMESIZE($30)
! cfi_adjust_cfa_offset (FRAMESIZE)
/* Preserve all argument registers. This also constructs the
La_alpha_regs structure. */
! savei 26, 0*8
! savei 16, 2*8
! savei 17, 3*8
! savei 18, 4*8
! savei 19, 5*8
! savei 20, 6*8
! savei 21, 7*8
! lda $16, FRAMESIZE($30)
! savef 16, 8*8
! savef 17, 9*8
! savef 18, 10*8
! savef 19, 11*8
! savef 20, 12*8
! savef 21, 13*8
! stq $16, 1*8($30)
!
! /* Preserve all registers that C normally doesn't. */
! savei 0, 14*8
! savei 1, 15*8
! savei 2, 16*8
! savei 3, 17*8
! savei 4, 18*8
! savei 5, 19*8
! savei 6, 20*8
! savei 7, 21*8
! savei 8, 22*8
! savei 22, 23*8
! savei 23, 24*8
! savei 24, 25*8
! savei 25, 26*8
! savei 29, 27*8
! savef 0, 28*8
! savef 1, 29*8
! savef 10, 30*8
! savef 11, 31*8
! savef 12, 32*8
! savef 13, 33*8
! savef 14, 34*8
! savef 15, 35*8
! savef 22, 36*8
! savef 23, 37*8
! savef 24, 38*8
! savef 25, 39*8
! savef 26, 40*8
! savef 27, 41*8
! savef 28, 42*8
! savef 29, 43*8
! savef 30, 44*8
/* Set up our GP. */
br $29, .+4
! ldgp $29, 0($29)
/* Set up the arguments for _dl_profile_fixup:
$16 = link_map out of plt0
--- 60,136 ----
subq $28, $27, $17
ldq $16, 8($27)
subq $17, 20, $17
+ lda $29, 0($29) !gpdisp!1
mov $26, $18
addq $17, $17, $17
bsr $26, _dl_fixup !samegp
/* Move the destination address into position. */
mov $0, $27
!
! /* Restore argument registers. */
ldq $26, 0*8($30)
! ldq $16, 1*8($30)
! ldq $17, 2*8($30)
! ldq $18, 3*8($30)
! ldq $19, 4*8($30)
! ldq $20, 5*8($30)
! ldq $21, 6*8($30)
! ldt $f16, 7*8($30)
! ldt $f17, 8*8($30)
! ldt $f18, 9*8($30)
! ldt $f19, 10*8($30)
! ldt $f20, 11*8($30)
! ldt $f21, 12*8($30)
!
/* Flush the Icache after having modified the .plt code. */
imb
+
/* Clean up and turn control to the destination */
lda $30, FRAMESIZE($30)
jmp $31, ($27)
.end _dl_runtime_resolve
+
+ #undef FRAMESIZE
+ #define FRAMESIZE 20*8
+
.globl _dl_runtime_profile
.usepv _dl_runtime_profile, no
.type _dl_runtime_profile, @function
+ .align 4
/* We save the registers in a different order than desired by
.mask/.fmask, so we have to use explicit cfi directives. */
cfi_startproc
_dl_runtime_profile:
+ mov $30, $1
lda $30, -FRAMESIZE($30)
! cfi_adjust_cfa_offset(FRAMESIZE)
/* Preserve all argument registers. This also constructs the
La_alpha_regs structure. */
! stq $26, 0*8($30)
! cfi_rel_offset(26, 0*8)
! stq $1, 1*8($30)
! stq $16, 2*8($30)
! stq $17, 3*8($30)
! stq $18, 4*8($30)
! stq $19, 5*8($30)
! stq $20, 6*8($30)
! stq $21, 7*8($30)
! stt $f16, 8*8($30)
! stt $f17, 9*8($30)
! stt $f18, 10*8($30)
! stt $f19, 11*8($30)
! stt $f20, 12*8($30)
! stt $f21, 13*8($30)
/* Set up our GP. */
br $29, .+4
! ldah $29, 0($29) !gpdisp!2
/* Set up the arguments for _dl_profile_fixup:
$16 = link_map out of plt0
*************** _dl_runtime_profile:
*** 239,258 ****
ldq $16, 8($27)
subq $17, 20, $17
mov $26, $18
addq $17, $17, $17
lda $19, 0($30)
! lda $20, 45*8($30)
! stq $16, 48*8($30)
! stq $17, 49*8($30)
bsr $26, _dl_profile_fixup !samegp
/* Discover if we're wrapping this call. */
! ldq $18, 45*8($30)
! bge $18, 1f
- /* Move the destination address into position. */
- mov $0, $27
/* Restore program registers. */
ldq $26, 0*8($30)
ldq $16, 2*8($30)
--- 143,162 ----
ldq $16, 8($27)
subq $17, 20, $17
mov $26, $18
+ lda $29, 0($29) !gpdisp!2
addq $17, $17, $17
lda $19, 0($30)
! lda $20, 15*8($30)
!
! /* Save the link_map and offset computations for _dl_call_pltexit. */
! stq $16, 16*8($30)
! stq $17, 17*8($30)
bsr $26, _dl_profile_fixup !samegp
/* Discover if we're wrapping this call. */
! ldq $1, 15*8($30)
/* Restore program registers. */
ldq $26, 0*8($30)
ldq $16, 2*8($30)
*************** _dl_runtime_profile:
*** 267,360 ****
ldt $f19, 11*8($30)
ldt $f20, 12*8($30)
ldt $f21, 13*8($30)
! ldq $0, 14*8($30)
! ldq $1, 15*8($30)
! ldq $2, 16*8($30)
! ldq $3, 17*8($30)
! ldq $4, 18*8($30)
! ldq $5, 19*8($30)
! ldq $6, 20*8($30)
! ldq $7, 21*8($30)
! ldq $8, 22*8($30)
! ldq $22, 23*8($30)
! ldq $23, 24*8($30)
! ldq $24, 25*8($30)
! ldq $25, 26*8($30)
! ldq $29, 27*8($30)
! ldt $f0, 28*8($30)
! ldt $f1, 29*8($30)
! ldt $f10, 30*8($30)
! ldt $f11, 31*8($30)
! ldt $f12, 32*8($30)
! ldt $f13, 33*8($30)
! ldt $f14, 34*8($30)
! ldt $f15, 35*8($30)
! ldt $f22, 36*8($30)
! ldt $f23, 37*8($30)
! ldt $f24, 38*8($30)
! ldt $f25, 39*8($30)
! ldt $f26, 40*8($30)
! ldt $f27, 41*8($30)
! ldt $f28, 42*8($30)
! ldt $f29, 43*8($30)
! ldt $f30, 44*8($30)
/* Clean up and turn control to the destination. */
lda $30, FRAMESIZE($30)
jmp $31, ($27)
1:
/* Create a frame pointer and allocate a new argument frame. */
! savei 15, 45*8
mov $30, $15
! cfi_def_cfa_register (15)
! addq $18, 15, $18
! bic $18, 15, $18
! subq $30, $18, $30
!
! /* Save the call destination around memcpy. */
! stq $0, 46*8($30)
!
! /* Copy the stack arguments into place. */
! lda $16, 0($30)
! lda $17, FRAMESIZE($15)
! jsr $26, memcpy
! ldgp $29, 0($26)
! /* Reload the argument registers. */
! ldq $27, 46*8($30)
! ldq $16, 2*8($15)
! ldq $17, 3*8($15)
! ldq $18, 4*8($15)
! ldq $19, 5*8($15)
! ldq $20, 6*8($15)
! ldq $21, 7*8($15)
! ldt $f16, 8*8($15)
! ldt $f17, 9*8($15)
! ldt $f18, 10*8($15)
! ldt $f19, 11*8($15)
! ldt $f20, 12*8($15)
! ldt $f21, 13*8($15)
! jsr $26, ($27), 0
! ldgp $29, 0($26)
/* Set up for call to _dl_call_pltexit. */
! ldq $16, 48($15)
! ldq $17, 49($15)
! stq $0, 46*8($15)
! lda $18, 0($15)
! stq $1, 47*8($15)
! lda $19, 46*8($15)
! stt $f0, 48*8($15)
! stt $f1, 49*8($15)
bsr $26, _dl_call_pltexit !samegp
mov $15, $30
! cfi_def_cfa_register (30)
ldq $26, 0($30)
ldq $15, 45*8($30)
lda $30, FRAMESIZE($30)
ret
cfi_endproc
--- 171,234 ----
ldt $f19, 11*8($30)
ldt $f20, 12*8($30)
ldt $f21, 13*8($30)
!
! /* Move the destination address into position. */
! mov $0, $27
!
! bge $1, 1f
! cfi_remember_state
! cfi_restore(26)
/* Clean up and turn control to the destination. */
lda $30, FRAMESIZE($30)
+ cfi_adjust_cfa_offset(-FRAMESIZE)
jmp $31, ($27)
1:
+ cfi_restore_state
/* Create a frame pointer and allocate a new argument frame. */
! stq $15, 14*8
mov $30, $15
! cfi_rel_offset(15, 14*8)
! cfi_def_cfa_register(15)
! beq $1, 3f
! addq $1, 15, $1
! bic $1, 15, $1
! subq $30, $1, $30
! mov $15, $2
! mov $30, $3
! .align 4
! 2: ldq $4, 0($2)
! addq $3, 8, $3
! subq $1, 8, $1
! addq $2, 8, $2
! stq $4, -8($3)
! bgt $1, 2b
! 3: jsr $26, ($27), 0
! ldah $29, 0($26) !gpdisp!3
/* Set up for call to _dl_call_pltexit. */
! ldq $16, 16($15)
! ldq $17, 17($15)
! stq $0, 16*8($15)
! mov $15, $18
! stq $1, 17*8($15)
! lda $29, 0($29) !gpdisp!3
! stt $f0, 18*8($15)
! lda $19, 16*8($15)
! stt $f1, 19*8($15)
bsr $26, _dl_call_pltexit !samegp
mov $15, $30
! cfi_def_cfa_register(30)
ldq $26, 0($30)
ldq $15, 45*8($30)
+ cfi_restore(26)
+ cfi_restore(15)
lda $30, FRAMESIZE($30)
+ cfi_adjust_cfa_offset(-FRAMESIZE)
ret
cfi_endproc
Index: sysdeps/alpha/reml.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/reml.S,v
retrieving revision 1.8
diff -c -p -d -r1.8 reml.S
*** sysdeps/alpha/reml.S 6 Sep 2004 02:01:35 -0000 1.8
--- sysdeps/alpha/reml.S 24 Jan 2005 20:43:27 -0000
***************
*** 38,44 ****
.text
.align 4
.globl __reml
! .type __reml, @function
.usepv __reml, no
cfi_startproc
--- 38,45 ----
.text
.align 4
.globl __reml
! PROTECTED (__reml)
! .type __reml, DIV_FUNC_TYPE
.usepv __reml, no
cfi_startproc
Index: sysdeps/alpha/remq.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/remq.S,v
retrieving revision 1.9
diff -c -p -d -r1.9 remq.S
*** sysdeps/alpha/remq.S 6 Sep 2004 02:01:35 -0000 1.9
--- sysdeps/alpha/remq.S 24 Jan 2005 20:43:27 -0000
***************
*** 43,49 ****
.text
.align 4
.globl __remq
! .type __remq, @function
.usepv __remq, no
cfi_startproc
--- 43,50 ----
.text
.align 4
.globl __remq
! PROTECTED (__remq)
! .type __remq, DIV_FUNC_TYPE
.usepv __remq, no
cfi_startproc
Index: sysdeps/alpha/remqu.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/remqu.S,v
retrieving revision 1.10
diff -c -p -d -r1.10 remqu.S
*** sysdeps/alpha/remqu.S 6 Sep 2004 02:01:35 -0000 1.10
--- sysdeps/alpha/remqu.S 24 Jan 2005 20:43:27 -0000
***************
*** 43,49 ****
.text
.align 4
.globl __remqu
! .type __remqu, @function
.usepv __remqu, no
cfi_startproc
--- 43,50 ----
.text
.align 4
.globl __remqu
! PROTECTED (__remqu)
! .type __remqu, DIV_FUNC_TYPE
.usepv __remqu, no
cfi_startproc
Index: sysdeps/alpha/elf/initfini.c
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/elf/initfini.c,v
retrieving revision 1.4
diff -c -p -d -r1.4 initfini.c
*** sysdeps/alpha/elf/initfini.c 16 Aug 2004 04:51:02 -0000 1.4
--- sysdeps/alpha/elf/initfini.c 24 Jan 2005 20:43:27 -0000
*************** _init: \n\
*** 75,80 ****
--- 75,89 ----
ldq $29, 8($30) \n\
.align 3 \n\
1: \n\
+ .section .note.alpha.divnoplt, \"a\", @note \n\
+ .p2align 2 \n\
+ .long 1f-0f /* name length */ \n\
+ .long 3f-2f /* data length */ \n\
+ .long 0x10001 /* note type */ \n\
+ 0: .asciz \"GNU\" /* vendor name */ \n\
+ 1: .p2align 2 \n\
+ 2: .long 0 /* note data unused */ \n\
+ 3: .p2align 2 \n\
/*@_init_PROLOG_ENDS*/ \n\
\n\
/*@_init_EPILOG_BEGINS*/ \n\
Index: sysdeps/generic/abi-note.S
===================================================================
RCS file: sysdeps/generic/abi-note.S
diff -N sysdeps/generic/abi-note.S
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- sysdeps/generic/abi-note.S 24 Jan 2005 20:43:27 -0000
***************
*** 0 ****
--- 1,73 ----
+ /* Special .init and .fini section support.
+ Copyright (C) 1997, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+ /* Define an ELF note identifying the operating-system ABI that the
+ executable was created for. The ELF note information identifies a
+ particular OS or coordinated development effort within which the
+ ELF header's e_machine value plus (for dynamically linked programs)
+ the PT_INTERP dynamic linker name and DT_NEEDED shared library
+ names fully identify the runtime environment required by an
+ executable.
+
+ The general format of ELF notes is as follows.
+ Offsets and lengths are bytes or (parenthetical references) to the
+ values in other fields.
+
+ offset length contents
+ 0 4 length of name
+ 4 4 length of data
+ 8 4 note type
+ 12 (0) vendor name
+ - null-terminated ASCII string, padded to 4-byte alignment
+ 12+(0) (4) note data,
+
+ The GNU project and cooperating development efforts (including the
+ Linux community) use note type 1 and a vendor name string of "GNU"
+ for a note descriptor that indicates ABI requirements. The note data
+ is four 32-bit words. The first of these is an operating system
+ number (0=Linux, 1=Hurd, 2=Solaris, ...) and the remaining three
+ identify the earliest release of that OS that supports this ABI.
+ See abi-tags (top level) for details. */
+
+ #include <config.h>
+ #include <abi-tag.h> /* OS-specific ABI tag value */
+
+ /* The linker (GNU ld 2.8 and later) recognizes an allocated section whose
+ name begins with `.note' and creates a PT_NOTE program header entry
+ pointing at it. */
+
+ .section ".note.ABI-tag", "a"
+ .p2align 2
+ .long 1f - 0f /* name length */
+ .long 3f - 2f /* data length */
+ .long 1 /* note type */
+ 0: .asciz "GNU" /* vendor name */
+ 1: .p2align 2
+ 2: .long __ABI_TAG_OS /* note data: the ABI tag */
+ .long __ABI_TAG_VERSION
+ 3: .p2align 2 /* pad out section */