Browse Source

Move the FAQ. Add a docs dir. Add in a report on thread support.
-Erik

Eric Andersen 22 years ago
parent
commit
dfb5fe2dee
2 changed files with 2293 additions and 4 deletions
  1. 18 4
      docs/FAQ.txt
  2. 2275 0
      docs/threads.txt

+ 18 - 4
FAQ.txt → docs/FAQ.txt

@@ -5,6 +5,20 @@ have additions to this FAQ document, I'd love to add them,
  -Erik
  -Erik
 
 
 
 
+Q: What platforms does uClibc run on?
+
+    Currently uClibc runs on arm, i386, m68k, mipsel, powerpc, sh,
+    sparc, and v850.  
+    
+
+
+Q: Does uClibc support shared libraries?
+    
+    Yes.  uClibc has shared library support on x86, arm, and powerpc.  
+    Shared Libraries are _not_ currently supported on MMU-less systems. 
+
+
+
 Q: Why is it called uClibc?
 Q: Why is it called uClibc?
 
 
     The letter 'u' is short for the greek letter "mu".  "Mu" stands for
     The letter 'u' is short for the greek letter "mu".  "Mu" stands for
@@ -37,6 +51,7 @@ Q: Why are you doing this?  Whats wrong with glibc?
     not wanted in embedded systems." 24 May 1999
     not wanted in embedded systems." 24 May 1999
 
 
 
 
+
 Q: So uClibc is smaller then glibc?  Doesn't that mean it completely sucks?
 Q: So uClibc is smaller then glibc?  Doesn't that mean it completely sucks?
     How could it be smaller and not suck?
     How could it be smaller and not suck?
 
 
@@ -72,7 +87,6 @@ Q: Why should I use uClibc?
 
 
 
 
 
 
-
 Q: I want to create a closed source commercial application and  I want to
 Q: I want to create a closed source commercial application and  I want to
     protect my intellectual property.  If I use uClibc, don't I have to 
     protect my intellectual property.  If I use uClibc, don't I have to 
     release my source code?
     release my source code?
@@ -110,6 +124,7 @@ Q: How do I compile stuff?
 
 
 
 
 Q: How do I make autoconf and automake behave?
 Q: How do I make autoconf and automake behave?
+
     First run
     First run
 	export PATH=/usr/i386-linux-uclibc/bin:$PATH
 	export PATH=/usr/i386-linux-uclibc/bin:$PATH
     (or similar adjusted for your target architecture) then run you can simply
     (or similar adjusted for your target architecture) then run you can simply
@@ -135,7 +150,6 @@ Q: I need you to add <favorite feature> now!   How come you don't answer all my
     questions on the mailing list withing 5 minutes?  I demand that you help me
     questions on the mailing list withing 5 minutes?  I demand that you help me
     Right Now!
     Right Now!
 
 
-
     You have not paid me a single cent and yet you still have the product of
     You have not paid me a single cent and yet you still have the product of
     over year and a half of my work, and lots of work from other people.  How
     over year and a half of my work, and lots of work from other people.  How
     dare you treat me that way!  I work on uClibc because I find it
     dare you treat me that way!  I work on uClibc because I find it
@@ -146,11 +160,11 @@ Q: I need you to add <favorite feature> now!   How come you don't answer all my
 Q: I need you to add <favorite feature>!  Are the uClibc developers willing to 
 Q: I need you to add <favorite feature>!  Are the uClibc developers willing to 
     be paid in order to add in <favorite feature>?  Are you willing to provide
     be paid in order to add in <favorite feature>?  Are you willing to provide
     support contracts?  
     support contracts?  
-    
 
 
     Sure!  Now you have our attention!  What you should do is contact 
     Sure!  Now you have our attention!  What you should do is contact 
     Erik Andersen of CodePoet Consulting to bid on your project.  If Erik
     Erik Andersen of CodePoet Consulting to bid on your project.  If Erik
-    is too busy to personally add your feature
+    is too busy to personally add your feature, there are several other
+    active contributors who may be able to help you out.
     
     
     
     
 Q: I think you guys are great and I want to help support your work!
 Q: I think you guys are great and I want to help support your work!

+ 2275 - 0
docs/threads.txt

