OSDN Git Service

Work around a bug in nm from binutils-2.14.90.0.5.
[uclinux-h8/uClibc.git] / ldso / ldso / ld_string.h
1 #ifndef _LINUX_STRING_H_
2 #define _LINUX_STRING_H_
3
4 #include <sys/types.h>  /* for size_t */
5
6 extern void *_dl_malloc(int size);
7 extern char *_dl_getenv(const char *symbol, char **envp);
8 extern void _dl_unsetenv(const char *symbol, char **envp);
9 extern char *_dl_strdup(const char *string);
10 extern void _dl_dprintf(int, const char *, ...);
11
12
13 static size_t _dl_strlen(const char * str);
14 static char *_dl_strcat(char *dst, const char *src);
15 static char * _dl_strcpy(char * dst,const char *src);
16 static int _dl_strcmp(const char * s1,const char * s2);
17 static int _dl_strncmp(const char * s1,const char * s2,size_t len);
18 static char * _dl_strchr(const char * str,int c);
19 static char *_dl_strrchr(const char *str, int c);
20 static char *_dl_strstr(const char *s1, const char *s2);
21 static void * _dl_memcpy(void * dst, const void * src, size_t len);
22 static int _dl_memcmp(const void * s1,const void * s2,size_t len);
23 static void *_dl_memset(void * str,int c,size_t len);
24 static char *_dl_get_last_path_component(char *path);
25 static char *_dl_simple_ltoa(char * local, unsigned long i);
26 static char *_dl_simple_ltoahex(char * local, unsigned long i);
27
28 #ifndef NULL
29 #define NULL ((void *) 0)
30 #endif
31
32 static inline size_t _dl_strlen(const char * str)
33 {
34         register char *ptr = (char *) str;
35
36         while (*ptr)
37                 ptr++;
38         return (ptr - str);
39 }
40
41 static inline char *_dl_strcat(char *dst, const char *src)
42 {
43         register char *ptr = dst;
44
45         while (*ptr)
46                 ptr++;
47
48         while (*src)
49                 *ptr++ = *src++;
50         *ptr = '\0';
51
52         return dst;
53 }
54
55 static inline char * _dl_strcpy(char * dst,const char *src)
56 {
57         register char *ptr = dst;
58
59         while (*src)
60                 *dst++ = *src++;
61         *dst = '\0';
62
63         return ptr;
64 }
65  
66 static inline int _dl_strcmp(const char * s1,const char * s2)
67 {
68         register unsigned char c1, c2;
69
70         do {
71                 c1 = (unsigned char) *s1++;
72                 c2 = (unsigned char) *s2++;
73                 if (c1 == '\0')
74                         return c1 - c2;
75         }
76         while (c1 == c2);
77
78         return c1 - c2;
79 }
80
81 static inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
82 {
83         register unsigned char c1 = '\0';
84         register unsigned char c2 = '\0';
85
86         while (len > 0) {
87                 c1 = (unsigned char) *s1++;
88                 c2 = (unsigned char) *s2++;
89                 if (c1 == '\0' || c1 != c2)
90                         return c1 - c2;
91                 len--;
92         }
93
94         return c1 - c2;
95 }
96
97 static inline char * _dl_strchr(const char * str,int c)
98 {
99         register char ch;
100
101         do {
102                 if ((ch = *str) == c)
103                         return (char *) str;
104                 str++;
105         }
106         while (ch);
107
108         return 0;
109 }
110
111 static inline char *_dl_strrchr(const char *str, int c)
112 {
113     register char *prev = 0;
114     register char *ptr = (char *) str;
115
116     while (*ptr != '\0') {
117         if (*ptr == c)
118             prev = ptr;
119         ptr++;  
120     }   
121     if (c == '\0')
122         return(ptr);
123     return(prev);
124 }
125
126
127 static inline char *_dl_strstr(const char *s1, const char *s2)
128 {
129     register const char *s = s1;
130     register const char *p = s2;
131     
132     do {
133         if (!*p) {
134             return (char *) s1;;
135         }
136         if (*p == *s) {
137             ++p;
138             ++s;
139         } else {
140             p = s2;
141             if (!*s) {
142               return NULL;
143             }
144             s = ++s1;
145         }
146     } while (1);
147 }
148
149 static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
150 {
151         register char *a = dst;
152         register const char *b = src;
153
154         while (len--)
155                 *a++ = *b++;
156
157         return dst;
158 }
159
160
161 static inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
162 {
163         unsigned char *c1 = (unsigned char *)s1;
164         unsigned char *c2 = (unsigned char *)s2;
165
166         while (len--) {
167                 if (*c1 != *c2) 
168                         return *c1 - *c2;
169                 c1++;
170                 c2++;
171         }
172         return 0;
173 }
174
175 static inline void * _dl_memset(void * str,int c,size_t len)
176 {
177         register char *a = str;
178
179         while (len--)
180                 *a++ = c;
181
182         return str;
183 }
184
185 static inline char *_dl_get_last_path_component(char *path)
186 {
187         char *s;
188         register char *ptr = path;
189         register char *prev = 0;
190
191         while (*ptr)
192                 ptr++;
193         s = ptr - 1;
194
195         /* strip trailing slashes */
196         while (s != path && *s == '/') {
197                 *s-- = '\0';
198         }
199
200         /* find last component */
201         ptr = path;
202         while (*ptr != '\0') {
203             if (*ptr == '/')
204                 prev = ptr;
205             ptr++;  
206         }   
207         s = prev;
208
209         if (s == NULL || s[1] == '\0')
210                 return path;
211         else
212                 return s+1;
213 }
214
215 /* Early on, we can't call printf, so use this to print out
216  * numbers using the SEND_STDERR() macro */
217 static inline char *_dl_simple_ltoa(char * local, unsigned long i)
218 {
219         /* 21 digits plus null terminator, good for 64-bit or smaller ints */
220         char *p = &local[22];
221         *p-- = '\0';
222         do {
223                 *p-- = '0' + i % 10;
224                 i /= 10;
225         } while (i > 0);
226         return p + 1;
227 }
228
229 static inline char *_dl_simple_ltoahex(char * local, unsigned long i)
230 {
231         /* 21 digits plus null terminator, good for 64-bit or smaller ints */
232         char *p = &local[22];
233         *p-- = '\0';
234         do {
235                 char temp = i % 0x10;
236                 if (temp <= 0x09)
237                     *p-- = '0' + temp;
238                 else
239                     *p-- = 'a' - 0x0a + temp;
240                 i /= 0x10;
241         } while (i > 0);
242         *p-- = 'x';
243         *p-- = '0';
244         return p + 1;
245 }
246
247
248 #if defined mc68000 || defined __arm__ || defined __mips__ || defined __sh__
249 /* On some arches constant strings are referenced through the GOT. */
250 /* XXX Requires load_addr to be defined. */
251 #define SEND_STDERR(X)                          \
252   { const char *__s = (X);                      \
253     if (__s < (const char *) load_addr) __s += load_addr;       \
254     _dl_write (2, __s, _dl_strlen (__s));       \
255   }
256 #else
257 #define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X));
258 #endif
259
260 #define SEND_ADDRESS_STDERR(X, add_a_newline) { \
261     char tmp[22], *tmp1; \
262     _dl_memset(tmp, 0, sizeof(tmp)); \
263     tmp1=_dl_simple_ltoahex( tmp, (unsigned long)(X)); \
264     _dl_write(2, tmp1, _dl_strlen(tmp1)); \
265     if (add_a_newline) { \
266         tmp[0]='\n'; \
267         _dl_write(2, tmp, 1); \
268     } \
269 };
270
271 #define SEND_NUMBER_STDERR(X, add_a_newline) { \
272     char tmp[22], *tmp1; \
273     _dl_memset(tmp, 0, sizeof(tmp)); \
274     tmp1=_dl_simple_ltoa( tmp, (unsigned long)(X)); \
275     _dl_write(2, tmp1, _dl_strlen(tmp1)); \
276     if (add_a_newline) { \
277         tmp[0]='\n'; \
278         _dl_write(2, tmp, 1); \
279     } \
280 };
281
282
283 #endif