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
20 #include "objcommon.h"
21 #include "kmodsrc/ksplice.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
);
34 FILE *fp
= open_memstream(&buf
, &bufsize
);
37 for (i
= 0; i
< size
; ++i
)
38 fprintf(fp
, "%lx ", read_num(data_ss
, &data
[i
]));
44 char *str_ksplice_symbol(struct supersect
*ss
,
45 const struct ksplice_symbol
*ksymbol
)
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
)));
56 char *str_ksplice_symbolp(struct supersect
*ptr_ss
,
57 const struct ksplice_symbol
*const *ksymbolp
)
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"
71 "pcrel: %x size: %x dst_mask: %lx rightshift: %x\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
);
93 void show_ksplice_size_flags(const struct ksplice_size
*ksize
)
96 if (ksize
->flags
& KSPLICE_SIZE_DELETED
)
98 if (ksize
->flags
& KSPLICE_SIZE_RODATA
)
100 if (ksize
->flags
& KSPLICE_SIZE_TEXT
)
102 if (ksize
->flags
& KSPLICE_SIZE_DATA
)
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
);
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
);
128 void show_ksplice_patch(struct supersect
*ss
,
129 const struct ksplice_patch
*kpatch
)
134 read_string(ss
, &kpatch
->label
),
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
);
148 void show_ksplice_export(struct supersect
*ss
,
149 const struct ksplice_export
*export
)
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
);
170 int main(int argc
, char *argv
[])
176 ibfd
= bfd_openr(argv
[1], NULL
);
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
);
191 printf("No ksplice init relocations.\n\n");
194 asection
*kreloc_sect
= bfd_get_section_by_name(ibfd
,
196 if (kreloc_sect
!= NULL
) {
197 struct supersect
*kreloc_ss
=
198 fetch_supersect(sbfd
, kreloc_sect
);
199 show_ksplice_relocs(kreloc_ss
);
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
);
209 printf("No ksplice sizes.\n\n");
212 asection
*kpatch_sect
= bfd_get_section_by_name(ibfd
,
214 if (kpatch_sect
!= NULL
) {
215 struct supersect
*kpatch_ss
=
216 fetch_supersect(sbfd
, kpatch_sect
);
217 show_ksplice_patches(kpatch_ss
);
219 printf("No ksplice patches.\n\n");
222 asection
*export_sect
= bfd_get_section_by_name(ibfd
,
224 if (export_sect
!= NULL
) {
225 struct supersect
*export_ss
=
226 fetch_supersect(sbfd
, export_sect
);
227 show_ksplice_exports(export_ss
);
229 printf("No ksplice exports.\n\n");