1 /* This file is based in part on objcopy.c from GNU Binutils v2.17.
3 * Copyright (C) 1991-2006 Free Software Foundation, Inc.
4 * Copyright (C) 2007-2009 Ksplice, Inc.
5 * Authors: Jeff Arnold, Anders Kaseorg, Tim Abbott
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 /* objmanip performs various object file manipulations for Ksplice. Its first
22 * two arguments are always an input object file and an output object file.
24 * - keep-new-code: "objmanip <post.o> <out.o> keep-new-code <pre.o> <kid>"
26 * This mode prepares the object file to be installed as a ksplice update. The
27 * kid argument is the ksplice id string for the ksplice update being built.
29 * - keep-old-code: "objmanip <pre.o> <out.o> keep-old-code"
31 * This mode prepares the object file to be used for run-pre matching. This
32 * involves replacing all ELF relocations with ksplice relocations and
33 * writing ksplice_section structures for each ELF text or data section.
35 * - rmsyms mode: "objmanip <in.o> <out.o> rmsyms
37 * In this mode, any ELF relocations involving the list of symbol names given on
38 * standard input are replaced with ksplice relocations. This is used only
39 * for KSPLICE_STANDALONE.
41 * - finalize mode: "objmanip <in.o> <out.o> finalize"
43 * In this mode, any ELF relocations to undefined symbols are replaced with
44 * ksplice relocations.
47 /* Always define KSPLICE_STANDALONE, even if you're using integrated Ksplice.
48 objmanip won't compile without it. */
49 #define KSPLICE_STANDALONE
52 #include "objcommon.h"
53 #include "kmodsrc/ksplice.h"
54 #include "kmodsrc/offsets.h"
55 #include "ksplice-patch/ksplice-patch.h"
62 #define KSPLICE_SYMBOL_STR "KSPLICE_SYMBOL_"
64 #define symbol_init(sym) *(sym) = (asymbol *)NULL
65 DEFINE_HASH_TYPE(asymbol
*, symbol_hash
, symbol_hash_init
, symbol_hash_free
,
66 symbol_hash_lookup
, symbol_init
);
68 DECLARE_VEC_TYPE(const char *, str_vec
);
70 DECLARE_VEC_TYPE(unsigned long, ulong_vec
);
72 #define bool_init(b) *(b) = false
73 DEFINE_HASH_TYPE(bool, bool_hash
, bool_hash_init
, bool_hash_free
,
74 bool_hash_lookup
, bool_init
);
76 #define ulong_init(x) *(x) = 0
77 DEFINE_HASH_TYPE(unsigned long, ulong_hash
, ulong_hash_init
,
78 ulong_hash_free
, ulong_hash_lookup
, ulong_init
);
80 void do_keep_new_code(struct superbfd
*isbfd
, const char *pre
);
81 void do_keep_old_code(struct superbfd
*isbfd
);
82 void do_finalize(struct superbfd
*isbfd
);
83 void do_rmsyms(struct superbfd
*isbfd
);
85 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
86 arelent
*old_reloc
, arelent
*new_reloc
);
87 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
);
88 bool all_relocs_equal(struct span
*old_span
, struct span
*new_span
);
89 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
);
90 static bool nonrelocs_equal(struct span
*old_span
, struct span
*new_span
);
91 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
92 struct superbfd
*newsbfd
);
93 static void compute_entry_points(struct superbfd
*sbfd
);
94 static void copy_patched_entry_points(struct superbfd
*oldsbfd
,
95 struct superbfd
*newsbfd
);
97 enum supersect_type
supersect_type(struct supersect
*ss
);
98 void initialize_supersect_types(struct superbfd
*sbfd
);
99 static void initialize_spans(struct superbfd
*sbfd
);
100 static void initialize_string_spans(struct supersect
*ss
);
101 static void initialize_table_spans(struct superbfd
*sbfd
,
102 struct table_section
*s
);
103 static void initialize_table_section_spans(struct superbfd
*sbfd
);
104 static void initialize_ksplice_call_spans(struct supersect
*ss
);
105 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
);
106 static struct span
*span_offset_target_span(struct span
*span
, int offset
);
107 static bfd_vma
reloc_target_offset(struct supersect
*ss
, arelent
*reloc
);
108 struct span
*find_span(struct supersect
*ss
, bfd_size_type address
);
109 void remove_unkept_spans(struct superbfd
*sbfd
);
110 void compute_span_shifts(struct superbfd
*sbfd
);
111 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
);
112 static bool is_table_section(const char *name
, bool consider_other
,
114 const struct table_section
*get_table_section(const char *name
);
115 void mangle_section_name(struct superbfd
*sbfd
, const char *name
);
117 void rm_relocs(struct superbfd
*isbfd
);
118 void rm_some_relocs(struct supersect
*ss
);
119 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
);
120 static void write_ksplice_reloc_howto(struct supersect
*ss
, const
121 struct ksplice_reloc_howto
*const *addr
,
122 reloc_howto_type
*howto
,
123 enum ksplice_reloc_howto_type type
);
124 static void write_ksplice_date_reloc(struct supersect
*ss
, unsigned long offset
,
126 enum ksplice_reloc_howto_type type
);
127 static void write_ksplice_patch_reloc(struct supersect
*ss
,
128 const char *sectname
, unsigned long *addr
,
129 bfd_size_type size
, const char *label
,
131 static void write_ksplice_nonreloc_howto(struct supersect
*ss
,
132 const struct ksplice_reloc_howto
134 enum ksplice_reloc_howto_type type
,
136 static void write_date_relocs(struct superbfd
*sbfd
, const char *str
,
137 enum ksplice_reloc_howto_type type
);
138 static void write_table_relocs(struct superbfd
*sbfd
, const char *sectname
,
139 enum ksplice_reloc_howto_type type
);
140 static void write_ksplice_table_reloc(struct supersect
*ss
,
141 unsigned long address
,
143 enum ksplice_reloc_howto_type type
);
144 void load_ksplice_symbol_offsets(struct superbfd
*sbfd
);
145 void write_canary(struct supersect
*ss
, int offset
, bfd_size_type size
,
147 static void write_ksplice_section(struct span
*span
);
148 void write_ksplice_patches(struct superbfd
*sbfd
, struct span
*span
);
149 void write_ksplice_patch(struct superbfd
*sbfd
, struct span
*span
,
150 const char *label
, long offset
);
151 void *write_patch_storage(struct supersect
*ss
, struct ksplice_patch
*patch
,
152 size_t size
, struct supersect
**data_ssp
);
153 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
154 const char *label
, const char *sectname
,
156 static void write_bugline_patches(struct superbfd
*sbfd
);
157 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
);
158 void filter_table_sections(struct superbfd
*isbfd
);
159 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
);
160 void keep_referenced_sections(struct superbfd
*sbfd
);
161 void mark_precallable_spans(struct superbfd
*sbfd
);
162 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
);
163 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
);
164 static void setup_new_section(bfd
*obfd
, struct supersect
*ss
);
165 static void write_section(bfd
*obfd
, asection
*osection
, void *arg
);
166 static void delete_obsolete_relocs(struct supersect
*ss
);
167 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
169 static void ss_mark_symbols_used_in_relocations(struct supersect
*ss
);
170 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
171 struct asymbolp_vec
*isyms
);
172 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
);
173 struct supersect
*__attribute((format(printf
, 2, 3)))
174 make_section(struct superbfd
*sbfd
, const char *fmt
, ...);
175 void __attribute__((format(printf
, 3, 4)))
176 write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...);
177 void write_ksplice_export(struct superbfd
*sbfd
, struct span
*span
, bool del
);
178 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
180 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
182 static void foreach_symbol_pair(struct superbfd
*oldsbfd
, struct superbfd
*newsbfd
,
183 void (*fn
)(struct span
*old_span
,
185 struct span
*new_span
,
187 static void check_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
188 struct span
*new_span
, asymbol
*newsym
);
189 static void match_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
190 struct span
*new_span
, asymbol
*newsym
);
191 static void match_symbol_spans(struct span
*old_span
, asymbol
*oldsym
,
192 struct span
*new_span
, asymbol
*newsym
);
193 static void match_table_spans(struct span
*old_span
, struct span
*new_span
);
194 static void match_other_spans(struct span
*old_span
, struct span
*new_span
);
196 static struct span
*get_crc_span(struct span
*span
,
197 const struct table_section
*ts
);
198 static void foreach_span_pair(struct superbfd
*oldsbfd
,
199 struct superbfd
*newsbfd
,
200 void (*fn
)(struct span
*old_span
,
201 struct span
*new_span
));
202 static void match_spans_by_label(struct span
*old_span
, struct span
*new_span
);
203 static void match_string_spans(struct span
*old_span
, struct span
*new_span
);
204 static void mark_new_spans(struct superbfd
*sbfd
);
205 static void handle_deleted_spans(struct superbfd
*oldsbfd
,
206 struct superbfd
*newsbfd
);
207 static void unmatch_addr_spans(struct span
*old_span
, struct span
*new_span
,
208 const struct table_section
*ts
);
209 static void compare_matched_spans(struct superbfd
*newsbfd
);
210 static void compare_spans(struct span
*old_span
, struct span
*new_span
);
211 static void update_nonzero_offsets(struct superbfd
*sbfd
);
212 static void handle_nonzero_offset_relocs(struct supersect
*ss
);
213 static void keep_span(struct span
*span
);
215 static void init_objmanip_superbfd(struct superbfd
*sbfd
);
216 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
);
217 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
219 static void print_label_changes(struct superbfd
*sbfd
);
220 static void init_label_map(struct superbfd
*sbfd
);
221 static void change_initial_label(struct span
*span
, const char *label
);
222 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
);
223 static void init_csyms(struct superbfd
*sbfd
);
224 static void init_callers(struct superbfd
*sbfd
);
225 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
);
226 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
);
227 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
);
228 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
);
231 #define debug_(sbfd, level, fmt, ...) \
233 if (verbose >= (level)) \
234 printf("%s: " fmt, (sbfd)->abfd->filename, \
237 #define debug0(sbfd, fmt, ...) debug_(sbfd, 0, fmt, ## __VA_ARGS__)
238 #define debug1(sbfd, fmt, ...) debug_(sbfd, 1, fmt, ## __VA_ARGS__)
239 #define err(sbfd, fmt, ...) \
241 fprintf(stderr, "%s: " fmt, (sbfd)->abfd->filename, \
245 struct str_vec delsects
;
246 struct asymbolp_vec extract_syms
;
249 struct ksplice_config
*config
;
251 const char *modestr
, *kid
, *finalize_target
= NULL
;
252 bool write_output
= true;
254 struct superbfd
*offsets_sbfd
= NULL
;
256 #define mode(str) strstarts(modestr, str)
258 DECLARE_VEC_TYPE(unsigned long, addr_vec
);
259 DEFINE_HASH_TYPE(struct addr_vec
, addr_vec_hash
,
260 addr_vec_hash_init
, addr_vec_hash_free
, addr_vec_hash_lookup
,
262 struct addr_vec_hash system_map
;
264 struct bool_hash system_map_written
;
265 struct ulong_hash ksplice_symbol_offset
;
266 struct ulong_hash ksplice_howto_offset
;
267 struct ulong_hash ksplice_string_offset
;
269 void load_system_map()
271 const char *config_dir
= getenv("KSPLICE_CONFIG_DIR");
273 FILE *fp
= fopen(strprintf("%s/System.map", config_dir
), "r");
275 addr_vec_hash_init(&system_map
);
279 while (fscanf(fp
, "%lx %c %as\n", &addr
, &type
, &sym
) == 3)
280 *vec_grow(addr_vec_hash_lookup(&system_map
, sym
, TRUE
),
285 void load_ksplice_symbol_offsets(struct superbfd
*sbfd
)
287 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
,
291 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
293 struct ksplice_symbol
*ksym
;
294 for (ksym
= ss
->contents
.data
;
295 (void *)ksym
< ss
->contents
.data
+ ss
->contents
.size
; ksym
++) {
296 const char *label
= read_string(ss
, &ksym
->label
);
297 unsigned long *ksymbol_offp
=
298 ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
299 *ksymbol_offp
= addr_offset(ss
, ksym
);
305 char *kmodsrc
= getenv("KSPLICE_KMODSRC");
306 assert(kmodsrc
!= NULL
);
307 bfd
*offsets_bfd
= bfd_openr(strprintf("%s/offsets.o", kmodsrc
), NULL
);
308 assert(offsets_bfd
!= NULL
);
310 assert(bfd_check_format_matches(offsets_bfd
, bfd_object
, &matching
));
311 offsets_sbfd
= fetch_superbfd(offsets_bfd
);
313 asection
*config_sect
= bfd_get_section_by_name(offsets_sbfd
->abfd
,
315 struct supersect
*config_ss
=
316 fetch_supersect(offsets_sbfd
, config_sect
);
318 config
= config_ss
->contents
.data
;
321 void load_options(struct superbfd
*sbfd
)
323 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
,
327 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
328 const struct ksplice_option
*opt
;
329 for (opt
= ss
->contents
.data
;
330 (void *)opt
< ss
->contents
.data
+ ss
->contents
.size
; opt
++) {
331 if (opt
->type
== KSPLICE_OPTION_ASSUME_RODATA
) {
332 arelent
*reloc
= find_reloc(ss
, &opt
->target
);
333 assert(reloc
!= NULL
);
334 struct span
*span
= reloc_target_span(ss
, reloc
);
335 assert(span
!= NULL
);
336 assert(span
->ss
->type
== SS_TYPE_DATA
);
337 assert(span
->start
== 0 &&
338 span
->size
== span
->ss
->contents
.size
);
339 span
->ss
->type
= SS_TYPE_RODATA
;
341 err(sbfd
, "Unrecognized Ksplice option %d\n",
348 bool matchable_data_section(struct supersect
*ss
)
350 if (ss
->type
== SS_TYPE_STRING
)
352 if (ss
->type
== SS_TYPE_RODATA
)
354 if (ss
->type
== SS_TYPE_DATA
&& ss
->relocs
.size
!= 0)
356 if (ss
->type
== SS_TYPE_EXPORT
)
358 if (ss
->type
== SS_TYPE_BUGTABLE
)
363 bool unchangeable_section(struct supersect
*ss
)
365 if (ss
->type
== SS_TYPE_DATA
)
367 if (ss
->type
== SS_TYPE_IGNORED
&& !strstarts(ss
->name
, ".debug") &&
368 strcmp(ss
->name
, "__ksymtab_strings") != 0)
373 int main(int argc
, char *argv
[])
375 if (getenv("KSPLICE_VERBOSE") != NULL
)
376 verbose
= atoi(getenv("KSPLICE_VERBOSE"));
379 bfd
*ibfd
= bfd_openr(argv
[1], NULL
);
383 if (bfd_check_format_matches(ibfd
, bfd_archive
, &matching
) &&
384 bfd_openr_next_archived_file(ibfd
, NULL
) == NULL
)
385 return 66; /* empty archive */
386 assert(bfd_check_format_matches(ibfd
, bfd_object
, &matching
));
388 const char *output_target
= bfd_get_target(ibfd
);
393 bool_hash_init(&system_map_written
);
394 ulong_hash_init(&ksplice_symbol_offset
);
395 ulong_hash_init(&ksplice_howto_offset
);
396 ulong_hash_init(&ksplice_string_offset
);
398 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
401 if (mode("finalize"))
402 finalize_target
= argv
[4];
403 init_objmanip_superbfd(isbfd
);
404 if (mode("keep-new-code")) {
406 do_keep_new_code(isbfd
, argv
[4]);
407 } else if (mode("keep-old-code")) {
408 do_keep_old_code(isbfd
);
409 } else if (mode("finalize")) {
411 } else if (mode("rmsyms")) {
416 bfd
*obfd
= bfd_openw(argv
[2], output_target
);
418 copy_object(ibfd
, obfd
);
419 assert(bfd_close(obfd
));
422 if (offsets_sbfd
!= NULL
)
423 assert(bfd_close(offsets_sbfd
->abfd
));
424 assert(bfd_close(ibfd
));
428 void do_keep_new_code(struct superbfd
*isbfd
, const char *pre
)
430 struct bfd
*prebfd
= bfd_openr(pre
, NULL
);
431 assert(prebfd
!= NULL
);
433 assert(bfd_check_format_matches(prebfd
, bfd_object
, &matching
));
435 struct superbfd
*presbfd
= fetch_superbfd(prebfd
);
436 init_objmanip_superbfd(presbfd
);
438 foreach_symbol_pair(presbfd
, isbfd
, match_global_symbols
);
439 debug1(isbfd
, "Matched global\n");
440 foreach_span_pair(presbfd
, isbfd
, match_string_spans
);
441 debug1(isbfd
, "Matched string spans\n");
442 foreach_symbol_pair(presbfd
, isbfd
, match_symbol_spans
);
443 debug1(isbfd
, "Matched by name\n");
444 foreach_span_pair(presbfd
, isbfd
, match_spans_by_label
);
445 debug1(isbfd
, "Matched by label\n");
446 foreach_span_pair(presbfd
, isbfd
, match_table_spans
);
447 debug1(isbfd
, "Matched table spans\n");
448 foreach_span_pair(presbfd
, isbfd
, match_other_spans
);
449 debug1(isbfd
, "Matched other spans\n");
453 compare_matched_spans(isbfd
);
454 update_nonzero_offsets(isbfd
);
455 mark_new_spans(isbfd
);
459 foreach_symbol_pair(presbfd
, isbfd
, check_global_symbols
);
461 handle_deleted_spans(presbfd
, isbfd
);
462 handle_section_symbol_renames(presbfd
, isbfd
);
464 copy_patched_entry_points(presbfd
, isbfd
);
466 assert(bfd_close(prebfd
));
470 mark_precallable_spans(isbfd
);
474 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
475 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
478 for (span
= ss
->spans
.data
;
479 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
480 if (strstarts(ss
->name
, ".ksplice_options"))
482 else if (span
->new || span
->patch
|| span
->datapatch
)
486 if (span
->patch
&& span
->precallable
) {
487 err(isbfd
, "Patched span %s can be reached "
488 "by a precall function\n", span
->label
);
494 print_label_changes(isbfd
);
496 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
497 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
499 for (span
= ss
->spans
.data
;
500 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
501 if (span
->patch
|| span
->bugpatch
|| span
->datapatch
)
502 debug0(isbfd
, "Patching span %s\n",
507 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
508 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
510 for (span
= ss
->spans
.data
;
511 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
513 debug0(isbfd
, "New span %s\n", span
->label
);
517 write_output
= false;
518 const char **sectname
;
519 for (sectname
= delsects
.data
;
520 sectname
< delsects
.data
+ delsects
.size
; sectname
++) {
522 debug0(isbfd
, "Deleted section: %s\n", *sectname
);
525 filter_table_sections(isbfd
);
527 compute_span_shifts(isbfd
);
529 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
530 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
531 if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
534 for (span
= ss
->spans
.data
;
535 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
536 if (span
->keep
|| span
->bugpatch
)
538 if (span
->patch
|| span
->new || span
->datapatch
)
539 write_ksplice_section(span
);
540 if (span
->patch
|| span
->datapatch
)
541 write_ksplice_patches(isbfd
, span
);
542 if (ss
->type
== SS_TYPE_EXPORT
&& span
->new)
543 write_ksplice_export(isbfd
, span
, false);
547 write_bugline_patches(isbfd
);
549 remove_unkept_spans(isbfd
);
552 void do_keep_old_code(struct superbfd
*isbfd
)
555 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
556 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
559 for (span
= ss
->spans
.data
;
560 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
562 if (ss
->type
== SS_TYPE_TEXT
&&
563 !strstarts(ss
->name
, ".fixup"))
565 if (ss
->type
== SS_TYPE_EXPORT
)
571 for (symp
= isbfd
->syms
.data
;
572 symp
< isbfd
->syms
.data
+ isbfd
->syms
.size
; symp
++) {
573 asymbol
*sym
= *symp
;
574 if (!bfd_is_const_section(sym
->section
) &&
575 (sym
->flags
& BSF_GLOBAL
) != 0) {
576 struct supersect
*sym_ss
=
577 fetch_supersect(isbfd
, sym
->section
);
578 if (sym
->value
== sym_ss
->contents
.size
)
580 struct span
*span
= find_span(sym_ss
, sym
->value
);
581 assert(span
!= NULL
);
582 if (sym_ss
->type
!= SS_TYPE_IGNORED
)
589 keep_referenced_sections(isbfd
);
592 filter_table_sections(isbfd
);
593 compute_span_shifts(isbfd
);
595 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
596 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
597 asymbol
*sym
= canonical_symbol(isbfd
, sect
->symbol
);
600 if ((sym
->flags
& BSF_WEAK
) != 0)
602 if (bfd_get_section_size(sect
) == 0)
606 if (ss
->type
!= SS_TYPE_TEXT
&& !matchable_data_section(ss
))
610 for (span
= ss
->spans
.data
;
611 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
613 write_ksplice_section(span
);
617 write_table_relocs(isbfd
, "__bug_table", KSPLICE_HOWTO_BUG
);
618 write_table_relocs(isbfd
, "__ex_table", KSPLICE_HOWTO_EXTABLE
);
620 remove_unkept_spans(isbfd
);
622 mangle_section_name(isbfd
, "__markers");
623 mangle_section_name(isbfd
, "__tracepoints");
624 mangle_section_name(isbfd
, "__ex_table");
625 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
626 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
627 if (ss
->type
== SS_TYPE_EXPORT
)
628 mangle_section_name(isbfd
, ss
->name
);
632 void do_finalize(struct superbfd
*isbfd
)
634 load_ksplice_symbol_offsets(isbfd
);
636 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
637 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
638 if (ss
->type
== SS_TYPE_EXIT
) {
640 for (span
= ss
->spans
.data
;
641 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
646 write_date_relocs(isbfd
, "<{DATE...}>", KSPLICE_HOWTO_DATE
);
647 write_date_relocs(isbfd
, "<{TIME}>", KSPLICE_HOWTO_TIME
);
651 void do_rmsyms(struct superbfd
*isbfd
)
653 asection
*extract_sect
= bfd_get_section_by_name(isbfd
->abfd
,
655 if (extract_sect
!= NULL
) {
656 struct supersect
*extract_ss
= fetch_supersect(isbfd
,
659 for (relocp
= extract_ss
->relocs
.data
;
660 relocp
< extract_ss
->relocs
.data
+ extract_ss
->relocs
.size
;
662 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
663 if (bfd_is_und_section(sym
->section
)) {
664 debug1(isbfd
, "extracting symbol %s\n",
666 *vec_grow(&extract_syms
, 1) = sym
;
674 void match_spans(struct span
*old_span
, struct span
*new_span
)
676 struct superbfd
*sbfd
= new_span
->ss
->parent
;
677 if (old_span
->match
== new_span
&& new_span
->match
== old_span
)
679 if (old_span
->match
!= NULL
) {
680 err(sbfd
, "Matching conflict: old %s: %s != %s\n",
681 old_span
->label
, old_span
->match
->label
, new_span
->label
);
684 if (new_span
->match
!= NULL
) {
685 err(sbfd
, "Matching conflict: new %s: %s != %s\n",
686 new_span
->label
, new_span
->match
->label
, old_span
->label
);
689 old_span
->match
= new_span
;
690 new_span
->match
= old_span
;
691 debug1(sbfd
, "Matched old %s to new %s\n", old_span
->label
,
693 if (old_span
->ss
->type
!= new_span
->ss
->type
&&
694 old_span
->ss
->type
== new_span
->ss
->orig_type
)
695 old_span
->ss
->type
= new_span
->ss
->type
;
697 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
698 if (ts
== NULL
|| !ts
->has_addr
|| ts
->other_sect
== NULL
)
700 struct span
*old_sym_span
=
701 span_offset_target_span(old_span
, ts
->other_offset
);
702 struct span
*new_sym_span
=
703 span_offset_target_span(new_span
, ts
->other_offset
);
704 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
705 match_spans(old_sym_span
, new_sym_span
);
708 void unmatch_span(struct span
*old_span
)
710 struct span
*new_span
= old_span
->match
;
711 old_span
->match
= NULL
;
712 new_span
->match
= NULL
;
714 new_span
->bugpatch
= false;
716 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
) {
717 const struct table_section
*ts
=
718 get_table_section(old_span
->ss
->name
);
719 if (ts
!= NULL
&& ts
->has_addr
)
720 unmatch_addr_spans(old_span
, new_span
, ts
);
723 new_span
->patch
= false;
724 new_span
->bugpatch
= false;
725 new_span
->datapatch
= false;
730 static void match_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
731 struct span
*new_span
, asymbol
*newsym
)
733 if (newsym
== NULL
||
734 (oldsym
->flags
& BSF_GLOBAL
) == 0 ||
735 (newsym
->flags
& BSF_GLOBAL
) == 0)
737 match_spans(old_span
, new_span
);
740 static void check_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
741 struct span
*new_span
, asymbol
*newsym
)
743 if ((oldsym
->flags
& BSF_GLOBAL
) == 0 ||
744 (newsym
!= NULL
&& (newsym
->flags
& BSF_GLOBAL
) == 0))
746 if (old_span
->ss
->type
== SS_TYPE_IGNORED
)
748 if (old_span
->match
!= new_span
) {
749 if (new_span
!= NULL
)
750 err(new_span
->ss
->parent
,
751 "Global symbol span mismatch: %s %s/%s\n",
752 oldsym
->name
, old_span
->label
, new_span
->label
);
754 err(old_span
->ss
->parent
,
755 "Global symbol span mismatch: %s %s/NULL\n",
756 oldsym
->name
, old_span
->label
);
761 static void foreach_symbol_pair(struct superbfd
*oldsbfd
, struct superbfd
*newsbfd
,
762 void (*fn
)(struct span
*old_span
,
764 struct span
*new_span
,
767 asymbol
**oldsymp
, **newsymp
;
768 for (oldsymp
= oldsbfd
->syms
.data
;
769 oldsymp
< oldsbfd
->syms
.data
+ oldsbfd
->syms
.size
; oldsymp
++) {
770 asymbol
*oldsym
= *oldsymp
;
771 if ((oldsym
->flags
& BSF_DEBUGGING
) != 0 ||
772 bfd_is_const_section(oldsym
->section
))
775 struct supersect
*old_ss
=
776 fetch_supersect(oldsbfd
, oldsym
->section
);
777 if (old_ss
->type
== SS_TYPE_SPECIAL
||
778 old_ss
->type
== SS_TYPE_EXPORT
)
781 struct span
*old_span
= find_span(old_ss
, oldsym
->value
);
782 if (old_span
== NULL
) {
783 err(oldsbfd
, "Could not find span for %s\n",
790 for (newsymp
= newsbfd
->syms
.data
;
791 newsymp
< newsbfd
->syms
.data
+ newsbfd
->syms
.size
;
793 asymbol
*newsym
= *newsymp
;
794 if ((newsym
->flags
& BSF_DEBUGGING
) != 0 ||
795 bfd_is_const_section(newsym
->section
))
797 if (strcmp(oldsym
->name
, newsym
->name
) != 0)
800 struct supersect
*new_ss
=
801 fetch_supersect(newsbfd
, newsym
->section
);
802 if (old_ss
->type
!= new_ss
->type
&&
803 old_ss
->type
!= new_ss
->orig_type
)
809 struct span
*new_span
=
810 find_span(new_ss
, newsym
->value
);
811 if (new_span
== NULL
) {
812 err(newsbfd
, "Could not find span for %s\n",
816 fn(old_span
, oldsym
, new_span
, newsym
);
820 fn(old_span
, oldsym
, NULL
, NULL
);
824 static void match_symbol_spans(struct span
*old_span
, asymbol
*oldsym
,
825 struct span
*new_span
, asymbol
*newsym
)
829 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
)
831 if (static_local_symbol(old_span
->ss
->parent
, oldsym
) ||
832 static_local_symbol(new_span
->ss
->parent
, newsym
))
834 if (old_span
->match
== NULL
&& new_span
->match
== NULL
)
835 match_spans(old_span
, new_span
);
838 static void match_spans_by_label(struct span
*old_span
, struct span
*new_span
)
840 if (old_span
->ss
->type
== SS_TYPE_STRING
||
841 (is_table_section(old_span
->ss
->name
, true, false) &&
842 !is_table_section(old_span
->ss
->name
, false, false)))
844 if (strcmp(old_span
->label
, new_span
->label
) == 0)
845 match_spans(old_span
, new_span
);
848 static void match_string_spans(struct span
*old_span
, struct span
*new_span
)
850 if (old_span
->ss
->type
!= SS_TYPE_STRING
||
851 strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
853 if (strcmp((char *)old_span
->ss
->contents
.data
+ old_span
->start
,
854 (char *)new_span
->ss
->contents
.data
+ new_span
->start
) == 0)
855 match_spans(old_span
, new_span
);
858 static void foreach_span_pair(struct superbfd
*oldsbfd
,
859 struct superbfd
*newsbfd
,
860 void (*fn
)(struct span
*old_span
,
861 struct span
*new_span
))
863 asection
*oldsect
, *newsect
;
864 struct supersect
*oldss
, *newss
;
865 struct span
*old_span
, *new_span
;
866 for (newsect
= newsbfd
->abfd
->sections
; newsect
!= NULL
;
867 newsect
= newsect
->next
) {
868 newss
= fetch_supersect(newsbfd
, newsect
);
869 for (oldsect
= oldsbfd
->abfd
->sections
; oldsect
!= NULL
;
870 oldsect
= oldsect
->next
) {
871 oldss
= fetch_supersect(oldsbfd
, oldsect
);
872 if (oldss
->type
!= newss
->type
)
874 for (new_span
= newss
->spans
.data
;
875 new_span
< newss
->spans
.data
+ newss
->spans
.size
;
877 for (old_span
= oldss
->spans
.data
;
878 old_span
< oldss
->spans
.data
+
879 oldss
->spans
.size
; old_span
++)
880 fn(old_span
, new_span
);
886 static void mark_new_spans(struct superbfd
*sbfd
)
889 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
890 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
891 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
894 for (span
= ss
->spans
.data
;
895 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
896 if (span
->match
== NULL
)
902 static void handle_deleted_spans(struct superbfd
*oldsbfd
,
903 struct superbfd
*newsbfd
)
906 for (sect
= oldsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
907 struct supersect
*ss
= fetch_supersect(oldsbfd
, sect
);
909 for (span
= ss
->spans
.data
;
910 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
911 if (span
->match
!= NULL
)
913 if (ss
->type
== SS_TYPE_EXPORT
) {
914 *vec_grow(&delsects
, 1) = span
->label
;
915 write_ksplice_export(newsbfd
, span
, true);
916 } else if (ss
->type
== SS_TYPE_TEXT
) {
917 *vec_grow(&delsects
, 1) = span
->label
;
918 if (span
->symbol
== NULL
)
920 write_ksplice_deleted_patch
921 (newsbfd
, span
->symbol
->name
, span
->label
,
928 static void handle_nonzero_offset_relocs(struct supersect
*ss
)
930 struct span
*address_span
, *target_span
;
932 for (relocp
= ss
->relocs
.data
;
933 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
934 arelent
*reloc
= *relocp
;
935 address_span
= find_span(ss
, reloc
->address
);
936 if (!address_span
->new && !address_span
->patch
)
939 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
940 if (bfd_is_const_section(sym
->section
))
942 bfd_vma offset
= reloc_target_offset(ss
, reloc
);
943 target_span
= reloc_target_span(ss
, reloc
);
944 if (sym
->value
+ offset
== target_span
->start
)
947 if (target_span
->ss
->type
!= SS_TYPE_TEXT
)
949 if (target_span
->patch
)
952 target_span
->patch
= true;
954 debug1(ss
->parent
, "Changing %s because a relocation from sect "
955 "%s has a nonzero offset %lx+%lx into it\n",
956 target_span
->label
, ss
->name
, (unsigned long)sym
->value
,
957 (unsigned long)offset
);
961 static void update_nonzero_offsets(struct superbfd
*sbfd
)
964 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
965 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
966 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
968 handle_nonzero_offset_relocs(ss
);
972 static void unmatch_addr_spans(struct span
*old_span
, struct span
*new_span
,
973 const struct table_section
*ts
)
975 struct span
*old_sym_span
=
976 span_offset_target_span(old_span
, ts
->addr_offset
);
977 struct span
*new_sym_span
=
978 span_offset_target_span(new_span
, ts
->addr_offset
);
979 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
980 if (old_sym_span
->match
== new_sym_span
&&
981 new_sym_span
->match
== old_sym_span
&&
982 !(new_sym_span
->patch
&& new_sym_span
->ss
->type
== SS_TYPE_TEXT
)) {
983 if (old_sym_span
->ss
->type
== SS_TYPE_TEXT
) {
984 debug1(new_span
->ss
->parent
, "Patching %s due "
985 "to relocations from special section %s\n",
986 new_sym_span
->label
, new_span
->label
);
987 new_sym_span
->patch
= true;
989 debug1(new_span
->ss
->parent
, "Unmatching %s and %s due "
990 "to relocations from special section %s/%s\n",
991 old_sym_span
->label
, new_sym_span
->label
,
992 old_span
->label
, new_span
->label
);
993 unmatch_span(old_sym_span
);
999 static void compare_spans(struct span
*old_span
, struct span
*new_span
)
1001 struct superbfd
*newsbfd
= new_span
->ss
->parent
;
1003 bool nonrelocs_match
= nonrelocs_equal(old_span
, new_span
);
1004 bool relocs_match
= all_relocs_equal(old_span
, new_span
);
1005 if (nonrelocs_match
&& relocs_match
) {
1006 const struct table_section
*ts
=
1007 get_table_section(old_span
->ss
->name
);
1008 if (ts
!= NULL
&& ts
->crc_sect
!= NULL
) {
1009 struct span
*old_crc_span
= get_crc_span(old_span
, ts
);
1010 struct span
*new_crc_span
= get_crc_span(new_span
, ts
);
1011 assert(old_crc_span
!= NULL
);
1012 assert(new_crc_span
!= NULL
);
1013 if (old_crc_span
->match
!= new_crc_span
||
1014 new_crc_span
->match
!= old_crc_span
) {
1015 debug1(newsbfd
, "Unmatching %s and %s due to "
1016 "nonmatching CRCs\n", old_span
->label
,
1018 unmatch_span(old_span
);
1025 if (new_span
->contents_size
!= old_span
->contents_size
)
1026 reason
= "differing sizes";
1027 else if (!nonrelocs_match
)
1028 reason
= "differing contents";
1030 reason
= "differing relocations";
1032 if (new_span
->ss
->type
== SS_TYPE_TEXT
) {
1033 if (new_span
->patch
)
1035 new_span
->patch
= true;
1036 debug1(newsbfd
, "Changing %s due to %s\n", new_span
->label
,
1038 } else if (old_span
->ss
->type
== SS_TYPE_BUGTABLE
&&
1039 new_span
->ss
->type
== SS_TYPE_BUGTABLE
&& relocs_match
) {
1040 if (new_span
->bugpatch
)
1042 debug1(newsbfd
, "Changing %s due to %s\n",
1043 new_span
->label
, reason
);
1044 new_span
->bugpatch
= true;
1045 } else if (new_span
->ss
->type
== SS_TYPE_RODATA
&&
1046 new_span
->contents_size
== old_span
->contents_size
) {
1047 if (new_span
->datapatch
)
1049 new_span
->datapatch
= true;
1050 debug1(newsbfd
, "Changing %s in-place due to %s\n",
1051 new_span
->label
, reason
);
1052 } else if (new_span
->ss
->type
== SS_TYPE_STRING
&&
1053 old_span
->ss
->type
== SS_TYPE_STRING
&& relocs_match
&&
1054 strcmp(new_span
->ss
->contents
.data
+ new_span
->start
,
1055 old_span
->ss
->contents
.data
+ old_span
->start
) == 0) {
1058 debug1(newsbfd
, "Unmatching %s and %s due to %s\n",
1059 old_span
->label
, new_span
->label
, reason
);
1060 unmatch_span(old_span
);
1063 if (unchangeable_section(new_span
->ss
))
1064 err(newsbfd
, "warning: ignoring change to nonpatchable "
1065 "section %s\n", new_span
->ss
->name
);
1068 static void compare_matched_spans(struct superbfd
*newsbfd
)
1071 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1072 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1074 for (span
= ss
->spans
.data
;
1075 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1076 if (span
->match
== NULL
)
1078 compare_spans(span
->match
, span
);
1083 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
1084 struct superbfd
*newsbfd
)
1088 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1089 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1090 for (span
= ss
->spans
.data
;
1091 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1092 if (span
->match
== NULL
)
1094 if (strcmp(span
->label
, span
->match
->label
) == 0)
1096 if (strcmp(span
->orig_label
, span
->label
) != 0 &&
1097 strcmp(span
->label
, span
->match
->label
) != 0)
1099 if (span
->symbol
!= NULL
)
1100 label_map_set(newsbfd
, span
->label
,
1101 span
->match
->label
);
1102 span
->label
= span
->match
->label
;
1107 static void copy_patched_entry_points(struct superbfd
*oldsbfd
,
1108 struct superbfd
*newsbfd
)
1112 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1113 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1114 for (span
= ss
->spans
.data
;
1115 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1118 assert(span
->match
!= NULL
);
1119 vec_init(&span
->pre_entry_points
);
1121 struct entry_point
*entry
;
1122 for (entry
= span
->match
->entry_points
.data
;
1123 entry
< span
->match
->entry_points
.data
+
1124 span
->match
->entry_points
.size
;
1126 struct entry_point
*e
=
1127 vec_grow(&span
->pre_entry_points
, 1);
1128 e
->name
= entry
->name
!= NULL
?
1129 strdup(entry
->name
) : NULL
;
1130 e
->label
= strdup(entry
->label
);
1131 e
->offset
= entry
->offset
;
1138 static int compare_entry_points(const void *va
, const void *vb
)
1140 const struct entry_point
*a
= va
, *b
= vb
;
1141 if (a
->offset
< b
->offset
)
1143 else if (a
->offset
> b
->offset
)
1149 static void compute_entry_points(struct superbfd
*sbfd
)
1152 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
1154 asymbol
*sym
= *symp
;
1155 if (bfd_is_const_section(sym
->section
))
1157 struct supersect
*old_ss
= fetch_supersect(sbfd
, sym
->section
);
1158 if ((sym
->flags
& BSF_GLOBAL
) == 0)
1160 struct span
*span
= find_span(old_ss
, sym
->value
);
1161 struct entry_point
*e
= vec_grow(&span
->entry_points
, 1);
1162 e
->label
= sym
->name
;
1163 e
->name
= sym
->name
;
1164 e
->offset
= sym
->value
- span
->start
;
1169 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1170 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1172 for (span
= ss
->spans
.data
;
1173 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1174 /* First make sure that 0 appears as an entry point */
1175 bool found_zero
= false;
1176 struct entry_point
*entry
;
1177 for (entry
= span
->entry_points
.data
;
1178 entry
< span
->entry_points
.data
+
1179 span
->entry_points
.size
;
1181 if (entry
->offset
== 0)
1185 struct entry_point
*e
=
1186 vec_grow(&span
->entry_points
, 1);
1187 e
->label
= span
->label
;
1190 e
->symbol
= span
->symbol
;
1193 qsort(span
->entry_points
.data
, span
->entry_points
.size
,
1194 sizeof(*span
->entry_points
.data
),
1195 compare_entry_points
);
1200 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
)
1203 for (relocp
= ss
->relocs
.data
;
1204 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
1205 arelent
*reloc
= *relocp
;
1206 if (addr
>= reloc
->address
&&
1207 addr
< reloc
->address
+ bfd_get_reloc_size(reloc
->howto
))
1213 static bool nonrelocs_equal(struct span
*old_span
, struct span
*new_span
)
1216 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1217 if (old_span
->contents_size
!= new_span
->contents_size
)
1219 const unsigned char *old
= old_ss
->contents
.data
+ old_span
->start
;
1220 const unsigned char *new = new_ss
->contents
.data
+ new_span
->start
;
1221 for (i
= 0; i
< old_span
->contents_size
; i
++) {
1222 if (old
[i
] != new[i
] &&
1223 !(part_of_reloc(old_ss
, i
+ old_span
->start
) &&
1224 part_of_reloc(new_ss
, i
+ new_span
->start
)))
1230 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
1231 arelent
*old_reloc
, arelent
*new_reloc
)
1233 struct superbfd
*oldsbfd
= old_src_ss
->parent
;
1234 struct superbfd
*newsbfd
= new_src_ss
->parent
;
1235 struct span
*old_addr_span
= find_span(old_src_ss
, old_reloc
->address
);
1236 struct span
*new_addr_span
= find_span(new_src_ss
, new_reloc
->address
);
1238 if (old_reloc
->address
- old_addr_span
->start
!=
1239 new_reloc
->address
- new_addr_span
->start
) {
1240 debug1(newsbfd
, "Section %s/%s has reloc address mismatch at "
1241 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1242 (unsigned long)old_reloc
->address
);
1246 if (old_reloc
->howto
!= new_reloc
->howto
) {
1247 debug1(newsbfd
, "Section %s/%s has howto type mismatch at "
1248 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1249 (unsigned long)old_reloc
->address
);
1253 if (non_dst_mask(old_src_ss
, old_reloc
) !=
1254 non_dst_mask(new_src_ss
, new_reloc
)) {
1255 debug1(newsbfd
, "Section %s/%s has contents mismatch at %lx\n",
1256 old_src_ss
->name
, new_src_ss
->name
,
1257 (unsigned long)old_reloc
->address
);
1261 asymbol
*old_sym
= *old_reloc
->sym_ptr_ptr
;
1262 asymbol
*new_sym
= *new_reloc
->sym_ptr_ptr
;
1263 asection
*old_sect
= old_sym
->section
;
1264 asection
*new_sect
= new_sym
->section
;
1266 bfd_vma old_offset
= reloc_target_offset(old_src_ss
, old_reloc
);
1267 bfd_vma new_offset
= reloc_target_offset(new_src_ss
, new_reloc
);
1269 if (bfd_is_und_section(old_sect
) || bfd_is_und_section(new_sect
)) {
1270 if (!bfd_is_und_section(new_sect
) && old_offset
!= 0 &&
1271 fetch_supersect(newsbfd
, new_sect
)->type
== SS_TYPE_TEXT
)
1274 if (!bfd_is_und_section(old_sect
) && new_offset
!= 0 &&
1275 fetch_supersect(oldsbfd
, old_sect
)->type
== SS_TYPE_TEXT
)
1278 return strcmp(old_sym
->name
, new_sym
->name
) == 0 &&
1279 old_offset
== new_offset
;
1282 if (bfd_is_abs_section(old_sect
) && bfd_is_abs_section(new_sect
)) {
1283 if (old_sym
->value
+ old_offset
== new_sym
->value
+ new_offset
)
1285 debug1(newsbfd
, "Differing relocations from %s/%s to ABS "
1286 "section: %lx/%lx\n", old_addr_span
->label
,
1287 new_addr_span
->label
,
1288 (unsigned long)(old_sym
->value
+ old_offset
),
1289 (unsigned long)(new_sym
->value
+ new_offset
));
1293 if (bfd_is_const_section(old_sect
) || bfd_is_const_section(new_sect
))
1296 struct supersect
*old_ss
= fetch_supersect(oldsbfd
, old_sect
);
1297 struct supersect
*new_ss
= fetch_supersect(newsbfd
, new_sect
);
1298 struct span
*old_span
= reloc_target_span(old_src_ss
, old_reloc
);
1299 struct span
*new_span
= reloc_target_span(new_src_ss
, new_reloc
);
1301 if (old_span
->match
!= new_span
|| new_span
->match
!= old_span
) {
1302 debug1(newsbfd
, "Nonmatching relocs from %s to %s/%s\n",
1303 new_src_ss
->name
, old_span
->label
, new_span
->label
);
1307 if (old_sym
->value
+ old_offset
- old_span
->start
!=
1308 new_sym
->value
+ new_offset
- new_span
->start
) {
1309 debug1(newsbfd
, "Offsets to %s/%s differ between %s "
1310 "and %s: %lx+%lx/%lx+%lx\n", old_ss
->name
,
1311 new_ss
->name
, old_src_ss
->name
, new_src_ss
->name
,
1312 (unsigned long)old_sym
->value
, (unsigned long)old_offset
,
1313 (unsigned long)new_sym
->value
,
1314 (unsigned long)new_offset
);
1318 if ((old_sym
->value
+ old_offset
- old_span
->start
!= 0 ||
1319 new_sym
->value
+ new_offset
- new_span
->start
!= 0) &&
1321 debug1(newsbfd
, "Relocation from %s to nonzero offsets "
1322 "%lx+%lx/%lx+%lx in changed section %s\n",
1323 new_src_ss
->name
, (unsigned long)old_sym
->value
,
1324 (unsigned long)old_offset
, (unsigned long)new_sym
->value
,
1325 (unsigned long)new_offset
, new_sym
->section
->name
);
1331 bool all_relocs_equal(struct span
*old_span
, struct span
*new_span
)
1333 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1334 arelent
**old_relocp
, **new_relocp
;
1336 for (old_relocp
= old_ss
->relocs
.data
;
1337 old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
;
1339 if (find_span(old_ss
, (*old_relocp
)->address
) == old_span
)
1343 for (new_relocp
= new_ss
->relocs
.data
;
1344 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
;
1346 if (find_span(new_ss
, (*new_relocp
)->address
) == new_span
)
1350 for (; old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1351 find_span(old_ss
, (*old_relocp
)->address
) == old_span
&&
1352 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1353 find_span(new_ss
, (*new_relocp
)->address
) == new_span
;
1354 old_relocp
++, new_relocp
++) {
1355 if (!relocs_equal(old_ss
, new_ss
, *old_relocp
, *new_relocp
))
1359 if ((old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1360 find_span(old_ss
, (*old_relocp
)->address
) == old_span
) ||
1361 (new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1362 find_span(new_ss
, (*new_relocp
)->address
) == new_span
)) {
1363 debug1(new_ss
->parent
, "Different reloc count between %s and "
1364 "%s\n", old_span
->label
, new_span
->label
);
1371 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
)
1373 int bits
= bfd_get_reloc_size(reloc
->howto
) * 8;
1374 void *address
= ss
->contents
.data
+ reloc
->address
;
1375 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1376 return x
& ~reloc
->howto
->dst_mask
;
1379 void rm_relocs(struct superbfd
*isbfd
)
1382 for (p
= isbfd
->abfd
->sections
; p
!= NULL
; p
= p
->next
) {
1383 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1384 bool remove_relocs
= ss
->keep
;
1386 if (mode("keep") && ss
->type
== SS_TYPE_SPECIAL
)
1387 remove_relocs
= false;
1389 if (ss
->type
== SS_TYPE_KSPLICE
||
1390 ss
->type
== SS_TYPE_KSPLICE_CALL
)
1391 remove_relocs
= false;
1392 if (mode("finalize") &&
1393 (strstarts(ss
->name
, ".ksplice_patches") ||
1394 strstarts(ss
->name
, ".ksplice_relocs")))
1395 remove_relocs
= true;
1402 void rm_some_relocs(struct supersect
*ss
)
1404 struct arelentp_vec orig_relocs
;
1405 vec_move(&orig_relocs
, &ss
->relocs
);
1408 for (relocp
= orig_relocs
.data
;
1409 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
1410 bool rm_reloc
= false;
1411 asymbol
*sym_ptr
= *(*relocp
)->sym_ptr_ptr
;
1413 if (mode("rmsyms") && bfd_is_und_section(sym_ptr
->section
)) {
1415 for (esymp
= extract_syms
.data
;
1416 esymp
< extract_syms
.data
+ extract_syms
.size
;
1418 if (sym_ptr
== *esymp
) {
1428 if (mode("keep-new-code")) {
1429 if (bfd_is_const_section(sym_ptr
->section
)) {
1432 bfd_vma offset
= reloc_target_offset(ss
, *relocp
);
1433 struct span
*target_span
=
1434 reloc_target_span(ss
, *relocp
);
1435 if (target_span
->new ||
1436 (target_span
->ss
->type
== SS_TYPE_TEXT
&&
1437 sym_ptr
->value
+ offset
!=
1438 target_span
->start
))
1442 const struct table_section
*ts
=
1443 get_table_section(ss
->name
);
1444 if (ts
!= NULL
&& ts
->has_addr
&&
1445 ((*relocp
)->address
% ts
->entry_size
==
1447 (*relocp
)->address
% ts
->entry_size
==
1452 if (mode("finalize") && bfd_is_und_section(sym_ptr
->section
))
1455 if (strcmp(sym_ptr
->name
, "mcount") == 0 &&
1456 bfd_is_und_section(sym_ptr
->section
))
1459 if (!find_span(ss
, (*relocp
)->address
)->keep
)
1463 write_ksplice_reloc(ss
, *relocp
);
1465 *vec_grow(&ss
->relocs
, 1) = *relocp
;
1469 struct supersect
*make_section(struct superbfd
*sbfd
, const char *fmt
, ...)
1473 char *name
= vstrprintf(fmt
, ap
);
1476 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
1478 return fetch_supersect(sbfd
, sect
);
1480 return new_supersect(sbfd
, name
);
1483 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1486 bfd_reloc_code_real_type code
;
1487 switch (bfd_arch_bits_per_address(ss
->parent
->abfd
)) {
1489 code
= BFD_RELOC_32
;
1492 code
= BFD_RELOC_64
;
1498 arelent
*reloc
= malloc(sizeof(*reloc
));
1499 reloc
->sym_ptr_ptr
= symp
;
1500 reloc
->address
= addr_offset(ss
, addr
);
1501 reloc
->howto
= bfd_reloc_type_lookup(ss
->parent
->abfd
, code
);
1502 reloc
->addend
= offset
;
1506 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1509 *vec_grow(&ss
->new_relocs
, 1) = create_reloc(ss
, addr
, symp
, offset
);
1512 void write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...)
1515 struct supersect
*str_ss
= make_section(ss
->parent
, ".ksplice_str");
1518 int len
= vasprintf(&str
, fmt
, ap
);
1522 unsigned long *str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
,
1524 if (str_offp
== NULL
) {
1525 char *buf
= sect_grow(str_ss
, len
+ 1, char);
1526 memcpy(buf
, str
, len
+ 1);
1527 str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
, TRUE
);
1528 *str_offp
= addr_offset(str_ss
, buf
);
1531 write_reloc(ss
, addr
, &str_ss
->symbol
, *str_offp
);
1534 void lookup_system_map(struct addr_vec
*addrs
, const char *name
, long offset
)
1536 struct addr_vec
*map_addrs
=
1537 addr_vec_hash_lookup(&system_map
, name
, FALSE
);
1538 if (map_addrs
== NULL
)
1541 unsigned long *addr
, *map_addr
;
1542 for (map_addr
= map_addrs
->data
;
1543 map_addr
< map_addrs
->data
+ map_addrs
->size
; map_addr
++) {
1544 for (addr
= addrs
->data
; addr
< addrs
->data
+ addrs
->size
;
1546 if (*addr
== *map_addr
+ offset
)
1549 if (addr
< addrs
->data
+ addrs
->size
)
1551 *vec_grow(addrs
, 1) = *map_addr
+ offset
;
1555 void compute_system_map_array(struct superbfd
*sbfd
, struct addr_vec
*addrs
,
1558 if (bfd_is_abs_section(sym
->section
)) {
1559 *vec_grow(addrs
, 1) = sym
->value
;
1560 } else if (bfd_is_und_section(sym
->section
)) {
1561 lookup_system_map(addrs
, sym
->name
, 0);
1562 } else if (!bfd_is_const_section(sym
->section
)) {
1564 for (gsymp
= sbfd
->syms
.data
;
1565 gsymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; gsymp
++) {
1566 asymbol
*gsym
= *gsymp
;
1567 if ((gsym
->flags
& BSF_DEBUGGING
) == 0 &&
1568 gsym
->section
== sym
->section
)
1569 lookup_system_map(addrs
, gsym
->name
,
1570 sym
->value
- gsym
->value
);
1575 void write_ksplice_system_map(struct superbfd
*sbfd
, asymbol
*sym
,
1578 bool *done
= bool_hash_lookup(&system_map_written
, label
, TRUE
);
1583 struct addr_vec addrs
;
1586 compute_system_map_array(sbfd
, &addrs
, sym
);
1587 if (addrs
.size
!= 0) {
1588 struct supersect
*smap_ss
=
1589 make_section(sbfd
, ".ksplice_system_map");
1590 struct ksplice_system_map
*smap
=
1591 sect_grow(smap_ss
, 1, struct ksplice_system_map
);
1592 write_string(smap_ss
, &smap
->label
, "%s", label
);
1594 struct supersect
*array_ss
= make_section(sbfd
,
1596 void *buf
= sect_grow(array_ss
, addrs
.size
,
1597 typeof(*addrs
.data
));
1598 memcpy(buf
, addrs
.data
, addrs
.size
* sizeof(*addrs
.data
));
1599 smap
->nr_candidates
= addrs
.size
;
1600 write_reloc(smap_ss
, &smap
->candidates
, &array_ss
->symbol
,
1601 addr_offset(array_ss
, buf
));
1606 void write_ksplice_symbol_backend(struct supersect
*ss
,
1607 struct ksplice_symbol
*const *addr
,
1608 asymbol
*sym
, const char *label
,
1611 struct supersect
*ksymbol_ss
= make_section(ss
->parent
,
1612 ".ksplice_symbols");
1613 struct ksplice_symbol
*ksymbol
;
1614 unsigned long *ksymbol_offp
;
1616 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, FALSE
);
1617 if (ksymbol_offp
!= NULL
) {
1618 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1621 ksymbol
= sect_grow(ksymbol_ss
, 1, struct ksplice_symbol
);
1622 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
1623 *ksymbol_offp
= addr_offset(ksymbol_ss
, ksymbol
);
1625 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1626 write_string(ksymbol_ss
, &ksymbol
->label
, "%s", label
);
1628 write_string(ksymbol_ss
, &ksymbol
->name
, "%s", name
);
1629 write_ksplice_system_map(ksymbol_ss
->parent
, sym
, label
);
1633 void write_ksplice_symbol(struct supersect
*ss
,
1634 struct ksplice_symbol
*const *addr
,
1635 asymbol
*sym
, struct span
*span
,
1636 const char *addstr_sect
)
1638 const char *label
, *name
;
1639 if (span
!= NULL
&& span
->start
!= 0)
1640 label
= span
->label
;
1642 label
= label_lookup(ss
->parent
, sym
);
1644 asymbol
*gsym
= canonical_symbol(ss
->parent
, sym
);
1645 if (strcmp(addstr_sect
, "") != 0)
1647 else if (bfd_is_und_section(sym
->section
))
1649 else if (bfd_is_const_section(sym
->section
))
1651 else if (span
!= NULL
&& span
->symbol
== NULL
)
1653 else if (gsym
== NULL
|| (gsym
->flags
& BSF_SECTION_SYM
) != 0)
1658 write_ksplice_symbol_backend(ss
, addr
, sym
,
1659 strprintf("%s%s", addstr_sect
, label
),
1663 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
)
1665 asymbol
*sym_ptr
= *orig_reloc
->sym_ptr_ptr
;
1666 bfd_vma reloc_addend
= reloc_offset(ss
, orig_reloc
);
1667 bfd_vma target_addend
= reloc_target_offset(ss
, orig_reloc
);
1668 unsigned long *repladdr
= ss
->contents
.data
+ orig_reloc
->address
;
1670 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_patches")) {
1674 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_relocs")) {
1675 assert(strstarts(sym_ptr
->name
, KSPLICE_SYMBOL_STR
));
1677 fake_sym
.name
= sym_ptr
->name
+ strlen(KSPLICE_SYMBOL_STR
);
1678 fake_sym
.section
= bfd_und_section_ptr
;
1682 write_ksplice_symbol_backend
1683 (ss
, (struct ksplice_symbol
**)repladdr
, &fake_sym
,
1684 fake_sym
.name
, fake_sym
.name
);
1688 struct span
*span
= reloc_target_span(ss
, orig_reloc
);
1689 if (span
== ss
->spans
.data
&& span
->start
!= target_addend
)
1691 write_canary(ss
, orig_reloc
->address
,
1692 bfd_get_reloc_size(orig_reloc
->howto
),
1693 orig_reloc
->howto
->dst_mask
);
1695 struct supersect
*kreloc_ss
=
1696 make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1697 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1698 struct ksplice_reloc
);
1700 struct span
*address_span
= find_span(ss
, orig_reloc
->address
);
1701 write_reloc(kreloc_ss
, &kreloc
->blank_addr
,
1702 &ss
->symbol
, orig_reloc
->address
+ address_span
->shift
);
1703 if (bfd_is_und_section(sym_ptr
->section
) && mode("keep")) {
1704 char *name
= strprintf(KSPLICE_SYMBOL_STR
"%s", sym_ptr
->name
);
1705 asymbol
**symp
= make_undefined_symbolp(ss
->parent
, name
);
1706 write_reloc(kreloc_ss
, &kreloc
->symbol
, symp
, 0);
1708 write_ksplice_symbol(kreloc_ss
, &kreloc
->symbol
, sym_ptr
, span
,
1711 if (span
!= NULL
&& span
->start
!= 0) {
1712 reloc_addend
+= sym_ptr
->value
- span
->start
;
1713 target_addend
+= sym_ptr
->value
- span
->start
;
1715 kreloc
->insn_addend
= reloc_addend
- target_addend
;
1716 kreloc
->target_addend
= target_addend
;
1717 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, orig_reloc
->howto
,
1718 KSPLICE_HOWTO_RELOC
);
1721 static void write_ksplice_reloc_howto(struct supersect
*ss
, const
1722 struct ksplice_reloc_howto
*const *addr
,
1723 reloc_howto_type
*howto
,
1724 enum ksplice_reloc_howto_type type
)
1726 struct supersect
*khowto_ss
= make_section(ss
->parent
,
1727 ".ksplice_reloc_howtos");
1728 struct ksplice_reloc_howto
*khowto
;
1729 unsigned long *khowto_offp
;
1731 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1733 if (khowto_offp
!= NULL
) {
1734 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1737 khowto
= sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1738 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1740 *khowto_offp
= addr_offset(khowto_ss
, khowto
);
1742 khowto
->type
= type
;
1743 khowto
->pcrel
= howto
->pc_relative
;
1744 khowto
->size
= bfd_get_reloc_size(howto
);
1745 khowto
->dst_mask
= howto
->dst_mask
;
1746 khowto
->rightshift
= howto
->rightshift
;
1747 khowto
->signed_addend
=
1748 (howto
->complain_on_overflow
== complain_overflow_signed
) ||
1749 (howto
->complain_on_overflow
== complain_overflow_bitfield
);
1750 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1753 #define CANARY(x, canary) ((x & ~howto->dst_mask) | (canary & howto->dst_mask))
1755 void write_canary(struct supersect
*ss
, int offset
, bfd_size_type size
,
1758 int bits
= size
* 8;
1759 void *address
= ss
->contents
.data
+ offset
;
1760 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1761 x
= (x
& ~dst_mask
) | ((bfd_vma
)KSPLICE_CANARY
& dst_mask
);
1762 bfd_put(bits
, ss
->parent
->abfd
, x
, address
);
1765 static void write_date_relocs(struct superbfd
*sbfd
, const char *str
,
1766 enum ksplice_reloc_howto_type type
)
1769 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1770 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1771 if (ss
->type
!= SS_TYPE_STRING
&& ss
->type
!= SS_TYPE_RODATA
)
1775 for (span
= ss
->spans
.data
;
1776 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1779 for (ptr
= ss
->contents
.data
+ span
->start
;
1780 ptr
+ strlen(str
) < ss
->contents
.data
+
1781 span
->start
+ span
->contents_size
; ptr
++) {
1782 if (strcmp((const char *)ptr
, str
) == 0)
1783 write_ksplice_date_reloc
1784 (ss
, addr_offset(ss
, ptr
), str
,
1791 static void write_ksplice_date_reloc(struct supersect
*ss
, unsigned long offset
,
1793 enum ksplice_reloc_howto_type type
)
1795 struct supersect
*kreloc_ss
;
1796 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1797 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1798 struct ksplice_reloc
);
1800 const char *filename
= ss
->parent
->abfd
->filename
;
1801 char *c
= strstr(filename
, ".KSPLICE");
1802 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
1804 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1805 strprintf("%s<%.*s>", str
, flen
, filename
),
1808 struct span
*span
= find_span(ss
, offset
);
1809 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1810 offset
+ span
->shift
);
1811 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
,
1815 static void write_table_relocs(struct superbfd
*sbfd
, const char *sectname
,
1816 enum ksplice_reloc_howto_type type
)
1818 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, sectname
);
1821 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1823 const struct table_section
*s
= get_table_section(sectname
);
1828 for (entry
= ss
->contents
.data
;
1829 entry
< ss
->contents
.data
+ ss
->contents
.size
;
1830 entry
+= s
->entry_size
) {
1831 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
1832 assert(span
!= NULL
);
1836 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
1837 assert(reloc
!= NULL
);
1838 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
1839 assert(!bfd_is_const_section(sym
->section
));
1840 struct supersect
*sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1841 unsigned long addr
= sym
->value
+
1842 reloc_target_offset(ss
, reloc
);
1843 write_ksplice_table_reloc(sym_ss
, addr
, span
->label
, type
);
1847 static void write_ksplice_table_reloc(struct supersect
*ss
,
1848 unsigned long address
,
1850 enum ksplice_reloc_howto_type type
)
1852 struct supersect
*kreloc_ss
;
1853 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1854 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1855 struct ksplice_reloc
);
1856 struct span
*span
= find_span(ss
, address
);
1857 assert(span
!= NULL
);
1859 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1861 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1862 address
+ span
->shift
);
1863 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
, 0);
1866 static void write_ksplice_nonreloc_howto(struct supersect
*ss
,
1867 const struct ksplice_reloc_howto
1869 enum ksplice_reloc_howto_type type
,
1872 struct supersect
*khowto_ss
=
1873 make_section(ss
->parent
, ".ksplice_reloc_howtos");
1874 struct ksplice_reloc_howto
*khowto
=
1875 sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1877 khowto
->type
= type
;
1878 khowto
->size
= size
;
1880 khowto
->dst_mask
= 0;
1881 khowto
->rightshift
= 0;
1882 khowto
->signed_addend
= 0;
1883 write_reloc(ss
, addr
, &khowto_ss
->symbol
,
1884 addr_offset(khowto_ss
, khowto
));
1887 static void write_ksplice_symbol_reloc(struct supersect
*ss
,
1888 const char *sectname
,
1889 unsigned long *addr
, asymbol
*sym
,
1890 const char *label
, const char *name
)
1892 struct supersect
*kreloc_ss
;
1893 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1894 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1895 struct ksplice_reloc
);
1897 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, sym
, label
,
1899 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1900 addr_offset(ss
, addr
));
1901 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
,
1902 KSPLICE_HOWTO_SYMBOL
, 0);
1905 static void write_ksplice_section(struct span
*span
)
1907 struct supersect
*ss
= span
->ss
;
1908 const char *sectname
= span
->ss
->name
;
1909 const struct table_section
*ts
= get_table_section(ss
->name
);
1911 if (ts
!= NULL
&& ts
->has_addr
) {
1912 arelent
*reloc
= find_reloc(ss
, ss
->contents
.data
+ span
->start
1914 assert(reloc
!= NULL
);
1915 asymbol
*rsym
= *reloc
->sym_ptr_ptr
;
1916 assert(!bfd_is_const_section(rsym
->section
));
1917 sectname
= rsym
->section
->name
;
1920 struct supersect
*ksect_ss
=
1921 make_section(ss
->parent
, ".ksplice_sections%s", sectname
);
1922 struct ksplice_section
*ksect
= sect_grow(ksect_ss
, 1,
1923 struct ksplice_section
);
1924 asymbol
*sym
= span
->symbol
== NULL
? ss
->symbol
: span
->symbol
;
1926 write_ksplice_symbol(ksect_ss
, &ksect
->symbol
, sym
, span
,
1927 mode("keep-new-code") ? "(post)" : "");
1928 ksect
->size
= span
->size
;
1931 if (ss
->type
== SS_TYPE_RODATA
|| ss
->type
== SS_TYPE_STRING
||
1932 ss
->type
== SS_TYPE_EXPORT
|| ss
->type
== SS_TYPE_BUGTABLE
)
1933 ksect
->flags
|= KSPLICE_SECTION_RODATA
;
1934 if (ss
->type
== SS_TYPE_DATA
)
1935 ksect
->flags
|= KSPLICE_SECTION_DATA
;
1936 if (ss
->type
== SS_TYPE_TEXT
)
1937 ksect
->flags
|= KSPLICE_SECTION_TEXT
;
1938 assert(ksect
->flags
!= 0);
1940 if (ss
->type
== SS_TYPE_STRING
)
1941 ksect
->flags
|= KSPLICE_SECTION_STRING
;
1943 write_reloc(ksect_ss
, &ksect
->address
, &ss
->symbol
,
1944 span
->start
+ span
->shift
);
1946 if (mode("keep-old-code")) {
1947 /* Write ksplice_symbols for all the entry points */
1948 struct entry_point
*entry
;
1949 for (entry
= span
->entry_points
.data
;
1950 entry
< span
->entry_points
.data
+ span
->entry_points
.size
;
1952 write_ksplice_symbol_reloc
1953 (span
->ss
, sectname
, span
->ss
->contents
.data
+
1954 span
->start
+ span
->shift
+ entry
->offset
,
1955 entry
->symbol
, entry
->label
, entry
->name
);
1959 static void write_ksplice_patch_reloc(struct supersect
*ss
,
1960 const char *sectname
, unsigned long *addr
,
1961 bfd_size_type size
, const char *label
,
1964 struct supersect
*kreloc_ss
;
1965 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1966 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1967 struct ksplice_reloc
);
1969 write_canary(ss
, addr_offset(ss
, addr
), size
, -1);
1970 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1972 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1973 addr_offset(ss
, addr
));
1974 reloc_howto_type
*howto
=
1975 bfd_reloc_type_lookup(ss
->parent
->abfd
,
1976 PASTE(BFD_RELOC_
, LONG_BIT
));
1977 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, howto
,
1978 KSPLICE_HOWTO_RELOC
);
1979 kreloc
->target_addend
= addend
;
1980 kreloc
->insn_addend
= 0;
1983 /* Assumes symbol is global, aka only one symbol of that name */
1984 static asymbol
*name_to_symbol(struct superbfd
*sbfd
, const char *name
)
1990 for (symp
= sbfd
->syms
.data
;
1991 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
1992 asymbol
*sym
= *symp
;
1993 if (strcmp(name
, sym
->name
) == 0 &&
1994 ((sym
->flags
& BSF_GLOBAL
) != 0 ||
1995 bfd_is_und_section(sym
->section
)))
2001 void write_ksplice_patches(struct superbfd
*sbfd
, struct span
*span
)
2003 if (span
->datapatch
) {
2004 write_ksplice_patch(sbfd
, span
, span
->label
, 0);
2008 assert(span
->patch
);
2010 long prev_offset
= LONG_MIN
;
2011 asymbol
*prev_sym
= NULL
;
2012 const char *prev_label
= NULL
;
2013 struct entry_point
*entry
;
2014 for (entry
= span
->pre_entry_points
.data
;
2015 entry
< span
->pre_entry_points
.data
+ span
->pre_entry_points
.size
;
2017 asymbol
*sym
= name_to_symbol(sbfd
, entry
->name
);
2018 if (sym
== NULL
&& entry
->offset
!= 0) {
2019 /* Since it was global, name and label are the same */
2020 write_ksplice_deleted_patch
2021 (sbfd
, entry
->label
, entry
->label
, span
->ss
->name
,
2023 } else if (entry
->offset
!= prev_offset
) {
2024 debug1(sbfd
, "entry point: %s(%s) %lx\n", entry
->label
,
2025 entry
->name
, entry
->offset
);
2027 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> entry
->offset
) {
2029 "Overlapping trampolines: %s %lx/%lx\n",
2030 span
->label
, prev_offset
, entry
->offset
);
2034 long target_offset
= 0;
2036 target_offset
= sym
->value
- span
->start
;
2037 write_ksplice_patch(sbfd
, span
, entry
->label
,
2039 prev_offset
= entry
->offset
;
2043 if (prev_sym
== NULL
) {
2045 prev_label
= entry
->label
;
2046 } else if (sym
!= NULL
&&
2047 (prev_sym
->section
!= sym
->section
||
2048 prev_sym
->value
!= sym
->value
)) {
2049 err(sbfd
, "Splitting global symbols in the middle of a "
2050 "span: %s+%lx != %s+%lx!\n",
2051 prev_label
, (unsigned long)prev_sym
->value
,
2052 entry
->label
, (unsigned long)sym
->value
);
2057 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> span
->size
) {
2058 err(sbfd
, "Trampoline ends outside span: %s %lx/%lx\n",
2059 span
->label
, prev_offset
, (unsigned long)span
->size
);
2064 void write_ksplice_patch(struct superbfd
*sbfd
, struct span
*span
,
2065 const char *label
, long offset
)
2067 struct supersect
*kpatch_ss
=
2068 make_section(sbfd
, ".ksplice_patches%s", span
->ss
->name
);
2069 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2070 struct ksplice_patch
);
2072 write_ksplice_patch_reloc(kpatch_ss
, span
->ss
->name
, &kpatch
->oldaddr
,
2073 sizeof(kpatch
->oldaddr
), label
, 0);
2074 if (span
->ss
->type
== SS_TYPE_TEXT
) {
2075 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2076 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
,
2079 kpatch
->type
= KSPLICE_PATCH_DATA
;
2080 kpatch
->size
= span
->contents_size
;
2081 struct supersect
*data_ss
=
2082 make_section(sbfd
, ".ksplice_patch_data");
2083 write_reloc(kpatch_ss
, &kpatch
->contents
, &span
->ss
->symbol
,
2084 span
->start
+ span
->shift
);
2085 char *saved
= sect_do_grow(data_ss
, 1, span
->contents_size
, 1);
2086 write_reloc(kpatch_ss
, &kpatch
->saved
, &data_ss
->symbol
,
2087 addr_offset(data_ss
, saved
));
2089 write_reloc(kpatch_ss
, &kpatch
->repladdr
, &span
->ss
->symbol
,
2090 span
->start
+ span
->shift
+ offset
);
2093 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
)
2096 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
2098 asymbol
*sym
= *symp
;
2099 if (strcmp(name
, sym
->name
) == 0 &&
2100 bfd_is_und_section(sym
->section
))
2104 for (sympp
= sbfd
->new_syms
.data
;
2105 sympp
< sbfd
->new_syms
.data
+ sbfd
->new_syms
.size
; sympp
++) {
2106 asymbol
**symp
= *sympp
;
2107 asymbol
*sym
= *symp
;
2108 if (strcmp(name
, sym
->name
) == 0 &&
2109 bfd_is_und_section(sym
->section
))
2113 symp
= malloc(sizeof(*symp
));
2114 *symp
= bfd_make_empty_symbol(sbfd
->abfd
);
2115 asymbol
*sym
= *symp
;
2117 sym
->section
= bfd_und_section_ptr
;
2120 *vec_grow(&sbfd
->new_syms
, 1) = symp
;
2124 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
2125 const char *label
, const char *sectname
,
2128 struct supersect
*kpatch_ss
=
2129 make_section(sbfd
, ".ksplice_patches%s", sectname
);
2130 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2131 struct ksplice_patch
);
2133 write_ksplice_patch_reloc(kpatch_ss
, sectname
, &kpatch
->oldaddr
,
2134 sizeof(kpatch
->oldaddr
), label
, 0);
2135 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2136 asymbol
**symp
= make_undefined_symbolp(sbfd
, strdup(name
));
2137 write_reloc(kpatch_ss
, &kpatch
->repladdr
, symp
, offset
);
2138 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
, NULL
);
2141 void write_ksplice_export(struct superbfd
*sbfd
, struct span
*span
, bool del
)
2143 struct supersect
*kpatch_ss
= make_section(sbfd
, ".ksplice_patches");
2144 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2145 struct ksplice_patch
);
2146 struct supersect
*data_ss
;
2148 const struct table_section
*ts
= get_table_section(span
->ss
->name
);
2151 span
->ss
->contents
.data
+ span
->start
+ ts
->other_offset
;
2152 const char *symname
= read_string(span
->ss
, addr
);
2154 char *oldname
, *newname
;
2156 oldname
= strprintf("%s:%s", span
->ss
->name
, symname
);
2157 newname
= strprintf("DISABLED_%s_%s", symname
, kid
);
2159 oldname
= strprintf("%s:DISABLED_%s_%s", span
->ss
->name
,
2161 newname
= strprintf("%s", symname
);
2162 write_string(span
->ss
, addr
, "DISABLED_%s_%s", symname
, kid
);
2165 write_ksplice_patch_reloc(kpatch_ss
, "", &kpatch
->oldaddr
,
2166 sizeof(kpatch
->oldaddr
), oldname
,
2168 kpatch
->type
= KSPLICE_PATCH_EXPORT
;
2169 const char **namep
= write_patch_storage(kpatch_ss
, kpatch
,
2170 sizeof(newname
), &data_ss
);
2171 write_string(data_ss
, namep
, "%s", newname
);
2174 void filter_table_sections(struct superbfd
*isbfd
)
2176 struct supersect
*tables_ss
=
2177 fetch_supersect(offsets_sbfd
,
2178 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2179 ".ksplice_table_sections"));
2180 const struct table_section
*ts
;
2181 for (ts
= tables_ss
->contents
.data
;
2182 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2184 struct table_section s
= *ts
;
2185 s
.sect
= read_string(tables_ss
, &ts
->sect
);
2186 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
2187 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2188 filter_table_section(isbfd
, &s
);
2192 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
)
2194 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
2195 if (isection
== NULL
)
2197 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2200 for (entry
= ss
->contents
.data
;
2201 entry
< ss
->contents
.data
+ ss
->contents
.size
;
2202 entry
+= s
->entry_size
) {
2203 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
2204 assert(span
!= NULL
);
2207 struct span
*sym_span
=
2208 span_offset_target_span(span
, s
->addr_offset
);
2209 assert(sym_span
!= NULL
);
2214 if (s
->other_sect
!= NULL
) {
2215 struct span
*sym_span
=
2216 span_offset_target_span(span
, s
->other_offset
);
2217 assert(sym_span
!= NULL
);
2219 keep_span(sym_span
);
2222 if (s
->crc_sect
!= NULL
) {
2223 struct span
*crc_span
= get_crc_span(span
, s
);
2224 assert(crc_span
!= NULL
);
2225 if (span
->keep
&& mode("keep-new-code"))
2226 keep_span(crc_span
);
2231 static void match_other_spans(struct span
*old_span
, struct span
*new_span
)
2233 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2237 if (old_span
->match
== new_span
&& new_span
->match
== old_span
&&
2238 ts
->other_sect
!= NULL
) {
2239 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2240 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2241 arelent
*old_reloc
=
2242 find_reloc(old_span
->ss
, old_entry
+ ts
->other_offset
);
2243 arelent
*new_reloc
=
2244 find_reloc(new_span
->ss
, new_entry
+ ts
->other_offset
);
2245 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2246 struct span
*old_other_span
=
2247 reloc_target_span(old_span
->ss
, old_reloc
);
2248 struct span
*new_other_span
=
2249 reloc_target_span(new_span
->ss
, new_reloc
);
2250 assert(old_other_span
!= NULL
&& new_other_span
!= NULL
);
2251 match_spans(old_other_span
, new_other_span
);
2255 static void match_table_spans(struct span
*old_span
, struct span
*new_span
)
2257 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2259 if (strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
2261 if (ts
== NULL
|| old_span
->ss
->type
!= SS_TYPE_SPECIAL
||
2262 new_span
->ss
->type
!= SS_TYPE_SPECIAL
)
2264 if (old_span
->match
!= NULL
|| new_span
->match
!= NULL
)
2268 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2269 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2270 arelent
*old_reloc
=
2271 find_reloc(old_span
->ss
, old_entry
+ ts
->addr_offset
);
2272 arelent
*new_reloc
=
2273 find_reloc(new_span
->ss
, new_entry
+ ts
->addr_offset
);
2274 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2275 struct span
*old_sym_span
=
2276 reloc_target_span(old_span
->ss
, old_reloc
);
2277 struct span
*new_sym_span
=
2278 reloc_target_span(new_span
->ss
, new_reloc
);
2279 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
2280 if (old_sym_span
->match
== new_sym_span
&&
2281 new_sym_span
->match
== old_sym_span
&&
2282 old_reloc
->address
- old_sym_span
->start
==
2283 new_reloc
->address
- new_sym_span
->start
)
2284 match_spans(old_span
, new_span
);
2288 static struct span
*get_crc_span(struct span
*span
,
2289 const struct table_section
*ts
)
2291 void *entry
= span
->ss
->contents
.data
+ span
->start
;
2292 asection
*crc_sect
= bfd_get_section_by_name(span
->ss
->parent
->abfd
,
2294 if (crc_sect
== NULL
)
2296 struct supersect
*crc_ss
= fetch_supersect(span
->ss
->parent
, crc_sect
);
2299 struct span
*crc_span
= find_span(crc_ss
, addr_offset(span
->ss
, entry
) /
2300 ts
->entry_size
* ts
->crc_size
);
2304 void mark_precallable_spans(struct superbfd
*sbfd
)
2307 struct supersect
*ss
, *sym_ss
;
2308 struct span
*address_span
, *target_span
;
2309 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2310 ss
= fetch_supersect(sbfd
, sect
);
2312 if (ss
->type
== SS_TYPE_SPECIAL
)
2314 for (relocp
= ss
->relocs
.data
;
2315 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2316 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2317 address_span
= find_span(ss
, (*relocp
)->address
);
2318 if (!address_span
->precallable
)
2320 target_span
= reloc_target_span(ss
, *relocp
);
2321 if (target_span
== NULL
|| target_span
->keep
)
2323 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2324 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2326 target_span
->precallable
= true;
2332 void keep_referenced_sections(struct superbfd
*sbfd
)
2335 struct supersect
*ss
, *sym_ss
;
2336 struct span
*address_span
, *target_span
;
2337 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2338 ss
= fetch_supersect(sbfd
, sect
);
2340 if (ss
->type
== SS_TYPE_SPECIAL
)
2342 for (relocp
= ss
->relocs
.data
;
2343 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2344 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2345 address_span
= find_span(ss
, (*relocp
)->address
);
2346 if (!address_span
->keep
)
2348 target_span
= reloc_target_span(ss
, *relocp
);
2349 if (target_span
== NULL
|| target_span
->keep
)
2351 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2352 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2354 keep_span(target_span
);
2360 void copy_symbols(struct asymbolp_vec
*osyms
, struct asymbolpp_vec
*isyms
)
2363 for (sympp
= isyms
->data
; sympp
< isyms
->data
+ isyms
->size
; sympp
++)
2364 *vec_grow(osyms
, 1) = **sympp
;
2367 /* Modified function from GNU Binutils objcopy.c */
2368 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
)
2370 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2372 bfd_vma start
= bfd_get_start_address(ibfd
);
2374 flagword flags
= bfd_get_file_flags(ibfd
);
2375 flags
&= bfd_applicable_file_flags(obfd
);
2377 assert(bfd_set_start_address(obfd
, start
)
2378 && bfd_set_file_flags(obfd
, flags
));
2380 enum bfd_architecture iarch
= bfd_get_arch(ibfd
);
2381 unsigned int imach
= bfd_get_mach(ibfd
);
2382 assert(bfd_set_arch_mach(obfd
, iarch
, imach
));
2383 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2385 /* BFD mandates that all output sections be created and sizes set before
2386 any output is done. Thus, we traverse all sections multiple times. */
2387 bfd_map_over_sections(ibfd
, setup_section
, obfd
);
2389 struct supersect
*new_supersects
= fetch_superbfd(ibfd
)->new_supersects
;
2390 struct supersect
*ss
;
2391 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2392 setup_new_section(obfd
, ss
);
2394 /* Mark symbols used in output relocations so that they
2395 are kept, even if they are local labels or static symbols.
2397 Note we iterate over the input sections examining their
2398 relocations since the relocations for the output sections
2399 haven't been set yet. mark_symbols_used_in_relocations will
2400 ignore input sections which have no corresponding output
2403 bfd_map_over_sections(ibfd
, mark_symbols_used_in_relocations
, NULL
);
2404 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2405 ss_mark_symbols_used_in_relocations(ss
);
2406 struct asymbolp_vec osyms
;
2408 filter_symbols(ibfd
, obfd
, &osyms
, &fetch_superbfd(ibfd
)->syms
);
2409 copy_symbols(&osyms
, &fetch_superbfd(ibfd
)->new_syms
);
2411 bfd_set_symtab(obfd
, osyms
.data
, osyms
.size
);
2413 /* This has to happen after the symbol table has been set. */
2414 bfd_map_over_sections(obfd
, write_section
, NULL
);
2416 /* Allow the BFD backend to copy any private data it understands
2417 from the input BFD to the output BFD. This is done last to
2418 permit the routine to look at the filtered symbol table, which is
2419 important for the ECOFF code at least. */
2420 assert(bfd_copy_private_bfd_data(ibfd
, obfd
));
2425 /* Modified function from GNU Binutils objcopy.c */
2426 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
)
2428 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
2429 struct supersect
*ss
= fetch_supersect(isbfd
, isection
);
2430 bfd
*obfd
= obfdarg
;
2436 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2437 assert(osection
!= NULL
);
2439 osection
->userdata
= ss
;
2440 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2441 ss
->symbol
= osection
->symbol
;
2442 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2444 vma
= bfd_section_vma(ibfd
, isection
);
2445 assert(bfd_set_section_vma(obfd
, osection
, vma
));
2447 osection
->lma
= isection
->lma
;
2448 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2449 osection
->entsize
= ss
->entsize
;
2450 osection
->output_section
= osection
;
2451 osection
->output_offset
= 0;
2452 isection
->output_section
= osection
;
2453 isection
->output_offset
= 0;
2457 void setup_new_section(bfd
*obfd
, struct supersect
*ss
)
2459 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2460 assert(osection
!= NULL
);
2461 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2463 osection
->userdata
= ss
;
2464 ss
->symbol
= osection
->symbol
;
2465 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2466 assert(bfd_set_section_vma(obfd
, osection
, 0));
2469 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2470 osection
->entsize
= ss
->entsize
;
2471 osection
->output_section
= osection
;
2472 osection
->output_offset
= 0;
2475 static int compare_reloc_addresses(const void *aptr
, const void *bptr
)
2477 const arelent
*const *a
= aptr
, *const *b
= bptr
;
2478 return (*a
)->address
- (*b
)->address
;
2481 static void delete_obsolete_relocs(struct supersect
*ss
)
2483 if (ss
->new_relocs
.size
== 0)
2486 qsort(ss
->relocs
.data
, ss
->relocs
.size
, sizeof(*ss
->relocs
.data
),
2487 compare_reloc_addresses
);
2488 qsort(ss
->new_relocs
.data
, ss
->new_relocs
.size
,
2489 sizeof(*ss
->new_relocs
.data
), compare_reloc_addresses
);
2491 struct arelentp_vec orig_relocs
;
2492 vec_move(&orig_relocs
, &ss
->relocs
);
2494 arelent
**relocp
, **new_relocp
= ss
->new_relocs
.data
;
2495 for (relocp
= orig_relocs
.data
;
2496 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
2497 while (new_relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
&&
2498 (*new_relocp
)->address
< (*relocp
)->address
)
2500 arelent
*reloc
= *relocp
, *new_reloc
= *new_relocp
;
2501 if (new_relocp
== ss
->new_relocs
.data
+ ss
->new_relocs
.size
||
2502 reloc
->address
!= new_reloc
->address
)
2503 *vec_grow(&ss
->relocs
, 1) = reloc
;
2507 void write_section(bfd
*obfd
, asection
*osection
, void *arg
)
2509 struct supersect
*ss
= osection
->userdata
;
2511 if ((ss
->flags
& SEC_GROUP
) != 0 || ss
->contents
.size
== 0)
2514 delete_obsolete_relocs(ss
);
2517 char *error_message
;
2518 for (relocp
= ss
->new_relocs
.data
;
2519 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2521 if (bfd_get_arch(obfd
) == bfd_arch_arm
)
2522 val
= osection
->use_rela_p
? 0 : (*relocp
)->addend
;
2525 bfd_put(bfd_get_reloc_size((*relocp
)->howto
) * 8, obfd
, val
,
2526 ss
->contents
.data
+ (*relocp
)->address
);
2527 if (bfd_install_relocation(obfd
, *relocp
, ss
->contents
.data
,
2528 0, osection
, &error_message
) !=
2530 err(ss
->parent
, "ksplice: error installing reloc: %s",
2534 if (mode("finalize")) {
2535 /* Check that all our sections will be allocated */
2536 asymbol
*sym
= *((*relocp
)->sym_ptr_ptr
);
2537 if (!bfd_is_const_section(sym
->section
)) {
2538 struct supersect
*sym_ss
=
2539 fetch_supersect(ss
->parent
, sym
->section
);
2540 assert((sym_ss
->flags
& SEC_ALLOC
) != 0);
2544 memcpy(vec_grow(&ss
->relocs
, ss
->new_relocs
.size
), ss
->new_relocs
.data
,
2545 ss
->new_relocs
.size
* sizeof(*ss
->new_relocs
.data
));
2547 bfd_set_reloc(obfd
, osection
,
2548 ss
->relocs
.size
== 0 ? NULL
: ss
->relocs
.data
,
2551 if (ss
->flags
& SEC_HAS_CONTENTS
)
2552 assert(bfd_set_section_contents
2553 (obfd
, osection
, ss
->contents
.data
, 0,
2554 ss
->contents
.size
));
2557 /* Modified function from GNU Binutils objcopy.c
2559 * Mark all the symbols which will be used in output relocations with
2560 * the BSF_KEEP flag so that those symbols will not be stripped.
2562 * Ignore relocations which will not appear in the output file.
2564 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
2567 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2568 if (isection
->output_section
== NULL
)
2571 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2572 ss_mark_symbols_used_in_relocations(ss
);
2575 void ss_mark_symbols_used_in_relocations(struct supersect
*ss
)
2577 /* Examine each symbol used in a relocation. If it's not one of the
2578 special bfd section symbols, then mark it with BSF_KEEP. */
2580 for (relocp
= ss
->relocs
.data
;
2581 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2582 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2583 if (!(bfd_is_const_section(sym
->section
) &&
2584 sym
== sym
->section
->symbol
))
2585 sym
->flags
|= BSF_KEEP
;
2587 for (relocp
= ss
->new_relocs
.data
;
2588 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2589 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2590 if (!(bfd_is_const_section(sym
->section
) &&
2591 sym
== sym
->section
->symbol
))
2592 sym
->flags
|= BSF_KEEP
;
2596 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
)
2598 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2599 if (bfd_is_const_section(sym
->section
))
2601 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
2604 for (symp
= ss
->syms
.data
; symp
< ss
->syms
.data
+ ss
->syms
.size
; symp
++) {
2608 return symp
>= ss
->syms
.data
+ ss
->syms
.size
&&
2609 (sym
->flags
& BSF_SECTION_SYM
) == 0;
2612 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
2613 struct asymbolp_vec
*isyms
)
2616 struct superbfd
*sbfd
= fetch_superbfd(ibfd
);
2617 for (symp
= isyms
->data
; symp
< isyms
->data
+ isyms
->size
; symp
++) {
2618 asymbol
*sym
= *symp
;
2619 struct supersect
*sym_ss
= NULL
;
2620 struct span
*sym_span
= NULL
;
2621 if (!bfd_is_const_section(sym
->section
)) {
2622 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2623 sym_span
= find_span(sym_ss
, sym
->value
);
2626 if (mode("keep") && (sym
->flags
& BSF_GLOBAL
) != 0 &&
2627 !(mode("keep-new-code") && sym_span
!= NULL
&&
2629 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2631 if (mode("finalize") && (sym
->flags
& BSF_GLOBAL
) != 0)
2632 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2634 bool keep
= bfd_is_const_section(sym
->section
) ||
2635 (sym_ss
->keep
&& (sym
->flags
& BSF_SECTION_SYM
) != 0) ||
2636 (sym_span
!= NULL
&& sym_span
->keep
);
2637 if (bfd_is_und_section(sym
->section
) &&
2638 (sym
->flags
& BSF_KEEP
) == 0)
2640 if (bfd_is_abs_section(sym
->section
) &&
2641 (sym
->flags
& BSF_KEEP
) == 0 &&
2642 (sym
->flags
& BSF_FILE
) == 0)
2644 if (deleted_table_section_symbol(ibfd
, sym
))
2647 if (mode("keep-old-code") && sym_ss
!= NULL
&&
2648 sym_ss
->type
== SS_TYPE_EXPORT
)
2652 if (sym_ss
!= NULL
&& !sym_ss
->keep
) {
2653 err(sbfd
, "Kept symbol %s in unkept section "
2654 "%s\n", sym
->name
, sym
->section
->name
);
2657 *vec_grow(osyms
, 1) = sym
;
2662 static bool is_table_section(const char *name
, bool consider_other
,
2665 struct supersect
*tables_ss
=
2666 fetch_supersect(offsets_sbfd
,
2667 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2668 ".ksplice_table_sections"));
2669 const struct table_section
*ts
;
2670 for (ts
= tables_ss
->contents
.data
;
2671 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2673 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0)
2675 const char *osect_name
= read_string(tables_ss
,
2677 if (consider_other
&& osect_name
!= NULL
&&
2678 strcmp(name
, osect_name
) == 0)
2680 const char *crc_name
= read_string(tables_ss
, &ts
->crc_sect
);
2681 if (consider_crc
&& crc_name
!= NULL
&&
2682 strcmp(name
, crc_name
) == 0)
2688 const struct table_section
*get_table_section(const char *name
)
2690 struct supersect
*tables_ss
=
2691 fetch_supersect(offsets_sbfd
,
2692 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2693 ".ksplice_table_sections"));
2694 const struct table_section
*ts
;
2695 for (ts
= tables_ss
->contents
.data
;
2696 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2698 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0) {
2699 if (ts
->entry_contents_size
!= 0)
2700 assert(align(ts
->entry_contents_size
,
2703 struct table_section
*ns
= malloc(sizeof(*ns
));
2705 ns
->sect
= read_string(tables_ss
, &ts
->sect
);
2706 ns
->crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2708 read_string(tables_ss
, &ts
->other_sect
);
2715 enum supersect_type
supersect_type(struct supersect
*ss
)
2717 if (mode("finalize") &&
2718 strcmp(finalize_target
, "vmlinux") == 0 &&
2719 (strstarts(ss
->name
, ".ksplice_relocs.exit") ||
2720 strstarts(ss
->name
, ".ksplice_sections.exit") ||
2721 strstarts(ss
->name
, ".ksplice_patches.exit")))
2722 return SS_TYPE_EXIT
;
2723 if (strstarts(ss
->name
, ".ksplice_call"))
2724 return SS_TYPE_KSPLICE_CALL
;
2725 if (strstarts(ss
->name
, ".ksplice_extract"))
2726 return SS_TYPE_KSPLICE_EXTRACT
;
2727 if (strstarts(ss
->name
, ".ksplice_options"))
2728 return SS_TYPE_SPECIAL
;
2729 if (strstarts(ss
->name
, ".ksplice"))
2730 return SS_TYPE_KSPLICE
;
2732 if (strstarts(ss
->name
, ".init"))
2733 return SS_TYPE_IGNORED
;
2734 if (strstarts(ss
->name
, ".security_initcall.init"))
2735 return SS_TYPE_IGNORED
;
2736 if (strstarts(ss
->name
, ".con_initcall.init"))
2737 return SS_TYPE_IGNORED
;
2738 if (strstarts(ss
->name
, ".x86cpuvendor.init"))
2739 return SS_TYPE_IGNORED
;
2740 if (strstarts(ss
->name
, ".early_param.init"))
2741 return SS_TYPE_IGNORED
;
2742 if (strstarts(ss
->name
, ".taglist.init"))
2743 return SS_TYPE_IGNORED
;
2744 if (strstarts(ss
->name
, ".x86_cpu_dev.init"))
2745 return SS_TYPE_IGNORED
;
2746 if (strstarts(ss
->name
, ".arch.info.init"))
2747 return SS_TYPE_IGNORED
;
2748 if (strstarts(ss
->name
, ".proc.info.init"))
2749 return SS_TYPE_IGNORED
;
2750 /* .pci_fixup_* sections really should be treated as global rodata
2751 referenced only from quirks.c */
2752 if (strstarts(ss
->name
, ".pci_fixup_"))
2753 return SS_TYPE_IGNORED
;
2754 /* .builtin_fw sections are similar to .pci_fixup */
2755 if (strstarts(ss
->name
, ".builtin_fw"))
2756 return SS_TYPE_IGNORED
;
2757 /* same for .tracedata */
2758 if (strstarts(ss
->name
, ".tracedata"))
2759 return SS_TYPE_IGNORED
;
2760 if (strstarts(ss
->name
, ".debug"))
2761 return SS_TYPE_IGNORED
;
2762 /* .eh_frame should probably be discarded, not ignored */
2763 if (strstarts(ss
->name
, ".eh_frame"))
2764 return SS_TYPE_IGNORED
;
2765 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devinit"))
2766 return SS_TYPE_IGNORED
;
2767 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".meminit"))
2768 return SS_TYPE_IGNORED
;
2769 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuinit"))
2770 return SS_TYPE_IGNORED
;
2771 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devexit"))
2772 return SS_TYPE_IGNORED
;
2773 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".memexit"))
2774 return SS_TYPE_IGNORED
;
2775 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuexit"))
2776 return SS_TYPE_IGNORED
;
2777 if (strstarts(ss
->name
, ".vgetcpu_mode") ||
2778 strstarts(ss
->name
, ".jiffies") ||
2779 strstarts(ss
->name
, ".wall_jiffies") ||
2780 strstarts(ss
->name
, ".vxtime") ||
2781 strstarts(ss
->name
, ".sys_tz") ||
2782 strstarts(ss
->name
, ".sysctl_vsyscall") ||
2783 strstarts(ss
->name
, ".xtime") ||
2784 strstarts(ss
->name
, ".xtime_lock") ||
2785 strstarts(ss
->name
, ".vsyscall"))
2786 return SS_TYPE_IGNORED
;
2787 if (strstarts(ss
->name
, ".vdso"))
2788 return SS_TYPE_IGNORED
;
2790 if (strstarts(ss
->name
, ".exit.text"))
2791 return SS_TYPE_TEXT
;
2792 if (strstarts(ss
->name
, ".exit.data"))
2793 return SS_TYPE_DATA
;
2795 if (strstarts(ss
->name
, ".text") ||
2796 strstarts(ss
->name
, ".kernel.text") ||
2797 strstarts(ss
->name
, ".devinit.text") ||
2798 strstarts(ss
->name
, ".meminit.text") ||
2799 strstarts(ss
->name
, ".cpuinit.text") ||
2800 strstarts(ss
->name
, ".devexit.text") ||
2801 strstarts(ss
->name
, ".memexit.text") ||
2802 strstarts(ss
->name
, ".cpuexit.text") ||
2803 strstarts(ss
->name
, ".ref.text") ||
2804 strstarts(ss
->name
, ".spinlock.text") ||
2805 strstarts(ss
->name
, ".kprobes.text") ||
2806 strstarts(ss
->name
, ".sched.text") ||
2807 strstarts(ss
->name
, ".entry.text") || /* OpenVZ */
2808 (mode("keep-old-code") && strstarts(ss
->name
, ".fixup")))
2809 return SS_TYPE_TEXT
;
2812 if (sscanf(ss
->name
, ".rodata.str%*u.%*u%n", &n
) >= 0 &&
2813 n
== strlen(ss
->name
))
2814 return ss
->entsize
== 1 ? SS_TYPE_STRING
: SS_TYPE_RODATA
;
2816 if (strstarts(ss
->name
, ".rodata") ||
2817 strstarts(ss
->name
, ".kernel.rodata") ||
2818 strstarts(ss
->name
, ".devinit.rodata") ||
2819 strstarts(ss
->name
, ".meminit.rodata") ||
2820 strstarts(ss
->name
, ".cpuinit.rodata") ||
2821 strstarts(ss
->name
, ".devexit.rodata") ||
2822 strstarts(ss
->name
, ".memexit.rodata") ||
2823 strstarts(ss
->name
, ".cpuexit.rodata") ||
2824 strstarts(ss
->name
, ".ref.rodata") ||
2825 strstarts(ss
->name
, "__tracepoints_strings") ||
2826 strstarts(ss
->name
, "__markers_strings") ||
2827 (mode("keep-old-code") && strstarts(ss
->name
, "__ex_table")))
2828 return SS_TYPE_RODATA
;
2830 if (strstarts(ss
->name
, ".bss"))
2831 return SS_TYPE_DATA
;
2833 /* Ignore .data.percpu sections */
2834 if (strstarts(ss
->name
, ".data.percpu") ||
2835 strstarts(ss
->name
, ".kernel.data.percpu") ||
2836 strstarts(ss
->name
, ".data..percpu"))
2837 return SS_TYPE_IGNORED
;
2838 if (strstarts(ss
->name
, ".data") ||
2839 strstarts(ss
->name
, ".kernel.data") ||
2840 strstarts(ss
->name
, ".devinit.data") ||
2841 strstarts(ss
->name
, ".cpuinit.data") ||
2842 strstarts(ss
->name
, ".meminit.data") ||
2843 strstarts(ss
->name
, ".devexit.data") ||
2844 strstarts(ss
->name
, ".memexit.data") ||
2845 strstarts(ss
->name
, ".cpuexit.data") ||
2846 strstarts(ss
->name
, ".ref.data") ||
2847 strstarts(ss
->name
, "__tracepoints") ||
2848 strstarts(ss
->name
, "__markers"))
2849 return SS_TYPE_DATA
;
2851 /* We replace all the ksymtab strings, so delete them */
2852 if (strcmp(ss
->name
, "__ksymtab_strings") == 0)
2853 return SS_TYPE_STRING
;
2854 if (strstarts(ss
->name
, "__ksymtab"))
2855 return SS_TYPE_EXPORT
;
2857 if (strstarts(ss
->name
, "__bug_table"))
2858 return SS_TYPE_BUGTABLE
;
2860 if (is_table_section(ss
->name
, true, true))
2861 return SS_TYPE_SPECIAL
;
2863 if (strstarts(ss
->name
, ".ARM."))
2864 return SS_TYPE_SPECIAL
;
2866 if (strstarts(ss
->name
, ".note"))
2867 return SS_TYPE_IGNORED
;
2868 if (strstarts(ss
->name
, ".comment"))
2869 return SS_TYPE_IGNORED
;
2870 if (strstarts(ss
->name
, "__param"))
2871 return SS_TYPE_IGNORED
;
2872 if (strstarts(ss
->name
, "__obsparm"))
2873 return SS_TYPE_IGNORED
;
2874 if (strstarts(ss
->name
, ".exitcall.exit"))
2875 return SS_TYPE_IGNORED
;
2876 if (strstarts(ss
->name
, ".modinfo"))
2877 return SS_TYPE_IGNORED
;
2879 return SS_TYPE_UNKNOWN
;
2882 void initialize_supersect_types(struct superbfd
*sbfd
)
2885 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2886 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2887 ss
->type
= supersect_type(ss
);
2888 ss
->orig_type
= ss
->type
;
2889 if (ss
->type
== SS_TYPE_UNKNOWN
) {
2890 err(sbfd
, "Unknown section type: %s\n", ss
->name
);
2896 static void init_label_map(struct superbfd
*sbfd
)
2898 struct label_map
*map
;
2900 vec_init(&sbfd
->maps
);
2904 struct symbol_hash csyms
;
2905 symbol_hash_init(&csyms
);
2908 for (symp
= sbfd
->syms
.data
;
2909 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2910 asymbol
*csym
= canonical_symbol(sbfd
, *symp
);
2913 char *key
= strprintf("%p", csym
);
2914 asymbol
**csymp
= symbol_hash_lookup(&csyms
, key
, TRUE
);
2920 map
= vec_grow(&sbfd
->maps
, 1);
2923 map
->label
= symbol_label(sbfd
, csym
);
2926 struct label_mapp_hash label_maps
;
2927 label_mapp_hash_init(&label_maps
);
2928 for (map
= sbfd
->maps
.data
;
2929 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2930 struct label_map
**mapp
=
2931 label_mapp_hash_lookup(&label_maps
, map
->label
, TRUE
);
2932 if (*mapp
== NULL
) {
2937 struct label_map
*first_map
= *mapp
;
2938 if (first_map
->count
== 0)
2939 first_map
->label
= strprintf("%s~%d", map
->label
, 0);
2940 map
->label
= strprintf("%s~%d", map
->label
, ++first_map
->count
);
2943 label_mapp_hash_init(&sbfd
->maps_hash
);
2944 for (map
= sbfd
->maps
.data
;
2945 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2946 char *key
= strprintf("%p", map
->csym
);
2947 struct label_map
**mapp
=
2948 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, TRUE
);
2951 map
->orig_label
= map
->label
;
2955 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
)
2957 asymbol
*csym
= canonical_symbol(sbfd
, sym
);
2958 char *key
= strprintf("%p", csym
);
2959 struct label_map
**mapp
=
2960 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2964 return (*mapp
)->label
;
2967 static void print_label_changes(struct superbfd
*sbfd
)
2971 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2972 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2973 for (span
= ss
->spans
.data
;
2974 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
2975 if (strcmp(span
->label
, span
->orig_label
) != 0)
2976 debug1(sbfd
, "Label change: %s -> %s\n",
2977 span
->label
, span
->orig_label
);
2982 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
2985 struct label_map
*map
;
2986 for (map
= sbfd
->maps
.data
;
2987 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2988 if (strcmp(map
->orig_label
, oldlabel
) == 0) {
2989 if (strcmp(map
->orig_label
, map
->label
) != 0 &&
2990 strcmp(map
->label
, label
) != 0)
2999 static void change_initial_label(struct span
*span
, const char *label
)
3001 struct superbfd
*sbfd
= span
->ss
->parent
;
3002 span
->label
= label
;
3003 span
->orig_label
= label
;
3005 asymbol
*csym
= canonical_symbol(sbfd
, span
->symbol
);
3006 char *key
= strprintf("%p", csym
);
3007 struct label_map
**mapp
=
3008 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
3011 (*mapp
)->label
= span
->label
;
3012 (*mapp
)->orig_label
= span
->orig_label
;
3013 span
->symbol
= NULL
;
3017 static void init_callers(struct superbfd
*sbfd
)
3019 string_hash_init(&sbfd
->callers
);
3021 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3022 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3024 for (relocp
= ss
->relocs
.data
;
3025 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3026 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
3028 sym
->value
+ reloc_target_offset(ss
, *relocp
);
3029 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3031 const char **ret
= string_hash_lookup(&sbfd
->callers
,
3034 asymbol
*csym
= canonical_symbol(sbfd
, sect
->symbol
);
3036 *ret
= "*multiple_callers*";
3037 else if (static_local_symbol(sbfd
, csym
))
3038 *ret
= static_local_symbol(sbfd
, csym
);
3045 static const char *find_caller(struct supersect
*ss
, asymbol
*sym
)
3047 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3048 (unsigned long)sym
->value
);
3049 const char **ret
= string_hash_lookup(&ss
->parent
->callers
, key
, FALSE
);
3053 return "*no_caller*";
3057 static void init_csyms(struct superbfd
*sbfd
)
3059 asymbolpp_hash_init(&sbfd
->csyms
);
3062 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
3064 asymbol
*sym
= *symp
;
3065 if ((sym
->flags
& BSF_DEBUGGING
) != 0)
3067 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3068 (unsigned long)sym
->value
);
3069 asymbol
***csympp
= asymbolpp_hash_lookup(&sbfd
->csyms
, key
,
3072 if (*csympp
== NULL
) {
3076 asymbol
*csym
= **csympp
;
3077 if ((csym
->flags
& BSF_GLOBAL
) != 0)
3079 if ((sym
->flags
& BSF_GLOBAL
) != 0)
3084 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
)
3086 char *key
= strprintf("%s+%lx", ss
->name
, (unsigned long)value
);
3088 asymbolpp_hash_lookup(&ss
->parent
->csyms
, key
, FALSE
);
3093 /* For section symbols of sections containing no symbols, return the
3094 section symbol that relocations are generated against */
3100 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
)
3102 if (bfd_is_const_section(sym
->section
)) {
3104 for (csymp
= sbfd
->syms
.data
;
3105 csymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; csymp
++) {
3111 return symbolp_scan(fetch_supersect(sbfd
, sym
->section
), sym
->value
);
3114 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3116 if (bfd_is_const_section(sym
->section
))
3118 asymbol
**symp
= canonical_symbolp(sbfd
, sym
);
3119 return symp
!= NULL
? *symp
: NULL
;
3122 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3124 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
3125 if ((sym
->flags
& BSF_LOCAL
) == 0 || (sym
->flags
& BSF_OBJECT
) == 0)
3127 char *dot
= strrchr(sym
->name
, '.');
3128 if (dot
== NULL
|| dot
[1 + strspn(dot
+ 1, "0123546789")] != '\0')
3130 char *basename
= strndup(sym
->name
, dot
- sym
->name
);
3132 /* Handle C.123.12345 symbols */
3133 dot
= strrchr(basename
, '.');
3134 if (dot
!= NULL
&& dot
[1 + strspn(dot
+ 1, "0123546789")] == '\0')
3135 basename
= strndup(basename
, dot
- basename
);
3137 if (strcmp(basename
, "__func__") == 0 ||
3138 strcmp(basename
, "__PRETTY_FUNCTION__") == 0)
3139 caller
= (const char *)ss
->contents
.data
+ sym
->value
;
3141 caller
= find_caller(ss
, sym
);
3142 return strprintf("%s<%s>", basename
, caller
);
3145 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
)
3147 const char *filename
= sbfd
->abfd
->filename
;
3148 char *c
= strstr(filename
, ".KSPLICE");
3149 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
3152 if (bfd_is_und_section(sym
->section
) || (sym
->flags
& BSF_GLOBAL
) != 0) {
3153 label
= strdup(sym
->name
);
3154 } else if (bfd_is_const_section(sym
->section
)) {
3155 label
= strprintf("%s<%.*s>", sym
->name
, flen
, filename
);
3157 asymbol
*gsym
= canonical_symbol(sbfd
, sym
);
3160 label
= strprintf("%s+%lx<%.*s>",
3162 (unsigned long)sym
->value
,
3164 else if ((gsym
->flags
& BSF_GLOBAL
) != 0)
3165 label
= strdup(gsym
->name
);
3166 else if (static_local_symbol(sbfd
, gsym
))
3167 label
= strprintf("%s+%lx<%.*s>",
3168 static_local_symbol(sbfd
, gsym
),
3169 (unsigned long)sym
->value
,
3172 label
= strprintf("%s<%.*s>",
3173 gsym
->name
, flen
, filename
);
3179 static void keep_span(struct span
*span
)
3182 span
->ss
->keep
= true;
3185 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
)
3187 struct span
*span
= vec_grow(&ss
->spans
, 1);
3189 span
->contents_size
= size
;
3190 span
->start
= start
;
3194 span
->patch
= false;
3195 span
->bugpatch
= false;
3196 span
->datapatch
= false;
3197 span
->precallable
= strstarts(ss
->name
, ".ksplice_call_pre_apply") ||
3198 strstarts(ss
->name
, ".ksplice_call_check_apply") ||
3199 strstarts(ss
->name
, ".ksplice_call_fail_apply") ||
3200 strstarts(ss
->name
, ".ksplice_call_post_remove");
3202 vec_init(&span
->entry_points
);
3204 asymbol
**symp
= symbolp_scan(ss
, span
->start
);
3206 span
->symbol
= *symp
;
3207 span
->label
= label_lookup(ss
->parent
, span
->symbol
);
3209 span
->symbol
= NULL
;
3210 const char *label
= label_lookup(ss
->parent
, ss
->symbol
);
3211 if (span
->start
!= 0)
3212 span
->label
= strprintf("%s<span:%lx>", label
,
3213 (unsigned long)span
->start
);
3215 span
->label
= label
;
3217 span
->orig_label
= span
->label
;
3221 static void initialize_string_spans(struct supersect
*ss
)
3224 for (str
= ss
->contents
.data
;
3225 (void *)str
< ss
->contents
.data
+ ss
->contents
.size
;) {
3226 bfd_vma start
= (unsigned long)str
-
3227 (unsigned long)ss
->contents
.data
;
3228 bfd_vma size
= strlen(str
) + 1;
3229 bfd_vma contents_size
= size
;
3230 while ((start
+ size
) % (1 << ss
->alignment
) != 0 &&
3231 start
+ size
< ss
->contents
.size
) {
3232 /* Some string sections, like __ksymtab_strings, only
3233 align some strings with the declared alignment */
3234 if (str
[size
] != '\0')
3238 struct span
*span
= new_span(ss
, start
, size
);
3239 span
->contents_size
= contents_size
;
3244 static int compare_ulongs(const void *va
, const void *vb
)
3246 const unsigned long *a
= va
, *b
= vb
;
3250 static void initialize_table_spans(struct superbfd
*sbfd
,
3251 struct table_section
*s
)
3253 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
3254 if (isection
== NULL
)
3256 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
3257 if (ss
->alignment
< ffs(s
->entry_align
) - 1)
3258 ss
->alignment
= ffs(s
->entry_align
) - 1;
3260 asection
*other_sect
= NULL
;
3261 if (s
->other_sect
!= NULL
)
3262 other_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->other_sect
);
3263 struct supersect
*other_ss
= NULL
;
3264 if (other_sect
!= NULL
)
3265 other_ss
= fetch_supersect(sbfd
, other_sect
);
3267 asection
*crc_sect
= NULL
;
3268 if (s
->crc_sect
!= NULL
)
3269 crc_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->crc_sect
);
3270 struct supersect
*crc_ss
= NULL
;
3271 if (crc_sect
!= NULL
)
3272 crc_ss
= fetch_supersect(sbfd
, crc_sect
);
3274 struct ulong_vec offsets
;
3278 for (entry
= ss
->contents
.data
;
3279 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3280 entry
+= s
->entry_size
) {
3281 struct span
*span
= new_span(ss
, addr_offset(ss
, entry
),
3283 if (s
->entry_contents_size
!= 0)
3284 span
->contents_size
= s
->entry_contents_size
;
3285 if ((span
->symbol
== NULL
||
3286 (span
->symbol
->flags
& BSF_SECTION_SYM
) != 0) &&
3288 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
3290 struct span
*target_span
= reloc_target_span(ss
, reloc
);
3291 assert(target_span
);
3292 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3293 unsigned long val
= sym
->value
+
3294 reloc_target_offset(ss
, reloc
) -
3295 (target_span
->start
+ target_span
->shift
);
3296 char *label
= strprintf("%s<target:%s+%lx>", ss
->name
,
3297 target_span
->label
, val
);
3298 change_initial_label(span
, label
);
3301 if (other_sect
!= NULL
) {
3303 bfd_vma offset
= read_reloc(ss
, entry
+ s
->other_offset
,
3304 sizeof(void *), &sym
);
3305 if (sym
->section
== other_sect
) {
3306 assert(offset
>= 0 &&
3307 offset
< other_ss
->contents
.size
);
3308 *vec_grow(&offsets
, 1) = offset
;
3312 if (crc_sect
!= NULL
)
3313 new_span(crc_ss
, addr_offset(ss
, entry
) / s
->entry_size
3314 * s
->crc_size
, s
->crc_size
);
3316 if (ss
->type
== SS_TYPE_EXPORT
) {
3317 const char *symname
= read_string(ss
, entry
+
3319 char *label
= strprintf("%s:%s", ss
->name
, symname
);
3320 change_initial_label(span
, label
);
3324 if (other_sect
== NULL
)
3327 *vec_grow(&offsets
, 1) = 0;
3328 qsort(offsets
.data
, offsets
.size
, sizeof(*offsets
.data
),
3330 *vec_grow(&offsets
, 1) = other_ss
->contents
.size
;
3333 for (off
= offsets
.data
; off
< offsets
.data
+ offsets
.size
- 1; off
++) {
3334 if (*off
!= *(off
+ 1))
3335 new_span(other_ss
, *off
, *(off
+ 1) - *off
);
3339 static void initialize_table_section_spans(struct superbfd
*sbfd
)
3341 struct supersect
*tables_ss
=
3342 fetch_supersect(offsets_sbfd
,
3343 bfd_get_section_by_name(offsets_sbfd
->abfd
,
3344 ".ksplice_table_sections"));
3345 const struct table_section
*ts
;
3346 struct table_section s
;
3347 for (ts
= tables_ss
->contents
.data
;
3348 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
3351 s
.sect
= read_string(tables_ss
, &ts
->sect
);
3352 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
3353 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
3354 initialize_table_spans(sbfd
, &s
);
3358 static void initialize_ksplice_call_spans(struct supersect
*ss
)
3361 for (relocp
= ss
->relocs
.data
;
3362 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3363 arelent
*reloc
= *relocp
;
3364 new_span(ss
, reloc
->address
, bfd_get_reloc_size(reloc
->howto
));
3365 /* the span labels should already be unique */
3369 static void initialize_spans(struct superbfd
*sbfd
)
3372 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3373 if (is_table_section(sect
->name
, true, true) && mode("keep"))
3376 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3377 if (ss
->type
== SS_TYPE_STRING
)
3378 initialize_string_spans(ss
);
3379 else if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
3380 initialize_ksplice_call_spans(ss
);
3382 new_span(ss
, 0, ss
->contents
.size
);
3385 initialize_table_section_spans(sbfd
);
3388 /* Returns the span pointed to by the relocation at span->start + offset */
3389 static struct span
*span_offset_target_span(struct span
*span
, int offset
)
3391 void *entry
= span
->ss
->contents
.data
+ span
->start
;
3392 arelent
*reloc
= find_reloc(span
->ss
, entry
+ offset
);
3395 return reloc_target_span(span
->ss
, reloc
);
3398 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
)
3400 asymbol
*sym_ptr
= *reloc
->sym_ptr_ptr
;
3401 if (bfd_is_const_section(sym_ptr
->section
))
3404 bfd_vma addend
= sym_ptr
->value
;
3405 if ((sym_ptr
->flags
& BSF_SECTION_SYM
) != 0)
3406 addend
+= reloc_target_offset(ss
, reloc
);
3408 struct supersect
*sym_ss
=
3409 fetch_supersect(ss
->parent
, sym_ptr
->section
);
3410 struct span
*span
, *target_span
= sym_ss
->spans
.data
;
3411 for (span
= sym_ss
->spans
.data
;
3412 span
< sym_ss
->spans
.data
+ sym_ss
->spans
.size
; span
++) {
3413 if (addend
>= span
->start
&& addend
< span
->start
+ span
->size
)
3419 static bfd_vma
reloc_target_offset(struct supersect
*ss
, arelent
*reloc
)
3421 bfd_vma offset
= reloc_offset(ss
, reloc
);
3422 if (reloc
->howto
->pc_relative
) {
3423 if ((ss
->flags
& SEC_CODE
) != 0)
3424 return offset
+ bfd_get_reloc_size(reloc
->howto
);
3426 const struct table_section
*ts
= get_table_section(ss
->name
);
3427 if (ts
!= NULL
&& ts
->relative_addr
&&
3428 reloc
->address
% ts
->entry_size
== ts
->addr_offset
)
3429 return offset
- ts
->addr_offset
;
3430 if (ts
!= NULL
&& ts
->relative_other
&&
3431 reloc
->address
% ts
->entry_size
== ts
->other_offset
)
3432 return offset
- ts
->other_offset
;
3439 struct span
*find_span(struct supersect
*ss
, bfd_size_type address
)
3442 for (span
= ss
->spans
.data
; span
< ss
->spans
.data
+ ss
->spans
.size
;
3444 if (address
>= span
->start
&&
3445 address
< span
->start
+ span
->size
)
3448 /* Deal with empty BSS sections */
3449 if (ss
->contents
.size
== 0 && ss
->spans
.size
> 0)
3450 return ss
->spans
.data
;
3451 /* Deal with section end pointers */
3452 if (address
== ss
->contents
.size
&& ss
->spans
.size
== 1)
3453 return ss
->spans
.data
;
3457 void compute_span_shifts(struct superbfd
*sbfd
)
3461 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3462 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3465 bfd_size_type offset
= 0;
3466 for (span
= ss
->spans
.data
;
3467 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
3470 span
->shift
= offset
- span
->start
;
3471 offset
+= span
->size
;
3476 void remove_unkept_spans(struct superbfd
*sbfd
)
3480 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3481 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3482 delete_obsolete_relocs(ss
);
3483 struct arelentp_vec orig_relocs
;
3484 vec_move(&orig_relocs
, &ss
->relocs
);
3485 arelent
**relocp
, *reloc
;
3486 for (relocp
= orig_relocs
.data
;
3487 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
3489 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3490 span
= reloc_target_span(ss
, reloc
);
3491 if ((span
!= NULL
&& span
->keep
&& span
->shift
== 0) ||
3492 bfd_is_const_section(sym
->section
)) {
3493 *vec_grow(&ss
->relocs
, 1) = reloc
;
3496 struct supersect
*sym_ss
=
3497 fetch_supersect(sbfd
, sym
->section
);
3498 if (span
!= NULL
&& (sym
->flags
& BSF_SECTION_SYM
) == 0
3499 && find_span(sym_ss
, sym
->value
) != span
) {
3500 err(sbfd
, "Spans for symbol %s and relocation "
3501 "target do not match in sect %s\n",
3502 sym
->name
, sym_ss
->name
);
3505 if (span
!= NULL
&& span
->keep
) {
3506 arelent
*new_reloc
= malloc(sizeof(*new_reloc
));
3507 *new_reloc
= *reloc
;
3508 new_reloc
->addend
= reloc_offset(ss
, reloc
);
3509 new_reloc
->addend
+= span
->shift
;
3510 *vec_grow(&ss
->new_relocs
, 1) = new_reloc
;
3515 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3516 struct supersect
*ss
= fetch_supersect(sbfd
, sect
), orig_ss
;
3519 supersect_move(&orig_ss
, ss
);
3520 vec_init(&ss
->spans
);
3521 for (span
= orig_ss
.spans
.data
;
3522 span
< orig_ss
.spans
.data
+ orig_ss
.spans
.size
; span
++) {
3525 struct span
*new_span
= vec_grow(&ss
->spans
, 1);
3527 new_span
->start
= span
->start
+ span
->shift
;
3528 new_span
->shift
= 0;
3529 sect_copy(ss
, sect_do_grow(ss
, 1, span
->size
, 1),
3530 &orig_ss
, orig_ss
.contents
.data
+ span
->start
,
3536 static void init_objmanip_superbfd(struct superbfd
*sbfd
)
3538 init_label_map(sbfd
);
3539 initialize_supersect_types(sbfd
);
3540 initialize_spans(sbfd
);
3542 compute_entry_points(sbfd
);
3545 void mangle_section_name(struct superbfd
*sbfd
, const char *name
)
3547 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
3550 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3551 ss
->name
= strprintf(".ksplice_pre.%s", ss
->name
);
3554 static void write_bugline_patches(struct superbfd
*sbfd
)
3556 const struct table_section
*ts
= get_table_section("__bug_table");
3557 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, "__bug_table");
3560 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3564 for (entry
= ss
->contents
.data
;
3565 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3566 entry
+= ts
->entry_size
) {
3567 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
3568 assert(span
!= NULL
);
3569 if (!span
->bugpatch
)
3571 arelent
*reloc
= find_reloc(ss
, entry
+ ts
->addr_offset
);
3572 assert(reloc
!= NULL
);
3573 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3574 assert(!bfd_is_const_section(sym
->section
));
3575 struct supersect
*kpatch_ss
=
3576 make_section(sbfd
, ".ksplice_patches%s",
3577 sym
->section
->name
);
3579 bfd_vma offset
, start
= 0;
3580 for (offset
= 0; offset
<= span
->size
; offset
++) {
3581 if (offset
!= span
->size
&&
3582 !part_of_reloc(ss
, span
->start
+ offset
))
3584 if (start
== offset
) {
3588 /* an interval of non-relocations just passed */
3589 struct ksplice_patch
*kpatch
=
3590 sect_grow(kpatch_ss
, 1, struct ksplice_patch
);
3591 write_ksplice_patch_reloc
3592 (kpatch_ss
, sym
->section
->name
, &kpatch
->oldaddr
,
3593 sizeof(kpatch
->oldaddr
), span
->label
, start
);
3595 char *data
= write_patch_storage(kpatch_ss
, kpatch
,
3596 offset
- start
, NULL
);
3597 memcpy(data
, entry
+ start
, offset
- start
);
3598 kpatch
->type
= KSPLICE_PATCH_DATA
;
3604 void *write_patch_storage(struct supersect
*ss
, struct ksplice_patch
*kpatch
,
3605 size_t size
, struct supersect
**data_ssp
)
3607 struct supersect
*data_ss
= make_section(ss
->parent
,
3608 ".ksplice_patch_data");
3609 char *saved
= sect_do_grow(data_ss
, 1, size
, 1);
3610 write_reloc(ss
, &kpatch
->saved
, &data_ss
->symbol
,
3611 addr_offset(data_ss
, saved
));
3612 char *data
= sect_do_grow(data_ss
, 1, size
, 1);
3613 write_reloc(ss
, &kpatch
->contents
, &data_ss
->symbol
,
3614 addr_offset(data_ss
, data
));
3615 kpatch
->size
= size
;
3616 if (data_ssp
!= NULL
)
3617 *data_ssp
= data_ss
;