11 #include <sys/utsname.h>
13 static unsigned int crc32(const char *p
, unsigned int len
)
20 for (i
= 0; i
< 8; i
++)
21 crc
= (crc
>> 1) ^ ((crc
& 1) ? 0xedb88320 : 0);
26 /* module section methods */
28 struct sec_dso
*sec_dso__new_dso(const char *name
)
30 struct sec_dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
33 strcpy(self
->name
, name
);
35 self
->find_section
= sec_dso__find_section
;
41 static void sec_dso__delete_section(struct section
*self
)
46 void sec_dso__delete_sections(struct sec_dso
*self
)
49 struct rb_node
*next
= rb_first(&self
->secs
);
52 pos
= rb_entry(next
, struct section
, rb_node
);
53 next
= rb_next(&pos
->rb_node
);
54 rb_erase(&pos
->rb_node
, &self
->secs
);
55 sec_dso__delete_section(pos
);
59 void sec_dso__delete_self(struct sec_dso
*self
)
61 sec_dso__delete_sections(self
);
65 static void sec_dso__insert_section(struct sec_dso
*self
, struct section
*sec
)
67 struct rb_node
**p
= &self
->secs
.rb_node
;
68 struct rb_node
*parent
= NULL
;
69 const u64 hash
= sec
->hash
;
74 s
= rb_entry(parent
, struct section
, rb_node
);
80 rb_link_node(&sec
->rb_node
, parent
, p
);
81 rb_insert_color(&sec
->rb_node
, &self
->secs
);
84 struct section
*sec_dso__find_section(struct sec_dso
*self
, const char *name
)
94 hash
= crc32(name
, len
);
96 n
= self
->secs
.rb_node
;
99 struct section
*s
= rb_entry(n
, struct section
, rb_node
);
103 else if (hash
> s
->hash
)
106 if (!strcmp(name
, s
->name
))
109 n
= rb_next(&s
->rb_node
);
116 static size_t sec_dso__fprintf_section(struct section
*self
, FILE *fp
)
118 return fprintf(fp
, "name:%s vma:%llx path:%s\n",
119 self
->name
, self
->vma
, self
->path
);
122 size_t sec_dso__fprintf(struct sec_dso
*self
, FILE *fp
)
124 size_t ret
= fprintf(fp
, "dso: %s\n", self
->name
);
127 for (nd
= rb_first(&self
->secs
); nd
; nd
= rb_next(nd
)) {
128 struct section
*pos
= rb_entry(nd
, struct section
, rb_node
);
129 ret
+= sec_dso__fprintf_section(pos
, fp
);
135 static struct section
*section__new(const char *name
, const char *path
)
137 struct section
*self
= calloc(1, sizeof(*self
));
142 self
->name
= calloc(1, strlen(name
) + 1);
146 self
->path
= calloc(1, strlen(path
) + 1);
150 strcpy(self
->name
, name
);
151 strcpy(self
->path
, path
);
152 self
->hash
= crc32(self
->name
, strlen(name
));
170 struct mod_dso
*mod_dso__new_dso(const char *name
)
172 struct mod_dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
175 strcpy(self
->name
, name
);
176 self
->mods
= RB_ROOT
;
177 self
->find_module
= mod_dso__find_module
;
183 static void mod_dso__delete_module(struct module
*self
)
185 free(((void *)self
));
188 void mod_dso__delete_modules(struct mod_dso
*self
)
191 struct rb_node
*next
= rb_first(&self
->mods
);
194 pos
= rb_entry(next
, struct module
, rb_node
);
195 next
= rb_next(&pos
->rb_node
);
196 rb_erase(&pos
->rb_node
, &self
->mods
);
197 mod_dso__delete_module(pos
);
201 void mod_dso__delete_self(struct mod_dso
*self
)
203 mod_dso__delete_modules(self
);
207 static void mod_dso__insert_module(struct mod_dso
*self
, struct module
*mod
)
209 struct rb_node
**p
= &self
->mods
.rb_node
;
210 struct rb_node
*parent
= NULL
;
211 const u64 hash
= mod
->hash
;
216 m
= rb_entry(parent
, struct module
, rb_node
);
222 rb_link_node(&mod
->rb_node
, parent
, p
);
223 rb_insert_color(&mod
->rb_node
, &self
->mods
);
226 struct module
*mod_dso__find_module(struct mod_dso
*self
, const char *name
)
236 hash
= crc32(name
, len
);
238 n
= self
->mods
.rb_node
;
241 struct module
*m
= rb_entry(n
, struct module
, rb_node
);
245 else if (hash
> m
->hash
)
248 if (!strcmp(name
, m
->name
))
251 n
= rb_next(&m
->rb_node
);
258 static size_t mod_dso__fprintf_module(struct module
*self
, FILE *fp
)
260 return fprintf(fp
, "name:%s path:%s\n", self
->name
, self
->path
);
263 size_t mod_dso__fprintf(struct mod_dso
*self
, FILE *fp
)
268 ret
= fprintf(fp
, "dso: %s\n", self
->name
);
270 for (nd
= rb_first(&self
->mods
); nd
; nd
= rb_next(nd
)) {
271 struct module
*pos
= rb_entry(nd
, struct module
, rb_node
);
273 ret
+= mod_dso__fprintf_module(pos
, fp
);
279 static struct module
*module__new(const char *name
, const char *path
)
281 struct module
*self
= calloc(1, sizeof(*self
));
286 self
->name
= calloc(1, strlen(name
) + 1);
290 self
->path
= calloc(1, strlen(path
) + 1);
294 strcpy(self
->name
, name
);
295 strcpy(self
->path
, path
);
296 self
->hash
= crc32(self
->name
, strlen(name
));
312 static int mod_dso__load_sections(struct module
*mod
)
314 int count
= 0, path_len
;
315 struct dirent
*entry
;
321 path_len
= strlen("/sys/module/");
322 path_len
+= strlen(mod
->name
);
323 path_len
+= strlen("/sections/");
325 dir_path
= calloc(1, path_len
+ 1);
326 if (dir_path
== NULL
)
329 strcat(dir_path
, "/sys/module/");
330 strcat(dir_path
, mod
->name
);
331 strcat(dir_path
, "/sections/");
333 dir
= opendir(dir_path
);
337 while ((entry
= readdir(dir
))) {
338 struct section
*section
;
343 if (!strcmp(".", entry
->d_name
) || !strcmp("..", entry
->d_name
))
346 path
= calloc(1, path_len
+ strlen(entry
->d_name
) + 1);
349 strcat(path
, dir_path
);
350 strcat(path
, entry
->d_name
);
352 file
= fopen(path
, "r");
358 line_len
= getline(&line
, &n
, file
);
371 line
[--line_len
] = '\0'; /* \n */
373 vma
= strstr(line
, "0x");
381 section
= section__new(entry
->d_name
, path
);
383 fprintf(stderr
, "load_sections: allocation error\n");
389 hex2u64(vma
, §ion
->vma
);
390 sec_dso__insert_section(mod
->sections
, section
);
410 static int mod_dso__load_module_paths(struct mod_dso
*self
)
413 int count
= 0, len
, err
= -1;
422 len
= strlen("/lib/modules/");
423 len
+= strlen(uts
.release
);
424 len
+= strlen("/modules.dep");
426 dpath
= calloc(1, len
+ 1);
430 strcat(dpath
, "/lib/modules/");
431 strcat(dpath
, uts
.release
);
432 strcat(dpath
, "/modules.dep");
434 file
= fopen(dpath
, "r");
438 dir
= dirname(dpath
);
443 while (!feof(file
)) {
444 struct module
*module
;
445 char *name
, *path
, *tmp
;
449 line_len
= getline(&line
, &n
, file
);
456 line
[--line_len
] = '\0'; /* \n */
458 path
= strchr(line
, ':');
467 if (!strstr(path
, dir
)) {
468 if (strncmp(path
, "kernel/", 7))
472 path
= calloc(1, strlen(dir
) + strlen(line
) + 1);
479 modfile
= fopen(path
, "r");
488 name
= strtok(name
, "/");
492 tmp
= strtok(NULL
, "/");
497 name
= strsep(&name
, ".");
501 /* Quirk: replace '-' with '_' in all modules */
502 for (len
= strlen(name
); len
; len
--) {
503 if (*(name
+len
) == '-')
507 module
= module__new(name
, path
);
510 mod_dso__insert_module(self
, module
);
512 module
->sections
= sec_dso__new_dso("sections");
513 if (!module
->sections
)
516 module
->active
= mod_dso__load_sections(module
);
518 if (module
->active
> 0)
525 fprintf(stderr
, "load_module_paths: modules.dep parsing failure!\n");
538 int mod_dso__load_modules(struct mod_dso
*dso
)
542 err
= mod_dso__load_module_paths(dso
);