10 #include <sys/utsname.h>
12 static unsigned int crc32(const char *p
, unsigned int len
)
19 for (i
= 0; i
< 8; i
++)
20 crc
= (crc
>> 1) ^ ((crc
& 1) ? 0xedb88320 : 0);
25 /* module section methods */
27 struct sec_dso
*sec_dso__new_dso(const char *name
)
29 struct sec_dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
32 strcpy(self
->name
, name
);
34 self
->find_section
= sec_dso__find_section
;
40 static void sec_dso__delete_section(struct section
*self
)
45 void sec_dso__delete_sections(struct sec_dso
*self
)
48 struct rb_node
*next
= rb_first(&self
->secs
);
51 pos
= rb_entry(next
, struct section
, rb_node
);
52 next
= rb_next(&pos
->rb_node
);
53 rb_erase(&pos
->rb_node
, &self
->secs
);
54 sec_dso__delete_section(pos
);
58 void sec_dso__delete_self(struct sec_dso
*self
)
60 sec_dso__delete_sections(self
);
64 static void sec_dso__insert_section(struct sec_dso
*self
, struct section
*sec
)
66 struct rb_node
**p
= &self
->secs
.rb_node
;
67 struct rb_node
*parent
= NULL
;
68 const u64 hash
= sec
->hash
;
73 s
= rb_entry(parent
, struct section
, rb_node
);
79 rb_link_node(&sec
->rb_node
, parent
, p
);
80 rb_insert_color(&sec
->rb_node
, &self
->secs
);
83 struct section
*sec_dso__find_section(struct sec_dso
*self
, const char *name
)
93 hash
= crc32(name
, len
);
95 n
= self
->secs
.rb_node
;
98 struct section
*s
= rb_entry(n
, struct section
, rb_node
);
102 else if (hash
> s
->hash
)
105 if (!strcmp(name
, s
->name
))
108 n
= rb_next(&s
->rb_node
);
115 static size_t sec_dso__fprintf_section(struct section
*self
, FILE *fp
)
117 return fprintf(fp
, "name:%s vma:%llx path:%s\n",
118 self
->name
, self
->vma
, self
->path
);
121 size_t sec_dso__fprintf(struct sec_dso
*self
, FILE *fp
)
123 size_t ret
= fprintf(fp
, "dso: %s\n", self
->name
);
126 for (nd
= rb_first(&self
->secs
); nd
; nd
= rb_next(nd
)) {
127 struct section
*pos
= rb_entry(nd
, struct section
, rb_node
);
128 ret
+= sec_dso__fprintf_section(pos
, fp
);
134 static struct section
*section__new(const char *name
, const char *path
)
136 struct section
*self
= calloc(1, sizeof(*self
));
141 self
->name
= calloc(1, strlen(name
) + 1);
145 self
->path
= calloc(1, strlen(path
) + 1);
149 strcpy(self
->name
, name
);
150 strcpy(self
->path
, path
);
151 self
->hash
= crc32(self
->name
, strlen(name
));
169 struct mod_dso
*mod_dso__new_dso(const char *name
)
171 struct mod_dso
*self
= malloc(sizeof(*self
) + strlen(name
) + 1);
174 strcpy(self
->name
, name
);
175 self
->mods
= RB_ROOT
;
176 self
->find_module
= mod_dso__find_module
;
182 static void mod_dso__delete_module(struct module
*self
)
184 free(((void *)self
));
187 void mod_dso__delete_modules(struct mod_dso
*self
)
190 struct rb_node
*next
= rb_first(&self
->mods
);
193 pos
= rb_entry(next
, struct module
, rb_node
);
194 next
= rb_next(&pos
->rb_node
);
195 rb_erase(&pos
->rb_node
, &self
->mods
);
196 mod_dso__delete_module(pos
);
200 void mod_dso__delete_self(struct mod_dso
*self
)
202 mod_dso__delete_modules(self
);
206 static void mod_dso__insert_module(struct mod_dso
*self
, struct module
*mod
)
208 struct rb_node
**p
= &self
->mods
.rb_node
;
209 struct rb_node
*parent
= NULL
;
210 const u64 hash
= mod
->hash
;
215 m
= rb_entry(parent
, struct module
, rb_node
);
221 rb_link_node(&mod
->rb_node
, parent
, p
);
222 rb_insert_color(&mod
->rb_node
, &self
->mods
);
225 struct module
*mod_dso__find_module(struct mod_dso
*self
, const char *name
)
235 hash
= crc32(name
, len
);
237 n
= self
->mods
.rb_node
;
240 struct module
*m
= rb_entry(n
, struct module
, rb_node
);
244 else if (hash
> m
->hash
)
247 if (!strcmp(name
, m
->name
))
250 n
= rb_next(&m
->rb_node
);
257 static size_t mod_dso__fprintf_module(struct module
*self
, FILE *fp
)
259 return fprintf(fp
, "name:%s path:%s\n", self
->name
, self
->path
);
262 size_t mod_dso__fprintf(struct mod_dso
*self
, FILE *fp
)
267 ret
= fprintf(fp
, "dso: %s\n", self
->name
);
269 for (nd
= rb_first(&self
->mods
); nd
; nd
= rb_next(nd
)) {
270 struct module
*pos
= rb_entry(nd
, struct module
, rb_node
);
272 ret
+= mod_dso__fprintf_module(pos
, fp
);
278 static struct module
*module__new(const char *name
, const char *path
)
280 struct module
*self
= calloc(1, sizeof(*self
));
285 self
->name
= calloc(1, strlen(name
) + 1);
289 self
->path
= calloc(1, strlen(path
) + 1);
293 strcpy(self
->name
, name
);
294 strcpy(self
->path
, path
);
295 self
->hash
= crc32(self
->name
, strlen(name
));
311 static int mod_dso__load_sections(struct module
*mod
)
313 int count
= 0, path_len
;
314 struct dirent
*entry
;
320 path_len
= strlen("/sys/module/");
321 path_len
+= strlen(mod
->name
);
322 path_len
+= strlen("/sections/");
324 dir_path
= calloc(1, path_len
+ 1);
325 if (dir_path
== NULL
)
328 strcat(dir_path
, "/sys/module/");
329 strcat(dir_path
, mod
->name
);
330 strcat(dir_path
, "/sections/");
332 dir
= opendir(dir_path
);
336 while ((entry
= readdir(dir
))) {
337 struct section
*section
;
342 if (!strcmp(".", entry
->d_name
) || !strcmp("..", entry
->d_name
))
345 path
= calloc(1, path_len
+ strlen(entry
->d_name
) + 1);
348 strcat(path
, dir_path
);
349 strcat(path
, entry
->d_name
);
351 file
= fopen(path
, "r");
357 line_len
= getline(&line
, &n
, file
);
370 line
[--line_len
] = '\0'; /* \n */
372 vma
= strstr(line
, "0x");
380 section
= section__new(entry
->d_name
, path
);
382 fprintf(stderr
, "load_sections: allocation error\n");
388 hex2u64(vma
, §ion
->vma
);
389 sec_dso__insert_section(mod
->sections
, section
);
409 static int mod_dso__load_module_paths(struct mod_dso
*self
)
421 len
= strlen("/lib/modules/");
422 len
+= strlen(uts
.release
);
423 len
+= strlen("/modules.dep");
425 path
= calloc(1, len
);
429 strcat(path
, "/lib/modules/");
430 strcat(path
, uts
.release
);
431 strcat(path
, "/modules.dep");
433 file
= fopen(path
, "r");
438 while (!feof(file
)) {
439 char *path
, *name
, *tmp
;
440 struct module
*module
;
443 line_len
= getline(&line
, &n
, file
);
450 line
[--line_len
] = '\0'; /* \n */
452 path
= strtok(line
, ":");
457 name
= strtok(name
, "/");
462 tmp
= strtok(NULL
, "/");
466 name
= strsep(&name
, ".");
468 /* Quirk: replace '-' with '_' in sound modules */
469 for (len
= strlen(name
); len
; len
--) {
470 if (*(name
+len
) == '-')
474 module
= module__new(name
, path
);
476 fprintf(stderr
, "load_module_paths: allocation error\n");
479 mod_dso__insert_module(self
, module
);
481 module
->sections
= sec_dso__new_dso("sections");
482 if (!module
->sections
) {
483 fprintf(stderr
, "load_module_paths: allocation error\n");
487 module
->active
= mod_dso__load_sections(module
);
489 if (module
->active
> 0)
502 int mod_dso__load_modules(struct mod_dso
*dso
)
506 err
= mod_dso__load_module_paths(dso
);