Skip to content

Commit

Permalink
* sysdeps/powerpc/elf/libc-start.c (AUX_VECTOR_INIT): Define it.
Browse files Browse the repository at this point in the history
	(LIBC_START_MAIN, LIBC_START_MAIN_AUXVEC_ARG, MAIN_AUXVEC_ARG)
	(INIT_MAIN_ARGS): Define, and #include <sysdeps/generic/libc-start.c>.
	(__libc_start_main): Just call the generic one for most of the work.

	* sysdeps/generic/libc-start.c [LIBC_START_MAIN]: If defined, define a
	static function by that name instead of BP_SYM (__libc_start_main).
	[LIBC_START_MAIN_AUXVEC_ARG]: Take AUXVEC as argument.
	[MAIN_AUXVEC_ARG]: Pass 4th argument to MAIN.
	[INIT_MAIN_ARGS]: Give INIT the same args as MAIN.

	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start) [DL_PLATFORM_AUXV]:
	Use this macro for extra AT_* cases.
	* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c (DL_PLATFORM_AUXV):
	New macro, guts from ...
	(__aux_init_cache): ... here, function removed.
	(DL_PLATFORM_INIT): Don't define this.

	* sysdeps/powerpc/powerpc32/memset.S: Put __cache_line_size in bss.
	* sysdeps/powerpc/powerpc64/memset.S: Likewise.

	* Versions.def (libthread_db): Add GLICB_2.3.3 set.
  • Loading branch information
Roland McGrath committed Mar 15, 2003
1 parent 2b089f2 commit 124dcac
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 194 deletions.
25 changes: 25 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
2003-03-15 Roland McGrath <roland@redhat.com>

* sysdeps/powerpc/elf/libc-start.c (AUX_VECTOR_INIT): Define it.
(LIBC_START_MAIN, LIBC_START_MAIN_AUXVEC_ARG, MAIN_AUXVEC_ARG)
(INIT_MAIN_ARGS): Define, and #include <sysdeps/generic/libc-start.c>.
(__libc_start_main): Just call the generic one for most of the work.

* sysdeps/generic/libc-start.c [LIBC_START_MAIN]: If defined, define a
static function by that name instead of BP_SYM (__libc_start_main).
[LIBC_START_MAIN_AUXVEC_ARG]: Take AUXVEC as argument.
[MAIN_AUXVEC_ARG]: Pass 4th argument to MAIN.
[INIT_MAIN_ARGS]: Give INIT the same args as MAIN.

* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start) [DL_PLATFORM_AUXV]:
Use this macro for extra AT_* cases.
* sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c (DL_PLATFORM_AUXV):
New macro, guts from ...
(__aux_init_cache): ... here, function removed.
(DL_PLATFORM_INIT): Don't define this.

* sysdeps/powerpc/powerpc32/memset.S: Put __cache_line_size in bss.
* sysdeps/powerpc/powerpc64/memset.S: Likewise.

* Versions.def (libthread_db): Add GLICB_2.3.3 set.

2003-03-14 Roland McGrath <roland@redhat.com>

