OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [newlib-1.18.0/] [newlib/] [libc/] [sys/] [linux/] [dl/] [dl-misc.c] - Blame information for rev 207

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/* Miscellaneous support functions for dynamic linker
2
   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
 
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
 
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
 
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
 
20
#include <assert.h>
21
#include <fcntl.h>
22
#include <ldsodefs.h>
23
#include <limits.h>
24
#include <link.h>
25
#include <stdarg.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <unistd.h>
29
#include <sys/mman.h>
30
#include <sys/param.h>
31
#include <sys/stat.h>
32
#include <sys/uio.h>
33
 
34
#ifndef MAP_ANON
35
/* This is the only dl-sysdep.c function that is actually needed at run-time
36
   by _dl_map_object.  */
37
 
38
int
39
_dl_sysdep_open_zero_fill (void)
40
{
41
  return __open ("/dev/zero", O_RDONLY);
42
}
43
#endif
44
 
45
/* Read the whole contents of FILE into new mmap'd space with given
46
   protections.  *SIZEP gets the size of the file.  On error MAP_FAILED
47
   is returned.  */
48
 
49
void *
50
internal_function
51
_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
52
{
53
  void *result = MAP_FAILED;
54
  struct stat64 st;
55
  int fd = __open (file, O_RDONLY);
56
  if (fd >= 0)
57
    {
58
      if (fstat64 (fd, &st) >= 0)
59
        {
60
          *sizep = st.st_size;
61
 
62
          /* No need to map the file if it is empty.  */
63
          if (*sizep != 0)
64
            /* Map a copy of the file contents.  */
65
            result = mmap (NULL, *sizep, prot,
66
#ifdef MAP_COPY
67
                             MAP_COPY
68
#else
69
                             MAP_PRIVATE
70
#endif
71
#ifdef MAP_FILE
72
                             | MAP_FILE
73
#endif
74
                             , fd, 0);
75
        }
76
      close (fd);
77
    }
78
  return result;
79
}
80
 
81
 
82
/* Descriptor to write debug messages to.  */
83
int _dl_debug_fd = 2;
84
 
85
 
86
/* Bare-bone printf implementation.  This function only knows about
87
   the formats and flags needed and can handle only up to 64 stripes in
88
   the output.  */
