Changeset 40eab9f in mainline


Ignore:
Timestamp:
2023-11-03T18:47:41Z (6 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master, topic/msim-upgrade, topic/simplify-dev-export
Children:
b1397ab
Parents:
dcd8214
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-11-03 18:46:22)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2023-11-03 18:47:41)
Message:

Print symbol names and line numbers in stacktraces for init tasks

Only useful in select few situations, but useful nonetheless.

Files:
15 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/sysinfo.h

    rdcd8214 r40eab9f  
    3737#define _ABI_SYSINFO_H_
    3838
     39#include <_bits/size_t.h>
    3940#include <stdbool.h>
    4041#include <abi/proc/task.h>
  • kernel/generic/include/debug/line.h

    rdcd8214 r40eab9f  
    3333#include <stddef.h>
    3434#include <stdint.h>
     35#include <debug/sections.h>
    3536
    3637struct debug_line_program_header {
     
    103104}
    104105
    105 extern bool debug_line_get_address_info(uintptr_t addr, int op_index, const char **file, const char **dir, int *line, int *col);
     106extern bool debug_line_get_address_info(debug_sections_t *scs, uintptr_t addr, int op_index, const char **file, const char **dir, int *line, int *col);
    106107
    107108#endif /* DWARFS_LINE_H_ */
  • kernel/generic/include/debug/sections.h

    rdcd8214 r40eab9f  
    3333#include <stddef.h>
    3434
    35 extern const void *debug_aranges;
    36 extern size_t debug_aranges_size;
     35typedef struct {
     36        const void *debug_aranges;
     37        size_t debug_aranges_size;
    3738
    38 extern const void *debug_info;
    39 extern size_t debug_info_size;
     39        const void *debug_info;
     40        size_t debug_info_size;
    4041
    41 extern const void *debug_abbrev;
    42 extern size_t debug_abbrev_size;
     42        const void *debug_abbrev;
     43        size_t debug_abbrev_size;
    4344
    44 extern const void *debug_line;
    45 extern size_t debug_line_size;
     45        const void *debug_line;
     46        size_t debug_line_size;
    4647
    47 extern const char *debug_str;
    48 extern size_t debug_str_size;
     48        const char *debug_str;
     49        size_t debug_str_size;
    4950
    50 extern const char *debug_line_str;
    51 extern size_t debug_line_str_size;
     51        const char *debug_line_str;
     52        size_t debug_line_str_size;
    5253
    53 extern const void *debug_rnglists;
    54 extern size_t debug_rnglists_size;
     54        const void *debug_rnglists;
     55        size_t debug_rnglists_size;
    5556
    56 extern const void *eh_frame_hdr;
    57 extern size_t eh_frame_hdr_size;
     57        const void *eh_frame_hdr;
     58        size_t eh_frame_hdr_size;
    5859
    59 extern const void *eh_frame;
    60 extern size_t eh_frame_size;
     60        const void *eh_frame;
     61        size_t eh_frame_size;
    6162
    62 extern const elf_symbol_t *symtab;
    63 extern size_t symtab_size;
     63        const elf_symbol_t *symtab;
     64        size_t symtab_size;
    6465
    65 extern const char *strtab;
    66 extern size_t strtab_size;
     66        const char *strtab;
     67        size_t strtab_size;
     68} debug_sections_t;
     69
     70extern debug_sections_t kernel_sections;
     71
     72debug_sections_t get_debug_sections(const void *elf, size_t elf_size);
    6773
    6874#endif /* DEBUG_SECTIONS_H_ */
  • kernel/generic/include/proc/program.h

    rdcd8214 r40eab9f  
    5656
    5757extern errno_t program_create(as_t *, uspace_addr_t, char *, program_t *);
    58 extern errno_t program_create_from_image(void *, char *, program_t *);
     58extern errno_t program_create_from_image(void *, size_t, char *, program_t *);
    5959extern errno_t program_create_loader(program_t *, char *);
    6060extern void program_ready(program_t *);
  • kernel/generic/include/proc/task.h

    rdcd8214 r40eab9f  
    3636#define KERN_TASK_H_
    3737
    38 #include <cpu.h>
    39 #include <ipc/ipc.h>
    40 #include <ipc/event.h>
    41 #include <ipc/kbox.h>
    42 #include <synch/spinlock.h>
    43 #include <synch/mutex.h>
     38#include <abi/proc/task.h>
     39#include <abi/sysinfo.h>
    4440#include <adt/list.h>
    4541#include <adt/odict.h>
    46 #include <security/perm.h>
     42#include <arch/context.h>
     43#include <arch/cpu.h>
     44#include <arch/fpu_context.h>
    4745#include <arch/proc/task.h>
    4846#include <arch/proc/thread.h>
    49 #include <arch/context.h>
    50 #include <arch/fpu_context.h>
    51 #include <arch/cpu.h>
     47#include <arch.h>
     48#include <cap/cap.h>
     49#include <cpu.h>
     50#include <debug/sections.h>
     51#include <ipc/event.h>
     52#include <ipc/ipc.h>
     53#include <ipc/kbox.h>
     54#include <mm/as.h>
    5255#include <mm/tlb.h>
    5356#include <proc/scheduler.h>
     57#include <security/perm.h>
     58#include <synch/mutex.h>
     59#include <synch/spinlock.h>
    5460#include <udebug/udebug.h>
    55 #include <mm/as.h>
    56 #include <abi/proc/task.h>
    57 #include <abi/sysinfo.h>
    58 #include <arch.h>
    59 #include <cap/cap.h>
    6061
    6162#define TASK                 CURRENT->task
     
    131132        uint64_t ucycles;
    132133        uint64_t kcycles;
     134
     135        debug_sections_t *debug_sections;
    133136} task_t;
    134137
  • kernel/generic/include/symtab.h

    rdcd8214 r40eab9f  
    3636#define KERN_SYMTAB_H_
    3737
     38#include <stdbool.h>
    3839#include <typedefs.h>
     40#include <debug/sections.h>
    3941
    4042extern void symtab_print_search(const char *);
     
    4244extern const char *symtab_fmt_name_lookup(uintptr_t);
    4345extern errno_t symtab_addr_lookup(const char *, uintptr_t *);
    44 extern const char *symtab_name_lookup(uintptr_t, uintptr_t *);
     46extern const char *symtab_name_lookup(uintptr_t, uintptr_t *, debug_sections_t *);
    4547
    4648#endif
  • kernel/generic/src/debug/line.c

    rdcd8214 r40eab9f  
    297297}
    298298
    299 static void debug_line_program_header_parse(const uint8_t *data, const uint8_t *data_end, struct debug_line_program_header *hdr)
     299static void debug_line_program_header_parse(debug_sections_t *scs, const uint8_t *data, const uint8_t *data_end, struct debug_line_program_header *hdr)
    300300{
    301301        const uint8_t *unit_start = data;
     
    378378                hdr->v5.directories_end = data;
    379379
    380                 print_formatted_list("directories", hdr->v5.directories, hdr->v5.directories_end,
     380                print_formatted_list(scs, "directories", hdr->v5.directories, hdr->v5.directories_end,
    381381                    hdr->v5.directory_entry_format, hdr->v5.directory_entry_format_end, width);
    382382
     
    397397                hdr->v5.file_names_end = data;
    398398
    399                 print_formatted_list("file_names", hdr->v5.file_names, hdr->v5.file_names_end,
     399                print_formatted_list(scs, "file_names", hdr->v5.file_names, hdr->v5.file_names_end,
    400400                    hdr->v5.file_name_entry_format, hdr->v5.file_name_entry_format_end, width);
    401401        }
     
    463463}
    464464
    465 static const char *get_file_name_v5(struct debug_line_program_header *hdr, int file, int *dir)
     465static const char *get_file_name_v5(debug_sections_t *scs, struct debug_line_program_header *hdr, int file, int *dir)
    466466{
    467467        // DWARF5 has dynamic layout for file information, which is why
     
    493493                                if (form == DW_FORM_line_strp) {
    494494                                        uint64_t offset = read_uint(&fns, fns_end, hdr->width);
    495                                         if (offset < debug_line_str_size) {
    496                                                 filename = debug_line_str + offset;
     495                                        if (offset < scs->debug_line_str_size) {
     496                                                filename = scs->debug_line_str + offset;
    497497                                        }
    498498                                        continue;
     
    527527}
    528528
    529 static const char *get_file_name(struct debug_line_program_header *hdr, int file, int *dir)
     529static const char *get_file_name(debug_sections_t *scs, struct debug_line_program_header *hdr, int file, int *dir)
    530530{
    531531        switch (hdr->version) {
     
    534534                return get_file_name_v3(hdr, file, dir);
    535535        case 5:
    536                 return get_file_name_v5(hdr, file, dir);
     536                return get_file_name_v5(scs, hdr, file, dir);
    537537        default:
    538538                return NULL;
     
    558558}
    559559
    560 static const char *get_dir_name_v5(struct debug_line_program_header *hdr, int dir)
     560static const char *get_dir_name_v5(debug_sections_t *scs, struct debug_line_program_header *hdr, int dir)
    561561{
    562562        // TODO: basically a copypaste of get_file_name(). Try to deduplicate it.
     
    587587                                if (form == DW_FORM_line_strp) {
    588588                                        uint64_t offset = read_uint(&fns, fns_end, hdr->width);
    589                                         if (offset < debug_line_str_size) {
    590                                                 filename = debug_line_str + offset;
     589                                        if (offset < scs->debug_line_str_size) {
     590                                                filename = scs->debug_line_str + offset;
    591591                                        }
    592592                                        continue;
     
    604604}
    605605
    606 static const char *get_dir_name(struct debug_line_program_header *hdr, int dir)
     606static const char *get_dir_name(debug_sections_t *scs, struct debug_line_program_header *hdr, int dir)
    607607{
    608608        switch (hdr->version) {
     
    611611                return get_dir_name_v3(hdr, dir);
    612612        case 5:
    613                 return get_dir_name_v5(hdr, dir);
     613                return get_dir_name_v5(scs, hdr, dir);
    614614        default:
    615615                return NULL;
     
    617617}
    618618
    619 static const uint8_t *find_line_program(uintptr_t addr)
     619static const uint8_t *find_line_program(debug_sections_t *scs, uintptr_t addr)
    620620{
    621621        // TODO: use .debug_aranges to find the data quickly
     
    625625        const uint8_t *closest_prog = NULL;
    626626
    627         const uint8_t *debug_line_ptr = debug_line;
    628         const uint8_t *const debug_line_end = debug_line + debug_line_size;
     627        const uint8_t *debug_line_ptr = scs->debug_line;
     628        const uint8_t *const debug_line_end = scs->debug_line + scs->debug_line_size;
    629629
    630630        while (debug_line_ptr < debug_line_end) {
     
    633633                // Parse header
    634634                struct debug_line_program_header hdr = { };
    635                 debug_line_program_header_parse(prog, debug_line_end, &hdr);
     635                debug_line_program_header_parse(scs, prog, debug_line_end, &hdr);
    636636                assert(hdr.unit_end > debug_line_ptr);
    637637                assert(hdr.unit_end <= debug_line_end);
     
    678678                debug_line_program_advance(&lp);
    679679
    680                 if (!lp.truncated) {
    681                         // We check for the last address before addr, because addr
    682                         // is a return address and we want the call instruction.
    683                         if (lp.address >= addr && lp.op_advance >= op_index) {
    684                                 if (!first) {
    685                                         *file = last_file;
    686                                         *line = last_line;
    687                                         *column = last_column;
    688                                         return true;
    689                                 }
    690 
     680                if (lp.truncated)
     681                        continue;
     682
     683                /*
     684                 * Return previous entry when we pass the target address, because
     685                 * the address may not be aligned perfectly on instruction boundary.
     686                 */
     687                if (lp.address > addr || (lp.address == addr && lp.op_advance > op_index)) {
     688                        if (first) {
    691689                                // First address is already too large, skip to the next sequence.
    692690                                debug_line_program_skip_to_sequence_end(&lp);
    693                         }
    694 
    695                         last_file = lp.file;
    696                         last_line = lp.line;
    697                         last_column = lp.column;
    698                 }
     691                                continue;
     692                        }
     693
     694                        *file = last_file;
     695                        *line = last_line;
     696                        *column = last_column;
     697                        return true;
     698                }
     699
     700                last_file = lp.file;
     701                last_line = lp.line;
     702                last_column = lp.column;
    699703        }
    700704
     
    702706}
    703707
    704 bool debug_line_get_address_info(uintptr_t addr, int op_index, const char **file_name, const char **dir_name, int *line, int *column)
    705 {
    706         const uint8_t *data = find_line_program(addr);
     708bool debug_line_get_address_info(debug_sections_t *scs, uintptr_t addr, int op_index, const char **file_name, const char **dir_name, int *line, int *column)
     709{
     710        const uint8_t *data = find_line_program(scs, addr);
    707711        if (data == NULL) {
    708712                return false;
    709713        }
    710714
    711         const uint8_t *const debug_line_end = debug_line + debug_line_size;
     715        const uint8_t *const debug_line_end = scs->debug_line + scs->debug_line_size;
    712716
    713717        struct debug_line_program_header hdr = { };
    714         debug_line_program_header_parse(data, debug_line_end, &hdr);
     718        debug_line_program_header_parse(scs, data, debug_line_end, &hdr);
    715719        assert(hdr.unit_end > data);
    716720        assert(hdr.unit_end <= debug_line_end);
     
    727731
    728732        if (file >= 0)
    729                 *file_name = get_file_name(&hdr, file, &dir);
     733                *file_name = get_file_name(scs, &hdr, file, &dir);
    730734
    731735        if (dir >= 0)
    732                 *dir_name = get_dir_name(&hdr, dir);
     736                *dir_name = get_dir_name(scs, &hdr, dir);
    733737
    734738        return true;
  • kernel/generic/src/debug/sections.c

    rdcd8214 r40eab9f  
    2929#include <debug/sections.h>
    3030#include <debug/register.h>
     31#include <debug.h>
    3132
    3233#include <stdio.h>
    3334#include <str.h>
    3435
    35 const void *debug_aranges = NULL;
    36 size_t debug_aranges_size = 0;
     36#define DEBUGF dummy_printf
    3737
    38 const void *debug_info = NULL;
    39 size_t debug_info_size = 0;
    40 
    41 const void *debug_abbrev = NULL;
    42 size_t debug_abbrev_size = 0;
    43 
    44 const void *debug_line = NULL;
    45 size_t debug_line_size = 0;
    46 
    47 const char *debug_str = NULL;
    48 size_t debug_str_size = 0;
    49 
    50 const char *debug_line_str = NULL;
    51 size_t debug_line_str_size = 0;
    52 
    53 const void *debug_rnglists = NULL;
    54 size_t debug_rnglists_size = 0;
    55 
    56 // TODO: get this from the program image
    57 const void *eh_frame_hdr = NULL;
    58 size_t eh_frame_hdr_size = 0;
    59 
    60 const void *eh_frame = NULL;
    61 size_t eh_frame_size = 0;
    62 
    63 const elf_symbol_t *symtab = NULL;
    64 size_t symtab_size = 0;
    65 
    66 const char *strtab = NULL;
    67 size_t strtab_size = 0;
     38debug_sections_t kernel_sections;
    6839
    6940struct section_manifest {
     
    7344};
    7445
    75 #define section(name) { "." #name, (const void **)&name, &name##_size }
     46static void _check_string_section(const char *section, size_t *section_size)
     47{
     48        while (*section_size > 0 && section[*section_size - 1] != 0) {
     49                (*section_size)--;
     50        }
     51}
    7652
    77 static const struct section_manifest manifest[] = {
    78         section(debug_aranges),
    79         section(debug_info),
    80         section(debug_abbrev),
    81         section(debug_line),
    82         section(debug_str),
    83         section(debug_line_str),
    84         section(debug_rnglists),
    85         section(eh_frame_hdr),
    86         section(eh_frame),
    87         section(symtab),
    88         section(strtab),
    89 };
     53debug_sections_t get_debug_sections(const void *elf, size_t elf_size)
     54{
     55        debug_sections_t out = { };
    9056
    91 #undef section
     57#define section(name) { "." #name, (const void **)&out.name, &out.name##_size }
    9258
    93 static const size_t manifest_len = sizeof(manifest) / sizeof(struct section_manifest);
     59        const struct section_manifest manifest[] = {
     60                section(debug_aranges),
     61                section(debug_info),
     62                section(debug_abbrev),
     63                section(debug_line),
     64                section(debug_str),
     65                section(debug_line_str),
     66                section(debug_rnglists),
     67                section(eh_frame_hdr),
     68                section(eh_frame),
     69                section(symtab),
     70                section(strtab),
     71        };
    9472
    95 void register_debug_data(const void *data, size_t data_size)
    96 {
    97         const void *data_end = data + data_size;
     73        const size_t manifest_len = sizeof(manifest) / sizeof(struct section_manifest);
     74
     75        const void *data_end = elf + elf_size;
    9876
    9977        /*
     
    10381         */
    10482
    105         if (data_size < sizeof(elf_header_t)) {
     83        if (elf_size < sizeof(elf_header_t)) {
    10684                printf("bad debug data: too short\n");
    107                 return;
     85                return out;
    10886        }
    10987
    110         if (((uintptr_t) data) % 8 != 0) {
     88        if (((uintptr_t) elf) % 8 != 0) {
    11189                printf("bad debug data: unaligned input\n");
    112                 return;
     90                return out;
    11391        }
    11492
    115         const elf_header_t *hdr = data;
     93        const elf_header_t *hdr = elf;
    11694
    11795        if (hdr->e_ident[0] != ELFMAG0 || hdr->e_ident[1] != ELFMAG1 ||
    11896            hdr->e_ident[2] != ELFMAG2 || hdr->e_ident[3] != ELFMAG3) {
    11997                printf("bad debug data: wrong ELF magic bytes\n");
    120                 return;
     98                return out;
    12199        }
    122100
    123101        if (hdr->e_shentsize != sizeof(elf_section_header_t)) {
    124102                printf("bad debug data: wrong e_shentsize\n");
    125                 return;
     103                return out;
    126104        }
    127105
    128106        /* Get section header table. */
    129         const elf_section_header_t *shdr = data + hdr->e_shoff;
     107        const elf_section_header_t *shdr = elf + hdr->e_shoff;
    130108        size_t shdr_len = hdr->e_shnum;
    131109
    132110        if ((void *) &shdr[shdr_len] > data_end) {
    133111                printf("bad debug data: truncated section header table\n");
    134                 return;
     112                return out;
    135113        }
    136114
    137115        if (hdr->e_shstrndx >= shdr_len) {
    138116                printf("bad debug data: string table index out of range\n");
    139                 return;
     117                return out;
    140118        }
    141119
    142120        /* Get data on section name string table. */
    143121        const elf_section_header_t *shstr = &shdr[hdr->e_shstrndx];
    144         const char *shstrtab = data + shstr->sh_offset;
     122        const char *shstrtab = elf + shstr->sh_offset;
    145123        size_t shstrtab_size = shstr->sh_size;
    146124
    147125        if ((void *) shstrtab + shstrtab_size > data_end) {
    148126                printf("bad debug data: truncated string table\n");
    149                 return;
     127                return out;
    150128        }
    151129
    152130        /* Check NUL-terminator. */
    153         while (shstrtab_size > 0 && shstrtab[shstrtab_size - 1] != 0) {
    154                 shstrtab_size--;
    155         }
     131        _check_string_section(shstrtab, &shstrtab_size);
    156132
    157133        if (shstrtab_size == 0) {
    158134                printf("bad debug data: empty or non-null-terminated string table\n");
    159                 return;
     135                return out;
    160136        }
    161137
     
    167143                if (shdr[i].sh_name >= shstrtab_size) {
    168144                        printf("bad debug data: string table index out of range\n");
    169                         return;
     145                        continue;
    170146                }
    171147
     
    174150                size_t size = shdr[i].sh_size;
    175151
    176                 printf("section '%s': offset %zd (%zd bytes)\n", name, offset, size);
     152                DEBUGF("section '%s': offset %zd (%zd bytes)\n", name, offset, size);
    177153
    178                 if (data + offset + size > data_end) {
     154                if (elf + offset + size > data_end) {
    179155                        printf("bad debug data: truncated section %s\n", name);
    180156                        continue;
     
    183159                for (size_t i = 0; i < manifest_len; i++) {
    184160                        if (str_cmp(manifest[i].name, name) == 0) {
    185                                 *manifest[i].address_field = data + offset;
     161                                *manifest[i].address_field = elf + offset;
    186162                                *manifest[i].size_field = size;
    187163                                break;
     
    191167
    192168        /* Check NUL-terminator in .strtab, .debug_str and .debug_line_str */
    193         while (strtab_size > 0 && strtab[strtab_size - 1] != 0) {
    194                 strtab_size--;
    195         }
     169        _check_string_section(out.strtab, &out.strtab_size);
     170        _check_string_section(out.debug_str, &out.debug_str_size);
     171        _check_string_section(out.debug_line_str, &out.debug_line_str_size);
    196172
    197         while (debug_str_size > 0 && debug_str[debug_str_size - 1] != 0) {
    198                 debug_str_size--;
    199         }
     173        return out;
     174}
    200175
    201         while (debug_line_str_size > 0 && debug_str[debug_line_str_size - 1] != 0) {
    202                 debug_line_str_size--;
    203         }
     176void register_debug_data(const void *elf, size_t elf_size)
     177{
     178        kernel_sections = get_debug_sections(elf, elf_size);
    204179}
  • kernel/generic/src/debug/stacktrace.c

    rdcd8214 r40eab9f  
    6060                int column = 0;
    6161
     62                /*
     63                 * If this isn't the first frame, move pc back by one byte to read the
     64                 * position of the call instruction, not the return address.
     65                 */
     66                pc = cnt == 1 ? ctx->pc : ctx->pc - 1;
     67
    6268                if (ops->symbol_resolve &&
    63                     ops->symbol_resolve(ctx->pc, 0, &symbol, &symbol_addr, &file_name, &dir_name, &line, &column)) {
     69                    ops->symbol_resolve(pc, 0, &symbol, &symbol_addr, &file_name, &dir_name, &line, &column)) {
    6470
    6571                        if (symbol == NULL)
     
    130136{
    131137        *symbol_addr = 0;
    132         *symbol = symtab_name_lookup(addr, symbol_addr);
     138        *symbol = symtab_name_lookup(addr, symbol_addr, &kernel_sections);
    133139
    134         return debug_line_get_address_info(addr, op_index, filename, dirname, line, column) || *symbol_addr != 0;
     140        return debug_line_get_address_info(&kernel_sections, addr, op_index, filename, dirname, line, column) || *symbol_addr != 0;
     141}
     142
     143static bool
     144resolve_uspace_address(uintptr_t addr, int op_index,
     145    const char **symbol, uintptr_t *symbol_addr,
     146    const char **filename, const char **dirname,
     147    int *line, int *column)
     148{
     149        if (TASK->debug_sections == NULL)
     150                return false;
     151
     152        debug_sections_t *scs = TASK->debug_sections;
     153
     154        *symbol_addr = 0;
     155        *symbol = symtab_name_lookup(addr, symbol_addr, scs);
     156
     157        return debug_line_get_address_info(scs, addr, op_index, filename, dirname, line, column) || *symbol_addr != 0;
    135158}
    136159
     
    146169        .frame_pointer_prev = uspace_frame_pointer_prev,
    147170        .return_address_get = uspace_return_address_get,
    148         .symbol_resolve = NULL
     171        .symbol_resolve = resolve_uspace_address,
    149172};
    150173
  • kernel/generic/src/debug/symtab.c

    rdcd8214 r40eab9f  
    3636 */
    3737
     38#include <abi/elf.h>
     39#include <byteorder.h>
     40#include <console/prompt.h>
     41#include <debug/sections.h>
     42#include <errno.h>
     43#include <proc/task.h>
     44#include <stdio.h>
     45#include <str.h>
    3846#include <symtab.h>
    39 #include <byteorder.h>
    40 #include <str.h>
    41 #include <stdio.h>
    4247#include <typedefs.h>
    43 #include <errno.h>
    44 #include <console/prompt.h>
    45 
    46 #include <abi/elf.h>
    47 #include <debug/sections.h>
    48 
    49 static inline size_t symtab_len()
    50 {
    51         return symtab_size / sizeof(elf_symbol_t);
    52 }
    53 
    54 static inline const char *symtab_entry_name(int entry)
    55 {
    56         size_t index = symtab[entry].st_name;
    57 
    58         if (index >= strtab_size)
    59                 return NULL;
    60 
    61         return strtab + index;
    62 }
    63 
    64 static inline size_t symtab_next(size_t i)
    65 {
    66         for (; i < symtab_len(); i++) {
    67                 const char *name = symtab_entry_name(i);
    68                 int st_bind = elf_st_bind(symtab[i].st_info);
    69                 int st_type = elf_st_type(symtab[i].st_info);
     48
     49static inline const char *symtab_entry_name(debug_sections_t *scs, int entry)
     50{
     51        size_t index = scs->symtab[entry].st_name;
     52
     53        if (index >= scs->strtab_size)
     54                return NULL;
     55
     56        return scs->strtab + index;
     57}
     58
     59static inline size_t symtab_next(debug_sections_t *scs, size_t i)
     60{
     61        size_t symtab_len = scs->symtab_size / sizeof(elf_symbol_t);
     62
     63        for (; i < symtab_len; i++) {
     64                const char *name = symtab_entry_name(scs, i);
     65                int st_bind = elf_st_bind(scs->symtab[i].st_info);
     66                int st_type = elf_st_type(scs->symtab[i].st_info);
    7067
    7168                if (st_bind == STB_LOCAL)
     
    8279}
    8380
    84 const char *symtab_name_lookup(uintptr_t addr, uintptr_t *symbol_addr)
    85 {
     81const char *symtab_name_lookup(uintptr_t addr, uintptr_t *symbol_addr, debug_sections_t *scs)
     82{
     83        const elf_symbol_t *symtab = scs->symtab;
     84        size_t symtab_len = scs->symtab_size / sizeof(elf_symbol_t);
     85        const char *strtab = scs->strtab;
     86        size_t strtab_size = scs->strtab_size;
     87
    8688        if (symtab == NULL || strtab == NULL)
    8789                return NULL;
     
    9092        uintptr_t closest_symbol_name = 0;
    9193
    92         for (size_t i = symtab_next(0); i < symtab_len(); i = symtab_next(i + 1)) {
     94        for (size_t i = symtab_next(scs, 0); i < symtab_len; i = symtab_next(scs, i + 1)) {
    9395                if (symtab[i].st_value > addr)
    9496                        continue;
     
    132134const char *symtab_fmt_name_lookup(uintptr_t addr)
    133135{
    134         const char *name = symtab_name_lookup(addr, NULL);
     136        const char *name = symtab_name_lookup(addr, NULL, &kernel_sections);
    135137        if (name == NULL)
    136138                name = "<unknown>";
     
    150152errno_t symtab_addr_lookup(const char *name, uintptr_t *addr)
    151153{
    152         for (size_t i = symtab_next(0); i < symtab_len(); i = symtab_next(i + 1)) {
    153                 if (str_cmp(name, symtab_entry_name(i)) == 0) {
    154                         *addr = symtab[i].st_value;
     154        debug_sections_t *scs = &kernel_sections;
     155        size_t symtab_len = scs->symtab_size / sizeof(elf_symbol_t);
     156
     157        for (size_t i = symtab_next(scs, 0); i < symtab_len; i = symtab_next(scs, i + 1)) {
     158                if (str_cmp(name, symtab_entry_name(scs, i)) == 0) {
     159                        *addr = scs->symtab[i].st_value;
    155160                        return EOK;
    156161                }
     
    163168void symtab_print_search(const char *name)
    164169{
    165         if (symtab == NULL || strtab == NULL) {
     170        debug_sections_t *scs = &kernel_sections;
     171        size_t symtab_len = scs->symtab_size / sizeof(elf_symbol_t);
     172
     173        if (scs->symtab == NULL || scs->strtab == NULL) {
    166174                printf("No symbol information available.\n");
    167175                return;
     
    170178        size_t namelen = str_length(name);
    171179
    172         for (size_t i = symtab_next(0); i < symtab_len(); i = symtab_next(i + 1)) {
    173                 const char *n = symtab_entry_name(i);
     180        for (size_t i = symtab_next(scs, 0); i < symtab_len; i = symtab_next(scs, i + 1)) {
     181                const char *n = symtab_entry_name(scs, i);
    174182
    175183                if (str_lcmp(name, n, namelen) == 0) {
    176                         printf("%p: %s\n", (void *) symtab[i].st_value, n);
     184                        printf("%p: %s\n", (void *) scs->symtab[i].st_value, n);
    177185                }
    178186        }
     
    182190const char *symtab_hints_enum(const char *input, const char **help, void **ctx)
    183191{
    184         if (symtab == NULL || strtab == NULL)
     192        debug_sections_t *scs = &kernel_sections;
     193        size_t symtab_len = scs->symtab_size / sizeof(elf_symbol_t);
     194
     195        if (scs->symtab == NULL || scs->strtab == NULL)
    185196                return NULL;
    186197
     
    189200
    190201        size_t len = str_length(input);
    191         for (size_t i = symtab_next((size_t) *ctx); i < symtab_len(); i = symtab_next(i + 1)) {
    192                 const char *curname = symtab_entry_name(i);
     202        for (size_t i = symtab_next(scs, (size_t) *ctx); i < symtab_len; i = symtab_next(scs, i + 1)) {
     203                const char *curname = symtab_entry_name(scs, i);
    193204
    194205                if (str_lcmp(input, curname, len) == 0) {
  • kernel/generic/src/debug/util.c

    rdcd8214 r40eab9f  
    3333#include <debug/names.h>
    3434
    35 /*
    36  * These declarations cause global definitions for the functions to be emitted
    37  * in this compilation unit, so if the compiler decides not to inline some of
    38  * them, only one external copy exists. See C99 inline rules.
    39  */
    40 extern inline uint8_t read_byte(const uint8_t **, const uint8_t *);
    41 extern inline uint16_t read_uint16(const uint8_t **, const uint8_t *);
    42 extern inline uint32_t read_uint24(const uint8_t **, const uint8_t *);
    43 extern inline uint32_t read_uint32(const uint8_t **, const uint8_t *);
    44 extern inline uint64_t read_uint64(const uint8_t **, const uint8_t *);
    45 extern inline uint64_t read_uint(const uint8_t **, const uint8_t *, unsigned);
    46 extern inline uint64_t read_uleb128(const uint8_t **, const uint8_t *);
    47 extern inline int64_t read_sleb128(const uint8_t **, const uint8_t *);
    48 extern inline void skip_leb128(const uint8_t **, const uint8_t *);
    49 extern inline uint64_t read_initial_length(const uint8_t **, const uint8_t *, unsigned *);
    50 extern inline const char *read_string(const uint8_t **, const uint8_t *);
    51 extern inline void skip_string(const uint8_t **, const uint8_t *);
    52 extern inline void safe_increment(const uint8_t **, const uint8_t *, ptrdiff_t);
    53 
    54 extern inline void skip_format(const uint8_t **, const uint8_t *, unsigned);
    55 extern inline void skip_formatted_entry(const uint8_t **, const uint8_t *,
    56     const uint8_t *, const uint8_t *, unsigned);
    57 extern inline void skip_formatted_list(const uint8_t **, const uint8_t *,
    58     unsigned, const uint8_t *, const uint8_t *, unsigned);
    59 
    6035bool skip_data(unsigned form, const uint8_t **const data,
    6136    const uint8_t *data_end, unsigned width)
     
    159134}
    160135
    161 void print_formatted_list(const char *name,
     136void print_formatted_list(debug_sections_t *scs, const char *name,
    162137    const uint8_t *data, const uint8_t *const data_end,
    163138    const uint8_t *format, const uint8_t *format_end,
     
    175150
    176151                        DEBUGF("%s:%s:", dw_lnct_name(lnct), dw_form_name(form));
    177                         print_formed_data(form, &data, data_end, width);
     152                        print_formed_data(scs, form, &data, data_end, width);
    178153                        DEBUGF("\n");
    179154                }
     
    196171}
    197172
    198 void print_formed_data(unsigned form, const uint8_t **const data,
     173void print_formed_data(debug_sections_t *scs, unsigned form, const uint8_t **const data,
    199174    const uint8_t *data_end, unsigned width)
    200175{
     
    210185        case DW_FORM_strp_sup:
    211186                offset = read_uint(data, data_end, width);
    212                 if (offset >= debug_str_size)
     187                if (offset >= scs->debug_str_size)
    213188                        DEBUGF("<out of range>");
    214189                else
    215                         DEBUGF("\"%s\"", debug_str + offset);
     190                        DEBUGF("\"%s\"", scs->debug_str + offset);
    216191                break;
    217192
    218193        case DW_FORM_line_strp:
    219194                offset = read_uint(data, data_end, width);
    220                 if (offset >= debug_line_str_size)
     195                if (offset >= scs->debug_line_str_size)
    221196                        DEBUGF("<out of range>");
    222197                else
    223                         DEBUGF("\"%s\"", debug_line_str + offset);
     198                        DEBUGF("\"%s\"", scs->debug_line_str + offset);
    224199                break;
    225200
  • kernel/generic/src/debug/util.h

    rdcd8214 r40eab9f  
    3333#include <stdint.h>
    3434#include <debug/constants.h>
     35#include <debug/sections.h>
    3536#include <debug.h>
    3637
     
    3940extern bool skip_data(unsigned, const uint8_t **const, const uint8_t *, unsigned);
    4041extern void print_format(const char *, const uint8_t *, const uint8_t *);
    41 extern void print_formatted_list(const char *, const uint8_t *, const uint8_t *,
    42     const uint8_t *, const uint8_t *, unsigned);
     42extern void print_formatted_list(debug_sections_t *, const char *,
     43    const uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, unsigned);
    4344
    4445extern void print_block(const uint8_t **, const uint8_t *, unsigned);
    45 extern void print_formed_data(unsigned, const uint8_t **const, const uint8_t *, unsigned);
    46 
    47 inline uint8_t read_byte(const uint8_t **data, const uint8_t *data_end)
     46extern void print_formed_data(debug_sections_t *scs, unsigned, const uint8_t **const, const uint8_t *, unsigned);
     47
     48static inline uint8_t read_byte(const uint8_t **data, const uint8_t *data_end)
    4849{
    4950        if (*data >= data_end) {
     
    6768} __attribute__((packed));
    6869
    69 inline uint16_t read_uint16(const uint8_t **data, const uint8_t *data_end)
     70static inline uint16_t read_uint16(const uint8_t **data, const uint8_t *data_end)
    7071{
    7172        if (*data + 2 > data_end) {
     
    8081}
    8182
    82 inline uint32_t read_uint24(const uint8_t **data, const uint8_t *data_end)
     83static inline uint32_t read_uint24(const uint8_t **data, const uint8_t *data_end)
    8384{
    8485        if (*data + 3 > data_end) {
     
    9899}
    99100
    100 inline uint32_t read_uint32(const uint8_t **data, const uint8_t *data_end)
     101static inline uint32_t read_uint32(const uint8_t **data, const uint8_t *data_end)
    101102{
    102103        if (*data + 4 > data_end) {
     
    111112}
    112113
    113 inline uint64_t read_uint64(const uint8_t **data, const uint8_t *data_end)
     114static inline uint64_t read_uint64(const uint8_t **data, const uint8_t *data_end)
    114115{
    115116        if (*data + 8 > data_end) {
     
    124125}
    125126
    126 inline uint64_t read_uint(const uint8_t **data, const uint8_t *data_end, unsigned bytes)
     127static inline uint64_t read_uint(const uint8_t **data, const uint8_t *data_end, unsigned bytes)
    127128{
    128129        switch (bytes) {
     
    140141}
    141142
    142 inline uint64_t read_uleb128(const uint8_t **data, const uint8_t *data_end)
     143static inline uint64_t read_uleb128(const uint8_t **data, const uint8_t *data_end)
    143144{
    144145        uint64_t result = 0;
     
    157158}
    158159
    159 inline int64_t read_sleb128(const uint8_t **data, const uint8_t *data_end)
     160static inline int64_t read_sleb128(const uint8_t **data, const uint8_t *data_end)
    160161{
    161162        uint64_t result = 0;
     
    179180}
    180181
    181 inline void skip_leb128(const uint8_t **data, const uint8_t *data_end)
     182static inline void skip_leb128(const uint8_t **data, const uint8_t *data_end)
    182183{
    183184        while (*data < data_end) {
     
    188189}
    189190
    190 inline uint64_t read_initial_length(const uint8_t **data, const uint8_t *data_end, unsigned *width)
     191static inline uint64_t read_initial_length(const uint8_t **data, const uint8_t *data_end, unsigned *width)
    191192{
    192193        uint32_t initial = read_uint32(data, data_end);
     
    200201}
    201202
    202 inline const char *read_string(const uint8_t **data, const uint8_t *data_end)
     203static inline const char *read_string(const uint8_t **data, const uint8_t *data_end)
    203204{
    204205        const char *start = (const char *) *data;
     
    218219}
    219220
    220 inline void skip_string(const uint8_t **data, const uint8_t *data_end)
     221static inline void skip_string(const uint8_t **data, const uint8_t *data_end)
    221222{
    222223        (void) read_string(data, data_end);
    223224}
    224225
    225 inline void safe_increment(const uint8_t **data,
     226static inline void safe_increment(const uint8_t **data,
    226227    const uint8_t *data_end, ptrdiff_t increment)
    227228{
     
    235236}
    236237
    237 inline void skip_format(const uint8_t **data, const uint8_t *const data_end,
     238static inline void skip_format(const uint8_t **data, const uint8_t *const data_end,
    238239    unsigned count)
    239240{
     
    244245}
    245246
    246 inline void skip_formatted_entry(const uint8_t **data, const uint8_t *const data_end,
     247static inline void skip_formatted_entry(const uint8_t **data, const uint8_t *const data_end,
    247248    const uint8_t *format, const uint8_t *format_end, unsigned width)
    248249{
     
    256257}
    257258
    258 inline void skip_formatted_list(const uint8_t **data, const uint8_t *const data_end,
     259static inline void skip_formatted_list(const uint8_t **data, const uint8_t *const data_end,
    259260    unsigned count,     const uint8_t *format, const uint8_t *format_end,
    260261    unsigned width)
  • kernel/generic/src/main/kinit.c

    rdcd8214 r40eab9f  
    268268                }
    269269
    270                 errno_t rc = program_create_from_image((void *) page, namebuf,
     270                errno_t rc = program_create_from_image((void *) page, init.tasks[i].size, namebuf,
    271271                    &programs[i]);
    272272
  • kernel/generic/src/proc/program.c

    rdcd8214 r40eab9f  
    143143 *
    144144 */
    145 errno_t program_create_from_image(void *image_addr, char *name, program_t *prg)
     145errno_t program_create_from_image(void *image_addr, size_t image_size, char *name, program_t *prg)
    146146{
    147147        as_t *as = as_create(0);
     
    157157        }
    158158
    159         return program_create(as, ((elf_header_t *) image_addr)->e_entry,
     159        errno_t rc = program_create(as, ((elf_header_t *) image_addr)->e_entry,
    160160            name, prg);
     161
     162        if (rc == EOK) {
     163                prg->task->debug_sections = calloc(1, sizeof(debug_sections_t));
     164                if (prg->task->debug_sections != NULL)
     165                        *prg->task->debug_sections = get_debug_sections(image_addr, image_size);
     166        }
     167
     168        return rc;
    161169}
    162170
  • kernel/generic/src/proc/task.c

    rdcd8214 r40eab9f  
    225225        task->answerbox.active = true;
    226226
     227        task->debug_sections = NULL;
     228
    227229#ifdef CONFIG_UDEBUG
    228230        /* Init debugging stuff */
Note: See TracChangeset for help on using the changeset viewer.