* dlfcn/dlerror.c (dlerror): If objname is "", don't put ": " after it.
Expand Down
1 change: 1 addition & 0 deletions Versions.def
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ libthread_db {
GLIBC_2.1.3
GLIBC_2.2.3
GLIBC_2.3
GLIBC_2.3.3
}
libanl {
GLIBC_2.2.3
Expand Down
3 changes: 3 additions & 0 deletions sysdeps/generic/dl-sysdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ _dl_sysdep_start (void **start_argptr,
case AT_SYSINFO:
GL(dl_sysinfo) = av->a_un.a_val;
break;
#endif
#ifdef DL_PLATFORM_AUXV
DL_PLATFORM_AUXV
#endif
}

Expand Down
132 changes: 28 additions & 104 deletions sysdeps/powerpc/elf/libc-start.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 1998,2000,2001,2002 Free Software Foundation, Inc.
/* Copyright (C) 1998,2000,2001,2002,2003 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
Expand All @@ -22,31 +22,9 @@
#include <bp-start.h>
#include <bp-sym.h>

extern void __libc_init_first (int argc, char **argv, char **envp);

extern int __cache_line_size;
weak_extern (__cache_line_size)

extern int __libc_multiple_libcs;
extern void *__libc_stack_end;

#ifndef SHARED
# include <tls.h>
extern void __pthread_initialize_minimal (void)
# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
__attribute__ ((weak))
# endif
;
#endif

struct startup_info
{
void *__unbounded sda_base;
int (*main) (int, char **, char **, void *);
int (*init) (int, char **, char **, void *);
void (*fini) (void);
};

/* Scan the Aux Vector for the "Data Cache Block Size" entry. If found
verify that the static extern __cache_line_size is defined by checking
for not NULL. If it is defined then assign the cache block size
Expand All @@ -66,32 +44,42 @@ __aux_init_cache (ElfW(auxv_t) *av)
break;
}
}
/* This is used in sysdeps/generic/libc-start.c. */
#define AUX_VECTOR_INIT __aux_init_cache

/* The main work is done in the generic function. */
#define LIBC_START_MAIN generic_start_main
#define LIBC_START_MAIN_AUXVEC_ARG
#define MAIN_AUXVEC_ARG
#define INIT_MAIN_ARGS
#include <sysdeps/generic/libc-start.c>


struct startup_info
{
void *__unbounded sda_base;
int (*main) (int, char **, char **, void *);
int (*init) (int, char **, char **, void *);
void (*fini) (void);
};


int
/* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the
BPs in the arglist of startup_info.main and startup_info.init. */
BP_SYM (__libc_start_main) (int argc, char *__unbounded *__unbounded ubp_av,
char *__unbounded *__unbounded ubp_ev,
ElfW(auxv_t) *__unbounded auxvec, void (*rtld_fini) (void),
struct startup_info *__unbounded stinfo,
char *__unbounded *__unbounded stack_on_entry)
char *__unbounded *__unbounded ubp_ev,
ElfW(auxv_t) *__unbounded auxvec,
void (*rtld_fini) (void),
struct startup_info *__unbounded stinfo,
char *__unbounded *__unbounded stack_on_entry)
{
#if __BOUNDED_POINTERS__
char **argv;
#else
# define argv ubp_av
#endif

#ifndef SHARED
/* The next variable is only here to work around a bug in gcc <= 2.7.2.2.
If the address would be taken inside the expression the optimizer
would try to be too smart and throws it away. Grrr. */
int *dummy_addr = &_dl_starting_up;

__libc_multiple_libcs = dummy_addr && !_dl_starting_up;
#endif

/* the PPC SVR4 ABI says that the top thing on the stack will
be a NULL pointer, so if not we assume that we're being called
as a statically-linked program by Linux... */
Expand All @@ -110,78 +98,14 @@ BP_SYM (__libc_start_main) (int argc, char *__unbounded *__unbounded ubp_av,
while (*temp != NULL)
++temp;
auxvec = (ElfW(auxv_t) *)++temp;

# ifndef SHARED
_dl_aux_init (auxvec);
# endif
#endif
rtld_fini = NULL;
}

INIT_ARGV_and_ENVIRON;

/* Initialize the __cache_line_size variable from the aux vector. */
__aux_init_cache(auxvec);

/* Store something that has some relationship to the end of the
stack, for backtraces. This variable should be thread-specific.
Use +8 so it works for both 32- and 64-bit. */
__libc_stack_end = stack_on_entry + 8;

#ifndef SHARED
# ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs)
{
/* This needs to run to initiliaze _dl_osversion before TLS
setup might check it. */
DL_SYSDEP_OSCHECK (__libc_fatal);
}
# endif
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. If there is no thread library and we
handle TLS the function is defined in the libc to initialized the
TLS handling. */
# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
if (__pthread_initialize_minimal)
# endif
__pthread_initialize_minimal ();

/* Some security at this point. Prevent starting a SUID binary where
the standard file descriptors are not opened. We have to do this
only for statically linked applications since otherwise the dynamic
loader did the work already. */
if (__builtin_expect (__libc_enable_secure, 0))
__libc_check_standard_fds ();
#endif

/* Register the destructor of the dynamic linker if there is any. */
if (rtld_fini != NULL)
__cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);

/* Call the initializer of the libc. */
#ifdef SHARED
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
_dl_debug_printf ("\ninitialize libc\n\n");
#endif
__libc_init_first (argc, argv, __environ);

/* Register the destructor of the program, if any. */
if (stinfo->fini)
__cxa_atexit ((void (*) (void *)) stinfo->fini, NULL, NULL);

/* Call the initializer of the program, if any. */
#ifdef SHARED
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
_dl_debug_printf ("\ninitialize program: %s\n\n", argv[0]);
#endif
if (stinfo->init)
stinfo->init (argc, argv, __environ, auxvec);

#ifdef SHARED
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
_dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
#endif
__aux_init_cache (auxvec);

exit (stinfo->main (argc, argv, __environ, auxvec));
return generic_start_main (stinfo->main, argc, ubp_av, auxvec,
stinfo->init, stinfo->fini, rtld_fini,
stack_on_entry);
}
76 changes: 36 additions & 40 deletions sysdeps/powerpc/powerpc32/memset.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Optimized memset implementation for PowerPC.
Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2000, 2003 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
Expand All @@ -21,27 +21,23 @@
#include <bp-sym.h>
#include <bp-asm.h>

/* Define a global static that can hold the cache line size. The
/* Define a global static that can hold the cache line size. The
assumption is that startup code will access the "aux vector" to
to obtain the value set by the kernel and store it into this
to obtain the value set by the kernel and store it into this
variable. */

.globl __cache_line_size
.section ".data","aw"
.align 2
.type __cache_line_size,@object
.size __cache_line_size,4
__cache_line_size:
.long 0
.section ".text"
.lcomm __cache_line_size,4,4