89
static void
90
_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
91
{
92
  const int niovmax = 64;
93
  struct iovec iov[niovmax];
94
  int niov = 0;
95
  pid_t pid = 0;
96
  char pidbuf[7];
97
 
98
  while (*fmt != '\0')
99
    {
100
      const char *startp = fmt;
101
 
102
      if (tag_p > 0)
103
        {
104
          /* Generate the tag line once.  It consists of the PID and a
105
             colon followed by a tab.  */
106
          if (pid == 0)
107
            {
108
              char *p = "0";
109
              pid = __getpid ();
110
              assert (pid >= 0 && pid < 100000);
111
              while (p > pidbuf)
112
                *--p = '0';
113
              pidbuf[5] = ':';
114
              pidbuf[6] = '\t';
115
            }
116
 
117
          /* Append to the output.  */
118
          assert (niov < niovmax);
119
          iov[niov].iov_len = 7;
120
          iov[niov++].iov_base = pidbuf;
121
 
122
          /* No more tags until we see the next newline.  */
123
          tag_p = -1;
124
        }
125
 
126
      /* Skip everything except % and \n (if tags are needed).  */
127
      while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
128
        ++fmt;
129
 
130
      /* Append constant string.  */
131
      assert (niov < niovmax);
132
      if ((iov[niov].iov_len = fmt - startp) != 0)
133
        iov[niov++].iov_base = (char *) startp;
134
 
135
      if (*fmt == '%')
136
        {
137
          /* It is a format specifier.  */
138
          char fill = ' ';
139
          int width = -1;
140
#if LONG_MAX != INT_MAX
141
          int long_mod = 0;
142
#endif
143
 
144
          /* Recognize zero-digit fill flag.  */
145
          if (*++fmt == '0')
146
            {
147
              fill = '0';
148
              ++fmt;
149
            }
150
 
151
          /* See whether with comes from a parameter.  Note that no other
152
             way to specify the width is implemented.  */
153
          if (*fmt == '*')
154
            {
155
              width = va_arg (arg, int);
156
              ++fmt;
157
            }
158
 
159
          /* Recognize the l modifier.  It is only important on some
160
             platforms where long and int have a different size.  We
161
             can use the same code for size_t.  */
162
          if (*fmt == 'l' || *fmt == 'Z')
163
            {
164
#if LONG_MAX != INT_MAX
165
              long_mod = 1;
166
#endif
167
              ++fmt;
168
            }
169
 
170
          switch (*fmt)
171
            {
172
              /* Integer formatting.  */
173
            case 'u':
174
            case 'x':
175
              {
176
                /* We have to make a difference if long and int have a
177
                   different size.  */
178
#if LONG_MAX != INT_MAX
179
                unsigned long int num = (long_mod
180
                                         ? va_arg (arg, unsigned long int)
181
                                         : va_arg (arg, unsigned int));
182
#else
183
                unsigned long int num = va_arg (arg, unsigned int);
184
#endif
185
                /* We use alloca() to allocate the buffer with the most
186
                   pessimistic guess for the size.  Using alloca() allows
187
                   having more than one integer formatting in a call.  */
188
                char *buf = (char *) alloca (3 * sizeof (unsigned long int));
189
                char *endp = &buf[3 * sizeof (unsigned long int)];
190
                char *cp = "0";
191
 
192
                /* Pad to the width the user specified.  */
193
                if (width != -1)
194
                  while (endp - cp < width)
195
                    *--cp = fill;
196
 
197
                iov[niov].iov_base = cp;
198
                iov[niov].iov_len = endp - cp;
199
                ++niov;
200
              }
201
              break;
202
 
203
            case 's':
204
              /* Get the string argument.  */
205
              iov[niov].iov_base = va_arg (arg, char *);
206
              iov[niov].iov_len = strlen (iov[niov].iov_base);
207
              ++niov;
208
              break;
209
 
210
            case '%':
211
              iov[niov].iov_base = (void *) fmt;
212
              iov[niov].iov_len = 1;
213
              ++niov;
214
              break;
215
 
216
            default:
217
              assert (! "invalid format specifier");
218
            }
219
          ++fmt;
220
        }
221
      else if (*fmt == '\n')
222
        {
223
          /* See whether we have to print a single newline character.  */
224
          if (fmt == startp)
225
            {
226
              iov[niov].iov_base = (char *) startp;
227
              iov[niov++].iov_len = 1;
228
            }
229
          else
230
            /* No, just add it to the rest of the string.  */
231
            ++iov[niov - 1].iov_len;
232
 
233
          /* Next line, print a tag again.  */
234
          tag_p = 1;
235
          ++fmt;
236
        }
237
    }
238
 
239
  /* Finally write the result.  */
240
  writev (fd, iov, niov);
241
}
242
 
243
 
244
/* Write to debug file.  */
245
void
246
_dl_debug_printf (const char *fmt, ...)
247
{
248
  va_list arg;
249
 
250
  va_start (arg, fmt);
251
  _dl_debug_vdprintf (_dl_debug_fd, 1, fmt, arg);
252
  va_end (arg);
253
}
254
 
255
 
256
/* Write to debug file but don't start with a tag.  */
257
void
258
_dl_debug_printf_c (const char *fmt, ...)
259
{
260
  va_list arg;
261
 
262
  va_start (arg, fmt);
263
  _dl_debug_vdprintf (_dl_debug_fd, -1, fmt, arg);
264
  va_end (arg);
265
}
266
 
267
 
268
/* Write the given file descriptor.  */
269
void
270
_dl_dprintf (int fd, const char *fmt, ...)
271
{
272
  va_list arg;
273
 
274
  va_start (arg, fmt);
275
  _dl_debug_vdprintf (fd, 0, fmt, arg);
276
  va_end (arg);
277
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.