19
19
*
20
20
*/
21
21
22
+ #include <errno.h>
22
23
#include <getopt.h>
23
24
#include <stdbool.h>
24
25
#include <stdio.h>
29
30
30
31
#define ARRAY_SIZE (arr ) (sizeof(arr) / sizeof(arr[0]))
31
32
32
- #define _stringify_1 (x ) #x
33
- #define _stringify (x ) _stringify_1(x)
34
-
35
33
#define KSYM_NAME_LEN 512
36
34
37
- /*
38
- * A substantially bigger size than the current maximum.
39
- *
40
- * It cannot be defined as an expression because it gets stringified
41
- * for the fscanf() format string. Therefore, a _Static_assert() is
42
- * used instead to maintain the relationship with KSYM_NAME_LEN.
43
- */
44
- #define KSYM_NAME_LEN_BUFFER 2048
45
- _Static_assert (
46
- KSYM_NAME_LEN_BUFFER == KSYM_NAME_LEN * 4 ,
47
- "Please keep KSYM_NAME_LEN_BUFFER in sync with KSYM_NAME_LEN"
48
- );
49
-
50
35
struct sym_entry {
51
36
unsigned long long addr ;
52
37
unsigned int len ;
@@ -136,24 +121,40 @@ static void check_symbol_range(const char *sym, unsigned long long addr,
136
121
}
137
122
}
138
123
139
- static struct sym_entry * read_symbol (FILE * in )
124
+ static struct sym_entry * read_symbol (FILE * in , char * * buf , size_t * buf_len )
140
125
{
141
- char name [ KSYM_NAME_LEN_BUFFER + 1 ] , type ;
126
+ char * name , type , * p ;
142
127
unsigned long long addr ;
143
- unsigned int len ;
128
+ size_t len ;
129
+ ssize_t readlen ;
144
130
struct sym_entry * sym ;
145
- int rc ;
146
131
147
- rc = fscanf (in , "%llx %c %" _stringify (KSYM_NAME_LEN_BUFFER ) "s\n" , & addr , & type , name );
148
- if (rc != 3 ) {
149
- if (rc != EOF && fgets (name , ARRAY_SIZE (name ), in ) == NULL )
150
- fprintf (stderr , "Read error or end of file.\n" );
132
+ readlen = getline (buf , buf_len , in );
133
+ if (readlen < 0 ) {
134
+ if (errno ) {
135
+ perror ("read_symbol" );
136
+ exit (EXIT_FAILURE );
137
+ }
151
138
return NULL ;
152
139
}
153
- if (strlen (name ) >= KSYM_NAME_LEN ) {
140
+
141
+ if ((* buf )[readlen - 1 ] == '\n' )
142
+ (* buf )[readlen - 1 ] = 0 ;
143
+
144
+ addr = strtoull (* buf , & p , 16 );
145
+
146
+ if (* buf == p || * p ++ != ' ' || !isascii ((type = * p ++ )) || * p ++ != ' ' ) {
147
+ fprintf (stderr , "line format error\n" );
148
+ exit (EXIT_FAILURE );
149
+ }
150
+
151
+ name = p ;
152
+ len = strlen (name );
153
+
154
+ if (len >= KSYM_NAME_LEN ) {
154
155
fprintf (stderr , "Symbol %s too long for kallsyms (%zu >= %d).\n"
155
156
"Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n" ,
156
- name , strlen ( name ) , KSYM_NAME_LEN );
157
+ name , len , KSYM_NAME_LEN );
157
158
return NULL ;
158
159
}
159
160
@@ -169,8 +170,7 @@ static struct sym_entry *read_symbol(FILE *in)
169
170
170
171
/* include the type field in the symbol name, so that it gets
171
172
* compressed together */
172
-
173
- len = strlen (name ) + 1 ;
173
+ len ++ ;
174
174
175
175
sym = malloc (sizeof (* sym ) + len + 1 );
176
176
if (!sym ) {
@@ -257,6 +257,8 @@ static void read_map(const char *in)
257
257
{
258
258
FILE * fp ;
259
259
struct sym_entry * sym ;
260
+ char * buf = NULL ;
261
+ size_t buflen = 0 ;
260
262
261
263
fp = fopen (in , "r" );
262
264
if (!fp ) {
@@ -265,7 +267,7 @@ static void read_map(const char *in)
265
267
}
266
268
267
269
while (!feof (fp )) {
268
- sym = read_symbol (fp );
270
+ sym = read_symbol (fp , & buf , & buflen );
269
271
if (!sym )
270
272
continue ;
271
273
@@ -284,6 +286,7 @@ static void read_map(const char *in)
284
286
table [table_cnt ++ ] = sym ;
285
287
}
286
288
289
+ free (buf );
287
290
fclose (fp );
288
291
}
289
292
0 commit comments