[Crash-utility] [RFC PATCH 06/15] Support "mod -s|-S" options
HAGIO KAZUHITO(萩尾 一仁)
k-hagio-ab at nec.com
Fri May 26 08:16:07 UTC 2023
On 2023/05/26 15:20, lijiang wrote:
> On Thu, May 11, 2023 at 12:35 PM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab at nec.com>
> wrote:
>
>> Support "mod -s|-S" with introducing lm->load_sym{table,end}
>>
>> but many functions like "mod -d|-D" are still not supported.
>>
>> Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com>
>> ---
>> defs.h | 9 +-
>> gdb-10.2.patch | 16 +++
>> symbols.c | 350 ++++++++++++++++++++++++++++++++++++++++++++-----
>> 3 files changed, 340 insertions(+), 35 deletions(-)
>>
>> diff --git a/defs.h b/defs.h
>> index 95e44e8cb87c..b2478b6741ec 100644
>> --- a/defs.h
>> +++ b/defs.h
>> @@ -2925,6 +2925,7 @@ struct mod_section_data {
>> ulong size;
>> int priority;
>> int flags;
>> + ulong addr;
>>
>
> Is it possible to reuse the member offset in module memory patches? I
> noticed that the offset is not used in the calculate_load_order_v3(). If it
> is doable to reuse the offset, that may avoid modifying the gdb patch? I
> haven't investigated the details.
Modifying the gdb patch will be unavoidable, because the calculation in
gdb/symtab.c is different from the existing one.
And if we reuse the offset member, anyway we need an additional flag or
something to switch the calculation above. So I decided to add the addr
member to clarify its meaning.
>
> };
>>
>> /* This is unlikely to change, so imported from kernel for now. */
>> @@ -2982,8 +2983,12 @@ struct load_module {
>>
>> /* For 6.4 module_memory */
>> struct module_memory mem[MOD_MEM_NUM_TYPES];
>
> - struct syment *symtable[MOD_MEM_NUM_TYPES];
>> - struct syment *symend[MOD_MEM_NUM_TYPES];
>> + struct syment **symtable;
>> + struct syment **symend;
>>
>
> Some similar member definitions are in the struct symbol_table_data
> and struct load_module, it looks confusing to me. But I'm not sure if it is
> better to move some of them to the struct symbol_talbe_data.
These are the information of each module, I think they should not be
moved to struct symbol_table_data.
>
> + struct syment *ext_symtable[MOD_MEM_NUM_TYPES];
>> + struct syment *ext_symend[MOD_MEM_NUM_TYPES];
>> + struct syment *load_symtable[MOD_MEM_NUM_TYPES];
>> + struct syment *load_symend[MOD_MEM_NUM_TYPES];
>> int address_order[MOD_MEM_NUM_TYPES];
>> int nr_mems;
>> };
>> diff --git a/gdb-10.2.patch b/gdb-10.2.patch
>> index 835aae9859be..b3f6d8b086eb 100644
>> --- a/gdb-10.2.patch
>> +++ b/gdb-10.2.patch
>> @@ -3120,3 +3120,19 @@ exit 0
>> return result;
>> }
>>
>> +--- gdb-10.2/gdb/symtab.c.orig
>> ++++ gdb-10.2/gdb/symtab.c
>> +@@ -7515,8 +7515,11 @@ gdb_add_symbol_file(struct gnu_request *
>> + secname = lm->mod_section_data[i].name;
>> + if ((lm->mod_section_data[i].flags &
>> SEC_FOUND) &&
>> + !STREQ(secname, ".text")) {
>> +- sprintf(buf, " -s %s 0x%lx", secname,
>> +- lm->mod_section_data[i].offset +
>> lm->mod_base);
>> ++ if (lm->mod_section_data[i].addr)
>> ++ sprintf(buf, " -s %s 0x%lx",
>> secname, lm->mod_section_data[i].addr);
>> ++ else
>> ++ sprintf(buf, " -s %s 0x%lx",
>> secname,
>> ++
>> lm->mod_section_data[i].offset + lm->mod_base);
>> + strcat(req->buf, buf);
>> + }
>> + }
>> diff --git a/symbols.c b/symbols.c
>> index ef00ce0b79ca..8343081f51f7 100644
>> --- a/symbols.c
>> +++ b/symbols.c
>> @@ -50,6 +50,8 @@ static void store_section_data(struct load_module *, bfd
>> *, asection *);
>> static void calculate_load_order_v1(struct load_module *, bfd *);
>> static void calculate_load_order_v2(struct load_module *, bfd *, int,
>> void *, long, unsigned int);
>> +static void calculate_load_order_v3(struct load_module *, bfd *, int,
>> + void *, long, unsigned int);
>
> static void check_insmod_builtin(struct load_module *, int, ulong *);
>> static int is_insmod_builtin(struct load_module *, struct syment *);
>> struct load_module;
>> @@ -2288,20 +2290,22 @@ store_module_symbols_v3(ulong total, int
>> mods_installed)
>>
>> for (sp = st->ext_module_symtable; sp <
>> st->ext_module_symend; sp++) {
>> if (STREQ(sp->name, buf1)) {
>> - lm->symtable[i] = sp;
>> + lm->ext_symtable[i] = sp;
>> break;
>> }
>> }
>> for ( ; sp < st->ext_module_symend; sp++) {
>> if (STREQ(sp->name, buf2)) {
>> - lm->symend[i] = sp;
>> + lm->ext_symend[i] = sp;
>> break;
>> }
>> }
>>
>> - if (lm->symtable[i] && lm->symend[i])
>> -
>> mod_symtable_hash_install_range(lm->symtable[i], lm->symend[i]);
>> + if (lm->ext_symtable[i] && lm->ext_symend[i])
>> +
>> mod_symtable_hash_install_range(lm->ext_symtable[i], lm->ext_symend[i]);
>> }
>> + lm->symtable = lm->ext_symtable;
>> + lm->symend = lm->ext_symend;
>> }
>>
>> st->flags |= MODULE_SYMS;
>> @@ -4090,15 +4094,27 @@ dump_symbol_table(void)
>> for (j = 0; j < lm->nr_mems; j++)
>> fprintf(fp, " %d", lm->address_order[j]);
>> fprintf(fp, "\n");
>> + fprintf(fp, " symtable: %lx\n",
>> (ulong)lm->symtable);
>> + fprintf(fp, " ext_symtable: %lx\n",
>> (ulong)lm->ext_symtable);
>> + for (j = MOD_TEXT; j < MOD_MEM_NUM_TYPES; j++) {
>> + fprintf(fp, " ext_symtable[%d]: %lx
>> - %lx\n",
>> + j, (ulong)lm->ext_symtable[j],
>> (ulong)lm->ext_symend[j]);
>> + }
>> + fprintf(fp, " load_symtable: %lx\n",
>> (ulong)lm->load_symtable);
>> + for (j = MOD_TEXT; j < MOD_MEM_NUM_TYPES; j++) {
>> + fprintf(fp, " load_symtable[%d]: %lx
>> - %lx\n",
>> + j, (ulong)lm->load_symtable[j],
>> (ulong)lm->load_symend[j]);
>> + }
>> }
>>
>> for (s = 0; s < lm->mod_sections; s++) {
>> fprintf(fp,
>> - " %12s prio: %x flags: %05x offset: %-8lx size:
>> %lx\n",
>> + " %20s prio: %x flags: %08x offset: %-8lx addr:
>> %-16lx size: %lx\n",
>> lm->mod_section_data[s].name,
>> lm->mod_section_data[s].priority,
>> lm->mod_section_data[s].flags,
>> lm->mod_section_data[s].offset,
>> + lm->mod_section_data[s].addr,
>> lm->mod_section_data[s].size);
>> }
>>
>> @@ -12122,6 +12138,7 @@ store_section_data(struct load_module *lm, bfd
>> *bfd, asection *section)
>> }
>> lm->mod_section_data[i].size = bfd_section_size(section);
>> lm->mod_section_data[i].offset = 0;
>> + lm->mod_section_data[i].addr = 0;
>> if (strlen(name) < MAX_MOD_SEC_NAME)
>> strcpy(lm->mod_section_data[i].name, name);
>> else
>> @@ -12367,6 +12384,133 @@ calculate_load_order_v2(struct load_module *lm,
>> bfd *bfd, int dynamic,
>> }
>> }
>>
>> +/* Linux 6.4 and later */
>> +static void
>> +calculate_load_order_v3(struct load_module *lm, bfd *bfd, int dynamic,
>> + void *minisyms, long symcount, unsigned int size)
>> +{
>> + struct syment *s1, *s2;
>> + ulong sec_start;
>> + bfd_byte *from, *fromend;
>> + asymbol *store;
>> + asymbol *sym;
>> + symbol_info syminfo;
>> + char *secname;
>> + int i, j;
>> +
>> + if ((store = bfd_make_empty_symbol(bfd)) == NULL)
>> + error(FATAL, "bfd_make_empty_symbol() failed\n");
>> +
>> + for (j = MOD_TEXT; j < MOD_MEM_NUM_TYPES; j++) {
>> +
>>
>
> The above for-loop is frequently used in these patches, can we introduce
> the following macro definition from the kernel?
>
> #define for_each_mod_mem_type(type) \
> for (enum mod_mem_type (type) = 0; \
> (type) < MOD_MEM_NUM_TYPES; (type)++)
>
> Looks more convenient to me.
Yes, agree, also I was thinking about something like this.
will try it in the next version.
(I'd like to use int as I wrote in the 02/15 thread though :)
Thanks,
Kazu
More information about the Crash-utility
mailing list