@@ -0,0 +1,2275 @@
+uClibc thread-safety analysis
+By Steve Thayer <sthayer@coactive.com>
+with updates by Erik Andersen <andersee@debian.org>
+
+Introduction:
+
+The purpose of this document is to identify the things that need to be done
+to the uClibc C library in order to make it thread-safe.  The goal is to be
+able to use a pthreads thread implementation under uClinux, using the uClibc
+C library.  To help identify the things that require changing, I used David R.
+Butenhof's book Programming With POSIX Threads, the source code for the
+glibc 2.1.3 C library, and the source code for the C library included in the
+Proventhreads distribution.
+
+References:
+
+Butenhof, David R., Programming With POSIX Threads,  Addison Wesley Longman, Inc., Reading, MA, ISBN 0-201-63392-2, 1997.
+
+
+The GNU C library is available from the Free Software Foundation 
+http://www.gnu.org/software/libc/libc.html
+
+Proventhreads is part of the Inferno Operating system.
+http://www.vitanuova.com/inferno/index.html
+
+
+1. Stdio:
+
+1.1 Buffer access mutexes
+
+        The following functions are required in order to protect shared
+        I/O buffers from being accessed by more than one thread at a time.
+        None of these functions are currently implemented in the uClibc
+        library, so they must be added.
+
+        flockfile               <required>                              <---
+        ftrylockfile            <required>                              <---
+        funlockfile             <required>                              <---
+
+1.2 Functions that must use buffer access mutexes, according to Butenhof
+
+        The following functions are identified by Butenhof as needing to use
+        buffer access mutexes.  This does not represent all functions that
+        need to use the mutexes.
+
+        getc                    <mutex required>                        <---
+        getchar                 <mutex required>                        <---
+        putc                    <mutex required>                        <---
+        putchar                 <mutex required>                        <---
+
+1.3 Functions from glibc (libio) that use buffer access mutexes
+
+        The following functions are functions found in glibc that currently
+        use the buffer access mutexes.  Comments in brackets represent
+        status of uClibc with regard to these functions.  Most of these
+        functions aren't even supported under uClibc, so no work is required.
+        The rest may require the access mutex. (These must be analyzed on a
+        case-by-case basis.)
+
+        clearerr                <mutex required>                        <---
+        feof                    <mutex required>                        <---
+        ferror                  <mutex required>                        <---
+        fputc                   <mutex required>                        <---
+        fputwc                  <not supported>
+        freopen                 <mutex required>                        <---
+        freopen64               <not supported>
+        fseek                   <mutex required>                        <---
+        fseeko                  <not supported>
+        fseeko64                <not supported>
+        ftello                  <not supported>
+        ftello64                <not supported>
+        fwide                   <not supported>
+        getc                    <macro for fgetc>
+        getchar                 <macro for fgetc>
+        getwc                   <not supported>
+        getwchar                <not supported>
+        iofclose                <not supported>
+        iofflush                <not supported>
+        iofgetpos               <not supported>
+        iofgetpos64             <not supported>
+        iofgets                 <not supported>
+        iofgetws                <not supported>
+        iofputs                 <not supported>
+        iofputws                <not supported>
+        iofread                 <not supported>
+        iofsetpos               <not supported>
+        iofsetpos64             <not supported>
+        ioftell                 <not supported>
+        iofwrite                <not supported>
+        iogetdelim              <not supported>
+        iogets                  <not supported>
+        ioputs                  <not supported>
+        ioseekoff               <not supported>
+        ioseekpos               <not supported>
+        iosetbuffer             <not supported>
+        iosetvbuf               <not supported>
+        ioungetc                <not supported>
+        ioungetwc               <not supported>
+        oldiofclose             <not supported>
+        oldiofgetpos            <not supported>
+        oldiofgetpos64          <not supported>
+        oldiofsetpos            <not supported>
+        oldiofsetpos64          <not supported>
+        peekc                   <not supported>
+        putc                    <macro for fputc>
+        putchar                 <macro for fputc>
+        putwc                   <not supported>
+        putwchar                <not supported>
+        rewind                  <mutex required>                        <---
+
+1.4 Functions from Proventhreads that use buffer access mutexes
+
+        See description above.  This applies only to the C library included
+        in the proventhreads distribution.
+
+        clearerr                <mutex required>                        <---
+        fclose                  <mutex required>                        <---
+        fflush                  <mutex required>                        <---
+        fgetc                   <mutex required>                        <---
+        __getc                  <not supported>
+        fgetline                <not supported>
+        fgetpos                 <mutex required>                        <---
+        fgets                   <mutex required>                        <---
+        fpurge                  <not supported>
+        fputc                   <mutex required>                        <---
+        __putc                  <not supported>
+        fputs                   <mutex required>                        <---
+        fread                   <mutex required>                        <---
+        freopen                 <mutex required>                        <---
+        fscanf                  <mutex required>                        <---
+        fseek                   <mutex required>                        <---
+        ftell                   <mutex required>                        <---
+        fwalk                   <not supported>
+        fwrite                  <mutex required>                        <---
+        getc                    <macro for fgetc>
+        getchar                 <mutex required>                        <---
+        putc                    <macro for fputc>
+        putchar                 <mutex required>                        <---
+        puts                    <mutex required>                        <---
+        putw                    <not supported>
+        refill                  <not supported>
+        rewind                  <mutex required>                        <---
+        scanf                   <mutex required>                        <---
+        setvbuf                 <mutex required>                        <---
+        ungetc                  <mutex required>                        <---
+        vfprintf                <mutex required>                        <---
+        vscanf                  <mutex required>                        <---
+
+1.5 Unlocked buffer access
+
+        These functions get used in situations where speed is important,
+        and locking isn't necessary, or for use in a section of code that
+        is already locked.  For example, a for-loop that makes multiple calls
+        to getc could make an exlicit call to flockfile outside the loop, and
+        then use getc_unlocked within the loop for speed.  That way, the lock
+        only needs to be grabbed and released once, rather than for each call.
+
+        getc_unlocked           <required>                              <---
+        getchar_unlocked        <required>                              <---
+        putc_unlocked           <required>                              <---
+        putchar_unlocked        <required>                              <---
+
+1.6 Additional unlocked calls made in glibc
+
+        These are additional functions (not mentioned by Butenhof) that the
+        glibc library uses for unlocked buffer access.  Though not strictly
+        necessary, these may be nice to have in uClibc.
+
+        fileno_unlocked         <desired>                               <---
+        clearerr_unlocked       <desired>                               <---
+        feof_unlocked           <desired>                               <---
+        ferror_unlocked         <desired>                               <---
+        fputc_unlocked          <desired>                               <---
+        fgetc_unlocked          <desired>                               <---
+        fflush_unlocked         <desired>                               <---
+        fread_unlocked          <desired>                               <---
+        fwrite_unlocked         <desired>                               <---
+        fgets_unlocked          <desired>                               <---
+        fputs_unlocked          <desired>                               <---
+
+1.7 Additional unlocked calls made in Proventhreads
+
+        Proventhreads only provides the four unlocked function calls above.
+
+        <none>
+
+
+2. Thread-safe functions:
+
+	There are some functions in the C library standard that are
+	simply not thread-safe and cannot be thread-safe using their
+	current interface.  For example, any function that returns a
+	pointer to static data, or requires static context between
+	calls.  To resolve this problem, new functions were added to
+	the standard that perform the same basic task, but use a new
+	interface that does not require static data.  These functions
+	share their name with the old unsafe functions, but have an
+	"_r" appended to the name.  By definition, these functions are
+	reentrant and thread-safe.  It is important to note that these
+	functions to do not depend on <pthread.h> and can be used even
+	if threading is not supported.
+
+2.1 User and terminal identification:
+
+        getlogin_r              <implemented>
+        ctermid                 <implemented>                           (1)
+        ttyname_r               <required>                              <---
+
+        1. ctermid is a special case.  The signature has not changed, but a
+        requirement has been added that its parameter point to a structure
+        of exactly L_ctermid bytes.  
+
+2.2 Directory searching
+
+        readdir_r               <required>                              <---
+
+2.3 String token
+
+        strtok_r                <implemented>
+
+2.4 Time representation
+
+        asctime_r               <implemented>
+        ctime_r                 <implemented>
+        gmtime_r                <implemented>
+        localtime_r             <implemented>
+
+2.5 Random number generation
+
+        rand_r                  <required>                              <---
+
+2.6 Group and user database
+
+        getgrgid_r              <required>                              <---
+        getgrnam_r              <required>                              <---
+        getpwuid_r              <implemented>
+        getpwnam_r              <implemented>
+
+2.7 Additional thread-safe functions implemented by glibc
+
+        The following is a list of additional functions implemented by glibc
+        that also provide thread-safe functionality.  Most of these functions
+        are not supported by uClibc, so there is no need to implement the
+        thread-safe version.  Those that do apply, but have not been
+        implemented yet are highlighted.
+
+        __fgetpwent_r                   <not supported>
+        fgetpwent_r                     <implemented>
+        __ttyname_r                     <not supported>
+        getttyname_r                    <not supported>
+        __getmntent_r                   <not supported>
+        getmntent_r                     <desired>                       <---
+        ecvt_r                          <not supported>
+        fcvt_r                          <not supported>
+        qecvt_r                         <not supported>
+        qfcvt_r                         <not supported>
+        hcreate_r                       <not supported>
+        hdestroy_r                      <not supported>
+        hsearch_r                       <not supported>
+        __getspent_r                    <not supported>
+        getspent_r                      <not supported>
+        __getspnam_r                    <not supported>
+        getspnam_r                      <not supported>
+        __sgetspent_r                   <not supported>
+        sgetspent_r                     <not supported>
+        __fgetspent_r                   <not supported>
+        fgetspent_r                     <not supported>
+        __gethostbyaddr_r               <not supported>
+        gethostbyaddr_r                 <desired>                       <---
+        __gethostbyname2_r              <not supported>
+        gethostbyname2_r                <not supported>
+        __gethostbyname_r               <not supported>
+        gethostbyname_r                 <desired>                       <---
+        __gethostent_r                  <not supported
+        gethostent_r                    <not supported>
+        __getnetbyaddr_r                <not supported>
+        getnetbyaddr_r                  <desired>                       <---
+        __getnetent_r                   <not supported>
+        getnetent_r                     <desired>                       <---
+        __getnetbyname_r                <not supported>
+        getnetbyname_r                  <desired>                       <---
+        __getprotobynumber_r            <not supported>
+        getprotobynumber_r              <desired>                       <---
+        __getprotoent_r                 <not supported>
+        getprotoent_r                   <desired>                       <---
+        __getprotobyname_r              <not supported>
+        getprotobyname_r                <desired>                       <---
+        __getservbyname_r               <not supported>
+        getservbyname_r                 <desired>                       <---
+        __getservbyport_r               <not supported>
+        getservbyport_r                 <desired>                       <---
+        __getservent_r                  <not supported>
+        getservent_r                    <desired>                       <---
+        __getrpcent_r                   <not supported>
+        getrpcent_r                     <desired>                       <---
+        __getrpcbyname_r                <not supported>
+        getrpcbyname_r                  <desired>                       <---
+        __getrpcbynumber_r              <not supported>
+        getrpcbynumber_r                <desired>                       <---
+        ether_aton_r                    <not supported>
+        ether_ntoa_r                    <not supported>
+        __getnetgrent_r                 <not supported>
+        __internal_getnetgrent_r        <not supported>
+        getnetgrent_r                   <not supported>
+        __getaliasent_r                 <not supported>
+        getaliasent_r                   <not supported>
+        __getaliasbyname_r              <not supported>
+        getaliasbyname_r                <not supported>
+        __nscd_getpwnam_r               <not supported>
+        __nscd_getpwuid_r               <not supported>
+        nscd_getpw_r                    <not supported>
+        __nscd_getgrgid_r               <not supported>
+        __nscd_getgrnam_r               <not supported>
+        nscd_getgr_r                    <not supported>
+        __nscd_gethostbyaddr_r          <not supported>
+        __nscd_gethostbyname2_r         <not supported>
+        __nscd_gethostbyname_r          <not supported>
+        nscd_gethst_r                   <not supported>
+        __getutent_r                    <desired>                       <---
+        getutent_r                      <desired>                       <---
+        getutent_r_unknown              <not supported>
+        getutid_r_unknown               <not supported>
+        getutline_r_unknown             <not supported>
+        __getutid_r                     <not supported>
+        getutid_r                       <desired>                       <---
+        __getutline_r                   <not supported>
+        getutline_r                     <required>                      <---
+        getutent_r_file                 <not supported>
+        getutid_r_file                  <not supported>
+        getutline_r_file                <not supported>
+        internal_getut_r                <not supported>
+        getutent_r_daemon               <not supported>
+        getutid_r_daemon                <not supported>
+        getutline_r_daemon              <not supported>
+        __ptsname_r                     <not supported>
+        ptsname_r                       <not supported>
+
+
+2.8 Additional thread-safe functions implemented by Proventhreads
+
+        See description above.  This applies only to the C library included
+        in the proventhreads distribution.
+
+        inet_ntoa_r             <desired>                               <---
+        gethostbyaddr_r         <desired>                               <---
+        gethostbyname_r         <desired>                               <---
+        gethostent_r            <not supported>
+        getnetbyaddr_r          <desired>                               <---
+        getnetbyname_r          <desired>                               <---
+        getnetent_r             <desired>                               <---
+        getprotobynumber_r      <desired>                               <---
+        getprotoent_r           <desired>                               <---
+        getprotobyname_r        <desired>                               <---
+        getservbyname_r         <desired>                               <---
+        getservbyport_r         <desired>                               <---
+        getservent_r            <desired>                               <---
+
+
+3. List of functions in uClibc that use static data structures
+
+        The following is a list of static data structures found in uClibc,
+        and the functions that use them.  In most cases, static data is not
+        thread-safe, since multiple threads can access the same data at the
+        same time.  This is an attempt to identify all of the static data that
+        is not considered thread-safe.  Some of these problems will get
+        resolved by the changes outlines above.
+
+        crypt/crypt.c:
+
+        static struct crypt_data __crypt_data;
+
+        crypt                   <crypt_r implemented>
+        setkey                  <setkey_r implemented>
+        encrypt                 <encrypt_r implemented>
+
+        --------------------------------------------------------------------
+
+        crypt/md5.c:
+
+        static unsigned char PADDING[64]        <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/addr.c:
+
+        static char buf[16];
+
+        inet_ntoa               <inet_ntoa_r not implemented>           <---
+
+        --------------------------------------------------------------------
+
+        inet/getnetent.c:
+
+        static FILE *netf = NULL;
+        static char line[BUFSIZ+1];
+        static struct netent net;
+        static char *net_aliases[MAXALIASES];
+
+        setnetent               <fix required>                          <---
+        endnetent               <fix required>                          <---
+        getnetent               <getnetent_r required>                  <---
+
+        NOTE: setnetent and endnetent are not implemented in glibc.
+        Proventhreads uses pthread mutexes to protect this static data.
+
+        --------------------------------------------------------------------
+
+        inet/getproto.c:
+
+        static FILE *protof = NULL;
+        static char line[BUFSIZ+1];
+        static struct protoent proto;
+        static char *proto_aliases[MAXALIASES];
+        static int proto_stayopen;
+
+        setprotoent             <fix required>                          <---
+        endprotoent             <fix required>                          <---
+        getprotoent             <getprotoent_r required>                <---
+        getprotobyname          <getprotobyname_r required>             <---
+        getprotobynumber        <getprotobynumber required>             <---
+
+        NOTE: setprotoent and endprotoent are not implemented in glibc.
+        Proventhreads uses pthread mutexes to protect this static data.
+
+        --------------------------------------------------------------------
+
+        inet/getservice.c:
+
+        static FILE *servf = NULL;
+        static char line[BUFSIZ+1];
+        static struct servent serv;
+        static char *serv_aliases[MAXALIASES];
+        static int serv_stayopen;
+
+        setservent              <fix required>                          <---
+        endservent              <fix required>                          <---
+        getservent              <getservent_r required>                 <---
+        getservbyname           <getservbyname_r required>              <---
+        getservbyport           <getservbyport_r required>              <---
+
+        NOTE: setservent and endservent are not implemented in glibc.
+        Proventhreads uses pthread mutexes to protect this static data.
+
+        --------------------------------------------------------------------
+
+        net/resolv.c:   
+
+        static int id = 1;
+        static int ns = 0;
+
+        dns_lookup              <fix required>                          <---
+
+        NOTE: dns_lookup is not implemented by glibc or Proventhreads.
+
+        static struct hostent h;
+        static char namebuf[256];
+        static struct in_addr in;
+        static struct in_addr *addr_list[2];
+
+        gethostbyname           <gethostbyname_r required>              <---
+
+        static struct hostent h;
+        static char namebuf[256];
+        static struct in_addr in;
+        static struct in_addr *addr_list[2];
+
+        gethostbyaddr           <gethostbyaddr_r required>              <---
+
+        static struct hostent   h;
+        static struct in_addr   in;
+        static struct in_addr   *addr_list[2];
+        static char                             line[80];
+
+        read_etc_hosts          <fix required>                          <---
+
+        NOTE: dns_lookup is not implemented by glibc or Proventhreads.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/auth_none.c:
+
+        static struct auth_ops ops
+        static struct authnone_private
+
+        authnone_create         <fix required>                          <---
+        authnone_marshal        <fix required>                          <---
+
+        NOTE: This file makes a lot of use of this static variable and
+        also a global allocated authentication structure.  Care should
+        be taken in fixing this to make it thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/auth_unix.c:
+
+        static struct auth_ops auth_unix_ops
+
+        authunix_create         <fix required>                          <---
+        marshal_new_auth        <fix required>                          <---
+
+        NOTE: This file makes a lot of use of this static variable and
+        also a global allocated authentication structure.  Care should
+        be taken in fixing this to make it thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/bindresvport.c:
+
+        static short port;
+
+        bindresvport            <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        inet/rpc/clnt_perror.c:
+
+        static char *buf;
+        static struct rpc_errtab rpc_errlist[]
+        static struct auth_errtab auth_errlist[]
+
+        NOTE: These static structures all have #if 0 around them, so they
+        do not get compiled in.  Hopefully, we don't have to worry about
+        them right now, but prehaps a comment should be added to the code
+        indicating that it is not thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/clnt_raw.c:
+
+        static struct clntraw_private
+        static struct clnt_ops client_ops
+        
+        clntraw_create          <fix required>                          <---
+        clntraw_call            <fix required>                          <---
+        clntraw_freeres         <fix required>                          <---
+
+        NOTE: This file makes a lot of use of these static variables and
+        also a global allocated client structure.  Care should
+        be taken in fixing this to make it thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/clnt_simple.c:
+
+        static struct callrpc_private
+
+        callrpc                 <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        inet/rpc/clnt_tcp.c:
+
+        static struct clnt_ops tcp_ops
+
+        clnttcp_create
+
+        NOTE: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/clnt_udp.c:
+
+        static struct clnt_ops udp_ops
+
+        clntudp_bufcreate
+
+        NOTE: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/getrpcent.c:
+
+        static char RPCDB[]     <fix desired>                           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/pmap_clnt.c:
+
+        static struct timeval timeout           <fix desired>           <---
+        static struct timeval tottimeout        <fix desired>           <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/pmap_getport.c:
+
+        static struct timeval timeout           <fix desired>           <---
+        static struct timeval tottimeout        <fix desired>           <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/pmap_rmt.c:
+
+        static struct timeval timeout           <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/rpc_dtablesize.c:
+
+        static int size;
+
+        _rpc_dtablesize         <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        inet/rpc/rpc_prot.c:
+
+        static struct xdr_discrim reply_dscrm[3]        <fix desired>   <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/svc.c:
+
+        static SVCXPRT **xports;
+        static SVCXPRT *xports[NOFILE];
+        static struct svc_callout
+
+        xprt_register           <fix required>                          <---
+        xprt_unregister         <fix required>                          <---
+        svc_getreqset           <fix required>                          <---
+        svc_register            <fix required>                          <---
+        svc_unregister          <fix required>                          <---
+        svc_callout             <fix required>                          <---
+
+        NOTE: This is intricate code, and care should be taken when making
+        this thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/svc_auth.c:
+
+        static struct svcauthsw         <fix desired>                   <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        net/rpc/svc_raw.c:      
+
+        static struct svcraw_private
+        static struct xp_ops server_ops
+
+        svcraw_create           <fix required>                          <---
+        svcraw_recv             <fix required>                          <---
+        svcraw_reply            <fix required>                          <---
+        svcraw_getargs          <fix required>                          <---
+        svcraw_freeargs         <fix required>                          <---
+
+        NOTE: This is intricate code, and care should be taken when making
+        this thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/svc_simple.c:
+
+        static struct proglst
+        static SVCXPRT *transp;
+
+        registerrpc             <fix required>                          <---
+        universal               <fix required>                          <---
+
+        NOTE: This is intricate code, and care should be taken when making
+        this thread-safe.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/svc_tcp.c:
+
+        static struct xp_ops svctcp_op
+        static struct xp_ops svctcp_rendezvous_op
+
+        svctcp_create           <fix required>                          <---
+        makefd_xprt             <fix required>                          <---
+
+        NOTE: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        static struct timeval wait_per_try
+
+        readtcp                 <fix required>                          <---
+
+        NOTE: This looks like a bug.  This static timeout value is passed
+        by reference to a select() call.  According to the linux man page
+        for select:
+
+                "On  Linux,  timeout  is  modified to reflect the amount of
+                time not slept; most other implementations do not do this.
+                This  causes  problems  both  when  Linux code which reads
+                timeout is ported to other  operating  systems,  and  when
+                code  is  ported to Linux that reuses a struct timeval for
+                multiple selects in  a  loop  without  reinitializing  it.
+                Consider timeout to be undefined after select returns."
+
+        Unless the implementation of select is different than that of Linux,
+        this needs to be fixed!
+
+        --------------------------------------------------------------------
+
+        inet/rpc/svc_udp.c:
+
+        static struct xp_ops svcudp_op          <fix desired>           (1)
+
+        svcudp_bufcreate
+
+        1: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/xdr.c: 
+
+        static char xdr_zero[BYTES_PER_XDR_UNIT]        <fix desired>   <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        static u_long crud[BYTES_PER_XDR_UNIT]
+
+        NOTE: This looks like it doesn't matter what's in this array.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/xdr_float.c:
+
+        static struct sgl_limits        <fix desired>                   <---
+        static struct dbl_limits        <fix desired>                   <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/xdr_mem.c:
+
+        static struct xdr_ops xdrmem_ops        <fix desired>           (1)
+
+        xdrmem_create
+
+        1: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/xdr_rec.c:
+
+        static struct xdr_ops xdrrec_ops        <fix desired>           (1)
+
+        xdrrec_create
+
+        1: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        --------------------------------------------------------------------
+
+        inet/rpc/xdr_stdio.c:
+
+        static struct xdr_ops xdrstdio_ops      <fix desired>           (1)
+
+        xdrstdio_create
+
+        1: This static structure is just a group of function pointers.
+        It could probably be made const, but this might affect the function
+        signature.  This should be investigated further.
+
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/boot1.c:
+
+        static char *_dl_malloc_addr
+        static char *_dl_mmap_zero
+        static char *_dl_not_lazy
+        static char *_dl_warn
+        static char *_dl_trace_loaded_objects
+
+        _dl_boot                <fix required>                          <---
+        _dl_malloc              <fix required>                          <---
+        _dl_fixup               <fix required>                          <---
+
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+        
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/readelflib1.c:
+
+        static caddr_t _dl_cache_addr
+        static size_t _dl_cache_size
+
+        _dl_map_cache           <fix required>                          <---
+        _dl_unmap_cache         <fix required>                          <---
+        _dl_load_shared_library <fix required>                          <---
+	
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+        
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/string.h:
+
+        static char local[22]
+
+        _dl_simple_ltoa         <fix required>                          <---
+        _dl_simple_ltoahex      <fix required>                          <---
+
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/arm/elfinterp.c:
+
+        static char *_dl_reltypes[]     <fix desired>                   <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/i386/elfinterp.c:
+
+        static char *_dl_reltypes[]     <fix desired>                   <---
+
+        NOTE: This is okay, but should use the const keyword.
+	
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/m68k/elfinterp.c:
+
+        static char *_dl_reltypes[]     <fix desired>                   <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+
+        --------------------------------------------------------------------
+
+        ld.so-1/d-link/sparc/elfinterp.c:
+
+        static char *_dl_reltypes[]     <fix desired>                   <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+
+        --------------------------------------------------------------------
+
+        ld.so-1/libdl/dlib.c:
+
+        static int dl_init
+
+        _dlopen                 <fix required>                          <---
+
+        static int __attribute__ ((unused)) foobar1     <fix required?> (1)
+
+        NOTE: The comment for this says it all: "This is a real hack." ;-)
+	
+
+        static char *type[]     <fix desired>                           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+	These are all part of the shared library loader, and are not
+	used by applications directly.  Therefore, fixing these is not 
+	a high priority item. 
+
+        --------------------------------------------------------------------
+
+        ld.so-1/util/ldconfig.c:
+
+        static header_t magic   <fix desired>                           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        static liblist_t *lib_head
+
+        cache_dolib             <fix required>                          <---
+        cache_write             <fix required>                          <---
+        
+	This is not actually part of the C library, and is not built by
+	default, so fixing these is not a high priority item. 
+
+        --------------------------------------------------------------------
+
+        misc/internals/tempname.c:
+
+        static uint64_t value;
+
+        __gen_tempname          <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        misc/locale/locale.c:
+
+        static char C_LOCALE_NAME[]="C";        <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        static struct SAV_LOADED_LOCALE sav_loaded_locale [1]
+        static struct SAV_LOADED_LOCALE * old_locale
+
+        setlocale               <fix required>                          <---
+
+        NOTE: Can different threads use different locales?  I don't see
+        why not.
+
+        --------------------------------------------------------------------
+
+        misc/locale/localeconv.c:
+
+        static struct lconv result;
+
+        localeconv              <fix required>                          <---
+
+        NOTE: This function returns a pointer to a static data structure.
+
+        static char *blank = "";        <fix desired>                   <---
+        static char *decimal = ".";     <fix desired>                   <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        misc/mntent/mntent.c:
+
+        static char buff[MNTMAXSTR];
+        static struct mntent mnt;
+
+        getmntent               <getmntent_r required>                  <---
+
+        --------------------------------------------------------------------
+
+        misc/regex/regex.c:
+
+        static char re_syntax_table[CHAR_SET_SIZE];
+        static int done = 0;
+
+        init_syntax_table       <fix required>                          <---
+
+        static int debug;
+
+        <several functions>     <fix required>                          <---
+
+        NOTE: This is used to turn on debugging, and is used in several
+        functions.  It will need to be fixed if you want differing debug
+        levels per thread.
+
+        static char reg_unset_dummy;
+
+        <REG_UNSET...>          <fix required>                          <---
+
+        static fail_stack_type fail_stack;
+
+        regex_compile           <fix required>                          <---
+        <FREE_VARIABLES>        <fix required>                          <---
+        <FAIL_STACK_EMPTY>      <fix required>                          <---
+        <FAIL_STACK_PTR_EMPTY>  <fix required>                          <---
+        <FAIL_STACK_FULL>       <fix required>                          <---
+        <INIT_FAIL_STACK>       <fix required>                          <---
+        <RESET_FAIL_STACK>      <fix required>                          <---
+        <DOUBLE_FAIL_STACK>     <fix required>                          <---
+        <PUSH_FAILURE_POINTER>  <fix required>                          <---
+        <PUSH_FAILURE_INT>      <fix required>                          <---
+        <PUSH_FAILURE_ELT>      <fix required>                          <---
+        <POP_FAILURE_POINTER>   <fix required>                          <---
+        <POP_FAILURE_INT>       <fix required>                          <---
+        <POP_FAILURE_ELT>       <fix required>                          <---
+        <REMAINING_AVAIL_SLOTS> <fix required>                          <---
+
+        static int regs_allocated_size;
+
+        regs_grow_registers     <fix required>                          <---
+
+        static register_info_type *reg_info;
+        static register_info_type *reg_info_dummy;
+        static unsigned failure_id;
+        static struct re_pattern_buffer re_comp_buf;
+
+        <too many to list>      <fix required>                          <---
+        
+        NOTE: This is just a NASTY file for static variables.  A lot of
+        work needs to be done here to clean this up.  But I'm not even
+        sure if it matters.  This code is taken directly from glibc.
+
+	This code is also very large (adds over 30k to the C library
+	all by itself).  This file needs a complete rewrite.
+
+        --------------------------------------------------------------------
+
+        misc/syslog/syslog.c:
+
+        static pthread_once__t _once_block = pthread_once_init;
+        static pthread_mutex_t _syslog_mutex;
+        
+        NOTE: I think these are okay. ;-)
+
+        static int LogFile = -1;
+        static int connected;
+        static int LogStat = 0;
+        static int LogFacility = LOG_USER;
+        static int LogMask = 0xff;
+        static char truncate_msg[12]
+        static struct sockaddr SyslogAddr;
+
+        NOTE: These are already protected.
+
+        --------------------------------------------------------------------
+
+        misc/time/asctime.c:
+
+        static char timebuf[26];
+
+        asctime                 <asctime_r implemented>
+
+        --------------------------------------------------------------------
+
+        misc/time/ctime.c:
+
+        static char cbuf[26];
+
+        ctime                   <ctime_r implemented>
+
+        --------------------------------------------------------------------
+
+        misc/time/gmtime.c:
+
+        static struct tm tmb;
+
+        gmtime                  <gmtime_r implemented>
+
+        --------------------------------------------------------------------
+
+        misc/time/localtime.c:
+
+        static struct tm tmb;
+
+        localtime               <localtime_r implemented>
+
+        --------------------------------------------------------------------
+
+        misc/time/mktime.c:
+
+        static tz_rule tz_rules[2];
+
+        tzset                   <fix required>                          <---
+
+        static time_t localtime_offset;
+
+        mktime                  <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        misc/time/tm_conv.c:
+
+        static int moffset[]    <fix desired>                           <---
+        
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        misc/utmp/utent.c:
+
+        static int ut_fd = -1;
+
+        setutent                <fix required>                          <---
+        endutent                <fix required>                          <---
+        getutent                <fix required>                          <---
+        getutid                 <fix required>                          <---
+        getutline               <fix required>                          <---
+        pututline               <fix required>                          <---
+        utmpname                <fix required>                          <---
+        
+        static struct utmp utmp;
+
+        __getutent              <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        pwd_grp/__getgrent.c:
+
+        static char line_buff[GR_MAX_LINE_LEN];
+        static char *members[GR_MAX_MEMBERS];
+        static char *line_buff = NULL;
+        static char **members = NULL;
+        static struct group group;
+
+        __getgrent              <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        pwd_grp/fgetpwent.c:
+
+        static char line_buff[PWD_BUFFER_SIZE];
+        static struct passwd pwd;
+
+        fgetpwent               <fgetpwent_r implemented>
+
+        --------------------------------------------------------------------
+
+        pwd_grp/getpwnam.c:
+
+        static char line_buff[PWD_BUFFER_SIZE];
+        static struct passwd pwd;
+
+        getpwnam                <getpwnam_r implemented>
+
+        --------------------------------------------------------------------
+
+        pwd_grp/getpwuid.c:
+
+        static char line_buff[PWD_BUFFER_SIZE];
+        static struct passwd pwd;
+
+        getpwuid                <getpwuid_r implemented>
+
+        --------------------------------------------------------------------
+
+        pwd_grp/grent.c:
+
+        static int grp_fd = -1;
+
+        setgrent                <fix required>                          <---
+        endgrent                <fix required>                          <---
+        getgrent                <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        pwd_grp/pwent.c:
+
+        static int pw_fd = -1;
+
+        setpwent                <fix required>                          <---
+        endpwent                <fix required>                          <---
+        getpwent_r              <fix required>                          <---
+
+        NOTE: Yeah, this looks weird, but getpwent_r isn't completely
+        thread-safe.
+
+        static char line_buff[PWD_BUFFER_SIZE]; 
+        static struct passwd pwd;
+
+        getpwent                <getpwent_r implemented>                <---
+
+        --------------------------------------------------------------------
+
+        stdio/tmpnam.c:
+
+        static char tmpnam_buffer[L_tmpnam];
+
+        tmpnam                  <tmpnam_r implemented>
+
+        --------------------------------------------------------------------
+
+        stdlib/atexit.c:
+
+        static vfuncp __atexit_table[__UCLIBC_MAX_ATEXIT];
+        static int __atexit_count = 0;
+
+        atexit_handler          <fix required>                          <---
+        atexit                  <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        stdlib/bsearch.c:
+
+        static int _bsearch;
+
+        bsearch                 <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        stdlib/putenv.c:
+
+        static char **mall_env = 0;
+        static int extras = 0;
+
+        putenv                  <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        stdlib/random.c:
+
+        static long int seed1 = 1;
+        static long int seed2 = 1;
+        static long int seed3 = 1;
+
+        random                  <fix required?>                         (1)
+        srandom                 <fix required?>                         (1)
+
+        1: I'm not sure if it matters if these are static, since they
+        are random number seeds.  Who cares if more than one thread changes
+        their value?
+
+        --------------------------------------------------------------------
+
+        stdlib/setenv.c:
+
+        static pthread_once__t _once_block = pthread_once_init;         (1)
+        static pthread_mutex_t _setenv_mutex;                           (1)
+        static char **last_environ = NULL;                              (1)
+
+        1: Obviously, nothing to do here. (Unless I change the way we
+        deal with threads).
+
+        --------------------------------------------------------------------
+
+        stdlib/malloc/avlmacro.h
+
+        static objname *__Avl_##objname##pr##_new_node;
+
+        Avl_Tree_no_replace     <fix required>                          <---
+
+        NOTE: This will take a bit of study to figure out if it needs fixing.
+
+        --------------------------------------------------------------------
+
+        stdlib/malloc/malloc.c:
+
+        //static mutex_t malloc_lock = MUTEX_INITIALIZER;               <---
+
+        NOTE: Basically, thread support in malloc is broken and must be
+        fixed.  It looks like the infrastructure is there, but more
+        investigation is required.
+
+        --------------------------------------------------------------------
+
+        stdlib/malloc-930716/malloc.c:
+
+        static int heapsize;
+        static int initialized;
+        static size_t pagesize;
+        
+        inititalize             <fix required>                          <---
+        morecore                <fix required>                          <---
+        malloc                  <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        stdlib/malloc-930716/valloc.c:
+
+        static size_t pagesize;
+
+        valloc                  <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        string/config.c:
+
+        static char *args[16];
+        static char cfgbuf[128];
+
+        cfgread                 <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        string/strerror.c:
+
+        static char retbuf[48];
+        static char retbuf[33];
+
+        strerror                <fix required>                          <---
+        main                    <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        string/strsignal.c:
+
+        static char retbuf[28];
+
+        strsignal               <fix required>                          <---
+        main                    <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        string/strtok.c:
+
+        static char *save = 0;
+
+        strtok                  <strtok_r implemented>                  <---
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/common/kernel_version.c:
+
+        static int __linux_kernel_version = -1;
+
+        __get_linux_kernel_version      <fix required>                  (1)
+
+        1: This static value never actually gets updated!  This a bug.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/i386/bits/huge_val.h:
+
+        static __huge_val_t __huge_val          <fix desired>           <---
+        static __huge_valf_t __huge_valf        <fix desired>           <---
+        static __huge_vall_t __huge_vall        <fix desired>           <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/i386/bits/nan.h:
+
+        static union { ... } __nan_union        <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/m68k/bits/huge_val.h:
+
+        static union { ... } __huge_val         <fix desired>           <---
+        static union { ... } __huge_valf        <fix desired>           <---
+        static union { ... } __huge_vall        <fix desired>           <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/m68k/bits/nan.h:
+
+        static union { ... } __nan_union        <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/sh/bits/huge_val.h:
+
+        static __huge_val_t __huge_val          <fix desired>           <---
+        static __huge_valf_t __huge_valf        <fix desired>           <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/sh/bits/nan.h:
+
+        static union { ... } __nan_union        <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/sparc/bits/huge_val.h:
+
+        static __huge_val_t __huge_val          <fix desired>           <---
+        static __huge_valf_t __huge_valf        <fix desired>           <---
+
+        NOTE: These are okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        sysdeps/linux/sparc/bits/nan.h:
+
+        static union { ... } __nan_union        <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        termios/tcgetsid.c:
+
+        static int tiocgsid_does_not_work;
+
+        tcgestsid               <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        termios/ttyname.c:
+
+        static char dev[] = "/dev";
+
+        ttyname                 <fix desired>                           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        static char name[NAME_MAX];
+
+        ttyname                 <ttyname_r required>                    <---
+
+        --------------------------------------------------------------------
+
+        test/testsuite.h:
+
+        static int failures
+
+        error_msg               <fix required>                          <---
+        done_testing            <fix required>                          <---
+        init_testsuite          <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        unistd/getcwd.c:
+
+        static char *path_buf;
+        static int path_size;
+        static dev_t root_dev;
+        static ino_t root_ino;
+        static struct stat st;
+
+        getswd                  <fix required>                          <---
+        recurser                <fix required>                          <---
+        search_dir              <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        unistd/getopt.c:
+
+        static int sp = 1;
+
+        getopt                  <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        unistd/getpass.c:
+
+        static char buf[PWD_BUFFER_SIZE];
+
+        getpass                 <fix required>                          <---
+        
+        NOTE: This function returns a pointer to a static data structure.
+        This seems like it requires an _r version of this function.  Glibc
+        does the same thing.  Oops!  So much for thread-safe glibc!
+
+        --------------------------------------------------------------------
+
+        unistd/gnu_getopt.c:
+
+        static char *nextchar;
+        static enum ordering;
+        static int first_nonopt;
+        static int last_nonopt;
+
+        _getopt_initialize      <fix required>                          <---
+        _getopt_internal        <fix required>                          <---
+        exchange                <fix required>                          <---
+
+        static struct option long_options[]     <fix desired>           <---
+
+        NOTE: This is okay, but should use the const keyword.
+
+        --------------------------------------------------------------------
+
+        unistd/sysconf.c:
+
+        static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS];
+
+        find_or_add_in_table    <fix required?>                         <---
+        main                    <fix required?>                         <---
+
+        NOTE: I'm not sure if this needs to be multi-threaded or not.
+
+        --------------------------------------------------------------------
+
+        unistd/sysconf_src.c:
+
+        static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS];
+
+        find_or_add_in_table    <fix required?>                         <---
+        main                    <fix required?>                         <---
+
+        NOTE: I'm not sure if this needs to be multi-threaded or not.
+
+        --------------------------------------------------------------------
+
+        unistd/sysconf_i386.c:
+
+        static long int ret_vals[_UCLIBC_SYSCONF_NUM_VALID_ARGS];
+
+        find_or_add_in_table    <fix required?>                         <---
+        main                    <fix required?>                         <---
+
+        NOTE: I'm not sure if this needs to be multi-threaded or not.
+
+        --------------------------------------------------------------------
+
+
+4. List of functions that use global variables
+
+	The following is a list of functions that make use of global
+	variables.  Since multiple threads can access the same global
+	variable at the same time, access should be considered unsafe.
+	This is an attempt to identify all the areas where global
+	variables are used.  This does not necessarily mean that each
+	of these is unsafe.  It just means that there is a potential
+	for them to be unsafe.  If this code never runs in more than
+	one thread, then there's no problem.  More ivestigation will be
+	required to determine if changes are really required.
+
+        Global variable:
+
+        __environ (misc/internals/__uClibc_main.c)
+
+        __uClibc_main.c:
+
+        __uClibc_main           <fix required?>                         (1)
+
+        1: This should only get executed once, so it is probably fine.
+        
+        stdlib/getenv.c:
+
+        getenv                  <fix required>                          <---
+
+        stdlib/putenv.c:
+
+        putenv                  <fix required>                          <---
+
+        stdlib/setenv.c:
+
+        setenv                  <fix required>                          <---
+        unsetenv                <fix required>                          <---
+
+        test/args/arg_test.c:
+
+        main                    <fix required>                          <---
+
+        unistd/execl.c:
+
+        execl                   <fix required>                          <---
+
+        unistd/execlp.c:
+
+        execlp                  <fix required>                          <---
+
+        unistd/execv.c:
+
+        execv                   <fix required>                          <---
+
+        unistd/execvp.c:
+
+        execvep                 <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __uClibc_cleanup (misc/internals/__uClibc_main.c)
+
+        stdlib/abort.c:
+
+        abort                   <fix required>                          <---
+
+        stdlib/atexit.c:
+
+        atexit_handler          <fix required>                          <---
+        atexit                  <fix required>                          <---
+        exit                    <fix required>                          <---
+
+        NOTE: Not sure if multiple threads can be in this code or not.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        environ (misc/internals/__uClibc_main.c)
+
+        NOTE: This is a weak alias for __environ, but it doesn't ever get
+        used in the uClibc library.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        timezone (misc/time/tm_conv.c)
+
+        misc/time/tm_conv.c:
+
+        __tm_conv               <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        re_max_failures (misc/regex/regex.c)
+
+        misc/regex/regex.c:
+
+        DOUBLE_FAIL_STACK       <fix required>                          <---
+        regex_compile           <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        re_syntax_options (misc/regex/regex.c)
+
+        misc/regex/regex.c:
+
+        re_set_syntax           <fix required>                          <---
+        re_compile_pattern      <fix required>                          <---
+        re_comp                 <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __IO_list (stdio/stdio.c)
+
+        stdio/stdio.c:
+
+        fflush                  <fix required>                          <---
+        __fopen                 <fix required>                          <---
+        fclose                  <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _fixed_buffers (stdio/stdio.c)
+
+        stdio/stdio.c:
+
+        _alloc_stdio_buffer             <fix required>                  <---
+        _free_stdio_buffer_of_file      <fix required>                  <---
+        __init_stdio                    <fix required>                  <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _free_buffer_index (stdio/stdio.c)
+
+        stdio/stdio.c:
+
+        _alloc_stdio_buffer             <fix required>                  <---
+        _free_stdio_buffer_of_file      <fix required>                  <---
+        __init_stdio                    <fix required>                  <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _free_file_list (stdio/stdio.c)
+
+        stdio/stdio.c:
+
+        __init_stdio            <fix required>                          <---
+        _alloc_stdio_stream     <fix required>                          <---
+        _free_stdio_stream      <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _stderr (stdio/stdio.c)
+
+        ld.so-1/util/ldconfig.c:
+
+        warn                    <fix required>                          <---
+        error                   <fix required>                          <---
+        usage                   <fix required>                          <---
+
+        ld.so-1/util/ldd.c:
+
+        warn                    <fix required>                          <---
+        error                   <fix required>                          <---
+        is_bin                  <fix required>                          <---
+        main                    <fix required>                          <---
+        
+        misc/locale/locale.c:
+
+        setlocale               <fix required>                          <---
+        
+        misc/regex/regex.c:
+
+        printchar               <fix required>                          <---
+
+        stdio/perror.c:
+
+        perror                  <fix required>                          <---
+
+        stdlib/malloc/alloc.c:
+
+        calloc_dbg              <fix required>                          <---
+        malloc_dbg              <fix required>                          <---
+        free_dbg                <fix required>                          <---
+
+        stdlib/malloc/malloc.c:
+
+        __hunk_alloc            <fix required?>                         (1)
+        __malloc_init           <fix required?>                         (1)
+        malloc                  <fix required?>                         (1)
+
+        1: These are commented out with C++ style comments.
+
+        stdlib/malloc-simple/alloc.c:
+
+        calloc_dbg              <fix required>                          <---
+        malloc_dbg              <fix required>                          <---
+        free_dbg                <fix required>                          <---
+
+        string/strsignal.c:
+
+        psignal                 <fix required>                          <---
+
+        test/args/arg_test.c:
+
+        main                    <fix required>                          <---
+
+        test/assert/assert.c:
+
+        main                    <fix required>                          <---
+
+        unistd/getopt.c:
+
+        Err                     <fix required>                          <---
+
+        unistd/getpass.c:
+
+        getpass                 <fix required>                          <---
+
+        unistd/gnu_getopt.c:
+
+        _getopt_internal        <fix required>                          <---
+
+        unistd/sysconf.c:
+
+        main                    <fix required>                          <---
+
+        unistd/sysconf_src.c:
+
+        main                    <fix required>                          <---
+
+        unistd/sysconf_i386.c:
+
+        main                    <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _stdin (stdio/stdio.c)
+
+        include/stdio.h:
+
+        getchar                 <fix required>                          <---
+
+        include/bits/stdio.h:
+
+        getchar                 <fix required>                          <---
+        getchar_unlocked        <fix required>                          <---
+
+        stdio/scanf.c:
+
+        scanf                   <fix required>                          <---
+        vscanf                  <fix required>                          <---
+
+        stdio/stdio.c
+
+        gets                    <fix required>                          <---
+        getchar                 <fix required>                          <---
+
+        sysdeps/linux/i386/bits/stdio.h:
+
+        getchar                 <fix required>                          <---
+        getchar_unlocked        <fix required>                          <---
+
+        sysdeps/linux/m68k/bits/stdio.h:
+
+        getchar                 <fix required>                          <---
+        getchar_unlocked        <fix required>                          <---
+
+        sysdeps/linux/sh/bits/stdio.h:
+
+        getchar                 <fix required>                          <---
+        getchar_unlocked        <fix required>                          <---
+
+        sysdeps/linux/sparc/bits/stdio.h:
+
+        getchar                 <fix required>                          <---
+        getchar_unlocked        <fix required>                          <---
+
+        unistd/getpass.c:
+
+        getpass                 <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _stdio_streams (stdio/stdio.c)
+
+        stdio/stdio.c:
+
+        __init_stdio            <fix required>                          <---
+        _free_stdio_stream      <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _stdout (stdio/stdio.c)
+
+        include/stdio.h:
+
+        putchar                 <fix required>                          <---
+
+        include/bits/stdio.h:
+
+        vprintf                 <fix required>                          <---
+        putchar                 <fix required>                          <---
+        putchar_unlocked        <fix required>                          <---
+
+        ld.so-1/util/ldconfig.c:
+
+        warn                    <fix required>                          <---
+        error                   <fix required>                          <---
+
+        ld.so-1/util/ldd.c:
+
+        warn                    <fix required>                          <---
+        error                   <fix required>                          <---
+        main                    <fix required>                          <---
+
+        stdio/printf.c:
+
+        printf                  <fix required>                          <---
+        vprintf                 <fix required>                          <---
+
+        stdio/stdio.c:
+
+        puts                    <fix required>                          <---
+        _uClibc_fread           <fix required>                          <---
+        putchar                 <fix required>                          <---
+
+        sysdeps/linux/i386/bits/stdio.h:
+
+        vprintf                 <fix required>                          <---
+        putchar                 <fix required>                          <---
+        putchar_unlocked        <fix required>                          <---
+
+        sysdeps/linux/m68k/bits/stdio.h:
+
+        vprintf                 <fix required>                          <---
+        putchar                 <fix required>                          <---
+        putchar_unlocked        <fix required>                          <---
+
+        sysdeps/linux/sh/bits/stdio.h:
+
+        vprintf                 <fix required>                          <---
+        putchar                 <fix required>                          <---
+        putchar_unlocked        <fix required>                          <---
+
+        sysdeps/linux/sparc/bits/stdio.h:
+
+        vprintf                 <fix required>                          <---
+        putchar                 <fix required>                          <---
+        putchar_unlocked        <fix required>                          <---
+
+        test/pwd_grp/test_grp.c:
+
+        main                    <fix required>                          <---
+
+        test/pwd_grp/test_pwd.c:
+
+        main                    <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        dns_caught_signal (inet/resolv.c)
+
+        inet/resolv.c:
+
+        dns_catch_signal        <fix required>                          <---
+        dns_lookup              <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        nameserver (inet/resolv.c)
+        nameservers (inet/resolv.c)
+
+        inet/resolv.c:
+
+        open_nameservers        <fix required>                          <---
+        close_nameservers       <fix required>                          <---
+        resolve_name            <fix required>                          <---
+        gethostbyname           <fix required>                          <---
+        res_query               <fix required>                          <---
+        gethostbyaddr           <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        searchdomain (inet/resolv.c)
+        searchdomains (inet/resolv.c)
+
+        inet/resolv.c:
+
+        dns_lookup              <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _net_stayopen (inet/getnetent.c)
+
+        inet/getnetbyad.c:
+
+        getnetbyaddr            <fix required>                          <---
+
+        inet/getnetbynm.c:
+
+        getnetbyname            <fix required>                          <---
+
+        inet/getnetent.c:
+
+        setnetent               <fix required>                          <---
+        endnetent               <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        rpcdata (inet/rpc/getrpcent.c)
+
+        inet/rpc/getrpcent.c:
+
+        _rpcdata                <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _null_auth (inet/rpc/rpc_commondata.c)  <fix desired>           <---
+
+        NOTE: _null_auth is never actually initialized.  It never gets written,
+        only read.  So it should be thread safe.  But it should be declared
+        as a const if that is the case.  It should also be initialized.
+
+        inet/rpc/auth_none.c:
+
+        authnone_create 
+
+        inet/rpc/auth_unix.c:
+
+        authunix_create
+
+        inet/rpc/clnt_raw.c:
+
+        clntraw_call
+
+        inet/rpc/clnt_tcp.c:
+
+        clnttcp_call
+
+        inet/rpc/clnt_udp.c:
+
+        clntudp_call
+
+        inet/rpc/pmap_rmt.c:
+
+        clnt_broadcast
+
+        inet/rpc/svc_auth.c:
+
+        _authenticate
+
+        inet/rpc/svc_tcp.c:
+
+        svctcp_create
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        rpc_createerr (inet/rpc/rpc_commondata.c)
+
+        inet/rpc/clnt_generic.c:
+
+        clnt_create             <fix required>                          <---
+        
+        inet/rpc/clnt_perror.c:
+
+        clnt_spcreateerror      <fix desired?>                          <---
+
+        NOTE: This piece of code has an "#if 0" around it.
+
+        inet/rpc/clnt_simple.c:
+
+        callrpc                 <fix required>                          <---
+
+        inet/rpc/clnt_tcp.c:
+
+        clnttcp_create          <fix required>                          <---
+
+        inet/rpc/clnt_udp.c:
+
+        clntudp_bufcreate       <fix required>                          <---
+
+        inet/rpc/pmap_getport.c:
+
+        pmap_getport            <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        svc_fdset (inet/rpc/rpc_commondata.c)
+
+        inet/rpc/svc.c:
+
+        xprt_register           <fix required>                          <---
+        xprt_unregister         <fix required>                          <---
+        svc_getreq              <fix required>                          <---
+
+        inet/rpc/svc_run.c:
+
+        svc_run                 <fix required>                          <---
+
+        NOTE: Be careful to also fix the uses of the "svc_fds" #define.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        pl (inet/rpc/svc_simple.c)
+
+        registerrpc             <fix required>                          <---
+
+        NOTE: proglst is set up to point at pl, so it needs fixing as well.
+        (See proglst earlier in this document.)
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        _sigintr (signal/signal.c)
+
+        signal/bsd_sig.c:
+
+        __bsd_signal            <fix required>                          <---
+
+        signal/sigintr.c:
+
+        siginterrupt            <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __Avl_Block_tfree_mem_tree (stdlib/malloc/malloc.c)
+
+        stdlib/malloc/malloc.c:
+
+        __free_mem_del_block    <fix required>                          <---
+        bl_alloc                <fix required>                          <---
+        __malloc_init           <fix required>                          <---
+
+        NOTE: This code is very tricky stuff.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __Avl_Block_tptrs_tree (stdlib/malloc/malloc.c)
+
+        stdlib/malloc/malloc.c:
+
+        __bl_free               <fix required>                          <---
+        __malloc_init           <fix required>                          <---
+        free                    <fix required>                          <---
+        _realloc_no_move        <fix required>                          <---
+        realloc                 <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __bl_last (stdlib/malloc/malloc.c)
+
+        stdlib/malloc/malloc.c:
+
+        COMBINE_BLOCKS          <fix required>                          <---
+        SPLIT_BLOCK             <fix required>                          <---
+        bl_mapnew               <fix required>                          <---
+        bl_alloc                <fix required>                          <---
+        __malloc_init           <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __free_h (stdlib/malloc/malloc.c)
+
+        stdlib/malloc/malloc.c:
+
+        __hunk_alloc            <fix required>                          <---
+        __hunk_free             <fix required>                          <---
+        __malloc_init           <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __malloc_initialized (stdlib/malloc/malloc.c)
+
+        stdlib/malloc/malloc.c:
+
+        __malloc_init           <fix required>                          <---
+        malloc                  <fix required>                          <---
+        free                    <fix required>                          <---
+        _realloc_no_move        <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        __total_h (stdlib/malloc/malloc.c)
+
+        stdlib/malloc/malloc.c:
+
+        __hunk_alloc            <fix required>                          <---
+        __malloc_init           <fix required>                          <---
+        
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        errno (sysdeps/linux/common/errno.c)
+
+        sysdeps/linux/common/errno.c:
+
+        __errno_location        <fix required>                          <---
+
+        NOTE: Obviously, errno gets used all over the place.  I won't list
+        them all here.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        ___brk_addr (sysdeps/linux/i386/__init_brk.c)
+
+        sysdeps/linux/i386/__init_brk.c:
+
+        __init_brk              <fix required>                          <---
+
+        sysdeps/linux/i386/brk.c:
+
+        brk                     <fix required>                          <---
+
+        sysdeps/linux/i386/sbrk.c:
+
+        sbrk                    <fix required>                          <---
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        optarg (unistd/getopt_vars.c)
+
+        extra/locale/gen_ctype_from_glibc.c:
+
+        main                    <fix required?>                         (1)
+
+        ld.so-1/util/ldconfig.c:
+
+        main                    <fix required?>                         (1)
+
+        unistd/getopt.c:
+
+        getopt                  <fix required>                          <---
+
+        unistd/gnu_getopt.c:
+
+        _getopt_internal        <fix required>                          <---
+        main                    <fix required?>                         (1)
+
+        1: Probably not required unless this program is run on multiple
+        threads.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        opterr (unistd/getopt_vars.c)
+
+        ld.so-1/util/ldconfig.c:
+
+        main                    <fix required?>                         (1)
+
+        unistd/getopt.c:
+
+        Err                     <fix required>                          <---
+        getopt                  <fix required>                          <---
+
+        unistd/gnu_getopt.c:
+
+        _getopt_internal        <fix required>                          <---
+
+        1: Probably not required unless this program is run on multiple
+        threads.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        optind (unistd/getopt_vars.c)
+
+        extra/locale/gen_ctype_from_glibc.c:
+
+        main                    <fix required?>                         (1)
+        
+        ld.so-1/util/ldconfig.c:
+
+        main                    <fix required?>                         (1)
+
+        ld.so-1/util/ldd.c:
+
+        main                    <fix required?>                         (1)
+        
+        unistd/getopt.c:
+
+        Err                     <fix required>                          <---
+        getopt                  <fix required>                          <---
+
+        unistd/gnu_getopt.c:
+
+        exchange                <fix required>                          <---
+        _getopt_initialize      <fix required>                          <---
+        _getopt_internal        <fix required>                          <---
+        main                    <fix required?>                         (1)
+        main (2nd one)          <fix required?>                         (1)
+
+        1: Probably not required unless this program is run on multiple
+        threads.
+
+        --------------------------------------------------------------------
+
+        Global variable:
+
+        optopt (unistd/getopt_vars.c)
+
+        unistd/getopt.c:
+
+        Err                     <fix required>                          <---
+        getopt                  <fix required>                          <---
+
+        unistd/gnu_getopt.c:
+
+        _getopt_internal        <fix required>                          <---
+