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
)
103 void show_ksplice_size(struct supersect
*ss
, const struct ksplice_size
*ksize
)
105 printf("symbol: %s\n"
106 "thismod_addr: %s size: %lx\n",
107 str_ksplice_symbolp(ss
, &ksize
->symbol
),
108 str_pointer(ss
, (void *const *)&ksize
->thismod_addr
),
109 read_num(ss
, &ksize
->size
));
110 show_ksplice_size_flags(ksize
);
114 void show_ksplice_sizes(struct supersect
*ksize_ss
)
116 printf("KSPLICE SIZES:\n\n");
117 struct ksplice_size
*ksize
;
118 for (ksize
= ksize_ss
->contents
.data
; (void *)ksize
<
119 ksize_ss
->contents
.data
+ ksize_ss
->contents
.size
; ksize
++)
120 show_ksplice_size(ksize_ss
, ksize
);
124 void show_ksplice_patch(struct supersect
*ss
,
125 const struct ksplice_patch
*kpatch
)
127 printf("symbol: %s\n"
130 str_ksplice_symbolp(ss
, &kpatch
->symbol
),
131 str_pointer(ss
, (void *const *)&kpatch
->repladdr
));
134 void show_ksplice_patches(struct supersect
*kpatch_ss
)
136 printf("KSPLICE PATCHES:\n\n");
137 const struct ksplice_patch
*kpatch
;
138 for (kpatch
= kpatch_ss
->contents
.data
; (void *)kpatch
<
139 kpatch_ss
->contents
.data
+ kpatch_ss
->contents
.size
; kpatch
++)
140 show_ksplice_patch(kpatch_ss
, kpatch
);
144 void show_ksplice_export(struct supersect
*ss
,
145 const struct ksplice_export
*export
)
151 read_string(ss
, &export
->name
),
152 read_string(ss
, &export
->new_name
),
153 read_string(ss
, &export
->type
));
156 void show_ksplice_exports(struct supersect
*export_ss
)
158 printf("KSPLICE EXPORTS:\n\n");
159 const struct ksplice_export
*export
;
160 for (export
= export_ss
->contents
.data
; (void *)export
<
161 export_ss
->contents
.data
+ export_ss
->contents
.size
; export
++)
162 show_ksplice_export(export_ss
, export
);
166 int main(int argc
, char *argv
[])
172 ibfd
= bfd_openr(argv
[1], NULL
);
176 assert(bfd_check_format_matches(ibfd
, bfd_object
, &matching
));
178 struct superbfd
*sbfd
= fetch_superbfd(ibfd
);
180 asection
*kreloc_init_sect
=
181 bfd_get_section_by_name(ibfd
, ".ksplice_init_relocs");
182 if (kreloc_init_sect
!= NULL
) {
183 struct supersect
*kreloc_init_ss
=
184 fetch_supersect(sbfd
, kreloc_init_sect
);
185 show_ksplice_relocs(kreloc_init_ss
);
187 printf("No ksplice init relocations.\n\n");
190 asection
*kreloc_sect
= bfd_get_section_by_name(ibfd
,
192 if (kreloc_sect
!= NULL
) {
193 struct supersect
*kreloc_ss
=
194 fetch_supersect(sbfd
, kreloc_sect
);
195 show_ksplice_relocs(kreloc_ss
);
197 printf("No ksplice relocations.\n\n");
200 asection
*ksize_sect
= bfd_get_section_by_name(ibfd
, ".ksplice_sizes");
201 if (ksize_sect
!= NULL
) {
202 struct supersect
*ksize_ss
= fetch_supersect(sbfd
, ksize_sect
);
203 show_ksplice_sizes(ksize_ss
);
205 printf("No ksplice sizes.\n\n");
208 asection
*kpatch_sect
= bfd_get_section_by_name(ibfd
,
210 if (kpatch_sect
!= NULL
) {
211 struct supersect
*kpatch_ss
=
212 fetch_supersect(sbfd
, kpatch_sect
);
213 show_ksplice_patches(kpatch_ss
);
215 printf("No ksplice patches.\n\n");
218 asection
*export_sect
= bfd_get_section_by_name(ibfd
,
220 if (export_sect
!= NULL
) {
221 struct supersect
*export_ss
=
222 fetch_supersect(sbfd
, export_sect
);
223 show_ksplice_exports(export_ss
);
225 printf("No ksplice exports.\n\n");