/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
Returns 's'.
The memset is done in four sizes: byte (8 bits), word (32 bits),
32-byte blocks (256 bits) and __cache_line_size (128, 256, 1024 bits).
There is a special case for setting whole cache lines to 0, which
There is a special case for setting whole cache lines to 0, which
takes advantage of the dcbz instruction. */

.section ".text"
EALIGN (BP_SYM (memset), 5, 1)

#define rTMP r0
Expand Down Expand Up @@ -123,14 +119,14 @@ L(caligned):
cmplwi cr1, rCHR, 0
clrrwi. rALIGN, rLEN, 5
mtcrf 0x01, rLEN /* 40th instruction from .align */

/* Check if we can use the special case for clearing memory using dcbz.
This requires that we know the correct cache line size for this
This requires that we know the correct cache line size for this
processor. Getting the __cache_line_size may require establishing GOT
addressability, so branch out of line to set this up. */
beq cr1, L(checklinesize)
/* Store blocks of 32-bytes (256-bits) starting on a 32-byte boundary.
beq cr1, L(checklinesize)

/* Store blocks of 32-bytes (256-bits) starting on a 32-byte boundary.
Can't assume that rCHR is zero or that the cache line size is either
32-bytes or even known. */
L(nondcbz):
Expand Down Expand Up @@ -172,7 +168,7 @@ L(cloopdone):

.align 5
nop
/* Clear cache lines of memory in 128-byte chunks.
/* Clear cache lines of memory in 128-byte chunks.
This code is optimized for processors with 32-byte cache lines.
It is further optimized for the 601 processor, which requires
some care in how the code is aligned in the i-cache. */
Expand Down Expand Up @@ -259,45 +255,45 @@ L(medium_28t):
stw rCHR, -4(rMEMP)
stw rCHR, -8(rMEMP)
blr

L(checklinesize):
#ifdef SHARED
mflr rTMP
/* If the remaining length is less the 32 bytes then don't bother getting
the cache line size. */
beq L(medium)
/* Establishes GOT addressability so we can load __cache_line_size
beq L(medium)
/* Establishes GOT addressability so we can load __cache_line_size
from static. This value was set from the aux vector during startup. */
bl _GLOBAL_OFFSET_TABLE_@local-4
mflr rGOT
lwz rGOT,__cache_line_size@got(rGOT)
lwz rCLS,0(rGOT)
mtlr rTMP
#else
/* Load __cache_line_size from static. This value was set from the
#else
/* Load __cache_line_size from static. This value was set from the
aux vector during startup. */
lis rCLS,__cache_line_size@ha
/* If the remaining length is less the 32 bytes then don't bother getting
the cache line size. */
beq L(medium)
lwz rCLS,__cache_line_size@l(rCLS)
#endif

/*If the cache line size was not set then goto to L(nondcbz), which is
safe for any cache line size. */
safe for any cache line size. */
cmplwi cr1,rCLS,0
beq cr1,L(nondcbz)

/* If the cache line size is 32 bytes then goto to L(zloopstart),
which is coded specificly for 32-byte lines (and 601). */
which is coded specificly for 32-byte lines (and 601). */
cmplwi cr1,rCLS,32
beq cr1,L(zloopstart)
/* Now we know the cache line size and it is not 32-bytes. However
we may not yet be aligned to the cache line and may have a partial
line to fill. Touch it 1st to fetch the cache line. */
dcbtst 0,rMEMP

/* Now we know the cache line size and it is not 32-bytes. However
we may not yet be aligned to the cache line and may have a partial
line to fill. Touch it 1st to fetch the cache line. */
dcbtst 0,rMEMP

addi rCLM,rCLS,-1
L(getCacheAligned):
cmplwi cr1,rLEN,32
Expand All @@ -317,8 +313,8 @@ L(getCacheAligned):
stw rCHR,-8(rMEMP)
stw rCHR,-4(rMEMP)
b L(getCacheAligned)
/* Now we are aligned to the cache line and can use dcbz. */

/* Now we are aligned to the cache line and can use dcbz. */
L(cacheAligned):
cmplw cr1,rLEN,rCLS
blt cr1,L(handletail32)
Expand All @@ -327,12 +323,12 @@ L(cacheAligned):
add rMEMP,rMEMP,rCLS
b L(cacheAligned)

/* We are here because; the cache line size was set, it was not
32-bytes, and the remainder (rLEN) is now less than the actual cache
line size. Set up the preconditions for L(nondcbz) and go there to
store the remaining bytes. */
/* We are here because; the cache line size was set, it was not
32-bytes, and the remainder (rLEN) is now less than the actual cache
line size. Set up the preconditions for L(nondcbz) and go there to
store the remaining bytes. */
L(handletail32):
clrrwi. rALIGN, rLEN, 5
b L(nondcbz)

END (BP_SYM (memset))
Loading

0 comments on commit 124dcac

Please sign in to comment.