diff options
author | no-author <no-author@gcc.gnu.org> | 2000-04-28 13:51:55 +0000 |
---|---|---|
committer | no-author <no-author@gcc.gnu.org> | 2000-04-28 13:51:55 +0000 |
commit | 9a430f9174dda082a7906cfae9399ba698515261 (patch) | |
tree | 85607f5e7a0716ae5204ddfa12484045c5869bc5 | |
parent | d583b266d30c1a2c77471aee0f59e991f959609d (diff) |
This commit was manufactured by cvs2svn to create branch
'condexec-branch'.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/condexec-branch@33510 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20000427-1.c | 9 | ||||
-rw-r--r-- | gcc/timevar.c | 503 | ||||
-rw-r--r-- | gcc/timevar.def | 73 | ||||
-rw-r--r-- | gcc/timevar.h | 86 | ||||
-rw-r--r-- | libiberty/aclocal.m4 | 71 | ||||
-rw-r--r-- | libiberty/strncmp.c | 28 |
6 files changed, 770 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.c-torture/compile/20000427-1.c b/gcc/testsuite/gcc.c-torture/compile/20000427-1.c new file mode 100644 index 00000000000..dc51419cf01 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20000427-1.c @@ -0,0 +1,9 @@ +int lwidth; +int lheight; +void ConvertFor3dDriver (int requirePO2, int maxAspect) +{ + int oldw = lwidth, oldh = lheight; + + lheight = FindNearestPowerOf2 (lheight); + while (lwidth/lheight > maxAspect) lheight += lheight; +} diff --git a/gcc/timevar.c b/gcc/timevar.c new file mode 100644 index 00000000000..756365bad5a --- /dev/null +++ b/gcc/timevar.c @@ -0,0 +1,503 @@ +/* Timing variables for measuring compiler performance. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Alex Samuel <samuel@codesourcery.com> + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" + +#ifdef HAVE_SYS_TIMES_H +# include <sys/times.h> +#endif + +#include "flags.h" +#include "timevar.h" + +/* See timevar.h for an explanation of timing variables. */ + +/* This macro evaluates to non-zero if timing variables are enabled. */ +#define TIMEVAR_ENABLE (!quiet_flag) + +/* A timing variable. */ + +struct timevar_def +{ + /* Elapsed time for this variable. */ + struct timevar_time_def elapsed; + + /* If this variable is timed independently of the timing stack, + using timevar_start, this contains the start time. */ + struct timevar_time_def start_time; + + /* The name of this timing variable. */ + const char *name; + + /* Non-zero if this timing variable is running as a standalone + timer. */ + unsigned standalone : 1; + + /* Non-zero if this timing variable was ever started or pushed onto + the timing stack. */ + unsigned used : 1; +}; + +/* An element on the timing stack. Elapsed time is attributed to the + topmost timing variable on the stack. */ + +struct timevar_stack_def +{ + /* The timing variable at this stack level. */ + struct timevar_def *timevar; + + /* The next lower timing variable context in the stack. */ + struct timevar_stack_def *next; +}; + +/* Declared timing variables. Constructed from the contents of + timevar.def. */ +static struct timevar_def timevars[TIMEVAR_LAST]; + +/* The top of the timing stack. */ +static struct timevar_stack_def *stack; + +/* A list of unused (i.e. allocated and subsequently popped) + timevar_stack_def instances. */ +static struct timevar_stack_def *unused_stack_instances; + +/* The time at which the topmost element on the timing stack was + pushed. Time elapsed since then is attributed to the topmost + element. */ +static struct timevar_time_def start_time; + +static void get_time + PARAMS ((struct timevar_time_def *)); +static void timevar_add + PARAMS ((struct timevar_time_def *, struct timevar_time_def *)); +static void timevar_accumulate + PARAMS ((struct timevar_time_def *, struct timevar_time_def *, + struct timevar_time_def *)); + +/* Fill the current times into TIME. The definition of this function + also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and + HAVA_WALL_TIME macros. */ + +static void +get_time (now) + struct timevar_time_def *now; +{ + now->user = 0; + now->sys = 0; + now->wall = 0; + + if (!TIMEVAR_ENABLE) + return; + +#ifdef __BEOS__ + /* Nothing. */ +#else /* not BeOS */ +#if defined (_WIN32) && !defined (__CYGWIN__) + if (clock () >= 0) + now->user = clock () * 1000; +#define HAVE_USER_TIME + +#else /* not _WIN32 */ +#ifdef _SC_CLK_TCK + { + static int tick; + struct tms tms; + if (tick == 0) + tick = 1000000 / sysconf (_SC_CLK_TCK); + now->wall = times (&tms) * tick; + now->user = tms.tms_utime * tick; + now->sys = tms.tms_stime * tick; + } +#define HAVE_USER_TIME +#define HAVE_SYS_TIME +#define HAVE_WALL_TIME + +#else +#ifdef USG + { + struct tms tms; +# if HAVE_SYSCONF && defined _SC_CLK_TCK +# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */ +# else +# ifdef CLK_TCK +# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */ +# else +# define TICKS_PER_SECOND HZ /* traditional UNIX */ +# endif +# endif + now->wall = times (&tms) * (1000000 / TICKS_PER_SECOND); + now->user = tms.tms_utime * (1000000 / TICKS_PER_SECOND); + now->sys = tms.tms_stime * (1000000 / TICKS_PER_SECOND); + } +#define HAVE_USER_TIME +#define HAVE_SYS_TIME +#define HAVE_WALL_TIME + +#else +#ifndef VMS + { + struct rusage rusage; + getrusage (0, &rusage); + now->user + = rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec; + now->sys + = rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec; + } +#define HAVE_USER_TIME +#define HAVE_SYS_TIME + +#else /* VMS */ + { + struct + { + int proc_user_time; + int proc_system_time; + int child_user_time; + int child_system_time; + } vms_times; + now->wall = times ((void *) &vms_times) * 10000; + now->user = vms_times.proc_user_time * 10000; + now->sys = vms_times.proc_system_time * 10000; + } +#define HAVE_USER_TIME +#define HAVE_SYS_TIME +#define HAVE_WALL_TIME + +#endif /* VMS */ +#endif /* USG */ +#endif /* _SC_CLK_TCK */ +#endif /* _WIN32 */ +#endif /* __BEOS__ */ +} + +/* Add ELAPSED to TIMER. */ + +static void +timevar_add (timer, elapsed) + struct timevar_time_def *timer; + struct timevar_time_def *elapsed; +{ + timer->user += elapsed->user; + timer->sys += elapsed->sys; + timer->wall += elapsed->wall; +} + +/* Add the difference between STOP_TIME and START_TIME to TIMER. */ + +static void +timevar_accumulate (timer, start_time, stop_time) + struct timevar_time_def *timer; + struct timevar_time_def *start_time; + struct timevar_time_def *stop_time; +{ + timer->user += stop_time->user - start_time->user; + timer->sys += stop_time->sys - start_time->sys; + timer->wall += stop_time->wall - start_time->wall; +} + +/* Initialize timing variables. */ + +void +init_timevar () +{ + if (!TIMEVAR_ENABLE) + return; + + /* Zero all elapsed times. */ + memset ((void *) timevars, 0, sizeof (timevars)); + + /* Initialize the names of timing variables. */ +#define DEFTIMEVAR(identifer__, name__) \ + timevars[identifer__].name = name__; +#include "timevar.def" +#undef DEFTIMEVAR +} + +/* Push TIMEVAR onto the timing stack. No further elapsed time is + attributed to the previous topmost timing variable on the stack; + subsequent elapsed time is attributed to TIMEVAR, until it is + popped or another element is pushed on top. + + TIMEVAR cannot be running as a standalone timer. */ + +void +timevar_push (timevar) + timevar_id_t timevar; +{ + struct timevar_def *tv = &timevars[timevar]; + struct timevar_stack_def *context; + struct timevar_time_def now; + + if (!TIMEVAR_ENABLE) + return; + + /* Mark this timing variable as used. */ + tv->used = 1; + + /* Can't push a standalone timer. */ + if (tv->standalone) + abort (); + + /* What time is it? */ + get_time (&now); + + /* If the stack isn't empty, attribute the current elapsed time to + the old topmost element. */ + if (stack) + timevar_accumulate (&stack->timevar->elapsed, &start_time, &now); + + /* Reset the start time; from now on, time is attributed to + TIMEVAR. */ + start_time = now; + + /* See if we have a previously-allocated stack instance. If so, + take it off the list. If not, malloc a new one. */ + if (unused_stack_instances != NULL) + { + context = unused_stack_instances; + unused_stack_instances = unused_stack_instances->next; + } + else + context = (struct timevar_stack_def *) + xmalloc (sizeof (struct timevar_stack_def)); + + /* Fill it in and put it on the stack. */ + context->timevar = tv; + context->next = stack; + stack = context; +} + +/* Pop the topmost timing variable element off the timing stack. The + popped variable must be TIMEVAR. Elapsed time since the that + element was pushed on, or since it was last exposed on top of the + stack when the element above it was popped off, is credited to that + timing variable. */ + +void +timevar_pop (timevar) + timevar_id_t timevar; +{ + struct timevar_time_def now; + struct timevar_stack_def *popped = stack; + + if (!TIMEVAR_ENABLE) + return; + + if (&timevars[timevar] != stack->timevar) + abort (); + + /* What time is it? */ + get_time (&now); + + /* Attribute the elapsed time to the element we're popping. */ + timevar_accumulate (&popped->timevar->elapsed, &start_time, &now); + + /* Reset the start time; from now on, time is attributed to the + element just exposed on the stack. */ + start_time = now; + + /* Take the item off the stack. */ + stack = stack->next; + + /* Don't delete the stack element; instead, add it to the list of + unused elements for later use. */ + popped->next = unused_stack_instances; + unused_stack_instances = popped; +} + +/* Start timing TIMEVAR independently of the timing stack. Elapsed + time until timevar_stop is called for the same timing variable is + attributed to TIMEVAR. */ + +void +timevar_start (timevar) + timevar_id_t timevar; +{ + struct timevar_def *tv = &timevars[timevar]; + + if (!TIMEVAR_ENABLE) + return; + + /* Mark this timing variable as used. */ + tv->used = 1; + + /* Don't allow the same timing variable to be started more than + once. */ + if (tv->standalone) + abort (); + tv->standalone = 1; + + get_time (&tv->start_time); +} + +/* Stop timing TIMEVAR. Time elapsed since timevar_start was called + is attributed to it. */ + +void +timevar_stop (timevar) + timevar_id_t timevar; +{ + struct timevar_def *tv = &timevars[timevar]; + struct timevar_time_def now; + + if (!TIMEVAR_ENABLE) + return; + + /* TIMEVAR must have been started via timevar_start. */ + if (!tv->standalone) + abort (); + + get_time (&now); + timevar_accumulate (&tv->elapsed, &tv->start_time, &now); +} + +/* Fill the elapsed time for TIMEVAR into ELAPSED. Returns + update-to-date information even if TIMEVAR is currently running. */ + +void +timevar_get (timevar, elapsed) + timevar_id_t timevar; + struct timevar_time_def *elapsed; +{ + struct timevar_def *tv = &timevars[timevar]; + + *elapsed = tv->elapsed; + + /* Is TIMEVAR currently running as a standalone timer? */ + if (tv->standalone) + /* Add the time elapsed since the it was started. */ + timevar_add (elapsed, &tv->start_time); + + /* Is TIMEVAR at the top of the timer stack? */ + if (stack->timevar == tv) + /* Add the elapsed time since it was pushed. */ + timevar_add (elapsed, &start_time); +} + +/* Summarize timing variables to FP. The timing variable TV_TOTAL has + a special meaning -- it's considered to be the total elapsed time, + for normalizing the others, and is displayed last. */ + +void +timevar_print (fp) + FILE *fp; +{ + /* Only print stuff if we have some sort of time information. */ +#if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME) + timevar_id_t id; + struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed; + + if (!TIMEVAR_ENABLE) + return; + + fprintf (fp, "\nExecution times (seconds)\n"); + for (id = 0; id < TIMEVAR_LAST; ++id) + { + struct timevar_def *tv = &timevars[id]; + + /* Don't print the total execution time here; that goes at the + end. */ + if (id == TV_TOTAL) + continue; + + /* Don't print timing variables that were never used. */ + if (!tv->used) + continue; + + /* The timing variable name. */ + fprintf (fp, " %-22s:", tv->name); + +#ifdef HAVE_USER_TIME + /* Print user-mode time for this process. */ + fprintf (fp, "%4ld.%02ld (%2.0f%%) usr", + tv->elapsed.user / 1000000, + (tv->elapsed.user % 1000000) / 10000, + (total->user == 0) ? 0.0 + : (100.0 * tv->elapsed.user / (double) total->user)); +#endif /* HAVE_USER_TIME */ + +#ifdef HAVE_SYS_TIME + /* Print system-mode time for this process. */ + fprintf (fp, "%4ld.%02ld (%2.0f%%) sys", + tv->elapsed.sys / 1000000, + (tv->elapsed.sys % 1000000) / 10000, + (total->sys == 0) ? 0.0 + : (100.0 * tv->elapsed.sys / (double) total->sys)); +#endif /* HAVE_SYS_TIME */ + +#ifdef HAVE_WALL_TIME + /* Print wall clock time elapsed. */ + fprintf (fp, "%4ld.%02ld (%2.0f%%) wall", + tv->elapsed.wall / 1000000, + (tv->elapsed.wall % 1000000) / 10000, + (total->wall == 0) ? 0.0 + : (100.0 * tv->elapsed.wall / (double) total->wall)); +#endif /* HAVE_WALL_TIME */ + + fprintf (fp, "\n"); + } + + /* Print total time. */ + fprintf (fp, " TOTAL :"); +#ifdef HAVE_USER_TIME + fprintf (fp, "%4ld.%02ld ", + total->user / 1000000, (total->user % 1000000) / 10000); +#endif +#ifdef HAVE_SYS_TIME + fprintf (fp, "%4ld.%02ld ", + total->sys / 1000000, (total->sys % 1000000) / 10000); +#endif +#ifdef HAVE_WALL_TIME + fprintf (fp, "%4ld.%02ld\n", + total->wall / 1000000, (total->wall % 1000000) / 10000); +#endif + +#endif /* defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) + || defined (HAVE_WALL_TIME) */ +} + +/* Returns time (user + system) used so far by the compiler process, + in microseconds. */ + +long +get_run_time () +{ + struct timevar_time_def total_elapsed; + timevar_get (TV_TOTAL, &total_elapsed); + return total_elapsed.user + total_elapsed.sys; +} + +/* Prints a message to stderr stating that time elapsed in STR is + TOTAL (given in microseconds). */ + +void +print_time (str, total) + const char *str; + long total; +{ + long all_time = get_run_time (); + fprintf (stderr, + "time in %s: %ld.%06ld (%ld%%)\n", + str, total / 1000000, total % 1000000, + all_time == 0 ? 0 + : (long) (((100.0 * (double) total) / (double) all_time) + .5)); +} diff --git a/gcc/timevar.def b/gcc/timevar.def new file mode 100644 index 00000000000..865d074df6a --- /dev/null +++ b/gcc/timevar.def @@ -0,0 +1,73 @@ +/* This file contains the definitions for timing variables used to + measure run-time performance of the compiler. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Alex Samuel <samuel@codesourcery.com> + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This file contains timing variable definitions, used by timevar.h + and timevar.c. + + Syntax: + + DEFTIMEVAR (id, name) + + where ID is the enumeral value used to identify the timing + variable, and NAME is a character string describing its purpose. */ + +/* The total execution time. */ +DEFTIMEVAR (TV_TOTAL , "total time") + +/* Time spent garbage-collecting. */ +DEFTIMEVAR (TV_GC , "garbage collection") + +/* Time spent generating dump files. */ +DEFTIMEVAR (TV_DUMP , "dump files") + +/* Timing in various stages of the compiler. */ +DEFTIMEVAR (TV_PARSE , "parser") +DEFTIMEVAR (TV_VARCONST , "varconst") +DEFTIMEVAR (TV_INTEGRATION , "integration") +DEFTIMEVAR (TV_JUMP , "jump") +DEFTIMEVAR (TV_CSE , "CSE") +DEFTIMEVAR (TV_GCSE , "global CSE") +DEFTIMEVAR (TV_LOOP , "loop analysis") +DEFTIMEVAR (TV_CSE2 , "CSE 2") +DEFTIMEVAR (TV_BRANCH_PROB , "branch prediction") +DEFTIMEVAR (TV_FLOW , "flow analysis") +DEFTIMEVAR (TV_COMBINE , "combiner") +DEFTIMEVAR (TV_REGMOVE , "regmove") +DEFTIMEVAR (TV_SCHED , "scheduling") +DEFTIMEVAR (TV_LOCAL_ALLOC , "local alloc") +DEFTIMEVAR (TV_GLOBAL_ALLOC , "global alloc") +DEFTIMEVAR (TV_RELOAD_CSE_REGS , "reload CSE regs") +DEFTIMEVAR (TV_FLOW2 , "flow 2") +DEFTIMEVAR (TV_PEEPHOLE2 , "peephole 2") +DEFTIMEVAR (TV_SCHED2 , "schedulding 2") +DEFTIMEVAR (TV_DBR_SCHED , "delay branch sched") +DEFTIMEVAR (TV_REORDER_BLOCKS , "reorder blocks") +DEFTIMEVAR (TV_RENAME_REGISTERS , "rename registers") +DEFTIMEVAR (TV_SHORTEN_BRANCH , "shorten branches") +DEFTIMEVAR (TV_REG_STACK , "reg stack") +DEFTIMEVAR (TV_TO_SSA , "convert to SSA") +DEFTIMEVAR (TV_FROM_SSA , "convert from SSA") +DEFTIMEVAR (TV_FINAL , "final") +DEFTIMEVAR (TV_SYMOUT , "symout") + +/* Everything else in rest_of_compilation not included above. */ +DEFTIMEVAR (TV_REST_OF_COMPILATION , "rest of compilation") diff --git a/gcc/timevar.h b/gcc/timevar.h new file mode 100644 index 00000000000..c7fcfa70456 --- /dev/null +++ b/gcc/timevar.h @@ -0,0 +1,86 @@ +/* Timing variables for measuring compiler performance. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Alex Samuel <samuel@codesourcery.com> + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Timing variables are used to measure elapsed time in various + portions of the compiler. Each measures elapsed user, system, and + wall-clock time, as appropriate to and supported by the host + system. + + Timing variables are defined using the DEFTIMEVAR macro in + timevar.def. Each has an enumeral identifier, used when referring + to the timing variable in code, and a character string name. + + Timing variables can be used in two ways: + + - On the timing stack, using timevar_push and timevar_pop. + Timing variables may be pushed onto the stack; elapsed time is + attributed to the topmost timing variable on the stack. When + another variable is pushed on, the previous topmost variable is + `paused' until the pushed variable is popped back off. + + - As a standalone timer, using timevar_start and timevar_stop. + All time elapsed between the two calls is attributed to the + variable. +*/ + +/* This structure stores the various varieties of time that can be + measured. Times are stored in microseconds. The time may be an + absolute time or a time difference; in the former case, the time + base is undefined, except that the difference between two times + produces a valid time difference. */ + +struct timevar_time_def +{ + /* User time in this process. */ + long user; + + /* System time (if applicable for this host platform) in this + process. */ + long sys; + + /* Wall clock time. */ + long wall; +}; + +/* An enumeration of timing variable indentifiers. Constructed from + the contents of timevar.def. */ + +#define DEFTIMEVAR(identifier__, name__) \ + identifier__, +typedef enum +{ +#include "timevar.def" + TIMEVAR_LAST +} +timevar_id_t; +#undef DEFTIMEVAR + +extern void init_timevar PARAMS ((void)); +extern void timevar_push PARAMS ((timevar_id_t)); +extern void timevar_pop PARAMS ((timevar_id_t)); +extern void timevar_start PARAMS ((timevar_id_t)); +extern void timevar_stop PARAMS ((timevar_id_t)); +extern void timevar_get PARAMS ((timevar_id_t, struct timevar_time_def *)); +extern void timevar_print PARAMS ((FILE *)); + +/* Provided for backward compatibility. */ +extern long get_run_time PARAMS ((void)); +extern void print_time PARAMS ((const char *, long)); diff --git a/libiberty/aclocal.m4 b/libiberty/aclocal.m4 new file mode 100644 index 00000000000..b6a38d60522 --- /dev/null +++ b/libiberty/aclocal.m4 @@ -0,0 +1,71 @@ +dnl See whether strncmp reads past the end of its string parameters. +dnl On some versions of SunOS4 at least, strncmp reads a word at a time +dnl but erroneously reads past the end of strings. This can cause +dnl a SEGV in some cases. +AC_DEFUN(libiberty_AC_FUNC_STRNCMP, +[AC_REQUIRE([AC_FUNC_MMAP]) +AC_CACHE_CHECK([for working strncmp], ac_cv_func_strncmp_works, +[AC_TRY_RUN([ +/* Test by Jim Wilson and Kaveh Ghazi. + Check whether strncmp reads past the end of its string parameters. */ +#include <sys/types.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#else +#define MAP_ANON MAP_FILE +#endif +#endif + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif + +#define MAP_LEN 0x10000 + +main () +{ +#if defined(HAVE_MMAP) || defined(HAVE_MMAP_ANYWHERE) + char *p; + int dev_zero; + + dev_zero = open ("/dev/zero", O_RDONLY); + if (dev_zero < 0) + exit (1); + + p = (char *) mmap (0, MAP_LEN, PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, dev_zero, 0); + if (p == (char *)-1) + exit (2); + else + { + char *string = "__si_type_info"; + char *q = (char *) p + MAP_LEN - strlen (string) - 2; + char *r = (char *) p + 0xe; + + strcpy (q, string); + strcpy (r, string); + strncmp (r, q, 14); + } +#endif /* HAVE_MMAP || HAVE_MMAP_ANYWHERE */ + exit (0); +} +], ac_cv_func_strncmp_works=yes, ac_cv_func_strncmp_works=no, + ac_cv_func_strncmp_works=no) +rm -f core core.* *.core]) +if test $ac_cv_func_strncmp_works = no ; then + LIBOBJS="$LIBOBJS strncmp.o" +fi +]) diff --git a/libiberty/strncmp.c b/libiberty/strncmp.c new file mode 100644 index 00000000000..b3b9de16b10 --- /dev/null +++ b/libiberty/strncmp.c @@ -0,0 +1,28 @@ +/* strncmp -- compare two strings, stop after n bytes. + This function is in the public domain. */ + +#include <ansidecl.h> +#ifdef __STDC__ +#include <stddef.h> +#else +#define size_t unsigned long +#endif + +int +strncmp(s1, s2, n) + const char *s1, *s2; + register size_t n; +{ + register unsigned char u1, u2; + + while (n-- > 0) + { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} |