| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: kern_ksyms.c,v 1.87 2017/11/04 22:17:55 christos Exp $ */ | | 1 | /* $NetBSD: kern_ksyms.c,v 1.87.8.1 2020/01/07 11:54:57 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software developed for The NetBSD Foundation | | 7 | * This code is derived from software developed for The NetBSD Foundation |
8 | * by Andrew Doran. | | 8 | * by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -63,27 +63,27 @@ | | | @@ -63,27 +63,27 @@ |
63 | * struct, placed in a circular list. The first entry is the kernel | | 63 | * struct, placed in a circular list. The first entry is the kernel |
64 | * symbol table. | | 64 | * symbol table. |
65 | */ | | 65 | */ |
66 | | | 66 | |
67 | /* | | 67 | /* |
68 | * TODO: | | 68 | * TODO: |
69 | * | | 69 | * |
70 | * Add support for mmap, poll. | | 70 | * Add support for mmap, poll. |
71 | * Constify tables. | | 71 | * Constify tables. |
72 | * Constify db_symtab and move it to .rodata. | | 72 | * Constify db_symtab and move it to .rodata. |
73 | */ | | 73 | */ |
74 | | | 74 | |
75 | #include <sys/cdefs.h> | | 75 | #include <sys/cdefs.h> |
76 | __KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.87 2017/11/04 22:17:55 christos Exp $"); | | 76 | __KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.87.8.1 2020/01/07 11:54:57 martin Exp $"); |
77 | | | 77 | |
78 | #if defined(_KERNEL) && defined(_KERNEL_OPT) | | 78 | #if defined(_KERNEL) && defined(_KERNEL_OPT) |
79 | #include "opt_copy_symtab.h" | | 79 | #include "opt_copy_symtab.h" |
80 | #include "opt_ddb.h" | | 80 | #include "opt_ddb.h" |
81 | #include "opt_dtrace.h" | | 81 | #include "opt_dtrace.h" |
82 | #endif | | 82 | #endif |
83 | | | 83 | |
84 | #define _KSYMS_PRIVATE | | 84 | #define _KSYMS_PRIVATE |
85 | | | 85 | |
86 | #include <sys/param.h> | | 86 | #include <sys/param.h> |
87 | #include <sys/queue.h> | | 87 | #include <sys/queue.h> |
88 | #include <sys/exec.h> | | 88 | #include <sys/exec.h> |
89 | #include <sys/systm.h> | | 89 | #include <sys/systm.h> |
| @@ -755,29 +755,29 @@ ksyms_modload(const char *name, void *sy | | | @@ -755,29 +755,29 @@ ksyms_modload(const char *name, void *sy |
755 | */ | | 755 | */ |
756 | void | | 756 | void |
757 | ksyms_modunload(const char *name) | | 757 | ksyms_modunload(const char *name) |
758 | { | | 758 | { |
759 | struct ksyms_symtab *st; | | 759 | struct ksyms_symtab *st; |
760 | | | 760 | |
761 | mutex_enter(&ksyms_lock); | | 761 | mutex_enter(&ksyms_lock); |
762 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { | | 762 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { |
763 | if (st->sd_gone) | | 763 | if (st->sd_gone) |
764 | continue; | | 764 | continue; |
765 | if (strcmp(name, st->sd_name) != 0) | | 765 | if (strcmp(name, st->sd_name) != 0) |
766 | continue; | | 766 | continue; |
767 | st->sd_gone = true; | | 767 | st->sd_gone = true; |
| | | 768 | ksyms_sizes_calc(); |
768 | if (!ksyms_isopen) { | | 769 | if (!ksyms_isopen) { |
769 | TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue); | | 770 | TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue); |
770 | ksyms_sizes_calc(); | | | |
771 | kmem_free(st->sd_nmap, | | 771 | kmem_free(st->sd_nmap, |
772 | st->sd_nmapsize * sizeof(uint32_t)); | | 772 | st->sd_nmapsize * sizeof(uint32_t)); |
773 | kmem_free(st, sizeof(*st)); | | 773 | kmem_free(st, sizeof(*st)); |
774 | } | | 774 | } |
775 | break; | | 775 | break; |
776 | } | | 776 | } |
777 | mutex_exit(&ksyms_lock); | | 777 | mutex_exit(&ksyms_lock); |
778 | KASSERT(st != NULL); | | 778 | KASSERT(st != NULL); |
779 | } | | 779 | } |
780 | | | 780 | |
781 | #ifdef DDB | | 781 | #ifdef DDB |
782 | /* | | 782 | /* |
783 | * Keep sifting stuff here, to avoid export of ksyms internals. | | 783 | * Keep sifting stuff here, to avoid export of ksyms internals. |
| @@ -846,26 +846,28 @@ ksyms_sift(char *mod, char *sym, int mod | | | @@ -846,26 +846,28 @@ ksyms_sift(char *mod, char *sym, int mod |
846 | * The actual (correct) value of st_name is preserved through a global | | 846 | * The actual (correct) value of st_name is preserved through a global |
847 | * offset stored in the symbol table structure. | | 847 | * offset stored in the symbol table structure. |
848 | * | | 848 | * |
849 | * Call with ksyms_lock held. | | 849 | * Call with ksyms_lock held. |
850 | */ | | 850 | */ |
851 | static void | | 851 | static void |
852 | ksyms_sizes_calc(void) | | 852 | ksyms_sizes_calc(void) |
853 | { | | 853 | { |
854 | struct ksyms_symtab *st; | | 854 | struct ksyms_symtab *st; |
855 | int i, delta; | | 855 | int i, delta; |
856 | | | 856 | |
857 | ksyms_symsz = ksyms_strsz = 0; | | 857 | ksyms_symsz = ksyms_strsz = 0; |
858 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { | | 858 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { |
| | | 859 | if (__predict_false(st->sd_gone)) |
| | | 860 | continue; |
859 | delta = ksyms_strsz - st->sd_usroffset; | | 861 | delta = ksyms_strsz - st->sd_usroffset; |
860 | if (delta != 0) { | | 862 | if (delta != 0) { |
861 | for (i = 0; i < st->sd_symsize/sizeof(Elf_Sym); i++) | | 863 | for (i = 0; i < st->sd_symsize/sizeof(Elf_Sym); i++) |
862 | st->sd_symstart[i].st_name += delta; | | 864 | st->sd_symstart[i].st_name += delta; |
863 | st->sd_usroffset = ksyms_strsz; | | 865 | st->sd_usroffset = ksyms_strsz; |
864 | } | | 866 | } |
865 | ksyms_symsz += st->sd_symsize; | | 867 | ksyms_symsz += st->sd_symsize; |
866 | ksyms_strsz += st->sd_strsize; | | 868 | ksyms_strsz += st->sd_strsize; |
867 | } | | 869 | } |
868 | } | | 870 | } |
869 | | | 871 | |
870 | static void | | 872 | static void |
871 | ksyms_fill_note(void) | | 873 | ksyms_fill_note(void) |
| @@ -1024,44 +1026,48 @@ ksymsread(dev_t dev, struct uio *uio, in | | | @@ -1024,44 +1026,48 @@ ksymsread(dev_t dev, struct uio *uio, in |
1024 | off = uio->uio_offset; | | 1026 | off = uio->uio_offset; |
1025 | if (off < sizeof(struct ksyms_hdr)) { | | 1027 | if (off < sizeof(struct ksyms_hdr)) { |
1026 | error = uiomove((char *)&ksyms_hdr + off, | | 1028 | error = uiomove((char *)&ksyms_hdr + off, |
1027 | sizeof(struct ksyms_hdr) - off, uio); | | 1029 | sizeof(struct ksyms_hdr) - off, uio); |
1028 | if (error != 0) | | 1030 | if (error != 0) |
1029 | return error; | | 1031 | return error; |
1030 | } | | 1032 | } |
1031 | | | 1033 | |
1032 | /* | | 1034 | /* |
1033 | * Copy out the symbol table. | | 1035 | * Copy out the symbol table. |
1034 | */ | | 1036 | */ |
1035 | filepos = sizeof(struct ksyms_hdr); | | 1037 | filepos = sizeof(struct ksyms_hdr); |
1036 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { | | 1038 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { |
| | | 1039 | if (__predict_false(st->sd_gone)) |
| | | 1040 | continue; |
1037 | if (uio->uio_resid == 0) | | 1041 | if (uio->uio_resid == 0) |
1038 | return 0; | | 1042 | return 0; |
1039 | if (uio->uio_offset <= st->sd_symsize + filepos) { | | 1043 | if (uio->uio_offset <= st->sd_symsize + filepos) { |
1040 | inpos = uio->uio_offset - filepos; | | 1044 | inpos = uio->uio_offset - filepos; |
1041 | error = uiomove((char *)st->sd_symstart + inpos, | | 1045 | error = uiomove((char *)st->sd_symstart + inpos, |
1042 | st->sd_symsize - inpos, uio); | | 1046 | st->sd_symsize - inpos, uio); |
1043 | if (error != 0) | | 1047 | if (error != 0) |
1044 | return error; | | 1048 | return error; |
1045 | } | | 1049 | } |
1046 | filepos += st->sd_symsize; | | 1050 | filepos += st->sd_symsize; |
1047 | } | | 1051 | } |
1048 | | | 1052 | |
1049 | /* | | 1053 | /* |
1050 | * Copy out the string table | | 1054 | * Copy out the string table |
1051 | */ | | 1055 | */ |
1052 | KASSERT(filepos == sizeof(struct ksyms_hdr) + | | 1056 | KASSERT(filepos == sizeof(struct ksyms_hdr) + |
1053 | ksyms_hdr.kh_shdr[SYMTAB].sh_size); | | 1057 | ksyms_hdr.kh_shdr[SYMTAB].sh_size); |
1054 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { | | 1058 | TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { |
| | | 1059 | if (__predict_false(st->sd_gone)) |
| | | 1060 | continue; |
1055 | if (uio->uio_resid == 0) | | 1061 | if (uio->uio_resid == 0) |
1056 | return 0; | | 1062 | return 0; |
1057 | if (uio->uio_offset <= st->sd_strsize + filepos) { | | 1063 | if (uio->uio_offset <= st->sd_strsize + filepos) { |
1058 | inpos = uio->uio_offset - filepos; | | 1064 | inpos = uio->uio_offset - filepos; |
1059 | error = uiomove((char *)st->sd_strstart + inpos, | | 1065 | error = uiomove((char *)st->sd_strstart + inpos, |
1060 | st->sd_strsize - inpos, uio); | | 1066 | st->sd_strsize - inpos, uio); |
1061 | if (error != 0) | | 1067 | if (error != 0) |
1062 | return error; | | 1068 | return error; |
1063 | } | | 1069 | } |
1064 | filepos += st->sd_strsize; | | 1070 | filepos += st->sd_strsize; |
1065 | } | | 1071 | } |
1066 | | | 1072 | |
1067 | /* | | 1073 | /* |