From 717ea8ba5523d333de9e9f23ea2733f6466ccd53 Mon Sep 17 00:00:00 2001 From: Toshikazu Nakayama Date: Fri, 5 Nov 2010 15:07:12 +0900 Subject: [PATCH 2/4] module's percpu basic procedure. - Initialize new member at module_init() - Make static SEC_FOUND to .data..percpu and .data.percpu sections at store_section_data() These can not read from /dev/mem or core file. (not include in kallsyms nor module_core.) - Install syms into st->mod_load_namespace at store_load_module_symbols() module's percpu section include bfd of module object. The syment.value is sum of bfd value and module.percpu. [v3] - Set percpu section size at store_section_data() I think bfd_section_size(module percpu section) can get the same value as kernel's percpu_modalloc(sh_size). - Register percpu section into gdb interface. Without registration, p &(module percpu symbol) is not work well. Signed-off-by: Toshikazu Nakayama --- kernel.c | 1 + symbols.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/kernel.c b/kernel.c index 9ba0dc4..3439c5a 100755 --- a/kernel.c +++ b/kernel.c @@ -2694,6 +2694,7 @@ module_init(void) MEMBER_OFFSET_INIT(module_init_size, "module", "init_size"); MEMBER_OFFSET_INIT(module_init_text_size, "module", "init_text_size"); + MEMBER_OFFSET_INIT(module_percpu, "module", "percpu"); /* * Make sure to pick the kernel "modules" list_head symbol, diff --git a/symbols.c b/symbols.c index ec9c893..5b59fb2 100755 --- a/symbols.c +++ b/symbols.c @@ -1349,6 +1349,7 @@ store_module_symbols_v2(ulong total, int mods_installed) lm->mod_ext_symcnt = mcnt; lm->mod_init_module_ptr = ULONG(modbuf + OFFSET(module_module_init)); + lm->mod_percpu = ULONG(modbuf + OFFSET(module_percpu)); if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) { lm->mod_etext_guess = lm->mod_base + UINT(modbuf + OFFSET(module_core_text_size)); @@ -8346,6 +8347,12 @@ store_section_data(struct load_module *lm, bfd *bfd, asection *section) lm->mod_section_data[i].section = section; lm->mod_section_data[i].priority = prio; lm->mod_section_data[i].flags = section->flags & ~SEC_FOUND; + /* percpu section isn't included in kallsyms nor module_core area. */ + if (lm->mod_percpu && + (STREQ(name,".data.percpu") || STREQ(name, ".data..percpu"))) { + lm->mod_percpu_size = bfd_section_size(bfd, section); + lm->mod_section_data[i].flags |= SEC_FOUND; + } lm->mod_section_data[i].size = bfd_section_size(bfd, section); lm->mod_section_data[i].offset = 0; if (strlen(name) < MAX_MOD_SEC_NAME) @@ -8791,13 +8798,26 @@ add_symbol_file(struct load_module *lm) { secname = lm->mod_section_data[i].name; if ((lm->mod_section_data[i].flags & SEC_FOUND) && - !STREQ(secname, ".text")) { + (!STREQ(secname, ".text") && + !STREQ(secname, ".data.percpu") && + !STREQ(secname, ".data..percpu"))) { sprintf(buf, " -s %s 0x%lx", secname, lm->mod_section_data[i].offset + lm->mod_base); len += strlen(buf); } } + for (i = 0; i < lm->mod_sections; i++) + { + secname = lm->mod_section_data[i].name; + if ((lm->mod_section_data[i].flags & SEC_FOUND) && + (STREQ(secname, ".data.percpu") || + STREQ(secname, ".data..percpu"))) { + sprintf(buf, " -s %s 0x%lx", secname, lm->mod_percpu); + len += strlen(buf); + } + } + req->command = GNU_ADD_SYMBOL_FILE; req->addr = (ulong)lm; req->buf = GETBUF(len+BUFSIZE); @@ -8816,6 +8836,32 @@ add_symbol_file(struct load_module *lm) } #ifdef GDB_7_0 +static long add_symbol_file_percpu(struct load_module *lm, char *buf, + long buflen) +{ + char pbuf[BUFSIZE]; + int i; + char *secname; + long len; + + len = strlen(buf); + for (i = 0; i < lm->mod_sections; i++) { + secname = lm->mod_section_data[i].name; + if ((lm->mod_section_data[i].flags & SEC_FOUND) && + (STREQ(secname, ".data.percpu") || + STREQ(secname, ".data..percpu"))) { + sprintf(pbuf, " -s %s 0x%lx", secname, lm->mod_percpu); + while ((len + strlen(pbuf)) >= buflen) { + RESIZEBUF(buf, buflen, buflen * 2); + buflen *= 2; + } + strcat(buf, pbuf); + len += strlen(pbuf); + } + } + return buflen; +} + /* * Gather the module section data from the in-kernel data structures. */ @@ -9035,6 +9081,9 @@ add_symbol_file_kallsyms(struct load_module *lm, struct gnu_request *req) return FALSE; } + /* too ugly but gdb registration request must be one-shot. */ + buflen = add_symbol_file_percpu(lm, req->buf, buflen); + lm->mod_flags |= MOD_NOPATCH; req->command = GNU_ADD_SYMBOL_FILE; req->addr = (ulong)lm; @@ -9314,7 +9363,12 @@ store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms, else if ((spx = kallsyms_module_symbol(lm, &syminfo))) { syminfo.value = spx->value; found = TRUE; - } else { + } else if (lm->mod_percpu && + (STREQ(secname, ".data.percpu") || + STREQ(secname, ".data..percpu"))) { + syminfo.value += lm->mod_percpu; + found = TRUE; + } else { syminfo.value += lm->mod_section_data[i].offset + lm->mod_base; found = TRUE; } -- 1.7.3.2.161.g3089c