Fold add_patch_dependencies into finalize_patches.
[ksplice.git] / inspect.c
blob26fb4e23891b879b1c2811fee5d91a42b23c0092
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 /* Always define KSPLICE_STANDALONE, even if you're using integrated Ksplice.
20 inspect won't compile without it. */
21 #define KSPLICE_STANDALONE
23 #define _GNU_SOURCE
24 #include "objcommon.h"
25 #include "kmodsrc/ksplice.h"
26 #include <stdio.h>
28 char *str_ulong_vec(struct supersect *ss, const unsigned long *const *datap,
29 const unsigned long *sizep)
31 struct supersect *data_ss;
32 const unsigned long *data =
33 read_pointer(ss, (void *const *)datap, &data_ss);
34 unsigned long size = read_num(ss, sizep);
36 char *buf = NULL;
37 size_t bufsize = 0;
38 FILE *fp = open_memstream(&buf, &bufsize);
39 fprintf(fp, "[ ");
40 size_t i;
41 for (i = 0; i < size; ++i)
42 fprintf(fp, "%lx ", read_num(data_ss, &data[i]));
43 fprintf(fp, "]");
44 fclose(fp);
45 return buf;
48 char *str_ksplice_symbol(struct supersect *ss,
49 const struct ksplice_symbol *ksymbol)
51 char *str;
52 assert(asprintf(&str, "%s (%s)",
53 read_string(ss, &ksymbol->label),
54 read_string(ss, &ksymbol->name)));
55 return str;
58 char *str_ksplice_symbolp(struct supersect *ptr_ss,
59 const struct ksplice_symbol *const *ksymbolp)
61 struct supersect *ss;
62 const struct ksplice_symbol *ksymbol =
63 read_pointer(ptr_ss, (void *const *)ksymbolp, &ss);
64 return ksymbol == NULL ? "(null)" : str_ksplice_symbol(ss, ksymbol);
67 void show_ksplice_reloc(struct supersect *ss,
68 const struct ksplice_reloc *kreloc)
70 printf("blank_addr: %s blank_offset: %lx\n"
71 "symbol: %s\n"
72 "addend: %lx\n"
73 "pcrel: %x size: %x dst_mask: %lx rightshift: %x\n"
74 "\n",
75 str_pointer(ss, (void *const *)&kreloc->blank_addr),
76 read_num(ss, &kreloc->blank_offset),
77 str_ksplice_symbolp(ss, &kreloc->symbol),
78 read_num(ss, &kreloc->addend),
79 read_num(ss, &kreloc->pcrel),
80 read_num(ss, &kreloc->size),
81 read_num(ss, &kreloc->dst_mask),
82 read_num(ss, &kreloc->rightshift));
85 void show_ksplice_relocs(struct supersect *kreloc_ss)
87 printf("KSPLICE RELOCATIONS IN SECTION %s:\n\n", kreloc_ss->name);
88 const struct ksplice_reloc *kreloc;
89 for (kreloc = kreloc_ss->contents.data; (void *)kreloc <
90 kreloc_ss->contents.data + kreloc_ss->contents.size; kreloc++)
91 show_ksplice_reloc(kreloc_ss, kreloc);
92 printf("\n");
95 void show_ksplice_section_flags(const struct ksplice_section *ksect)
97 printf("flags:");
98 if (ksect->flags & KSPLICE_SECTION_RODATA)
99 printf(" rodata");
100 if (ksect->flags & KSPLICE_SECTION_TEXT)
101 printf(" text");
102 if (ksect->flags & KSPLICE_SECTION_DATA)
103 printf(" data");
104 printf("\n");
107 void show_ksplice_section(struct supersect *ss,
108 const struct ksplice_section *ksect)
110 printf("symbol: %s\n"
111 "thismod_addr: %s size: %lx\n",
112 str_ksplice_symbolp(ss, &ksect->symbol),
113 str_pointer(ss, (void *const *)&ksect->thismod_addr),
114 read_num(ss, &ksect->size));
115 show_ksplice_section_flags(ksect);
116 printf("\n");
119 void show_ksplice_sections(struct supersect *ksect_ss)
121 printf("KSPLICE SECTIONS:\n\n");
122 struct ksplice_section *ksect;
123 for (ksect = ksect_ss->contents.data; (void *)ksect <
124 ksect_ss->contents.data + ksect_ss->contents.size; ksect++)
125 show_ksplice_section(ksect_ss, ksect);
126 printf("\n");
129 void show_ksplice_patch(struct supersect *ss,
130 const struct ksplice_patch *kpatch)
132 printf("label: %s\n"
133 "repladdr: %s\n"
134 "\n",
135 read_string(ss, &kpatch->label),
136 str_pointer(ss, (void *const *)&kpatch->repladdr));
139 void show_ksplice_patches(struct supersect *kpatch_ss)
141 printf("KSPLICE PATCHES:\n\n");
142 const struct ksplice_patch *kpatch;
143 for (kpatch = kpatch_ss->contents.data; (void *)kpatch <
144 kpatch_ss->contents.data + kpatch_ss->contents.size; kpatch++)
145 show_ksplice_patch(kpatch_ss, kpatch);
146 printf("\n");
149 void show_ksplice_export(struct supersect *ss,
150 const struct ksplice_export *export)
152 printf("name: %s\n"
153 "newname: %s\n"
154 "\n",
155 read_string(ss, &export->name),
156 read_string(ss, &export->new_name));
159 void show_ksplice_exports(struct supersect *export_ss)
161 printf("KSPLICE EXPORTS:\n\n");
162 const struct ksplice_export *export;
163 for (export = export_ss->contents.data; (void *)export <
164 export_ss->contents.data + export_ss->contents.size; export++)
165 show_ksplice_export(export_ss, export);
166 printf("\n");
169 void show_ksplice_system_map(struct supersect *ss,
170 const struct ksplice_system_map *smap)
172 printf("%s %s\n",
173 read_string(ss, &smap->label),
174 str_ulong_vec(ss, &smap->candidates, &smap->nr_candidates));
177 void show_ksplice_system_maps(struct supersect *smap_ss)
179 printf("KSPLICE SYSTEM.MAP:\n\n");
180 const struct ksplice_system_map *smap;
181 for (smap = smap_ss->contents.data;
182 (void *)smap < smap_ss->contents.data + smap_ss->contents.size;
183 smap++)
184 show_ksplice_system_map(smap_ss, smap);
185 printf("\n");
188 int main(int argc, char *argv[])
190 bfd *ibfd;
192 assert(argc >= 1);
193 bfd_init();
194 ibfd = bfd_openr(argv[1], NULL);
195 assert(ibfd);
197 char **matching;
198 assert(bfd_check_format_matches(ibfd, bfd_object, &matching));
200 struct superbfd *sbfd = fetch_superbfd(ibfd);
202 asection *kreloc_init_sect =
203 bfd_get_section_by_name(ibfd, ".ksplice_init_relocs");
204 if (kreloc_init_sect != NULL) {
205 struct supersect *kreloc_init_ss =
206 fetch_supersect(sbfd, kreloc_init_sect);
207 show_ksplice_relocs(kreloc_init_ss);
208 } else {
209 printf("No ksplice init relocations.\n\n");
212 asection *kreloc_sect = bfd_get_section_by_name(ibfd,
213 ".ksplice_relocs");
214 if (kreloc_sect != NULL) {
215 struct supersect *kreloc_ss =
216 fetch_supersect(sbfd, kreloc_sect);
217 show_ksplice_relocs(kreloc_ss);
218 } else {
219 printf("No ksplice relocations.\n\n");
222 asection *ksect_sect = bfd_get_section_by_name(ibfd,
223 ".ksplice_sections");
224 if (ksect_sect != NULL) {
225 struct supersect *ksect_ss = fetch_supersect(sbfd, ksect_sect);
226 show_ksplice_sections(ksect_ss);
227 } else {
228 printf("No ksplice sections.\n\n");
231 asection *kpatch_sect = bfd_get_section_by_name(ibfd,
232 ".ksplice_patches");
233 if (kpatch_sect != NULL) {
234 struct supersect *kpatch_ss =
235 fetch_supersect(sbfd, kpatch_sect);
236 show_ksplice_patches(kpatch_ss);
237 } else {
238 printf("No ksplice patches.\n\n");
241 asection *export_sect = bfd_get_section_by_name(ibfd,
242 ".ksplice_exports");
243 if (export_sect != NULL) {
244 struct supersect *export_ss =
245 fetch_supersect(sbfd, export_sect);
246 show_ksplice_exports(export_ss);
247 } else {
248 printf("No ksplice exports.\n\n");
251 asection *smap_sect = bfd_get_section_by_name(ibfd,
252 ".ksplice_system_map");
253 if (smap_sect != NULL) {
254 struct supersect *smap_ss = fetch_supersect(sbfd, smap_sect);
255 show_ksplice_system_maps(smap_ss);
256 } else {
257 printf("No ksplice System.map.\n\n");
260 return 0;