Add canonical_symbol helper function.
[ksplice.git] / inspect.c
blob6af827f028c63415b8f9ec611cea6c4068c36465
1 /* Copyright (C) 2008 Anders Kaseorg <andersk@mit.edu>,
2 * Tim Abbott <tabbott@mit.edu>,
3 * Jeffrey Brian Arnold <jbarnold@mit.edu>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
16 * 02110-1301, USA.
19 #define _GNU_SOURCE
20 #include "objcommon.h"
21 #include "kmodsrc/ksplice.h"
22 #include <stdio.h>
24 char *str_ulong_vec(struct supersect *ss, const unsigned long *const *datap,
25 const unsigned long *sizep)
27 struct supersect *data_ss;
28 const unsigned long *data =
29 read_pointer(ss, (void *const *)datap, &data_ss);
30 unsigned long size = read_num(ss, sizep);
32 char *buf = NULL;
33 size_t bufsize = 0;
34 FILE *fp = open_memstream(&buf, &bufsize);
35 fprintf(fp, "[ ");
36 size_t i;
37 for (i = 0; i < size; ++i)
38 fprintf(fp, "%lx ", read_num(data_ss, &data[i]));
39 fprintf(fp, "]");
40 fclose(fp);
41 return buf;
44 char *str_ksplice_symbol(struct supersect *ss,
45 const struct ksplice_symbol *ksymbol)
47 char *str;
48 assert(asprintf(&str, "%s (%s %s)",
49 read_string(ss, &ksymbol->label),
50 read_string(ss, &ksymbol->name),
51 str_ulong_vec(ss, &ksymbol->candidates,
52 &ksymbol->nr_candidates)));
53 return str;
56 char *str_ksplice_symbolp(struct supersect *ptr_ss,
57 const struct ksplice_symbol *const *ksymbolp)
59 struct supersect *ss;
60 const struct ksplice_symbol *ksymbol =
61 read_pointer(ptr_ss, (void *const *)ksymbolp, &ss);
62 return ksymbol == NULL ? "(null)" : str_ksplice_symbol(ss, ksymbol);
65 void show_ksplice_reloc(struct supersect *ss,
66 const struct ksplice_reloc *kreloc)
68 printf("blank_addr: %s blank_offset: %lx\n"
69 "symbol: %s\n"
70 "addend: %lx\n"
71 "pcrel: %x size: %x dst_mask: %lx rightshift: %x\n"
72 "\n",
73 str_pointer(ss, (void *const *)&kreloc->blank_addr),
74 read_num(ss, &kreloc->blank_offset),
75 str_ksplice_symbolp(ss, &kreloc->symbol),
76 read_num(ss, &kreloc->addend),
77 read_num(ss, &kreloc->pcrel),
78 read_num(ss, &kreloc->size),
79 read_num(ss, &kreloc->dst_mask),
80 read_num(ss, &kreloc->rightshift));
83 void show_ksplice_relocs(struct supersect *kreloc_ss)
85 printf("KSPLICE RELOCATIONS IN SECTION %s:\n\n", kreloc_ss->name);
86 const struct ksplice_reloc *kreloc;
87 for (kreloc = kreloc_ss->contents.data; (void *)kreloc <
88 kreloc_ss->contents.data + kreloc_ss->contents.size; kreloc++)
89 show_ksplice_reloc(kreloc_ss, kreloc);
90 printf("\n");
93 void show_ksplice_size_flags(const struct ksplice_size *ksize)
95 printf("flags:");
96 if (ksize->flags & KSPLICE_SIZE_DELETED)
97 printf(" deleted");
98 if (ksize->flags & KSPLICE_SIZE_RODATA)
99 printf(" rodata");
100 if (ksize->flags & KSPLICE_SIZE_TEXT)
101 printf(" text");
102 if (ksize->flags & KSPLICE_SIZE_DATA)
103 printf(" data");
104 printf("\n");
107 void show_ksplice_size(struct supersect *ss, const struct ksplice_size *ksize)
109 printf("symbol: %s\n"
110 "thismod_addr: %s size: %lx extended_size: %lx\n",
111 str_ksplice_symbolp(ss, &ksize->symbol),
112 str_pointer(ss, (void *const *)&ksize->thismod_addr),
113 read_num(ss, &ksize->size), read_num(ss, &ksize->extended_size));
114 show_ksplice_size_flags(ksize);
115 printf("\n");
118 void show_ksplice_sizes(struct supersect *ksize_ss)
120 printf("KSPLICE SIZES:\n\n");
121 struct ksplice_size *ksize;
122 for (ksize = ksize_ss->contents.data; (void *)ksize <
123 ksize_ss->contents.data + ksize_ss->contents.size; ksize++)
124 show_ksplice_size(ksize_ss, ksize);
125 printf("\n");
128 void show_ksplice_patch(struct supersect *ss,
129 const struct ksplice_patch *kpatch)
131 printf("symbol: %s\n"
132 "repladdr: %s\n"
133 "\n",
134 str_ksplice_symbolp(ss, &kpatch->symbol),
135 str_pointer(ss, (void *const *)&kpatch->repladdr));
138 void show_ksplice_patches(struct supersect *kpatch_ss)
140 printf("KSPLICE PATCHES:\n\n");
141 const struct ksplice_patch *kpatch;
142 for (kpatch = kpatch_ss->contents.data; (void *)kpatch <
143 kpatch_ss->contents.data + kpatch_ss->contents.size; kpatch++)
144 show_ksplice_patch(kpatch_ss, kpatch);
145 printf("\n");
148 void show_ksplice_export(struct supersect *ss,
149 const struct ksplice_export *export)
151 printf("name: %s\n"
152 "newname: %s\n"
153 "type: %s\n"
154 "\n",
155 read_string(ss, &export->name),
156 read_string(ss, &export->new_name),
157 read_string(ss, &export->type));
160 void show_ksplice_exports(struct supersect *export_ss)
162 printf("KSPLICE EXPORTS:\n\n");
163 const struct ksplice_export *export;
164 for (export = export_ss->contents.data; (void *)export <
165 export_ss->contents.data + export_ss->contents.size; export++)
166 show_ksplice_export(export_ss, export);
167 printf("\n");
170 int main(int argc, char *argv[])
172 bfd *ibfd;
174 assert(argc >= 1);
175 bfd_init();
176 ibfd = bfd_openr(argv[1], NULL);
177 assert(ibfd);
179 char **matching;
180 assert(bfd_check_format_matches(ibfd, bfd_object, &matching));
182 struct superbfd *sbfd = fetch_superbfd(ibfd);
184 asection *kreloc_init_sect =
185 bfd_get_section_by_name(ibfd, ".ksplice_init_relocs");
186 if (kreloc_init_sect != NULL) {
187 struct supersect *kreloc_init_ss =
188 fetch_supersect(sbfd, kreloc_init_sect);
189 show_ksplice_relocs(kreloc_init_ss);
190 } else {
191 printf("No ksplice init relocations.\n\n");
194 asection *kreloc_sect = bfd_get_section_by_name(ibfd,
195 ".ksplice_relocs");
196 if (kreloc_sect != NULL) {
197 struct supersect *kreloc_ss =
198 fetch_supersect(sbfd, kreloc_sect);
199 show_ksplice_relocs(kreloc_ss);
200 } else {
201 printf("No ksplice relocations.\n\n");
204 asection *ksize_sect = bfd_get_section_by_name(ibfd, ".ksplice_sizes");
205 if (ksize_sect != NULL) {
206 struct supersect *ksize_ss = fetch_supersect(sbfd, ksize_sect);
207 show_ksplice_sizes(ksize_ss);
208 } else {
209 printf("No ksplice sizes.\n\n");
212 asection *kpatch_sect = bfd_get_section_by_name(ibfd,
213 ".ksplice_patches");
214 if (kpatch_sect != NULL) {
215 struct supersect *kpatch_ss =
216 fetch_supersect(sbfd, kpatch_sect);
217 show_ksplice_patches(kpatch_ss);
218 } else {
219 printf("No ksplice patches.\n\n");
222 asection *export_sect = bfd_get_section_by_name(ibfd,
223 ".ksplice_exports");
224 if (export_sect != NULL) {
225 struct supersect *export_ss =
226 fetch_supersect(sbfd, export_sect);
227 show_ksplice_exports(export_ss);
228 } else {
229 printf("No ksplice exports.\n\n");
232 return 0;