/* List all sections in all modules. The callback routine is invoked with * token, module name, section name, section start, section end, section flags. */ int kallsyms_sections(void *token, int (*callback)(void *, const char *, const char *, ElfW(Addr), ElfW(Addr), ElfW(Word))) { const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ const struct kallsyms_section *ka_sec = NULL; const char *ka_str; const struct module *m; int i; kallsyms_do_first_time(); if (!kallsyms_module_list) return(0); for (m = *kallsyms_module_list; m; m = m->next) { if (!mod_member_present(m, kallsyms_start) || !mod_member_present(m, kallsyms_end) || m->kallsyms_start >= m->kallsyms_end) continue; ka_hdr = (struct kallsyms_header *)m->kallsyms_start; ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off); ka_str = ((char *)(ka_hdr) + ka_hdr->string_off); for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) { if (callback( token, *(m->name) ? m->name : "kernel", ka_sec->name_off + ka_str, ka_sec->start, ka_sec->start + ka_sec->size, ka_sec->flags)) return(0); } } return(1); }
/* Called by modules package when installing the driver */ int init_module(void) { if (!mod_member_present(&__this_module, can_unload)) { return -EBUSY; } __this_module.can_unload = can_unload; return zft_init(); }
static int __init fpe_init(void) { #ifdef MODULE if (!mod_member_present(&__this_module, can_unload)) return -EINVAL; __this_module.can_unload = fpe_unload; #else if (fpe_type[0] && strcmp(fpe_type, "fastfpe")) return 0; #endif printk("Fast Floating Point Emulator V0.0 (c) Peter Teichmann.\n"); /* Save pointer to the old FP handler and then patch ourselves in */ orig_fp_enter = kern_fp_enter; kern_fp_enter = fastfpe_enter; return 0; }
static int __init inet6_init(void) { struct sk_buff *dummy_skb; int err; #ifdef MODULE if (!mod_member_present(&__this_module, can_unload)) return -EINVAL; __this_module.can_unload = &ipv6_unload; #endif printk(KERN_INFO "IPv6 v0.8 for NET4.0\n"); if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "inet6_proto_init: size fault\n"); return -EINVAL; } /* * ipngwg API draft makes clear that the correct semantics * for TCP and UDP is to consider one TCP and UDP instance * in a host availiable by both INET and INET6 APIs and * able to communicate via both network protocols. */ #if defined(MODULE) && defined(CONFIG_SYSCTL) ipv6_sysctl_register(); #endif err = icmpv6_init(&inet6_family_ops); if (err) goto icmp_fail; err = ndisc_init(&inet6_family_ops); if (err) goto ndisc_fail; err = igmp6_init(&inet6_family_ops); if (err) goto igmp_fail; /* Create /proc/foo6 entries. */ #ifdef CONFIG_PROC_FS err = -ENOMEM; if (!proc_net_create("raw6", 0, raw6_get_info)) goto proc_raw6_fail; if (!proc_net_create("tcp6", 0, tcp6_get_info)) goto proc_tcp6_fail; if (!proc_net_create("udp6", 0, udp6_get_info)) goto proc_udp6_fail; if (!proc_net_create("sockstat6", 0, afinet6_get_info)) goto proc_sockstat6_fail; if (!proc_net_create("snmp6", 0, afinet6_get_snmp)) goto proc_snmp6_fail; #endif ipv6_netdev_notif_init(); ipv6_packet_init(); ip6_route_init(); ip6_flowlabel_init(); addrconf_init(); sit_init(); /* Init v6 transport protocols. */ udpv6_init(); tcpv6_init(); /* Now the userspace is allowed to create INET6 sockets. */ (void) sock_register(&inet6_family_ops); return 0; #ifdef CONFIG_PROC_FS proc_snmp6_fail: proc_net_remove("sockstat6"); proc_sockstat6_fail: proc_net_remove("udp6"); proc_udp6_fail: proc_net_remove("tcp6"); proc_tcp6_fail: proc_net_remove("raw6"); proc_raw6_fail: igmp6_cleanup(); #endif igmp_fail: ndisc_cleanup(); ndisc_fail: icmpv6_cleanup(); icmp_fail: #if defined(MODULE) && defined(CONFIG_SYSCTL) ipv6_sysctl_unregister(); #endif return err; }
int kallsyms_symbol_to_address( const char *name, /* Name to lookup */ unsigned long *token, /* Which module to start at */ const char **mod_name, /* Set to module name */ unsigned long *mod_start, /* Set to start address of module */ unsigned long *mod_end, /* Set to end address of module */ const char **sec_name, /* Set to section name */ unsigned long *sec_start, /* Set to start address of section */ unsigned long *sec_end, /* Set to end address of section */ const char **sym_name, /* Set to full symbol name */ unsigned long *sym_start, /* Set to start address of symbol */ unsigned long *sym_end /* Set to end address of symbol */ ) { const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ const struct kallsyms_section *ka_sec; const struct kallsyms_symbol *ka_sym = NULL; const char *ka_str = NULL; const struct module *m; int i = 0, l; const char *p, *pt_R; char *p2; kallsyms_do_first_time(); if (!kallsyms_module_list) return(0); /* Restart? */ m = *kallsyms_module_list; if (token && *token) { for (; m; m = m->next) if ((unsigned long)m == *token) break; if (m) m = m->next; } for (; m; m = m->next) { if (!mod_member_present(m, kallsyms_start) || !mod_member_present(m, kallsyms_end) || m->kallsyms_start >= m->kallsyms_end) continue; ka_hdr = (struct kallsyms_header *)m->kallsyms_start; ka_sym = (struct kallsyms_symbol *) ((char *)(ka_hdr) + ka_hdr->symbol_off); ka_str = ((char *)(ka_hdr) + ka_hdr->string_off); for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) { p = ka_str + ka_sym->name_off; if (strcmp(p, name) == 0) break; /* Unversioned requests match versioned names */ if (!(pt_R = strstr(p, "_R"))) continue; l = strlen(pt_R); if (l < 10) continue; /* Not _R.*xxxxxxxx */ (void)simple_strtoul(pt_R+l-8, &p2, 16); if (*p2) continue; /* Not _R.*xxxxxxxx */ if (strncmp(p, name, pt_R-p) == 0) break; /* Match with version */ } if (i < ka_hdr->symbols) break; } if (token) *token = (unsigned long)m; if (!m) return(0); /* not found */ ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off); *mod_name = *(m->name) ? m->name : "kernel"; *mod_start = ka_hdr->start; *mod_end = ka_hdr->end; *sec_name = ka_sec->name_off + ka_str; *sec_start = ka_sec->start; *sec_end = ka_sec->start + ka_sec->size; *sym_name = ka_sym->name_off + ka_str; *sym_start = ka_sym->symbol_addr; if (i < ka_hdr->symbols-1) { const struct kallsyms_symbol *ka_symn = ka_sym; kallsyms_next_sym(ka_hdr, ka_symn); *sym_end = ka_symn->symbol_addr; } else *sym_end = *sec_end; return(1); }
int kallsyms_address_to_symbol( unsigned long address, /* Address to lookup */ const char **mod_name, /* Set to module name */ unsigned long *mod_start, /* Set to start address of module */ unsigned long *mod_end, /* Set to end address of module */ const char **sec_name, /* Set to section name */ unsigned long *sec_start, /* Set to start address of section */ unsigned long *sec_end, /* Set to end address of section */ const char **sym_name, /* Set to full symbol name */ unsigned long *sym_start, /* Set to start address of symbol */ unsigned long *sym_end /* Set to end address of symbol */ ) { const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ const struct kallsyms_section *ka_sec = NULL; const struct kallsyms_symbol *ka_sym; const char *ka_str; const struct module *m; int i; unsigned long end; kallsyms_do_first_time(); if (!kallsyms_module_list) return(0); for (m = *kallsyms_module_list; m; m = m->next) { if (!mod_member_present(m, kallsyms_start) || !mod_member_present(m, kallsyms_end) || m->kallsyms_start >= m->kallsyms_end) continue; ka_hdr = (struct kallsyms_header *)m->kallsyms_start; ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off); /* Is the address in any section in this module? */ for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) { if (ka_sec->start <= address && (ka_sec->start + ka_sec->size) > address) break; } if (i < ka_hdr->sections) break; /* Found a matching section */ } if (!m) return(0); /* not found */ ka_sym = (struct kallsyms_symbol *) ((char *)(ka_hdr) + ka_hdr->symbol_off); ka_str = ((char *)(ka_hdr) + ka_hdr->string_off); *mod_name = *(m->name) ? m->name : "kernel"; *mod_start = ka_hdr->start; *mod_end = ka_hdr->end; *sec_name = ka_sec->name_off + ka_str; *sec_start = ka_sec->start; *sec_end = ka_sec->start + ka_sec->size; *sym_name = *sec_name; /* In case we find no matching symbol */ *sym_start = *sec_start; *sym_end = *sec_end; for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) { if (ka_sym->symbol_addr > address) continue; if (i < ka_hdr->symbols-1) { const struct kallsyms_symbol *ka_symn = ka_sym; kallsyms_next_sym(ka_hdr, ka_symn); end = ka_symn->symbol_addr; } else end = *sec_end; if (end <= address) continue; if ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off != (char *)ka_sec) continue; /* wrong section */ *sym_name = ka_str + ka_sym->name_off; *sym_start = ka_sym->symbol_addr; *sym_end = end; break; } return(1); }