mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
Tue Jul 16 00:31:31 1996 Richard Henderson <rth@tamu.edu>
* sysdeps/alpha/dl-machine.h: Mirror Roland's changes to i386/dl-machine.h of 960713. * sysdeps/generic/dl-sysdep.c: Include <sys/mman.h>. (_dl_sysdep_read_whole_file): Fix result variable declaration. Tue Jul 16 00:53:57 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * sysdeps/mach/hurd/uname.c: Call __gethostname to fill in the `nodename' member. Mon Jul 15 17:23:53 1996 Ulrich Drepper <drepper@cygnus.com> * stdio-common/vfprintf.c (vfprintf): Call parse_one_spec with pointer to local variable instead of NULL. 1996-07-15 Paul Eggert <eggert@twinsun.com> * time/strftime.c (strftime): Don't pass empty macro argument to `add'. Sat Jul 13 09:53:39 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Remove names that are already added by other means. * sysdeps/unix/sysv/linux/syscalls.list: Add more EXTRA's in the caller column to get those syscalls added automagically. * elf/rtld.c (dl_main) [ELF_MACHINE_DEBUG_SETUP]: Use this macro instead of setting the DT_DEBUG pointer. * csu/initfini.c (_init, _fini): Generate .end directives after standalone prologues and filter them out from epilogues.
This commit is contained in:
parent
ed36809a9c
commit
ec42724d69
36
ChangeLog
36
ChangeLog
@ -1,3 +1,33 @@
|
||||
Tue Jul 16 00:31:31 1996 Richard Henderson <rth@tamu.edu>
|
||||
|
||||
* sysdeps/alpha/dl-machine.h: Mirror Roland's changes to
|
||||
i386/dl-machine.h of 960713.
|
||||
|
||||
* sysdeps/generic/dl-sysdep.c: Include <sys/mman.h>.
|
||||
(_dl_sysdep_read_whole_file): Fix result variable declaration.
|
||||
|
||||
Tue Jul 16 00:53:57 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/mach/hurd/uname.c: Call __gethostname to fill in the
|
||||
`nodename' member.
|
||||
|
||||
Mon Jul 15 17:23:53 1996 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* stdio-common/vfprintf.c (vfprintf): Call parse_one_spec
|
||||
with pointer to local variable instead of NULL.
|
||||
|
||||
1996-07-15 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
* time/strftime.c (strftime): Don't pass empty macro argument to `add'.
|
||||
|
||||
Sat Jul 13 09:53:39 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Remove names
|
||||
that are already added by other means.
|
||||
|
||||
* sysdeps/unix/sysv/linux/syscalls.list: Add more EXTRA's in the
|
||||
caller column to get those syscalls added automagically.
|
||||
|
||||
Mon Jul 15 12:24:54 1996 Miles Bader <miles@gnu.ai.mit.edu>
|
||||
|
||||
* login/logout.c (logout): Initialize DATA to a state that will
|
||||
@ -5,6 +35,12 @@ Mon Jul 15 12:24:54 1996 Miles Bader <miles@gnu.ai.mit.edu>
|
||||
|
||||
Sun Jul 14 01:51:39 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/rtld.c (dl_main) [ELF_MACHINE_DEBUG_SETUP]: Use this macro
|
||||
instead of setting the DT_DEBUG pointer.
|
||||
|
||||
* csu/initfini.c (_init, _fini): Generate .end directives after
|
||||
standalone prologues and filter them out from epilogues.
|
||||
|
||||
* Makeconfig (rtld-installed-name): Set to ld.so.1.
|
||||
* sysdeps/unix/sysv/linux/Makefile (rtld-installed-name): Variable
|
||||
removed.
|
||||
|
35
FAQ
35
FAQ
@ -46,6 +46,9 @@ please let me know.
|
||||
|
||||
[Q12] ``The `gencat' utility cannot process the input which are
|
||||
successfully used on my Linux libc based system. Why?''
|
||||
|
||||
[Q13] ``How do I configure GNU libc so that the essential libraries
|
||||
like libc.so go into /lib and the other into /usr/lib?''
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q1] ``What systems does the GNU C Library run on?''
|
||||
@ -287,7 +290,6 @@ means to support the new techniques later.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
|
||||
[Q11] ``Where are the DST_* constants found in <sys/time.h> on many
|
||||
systems?''
|
||||
|
||||
@ -300,7 +302,6 @@ code for POSIX TZ environment variable handling.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
|
||||
[Q12] ``The `gencat' utility cannot process the input which are
|
||||
successfully used on my Linux libc based system. Why?''
|
||||
|
||||
@ -337,6 +338,36 @@ catalog files to the XPG4 form:
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
[Q13] ``How do I configure GNU libc so that the essential libraries
|
||||
like libc.so go into /lib and the other into /usr/lib?''
|
||||
|
||||
[A13] {UD} Like all other GNU packages GNU libc is configured to use a
|
||||
base directory and install all files relative to this. If you intend
|
||||
to really use GNU libc on your system this base directory is /usr. I.e.,
|
||||
you run
|
||||
configure --prefix=/usr <other_options>
|
||||
|
||||
Some systems like Linux have a filesystem standard which makes a
|
||||
difference between essential libraries and others. Essential
|
||||
libraries are placed in /lib because this directory is required to be
|
||||
located on the same disk partition as /. The /usr subtree might be
|
||||
found on another partition/disk.
|
||||
|
||||
To install the essential libraries which come with GNU libc in /lib
|
||||
one must explicitly tell this. Autoconf has no option for this so you
|
||||
have to use the file where all user supplied additional information
|
||||
should go in: `configparms' (see the `INSTALL' file). For Linux the
|
||||
`configparms' file should contain:
|
||||
|
||||
slibdir=/lib
|
||||
sysconfdir=/etc
|
||||
|
||||
The first line specifies the directory for the essential libraries,
|
||||
the second line the directory for file which are by tradition placed
|
||||
in a directory named /etc.
|
||||
|
||||
|
||||
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||
|
||||
Answers were given by:
|
||||
|
@ -77,10 +77,10 @@ _init (void)
|
||||
/* End the here document containing the .init prologue code.
|
||||
Then fetch the .section directive just written and append that
|
||||
to crtn.s-new, followed by the function epilogue. */
|
||||
asm ("\nEOF.crti.init
|
||||
\n\
|
||||
asm (".end _init\n\
|
||||
EOF.crti.init\n\
|
||||
fgrep .init crti.s-new >>crtn.s-new\n\
|
||||
cat >> crtn.s-new <<\\EOF.crtn.init");
|
||||
fgrep -v .end >> crtn.s-new <<\\EOF.crtn.init");
|
||||
}
|
||||
|
||||
/* End the here document containing the .init epilogue code.
|
||||
@ -96,8 +96,8 @@ _fini (void)
|
||||
/* End the here document containing the .fini prologue code.
|
||||
Then fetch the .section directive just written and append that
|
||||
to crtn.s-new, followed by the function epilogue. */
|
||||
asm ("\nEOF.crti.fini\
|
||||
\n\
|
||||
asm (".end _fini\n\
|
||||
EOF.crti.fini\n\
|
||||
cat > /dev/null <<\\EOF.fini.skip");
|
||||
|
||||
{
|
||||
@ -111,7 +111,7 @@ cat > /dev/null <<\\EOF.fini.skip");
|
||||
asm ("\nEOF.fini.skip\
|
||||
\n\
|
||||
fgrep .fini crti.s-new >>crtn.s-new\n\
|
||||
cat >> crtn.s-new <<\\EOF.crtn.fini");
|
||||
fgrep -v .end >> crtn.s-new <<\\EOF.crtn.fini");
|
||||
}
|
||||
|
||||
/* End the here document containing the .fini epilogue code.
|
||||
|
12
elf/rtld.c
12
elf/rtld.c
@ -414,6 +414,16 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr);
|
||||
|
||||
l = _dl_loaded;
|
||||
|
||||
#ifdef ELF_MACHINE_DEBUG_SETUP
|
||||
|
||||
/* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */
|
||||
|
||||
ELF_MACHINE_DEBUG_SETUP (l, r);
|
||||
ELF_MACHINE_DEBUG_SETUP (&_dl_rtld_map, r);
|
||||
|
||||
#else
|
||||
|
||||
if (l->l_info[DT_DEBUG])
|
||||
/* There is a DT_DEBUG entry in the dynamic section. Fill it in
|
||||
with the run-time address of the r_debug structure */
|
||||
@ -424,6 +434,8 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
if (_dl_rtld_map.l_info[DT_DEBUG])
|
||||
_dl_rtld_map.l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
|
||||
|
||||
#endif
|
||||
|
||||
/* Notify the debugger that all objects are now mapped in. */
|
||||
r->r_state = RT_ADD;
|
||||
_dl_debug_state ();
|
||||
|
@ -1115,7 +1115,8 @@ do_positional:
|
||||
}
|
||||
|
||||
/* Parse the format specifier. */
|
||||
nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg, NULL);
|
||||
nargs += parse_one_spec (f, nargs, &specs[nspecs], &max_ref_arg,
|
||||
&mbstate);
|
||||
}
|
||||
|
||||
/* Determine the number of arguments the format string consumes. */
|
||||
|
@ -18,14 +18,16 @@ License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This was written in the absense of an ABI -- don't expect
|
||||
/* This was written in the absence of an ABI -- don't expect
|
||||
it to remain unchanged. */
|
||||
|
||||
#ifndef dl_machine_h
|
||||
#define dl_machine_h 1
|
||||
|
||||
#define ELF_MACHINE_NAME "alpha"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
|
||||
|
||||
/* Return nonzero iff E_MACHINE is compatible with the running host. */
|
||||
@ -35,7 +37,6 @@ elf_machine_matches_host (Elf64_Word e_machine)
|
||||
return e_machine == EM_ALPHA;
|
||||
}
|
||||
|
||||
|
||||
/* Return the run-time address of the _GLOBAL_OFFSET_TABLE_.
|
||||
Must be inlined in a function which uses global data. */
|
||||
static inline Elf64_Addr *
|
||||
@ -45,7 +46,6 @@ elf_machine_got (void)
|
||||
return (Elf64_Addr *)(gp - 0x8000);
|
||||
}
|
||||
|
||||
|
||||
/* Return the run-time load address of the shared object. */
|
||||
static inline Elf64_Addr
|
||||
elf_machine_load_address (void)
|
||||
@ -78,180 +78,6 @@ elf_machine_load_address (void)
|
||||
return dot + 4 + zero_disp;
|
||||
}
|
||||
|
||||
|
||||
/* Fix up the instructions of a PLT entry to invoke the function
|
||||
rather than the dynamic linker. */
|
||||
static inline void
|
||||
elf_alpha_fix_plt(struct link_map *l,
|
||||
const Elf64_Rela *reloc,
|
||||
Elf64_Addr got_addr,
|
||||
Elf64_Addr value)
|
||||
{
|
||||
const Elf64_Rela *rela_plt;
|
||||
Elf64_Word *plte;
|
||||
long edisp;
|
||||
|
||||
/* Recover the PLT entry address by calculating reloc's index into the
|
||||
.rela.plt, and finding that entry in the .plt. */
|
||||
|
||||
rela_plt = (void *)(l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr);
|
||||
|
||||
plte = (void *)(l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
|
||||
plte += 3 * (reloc - rela_plt);
|
||||
|
||||
/* Find the displacement from the plt entry to the function. */
|
||||
|
||||
edisp = (long)(value - (Elf64_Addr)&plte[3]) / 4;
|
||||
|
||||
if (edisp >= -0x100000 && edisp < 0x100000)
|
||||
{
|
||||
/* If we are in range, use br to perfect branch prediction and
|
||||
elide the dependency on the address load. This case happens,
|
||||
e.g., when a shared library call is resolved to the same library. */
|
||||
|
||||
int hi, lo;
|
||||
hi = value - (Elf64_Addr)&plte[0];
|
||||
lo = (short)hi;
|
||||
hi = (hi - lo) >> 16;
|
||||
|
||||
/* Emit "ldah $27,H($27)" */
|
||||
plte[0] = 0x277b0000 | (hi & 0xffff);
|
||||
|
||||
/* Emit "lda $27,L($27)" */
|
||||
plte[1] = 0x237b0000 | (lo & 0xffff);
|
||||
|
||||
/* Emit "br $31,function" */
|
||||
plte[2] = 0xc3e00000 | (edisp & 0x1fffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Don't bother with the hint since we already know the hint is
|
||||
wrong. Eliding it prevents the wrong page from getting pulled
|
||||
into the cache. */
|
||||
|
||||
int hi, lo;
|
||||
hi = got_addr - (Elf64_Addr)&plte[0];
|
||||
lo = (short)hi;
|
||||
hi = (hi - lo) >> 16;
|
||||
|
||||
/* Emit "ldah $27,H($27)" */
|
||||
plte[0] = 0x277b0000 | (hi & 0xffff);
|
||||
|
||||
/* Emit "ldq $27,L($27)" */
|
||||
plte[1] = 0xa77b0000 | (lo & 0xffff);
|
||||
|
||||
/* Emit "jmp $31,($27)" */
|
||||
plte[2] = 0x6bfb0000;
|
||||
}
|
||||
|
||||
/* Flush the instruction cache now that we've diddled. Tag it as
|
||||
modifying memory to checkpoint memory writes during optimization. */
|
||||
asm volatile("call_pal 0x86" : : : "memory");
|
||||
}
|
||||
|
||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||
MAP is the object containing the reloc. */
|
||||
static inline void
|
||||
elf_machine_rela (struct link_map *map,
|
||||
const Elf64_Rela *reloc,
|
||||
const Elf64_Sym *sym,
|
||||
Elf64_Addr (*resolve) (const Elf64_Sym **ref,
|
||||
Elf64_Addr reloc_addr,
|
||||
int noplt))
|
||||
{
|
||||
Elf64_Addr *const reloc_addr = (void *)(map->l_addr + reloc->r_offset);
|
||||
unsigned long r_info = ELF64_R_TYPE (reloc->r_info);
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
|
||||
reference weak so static programs can still link. This declaration
|
||||
cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
|
||||
because rtld.c contains the common defn for _dl_rtld_map, which is
|
||||
incompatible with a weak decl in the same file. */
|
||||
weak_extern (_dl_rtld_map);
|
||||
#endif
|
||||
|
||||
/* We cannot use a switch here because we cannot locate the switch
|
||||
jump table until we've self-relocated. */
|
||||
|
||||
if (r_info == R_ALPHA_RELATIVE)
|
||||
{
|
||||
/* Already done in dynamic linker. */
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
if (map != &_dl_rtld_map)
|
||||
#endif
|
||||
*reloc_addr += map->l_addr;
|
||||
}
|
||||
else if (r_info == R_ALPHA_NONE)
|
||||
return;
|
||||
else
|
||||
{
|
||||
Elf64_Addr loadbase, sym_value;
|
||||
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
loadbase = (*resolve)(&sym, (Elf64_Addr)reloc_addr,
|
||||
r_info == R_ALPHA_JMP_SLOT);
|
||||
#else
|
||||
loadbase = map->l_addr;
|
||||
#endif
|
||||
sym_value = sym ? loadbase + sym->st_value : 0;
|
||||
|
||||
if (r_info == R_ALPHA_GLOB_DAT)
|
||||
*reloc_addr = sym_value;
|
||||
else if (r_info == R_ALPHA_JMP_SLOT)
|
||||
{
|
||||
*reloc_addr = sym_value;
|
||||
elf_alpha_fix_plt (map, reloc, (Elf64_Addr) reloc_addr, sym_value);
|
||||
}
|
||||
else if (r_info == R_ALPHA_REFQUAD)
|
||||
{
|
||||
sym_value += *reloc_addr;
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
if (map == &_dl_rtld_map)
|
||||
{
|
||||
/* Undo the relocation done here during bootstrapping.
|
||||
Now we will relocate anew, possibly using a binding
|
||||
found in the user program or a loaded library rather
|
||||
than the dynamic linker's built-in definitions used
|
||||
while loading those libraries. */
|
||||
const Elf64_Sym *const dlsymtab
|
||||
= (void *)(map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
sym_value -= map->l_addr;
|
||||
sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
sym_value += reloc->r_addend;
|
||||
*reloc_addr = sym_value;
|
||||
}
|
||||
else if (r_info == R_ALPHA_COPY)
|
||||
memcpy (reloc_addr, (void *) sym_value, sym->st_size);
|
||||
else
|
||||
assert (! "unexpected dynamic reloc type");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
|
||||
{
|
||||
Elf64_Addr *const reloc_addr = (void *)(map->l_addr + reloc->r_offset);
|
||||
unsigned long r_info = ELF64_R_TYPE (reloc->r_info);
|
||||
|
||||
if (r_info == R_ALPHA_JMP_SLOT)
|
||||
{
|
||||
/* Perform a RELATIVE reloc on the .got entry that transfers
|
||||
to the .plt. */
|
||||
*reloc_addr += map->l_addr;
|
||||
}
|
||||
else if (r_info == R_ALPHA_NONE)
|
||||
;
|
||||
else
|
||||
assert (! "unexpected PLT reloc type");
|
||||
}
|
||||
|
||||
/* The alpha never uses Elf_Rel relocations. */
|
||||
#define ELF_MACHINE_NO_REL 1
|
||||
|
||||
|
||||
/* Set up the loaded object described by L so its unrelocated PLT
|
||||
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||
|
||||
@ -399,3 +225,179 @@ _dl_start_user:
|
||||
/* Jump to the user's entry point. */
|
||||
mov $9, $27
|
||||
jmp ($9)");
|
||||
|
||||
/* Nonzero iff TYPE describes relocation of a PLT entry, so
|
||||
PLT entries should not be allowed to define the value. */
|
||||
#define elf_machine_pltrel_p(type) ((type) == R_ALPHA_JMP_SLOT)
|
||||
|
||||
/* The alpha never uses Elf64_Rel relocations. */
|
||||
#define ELF_MACHINE_NO_REL 1
|
||||
|
||||
#endif /* !dl_machine_h */
|
||||
|
||||
#ifdef RESOLVE
|
||||
|
||||
/* Fix up the instructions of a PLT entry to invoke the function
|
||||
rather than the dynamic linker. */
|
||||
static inline void
|
||||
elf_alpha_fix_plt(struct link_map *l,
|
||||
const Elf64_Rela *reloc,
|
||||
Elf64_Addr got_addr,
|
||||
Elf64_Addr value)
|
||||
{
|
||||
const Elf64_Rela *rela_plt;
|
||||
Elf64_Word *plte;
|
||||
long edisp;
|
||||
|
||||
/* Recover the PLT entry address by calculating reloc's index into the
|
||||
.rela.plt, and finding that entry in the .plt. */
|
||||
|
||||
rela_plt = (void *)(l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr);
|
||||
|
||||
plte = (void *)(l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
|
||||
plte += 3 * (reloc - rela_plt);
|
||||
|
||||
/* Find the displacement from the plt entry to the function. */
|
||||
|
||||
edisp = (long)(value - (Elf64_Addr)&plte[3]) / 4;
|
||||
|
||||
if (edisp >= -0x100000 && edisp < 0x100000)
|
||||
{
|
||||
/* If we are in range, use br to perfect branch prediction and
|
||||
elide the dependency on the address load. This case happens,
|
||||
e.g., when a shared library call is resolved to the same library. */
|
||||
|
||||
int hi, lo;
|
||||
hi = value - (Elf64_Addr)&plte[0];
|
||||
lo = (short)hi;
|
||||
hi = (hi - lo) >> 16;
|
||||
|
||||
/* Emit "ldah $27,H($27)" */
|
||||
plte[0] = 0x277b0000 | (hi & 0xffff);
|
||||
|
||||
/* Emit "lda $27,L($27)" */
|
||||
plte[1] = 0x237b0000 | (lo & 0xffff);
|
||||
|
||||
/* Emit "br $31,function" */
|
||||
plte[2] = 0xc3e00000 | (edisp & 0x1fffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Don't bother with the hint since we already know the hint is
|
||||
wrong. Eliding it prevents the wrong page from getting pulled
|
||||
into the cache. */
|
||||
|
||||
int hi, lo;
|
||||
hi = got_addr - (Elf64_Addr)&plte[0];
|
||||
lo = (short)hi;
|
||||
hi = (hi - lo) >> 16;
|
||||
|
||||
/* Emit "ldah $27,H($27)" */
|
||||
plte[0] = 0x277b0000 | (hi & 0xffff);
|
||||
|
||||
/* Emit "ldq $27,L($27)" */
|
||||
plte[1] = 0xa77b0000 | (lo & 0xffff);
|
||||
|
||||
/* Emit "jmp $31,($27)" */
|
||||
plte[2] = 0x6bfb0000;
|
||||
}
|
||||
|
||||
/* Flush the instruction cache now that we've diddled. Tag it as
|
||||
modifying memory to checkpoint memory writes during optimization. */
|
||||
asm volatile("call_pal 0x86" : : : "memory");
|
||||
}
|
||||
|
||||
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
|
||||
MAP is the object containing the reloc. */
|
||||
static inline void
|
||||
elf_machine_rela (struct link_map *map,
|
||||
const Elf64_Rela *reloc,
|
||||
const Elf64_Sym *sym)
|
||||
{
|
||||
Elf64_Addr * const reloc_addr = (void *)(map->l_addr + reloc->r_offset);
|
||||
unsigned long const r_info = ELF64_R_TYPE (reloc->r_info);
|
||||
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
|
||||
reference weak so static programs can still link. This declaration
|
||||
cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
|
||||
because rtld.c contains the common defn for _dl_rtld_map, which is
|
||||
incompatible with a weak decl in the same file. */
|
||||
weak_extern (_dl_rtld_map);
|
||||
#endif
|
||||
|
||||
/* We cannot use a switch here because we cannot locate the switch
|
||||
jump table until we've self-relocated. */
|
||||
|
||||
if (r_info == R_ALPHA_RELATIVE)
|
||||
{
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
/* Already done in dynamic linker. */
|
||||
if (map != &_dl_rtld_map)
|
||||
#endif
|
||||
*reloc_addr += map->l_addr;
|
||||
}
|
||||
else if (r_info == R_ALPHA_NONE)
|
||||
return;
|
||||
else
|
||||
{
|
||||
Elf64_Addr loadbase, sym_value;
|
||||
|
||||
loadbase = RESOLVE (&sym, (Elf64_Addr)reloc_addr,
|
||||
r_info == R_ALPHA_JMP_SLOT);
|
||||
sym_value = sym ? loadbase + sym->st_value : 0;
|
||||
|
||||
if (r_info == R_ALPHA_GLOB_DAT)
|
||||
*reloc_addr = sym_value;
|
||||
else if (r_info == R_ALPHA_JMP_SLOT)
|
||||
{
|
||||
*reloc_addr = sym_value;
|
||||
elf_alpha_fix_plt (map, reloc, (Elf64_Addr) reloc_addr, sym_value);
|
||||
}
|
||||
else if (r_info == R_ALPHA_REFQUAD)
|
||||
{
|
||||
sym_value += *reloc_addr;
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
if (map == &_dl_rtld_map)
|
||||
{
|
||||
/* Undo the relocation done here during bootstrapping.
|
||||
Now we will relocate anew, possibly using a binding
|
||||
found in the user program or a loaded library rather
|
||||
than the dynamic linker's built-in definitions used
|
||||
while loading those libraries. */
|
||||
const Elf64_Sym *const dlsymtab
|
||||
= (void *)(map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
sym_value -= map->l_addr;
|
||||
sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
sym_value += reloc->r_addend;
|
||||
*reloc_addr = sym_value;
|
||||
}
|
||||
else if (r_info == R_ALPHA_COPY)
|
||||
memcpy (reloc_addr, (void *) sym_value, sym->st_size);
|
||||
else
|
||||
assert (! "unexpected dynamic reloc type");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
|
||||
{
|
||||
Elf64_Addr * const reloc_addr = (void *)(map->l_addr + reloc->r_offset);
|
||||
unsigned long const r_info = ELF64_R_TYPE (reloc->r_info);
|
||||
|
||||
if (r_info == R_ALPHA_JMP_SLOT)
|
||||
{
|
||||
/* Perform a RELATIVE reloc on the .got entry that transfers
|
||||
to the .plt. */
|
||||
*reloc_addr += map->l_addr;
|
||||
}
|
||||
else if (r_info == R_ALPHA_NONE)
|
||||
return;
|
||||
else
|
||||
assert (! "unexpected PLT reloc type");
|
||||
}
|
||||
|
||||
#endif /* RESOLVE */
|
||||
|
@ -20,6 +20,7 @@ Cambridge, MA 02139, USA. */
|
||||
#include <elf.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <link.h>
|
||||
#include <unistd.h>
|
||||
@ -126,7 +127,7 @@ _dl_sysdep_open_zero_fill (void)
|
||||
void *
|
||||
_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
|
||||
{
|
||||
void *contents;
|
||||
void *result;
|
||||
struct stat st;
|
||||
int fd = __open (file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992, 1993, 1994, 1996 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
|
||||
@ -25,7 +25,20 @@ uname (struct utsname *uname)
|
||||
{
|
||||
error_t err;
|
||||
|
||||
err = __USEPORT (PROC, __proc_uname (port, uname));
|
||||
if (err = __USEPORT (PROC, __proc_uname (port, uname)))
|
||||
return __hurd_fail (err);
|
||||
|
||||
return err ? __hurd_fail (err) : 0;
|
||||
/* Fill in the hostname, which the proc server doesn't know. */
|
||||
err = errno;
|
||||
if (__gethostname (uname.nodename, sizeof uname.nodename) < 0)
|
||||
{
|
||||
if (errno == ENAMETOOLONG)
|
||||
/* Ignore the error of the buffer being too small.
|
||||
It is of fixed size, nothing to do about it. */
|
||||
errno = err;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,10 +1,5 @@
|
||||
ifeq ($(subdir), io)
|
||||
sysdep_routines += fxstat lxstat xstat
|
||||
endif
|
||||
|
||||
ifeq ($(subdir), misc)
|
||||
sysdep_routines += mount umount xmknod s_ptrace s_sysctl sysctl llseek \
|
||||
setfsgid setfsuid sysinfo uselib s_reboot
|
||||
sysdep_routines += sysctl
|
||||
|
||||
sysdep_headers += sys/mount.h sys/sysinfo.h sys/acct.h sys/sysctl.h \
|
||||
sys/module.h sys/io.h sys/klog.h sys/kdaemon.h \
|
||||
@ -27,7 +22,6 @@ generated += syscall-list.h syscall-list.d
|
||||
endif
|
||||
|
||||
ifeq ($(subdir), time)
|
||||
sysdep_routines += adjtimex
|
||||
sysdep_headers += sys/timex.h
|
||||
endif
|
||||
|
||||
|
@ -299,7 +299,7 @@ strftime (s, maxsize, format, tp)
|
||||
size_t len = strftime (p, maxsize - i, subfmt, tp);
|
||||
if (len == 0 && *subfmt)
|
||||
return 0;
|
||||
add(len, );
|
||||
add (len, ;);
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user