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
;
342 err(sbfd
, "Unrecognized Ksplice option %d\n",
349 bool matchable_data_section(struct supersect
*ss
)
351 if (ss
->type
== SS_TYPE_STRING
)
353 if (ss
->type
== SS_TYPE_RODATA
)
355 if (ss
->type
== SS_TYPE_DATA
&& ss
->relocs
.size
!= 0)
357 if (ss
->type
== SS_TYPE_EXPORT
)
359 if (ss
->type
== SS_TYPE_BUGTABLE
)
364 bool unchangeable_section(struct supersect
*ss
)
366 if (ss
->type
== SS_TYPE_DATA
)
368 if (ss
->type
== SS_TYPE_IGNORED
&& !strstarts(ss
->name
, ".debug") &&
369 strcmp(ss
->name
, "__ksymtab_strings") != 0)
374 int main(int argc
, char *argv
[])
376 if (getenv("KSPLICE_VERBOSE") != NULL
)
377 verbose
= atoi(getenv("KSPLICE_VERBOSE"));
380 bfd
*ibfd
= bfd_openr(argv
[1], NULL
);
384 if (bfd_check_format_matches(ibfd
, bfd_archive
, &matching
) &&
385 bfd_openr_next_archived_file(ibfd
, NULL
) == NULL
)
386 return 66; /* empty archive */
387 assert(bfd_check_format_matches(ibfd
, bfd_object
, &matching
));
389 const char *output_target
= bfd_get_target(ibfd
);
394 bool_hash_init(&system_map_written
);
395 ulong_hash_init(&ksplice_symbol_offset
);
396 ulong_hash_init(&ksplice_howto_offset
);
397 ulong_hash_init(&ksplice_string_offset
);
399 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
402 if (mode("finalize"))
403 finalize_target
= argv
[4];
404 init_objmanip_superbfd(isbfd
);
405 if (mode("keep-new-code")) {
407 do_keep_new_code(isbfd
, argv
[4]);
408 } else if (mode("keep-old-code")) {
409 do_keep_old_code(isbfd
);
410 } else if (mode("finalize")) {
412 } else if (mode("rmsyms")) {
417 bfd
*obfd
= bfd_openw(argv
[2], output_target
);
419 copy_object(ibfd
, obfd
);
420 assert(bfd_close(obfd
));
423 if (offsets_sbfd
!= NULL
)
424 assert(bfd_close(offsets_sbfd
->abfd
));
425 assert(bfd_close(ibfd
));
429 void do_keep_new_code(struct superbfd
*isbfd
, const char *pre
)
431 struct bfd
*prebfd
= bfd_openr(pre
, NULL
);
432 assert(prebfd
!= NULL
);
434 assert(bfd_check_format_matches(prebfd
, bfd_object
, &matching
));
436 struct superbfd
*presbfd
= fetch_superbfd(prebfd
);
437 init_objmanip_superbfd(presbfd
);
439 foreach_symbol_pair(presbfd
, isbfd
, match_global_symbols
);
440 debug1(isbfd
, "Matched global\n");
441 foreach_span_pair(presbfd
, isbfd
, match_string_spans
);
442 debug1(isbfd
, "Matched string spans\n");
443 foreach_symbol_pair(presbfd
, isbfd
, match_symbol_spans
);
444 debug1(isbfd
, "Matched by name\n");
445 foreach_span_pair(presbfd
, isbfd
, match_spans_by_label
);
446 debug1(isbfd
, "Matched by label\n");
447 foreach_span_pair(presbfd
, isbfd
, match_table_spans
);
448 debug1(isbfd
, "Matched table spans\n");
449 foreach_span_pair(presbfd
, isbfd
, match_other_spans
);
450 debug1(isbfd
, "Matched other spans\n");
454 compare_matched_spans(isbfd
);
455 update_nonzero_offsets(isbfd
);
456 mark_new_spans(isbfd
);
460 foreach_symbol_pair(presbfd
, isbfd
, check_global_symbols
);
462 handle_deleted_spans(presbfd
, isbfd
);
463 handle_section_symbol_renames(presbfd
, isbfd
);
465 copy_patched_entry_points(presbfd
, isbfd
);
467 assert(bfd_close(prebfd
));
471 mark_precallable_spans(isbfd
);
475 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
476 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
479 for (span
= ss
->spans
.data
;
480 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
481 if (strstarts(ss
->name
, ".ksplice_options"))
483 else if (span
->new || span
->patch
|| span
->datapatch
)
487 if (span
->patch
&& span
->precallable
) {
488 err(isbfd
, "Patched span %s can be reached "
489 "by a precall function\n", span
->label
);
495 print_label_changes(isbfd
);
497 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
498 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
500 for (span
= ss
->spans
.data
;
501 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
502 if (span
->patch
|| span
->bugpatch
|| span
->datapatch
)
503 debug0(isbfd
, "Patching span %s\n",
508 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
509 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
511 for (span
= ss
->spans
.data
;
512 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
514 debug0(isbfd
, "New span %s\n", span
->label
);
518 write_output
= false;
519 const char **sectname
;
520 for (sectname
= delsects
.data
;
521 sectname
< delsects
.data
+ delsects
.size
; sectname
++) {
523 debug0(isbfd
, "Deleted section: %s\n", *sectname
);
526 filter_table_sections(isbfd
);
528 compute_span_shifts(isbfd
);
530 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
531 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
532 if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
535 for (span
= ss
->spans
.data
;
536 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
537 if (span
->keep
|| span
->bugpatch
)
539 if (span
->patch
|| span
->new || span
->datapatch
)
540 write_ksplice_section(span
);
541 if (span
->patch
|| span
->datapatch
)
542 write_ksplice_patches(isbfd
, span
);
543 if (ss
->type
== SS_TYPE_EXPORT
&& span
->new)
544 write_ksplice_export(isbfd
, span
, false);
548 write_bugline_patches(isbfd
);
550 remove_unkept_spans(isbfd
);
553 void do_keep_old_code(struct superbfd
*isbfd
)
556 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
557 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
560 for (span
= ss
->spans
.data
;
561 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
563 if (ss
->type
== SS_TYPE_TEXT
&&
564 !strstarts(ss
->name
, ".fixup"))
566 if (ss
->type
== SS_TYPE_EXPORT
)
572 for (symp
= isbfd
->syms
.data
;
573 symp
< isbfd
->syms
.data
+ isbfd
->syms
.size
; symp
++) {
574 asymbol
*sym
= *symp
;
575 if (!bfd_is_const_section(sym
->section
) &&
576 (sym
->flags
& BSF_GLOBAL
) != 0) {
577 struct supersect
*sym_ss
=
578 fetch_supersect(isbfd
, sym
->section
);
579 if (sym
->value
== sym_ss
->contents
.size
)
581 struct span
*span
= find_span(sym_ss
, sym
->value
);
582 assert(span
!= NULL
);
583 if (sym_ss
->type
!= SS_TYPE_IGNORED
)
590 keep_referenced_sections(isbfd
);
593 filter_table_sections(isbfd
);
594 compute_span_shifts(isbfd
);
596 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
597 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
598 asymbol
*sym
= canonical_symbol(isbfd
, sect
->symbol
);
601 if ((sym
->flags
& BSF_WEAK
) != 0)
603 if (bfd_get_section_size(sect
) == 0)
607 if (ss
->type
!= SS_TYPE_TEXT
&& !matchable_data_section(ss
))
611 for (span
= ss
->spans
.data
;
612 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
614 write_ksplice_section(span
);
618 write_table_relocs(isbfd
, "__bug_table", KSPLICE_HOWTO_BUG
);
619 write_table_relocs(isbfd
, "__ex_table", KSPLICE_HOWTO_EXTABLE
);
621 remove_unkept_spans(isbfd
);
623 mangle_section_name(isbfd
, "__markers");
624 mangle_section_name(isbfd
, "__tracepoints");
625 mangle_section_name(isbfd
, "__ex_table");
626 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
627 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
628 if (ss
->type
== SS_TYPE_EXPORT
)
629 mangle_section_name(isbfd
, ss
->name
);
633 void do_finalize(struct superbfd
*isbfd
)
635 load_ksplice_symbol_offsets(isbfd
);
637 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
638 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
639 if (ss
->type
== SS_TYPE_EXIT
) {
641 for (span
= ss
->spans
.data
;
642 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
647 write_date_relocs(isbfd
, "<{DATE...}>", KSPLICE_HOWTO_DATE
);
648 write_date_relocs(isbfd
, "<{TIME}>", KSPLICE_HOWTO_TIME
);
652 void do_rmsyms(struct superbfd
*isbfd
)
654 asection
*extract_sect
= bfd_get_section_by_name(isbfd
->abfd
,
656 if (extract_sect
!= NULL
) {
657 struct supersect
*extract_ss
= fetch_supersect(isbfd
,
660 for (relocp
= extract_ss
->relocs
.data
;
661 relocp
< extract_ss
->relocs
.data
+ extract_ss
->relocs
.size
;
663 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
664 if (bfd_is_und_section(sym
->section
)) {
665 debug1(isbfd
, "extracting symbol %s\n",
667 *vec_grow(&extract_syms
, 1) = sym
;
675 void match_spans(struct span
*old_span
, struct span
*new_span
)
677 struct superbfd
*sbfd
= new_span
->ss
->parent
;
678 if (old_span
->match
== new_span
&& new_span
->match
== old_span
)
680 if (old_span
->match
!= NULL
) {
681 err(sbfd
, "Matching conflict: old %s: %s != %s\n",
682 old_span
->label
, old_span
->match
->label
, new_span
->label
);
685 if (new_span
->match
!= NULL
) {
686 err(sbfd
, "Matching conflict: new %s: %s != %s\n",
687 new_span
->label
, new_span
->match
->label
, old_span
->label
);
690 old_span
->match
= new_span
;
691 new_span
->match
= old_span
;
692 debug1(sbfd
, "Matched old %s to new %s\n", old_span
->label
,
694 if (old_span
->ss
->type
!= new_span
->ss
->type
&&
695 old_span
->ss
->type
== new_span
->ss
->orig_type
)
696 old_span
->ss
->type
= new_span
->ss
->type
;
698 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
699 if (ts
== NULL
|| !ts
->has_addr
|| ts
->other_sect
== NULL
)
701 struct span
*old_sym_span
=
702 span_offset_target_span(old_span
, ts
->other_offset
);
703 struct span
*new_sym_span
=
704 span_offset_target_span(new_span
, ts
->other_offset
);
705 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
706 match_spans(old_sym_span
, new_sym_span
);
709 void unmatch_span(struct span
*old_span
)
711 struct span
*new_span
= old_span
->match
;
712 old_span
->match
= NULL
;
713 new_span
->match
= NULL
;
715 new_span
->bugpatch
= false;
717 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
) {
718 const struct table_section
*ts
=
719 get_table_section(old_span
->ss
->name
);
720 if (ts
!= NULL
&& ts
->has_addr
)
721 unmatch_addr_spans(old_span
, new_span
, ts
);
724 new_span
->patch
= false;
725 new_span
->bugpatch
= false;
726 new_span
->datapatch
= false;
731 static void match_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
732 struct span
*new_span
, asymbol
*newsym
)
734 if (newsym
== NULL
||
735 (oldsym
->flags
& BSF_GLOBAL
) == 0 ||
736 (newsym
->flags
& BSF_GLOBAL
) == 0)
738 match_spans(old_span
, new_span
);
741 static void check_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
742 struct span
*new_span
, asymbol
*newsym
)
744 if ((oldsym
->flags
& BSF_GLOBAL
) == 0 ||
745 (newsym
!= NULL
&& (newsym
->flags
& BSF_GLOBAL
) == 0))
747 if (old_span
->ss
->type
== SS_TYPE_IGNORED
)
749 if (old_span
->match
!= new_span
) {
750 if (new_span
!= NULL
)
751 err(new_span
->ss
->parent
,
752 "Global symbol span mismatch: %s %s/%s\n",
753 oldsym
->name
, old_span
->label
, new_span
->label
);
755 err(old_span
->ss
->parent
,
756 "Global symbol span mismatch: %s %s/NULL\n",
757 oldsym
->name
, old_span
->label
);
762 static void foreach_symbol_pair(struct superbfd
*oldsbfd
, struct superbfd
*newsbfd
,
763 void (*fn
)(struct span
*old_span
,
765 struct span
*new_span
,
768 asymbol
**oldsymp
, **newsymp
;
769 for (oldsymp
= oldsbfd
->syms
.data
;
770 oldsymp
< oldsbfd
->syms
.data
+ oldsbfd
->syms
.size
; oldsymp
++) {
771 asymbol
*oldsym
= *oldsymp
;
772 if ((oldsym
->flags
& BSF_DEBUGGING
) != 0 ||
773 bfd_is_const_section(oldsym
->section
))
776 struct supersect
*old_ss
=
777 fetch_supersect(oldsbfd
, oldsym
->section
);
778 if (old_ss
->type
== SS_TYPE_SPECIAL
||
779 old_ss
->type
== SS_TYPE_EXPORT
)
782 struct span
*old_span
= find_span(old_ss
, oldsym
->value
);
783 if (old_span
== NULL
) {
784 err(oldsbfd
, "Could not find span for %s\n",
791 for (newsymp
= newsbfd
->syms
.data
;
792 newsymp
< newsbfd
->syms
.data
+ newsbfd
->syms
.size
;
794 asymbol
*newsym
= *newsymp
;
795 if ((newsym
->flags
& BSF_DEBUGGING
) != 0 ||
796 bfd_is_const_section(newsym
->section
))
798 if (strcmp(oldsym
->name
, newsym
->name
) != 0)
801 struct supersect
*new_ss
=
802 fetch_supersect(newsbfd
, newsym
->section
);
803 if (old_ss
->type
!= new_ss
->type
&&
804 old_ss
->type
!= new_ss
->orig_type
)
810 struct span
*new_span
=
811 find_span(new_ss
, newsym
->value
);
812 if (new_span
== NULL
) {
813 err(newsbfd
, "Could not find span for %s\n",
817 fn(old_span
, oldsym
, new_span
, newsym
);
821 fn(old_span
, oldsym
, NULL
, NULL
);
825 static void match_symbol_spans(struct span
*old_span
, asymbol
*oldsym
,
826 struct span
*new_span
, asymbol
*newsym
)
830 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
)
832 if (static_local_symbol(old_span
->ss
->parent
, oldsym
) ||
833 static_local_symbol(new_span
->ss
->parent
, newsym
))
835 if (old_span
->match
== NULL
&& new_span
->match
== NULL
)
836 match_spans(old_span
, new_span
);
839 static void match_spans_by_label(struct span
*old_span
, struct span
*new_span
)
841 if (old_span
->ss
->type
== SS_TYPE_STRING
||
842 (is_table_section(old_span
->ss
->name
, true, false) &&
843 !is_table_section(old_span
->ss
->name
, false, false)))
845 if (strcmp(old_span
->label
, new_span
->label
) == 0)
846 match_spans(old_span
, new_span
);
849 static void match_string_spans(struct span
*old_span
, struct span
*new_span
)
851 if (old_span
->ss
->type
!= SS_TYPE_STRING
||
852 strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
854 if (strcmp((char *)old_span
->ss
->contents
.data
+ old_span
->start
,
855 (char *)new_span
->ss
->contents
.data
+ new_span
->start
) == 0)
856 match_spans(old_span
, new_span
);
859 static void foreach_span_pair(struct superbfd
*oldsbfd
,
860 struct superbfd
*newsbfd
,
861 void (*fn
)(struct span
*old_span
,
862 struct span
*new_span
))
864 asection
*oldsect
, *newsect
;
865 struct supersect
*oldss
, *newss
;
866 struct span
*old_span
, *new_span
;
867 for (newsect
= newsbfd
->abfd
->sections
; newsect
!= NULL
;
868 newsect
= newsect
->next
) {
869 newss
= fetch_supersect(newsbfd
, newsect
);
870 for (oldsect
= oldsbfd
->abfd
->sections
; oldsect
!= NULL
;
871 oldsect
= oldsect
->next
) {
872 oldss
= fetch_supersect(oldsbfd
, oldsect
);
873 if (oldss
->type
!= newss
->type
)
875 for (new_span
= newss
->spans
.data
;
876 new_span
< newss
->spans
.data
+ newss
->spans
.size
;
878 for (old_span
= oldss
->spans
.data
;
879 old_span
< oldss
->spans
.data
+
880 oldss
->spans
.size
; old_span
++)
881 fn(old_span
, new_span
);
887 static void mark_new_spans(struct superbfd
*sbfd
)
890 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
891 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
892 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
895 for (span
= ss
->spans
.data
;
896 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
897 if (span
->match
== NULL
)
903 static void handle_deleted_spans(struct superbfd
*oldsbfd
,
904 struct superbfd
*newsbfd
)
907 for (sect
= oldsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
908 struct supersect
*ss
= fetch_supersect(oldsbfd
, sect
);
910 for (span
= ss
->spans
.data
;
911 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
912 if (span
->match
!= NULL
)
914 if (ss
->type
== SS_TYPE_EXPORT
) {
915 *vec_grow(&delsects
, 1) = span
->label
;
916 write_ksplice_export(newsbfd
, span
, true);
917 } else if (ss
->type
== SS_TYPE_TEXT
) {
918 *vec_grow(&delsects
, 1) = span
->label
;
919 if (span
->symbol
== NULL
)
921 write_ksplice_deleted_patch
922 (newsbfd
, span
->symbol
->name
, span
->label
,
929 static void handle_nonzero_offset_relocs(struct supersect
*ss
)
931 struct span
*address_span
, *target_span
;
933 for (relocp
= ss
->relocs
.data
;
934 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
935 arelent
*reloc
= *relocp
;
936 address_span
= find_span(ss
, reloc
->address
);
937 if (!address_span
->new && !address_span
->patch
)
940 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
941 if (bfd_is_const_section(sym
->section
))
943 bfd_vma offset
= reloc_target_offset(ss
, reloc
);
944 target_span
= reloc_target_span(ss
, reloc
);
945 if (sym
->value
+ offset
== target_span
->start
)
948 if (target_span
->ss
->type
!= SS_TYPE_TEXT
)
950 if (target_span
->patch
)
953 target_span
->patch
= true;
955 debug1(ss
->parent
, "Changing %s because a relocation from sect "
956 "%s has a nonzero offset %lx+%lx into it\n",
957 target_span
->label
, ss
->name
, (unsigned long)sym
->value
,
958 (unsigned long)offset
);
962 static void update_nonzero_offsets(struct superbfd
*sbfd
)
965 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
966 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
967 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
969 handle_nonzero_offset_relocs(ss
);
973 static void unmatch_addr_spans(struct span
*old_span
, struct span
*new_span
,
974 const struct table_section
*ts
)
976 struct span
*old_sym_span
=
977 span_offset_target_span(old_span
, ts
->addr_offset
);
978 struct span
*new_sym_span
=
979 span_offset_target_span(new_span
, ts
->addr_offset
);
980 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
981 if (old_sym_span
->match
== new_sym_span
&&
982 new_sym_span
->match
== old_sym_span
&&
983 !(new_sym_span
->patch
&& new_sym_span
->ss
->type
== SS_TYPE_TEXT
)) {
984 if (old_sym_span
->ss
->type
== SS_TYPE_TEXT
) {
985 debug1(new_span
->ss
->parent
, "Patching %s due "
986 "to relocations from special section %s\n",
987 new_sym_span
->label
, new_span
->label
);
988 new_sym_span
->patch
= true;
990 debug1(new_span
->ss
->parent
, "Unmatching %s and %s due "
991 "to relocations from special section %s/%s\n",
992 old_sym_span
->label
, new_sym_span
->label
,
993 old_span
->label
, new_span
->label
);
994 unmatch_span(old_sym_span
);
1000 static void compare_spans(struct span
*old_span
, struct span
*new_span
)
1002 struct superbfd
*newsbfd
= new_span
->ss
->parent
;
1004 bool nonrelocs_match
= nonrelocs_equal(old_span
, new_span
);
1005 bool relocs_match
= all_relocs_equal(old_span
, new_span
);
1006 if (nonrelocs_match
&& relocs_match
) {
1007 const struct table_section
*ts
=
1008 get_table_section(old_span
->ss
->name
);
1009 if (ts
!= NULL
&& ts
->crc_sect
!= NULL
) {
1010 struct span
*old_crc_span
= get_crc_span(old_span
, ts
);
1011 struct span
*new_crc_span
= get_crc_span(new_span
, ts
);
1012 assert(old_crc_span
!= NULL
);
1013 assert(new_crc_span
!= NULL
);
1014 if (old_crc_span
->match
!= new_crc_span
||
1015 new_crc_span
->match
!= old_crc_span
) {
1016 debug1(newsbfd
, "Unmatching %s and %s due to "
1017 "nonmatching CRCs\n", old_span
->label
,
1019 unmatch_span(old_span
);
1026 if (new_span
->contents_size
!= old_span
->contents_size
)
1027 reason
= "differing sizes";
1028 else if (!nonrelocs_match
)
1029 reason
= "differing contents";
1031 reason
= "differing relocations";
1033 if (new_span
->ss
->type
== SS_TYPE_TEXT
) {
1034 if (new_span
->patch
)
1036 new_span
->patch
= true;
1037 debug1(newsbfd
, "Changing %s due to %s\n", new_span
->label
,
1039 } else if (old_span
->ss
->type
== SS_TYPE_BUGTABLE
&&
1040 new_span
->ss
->type
== SS_TYPE_BUGTABLE
&& relocs_match
) {
1041 if (new_span
->bugpatch
)
1043 debug1(newsbfd
, "Changing %s due to %s\n",
1044 new_span
->label
, reason
);
1045 new_span
->bugpatch
= true;
1046 } else if (new_span
->ss
->type
== SS_TYPE_RODATA
&&
1047 new_span
->contents_size
== old_span
->contents_size
) {
1048 if (new_span
->datapatch
)
1050 new_span
->datapatch
= true;
1051 debug1(newsbfd
, "Changing %s in-place due to %s\n",
1052 new_span
->label
, reason
);
1053 } else if (new_span
->ss
->type
== SS_TYPE_STRING
&&
1054 old_span
->ss
->type
== SS_TYPE_STRING
&& relocs_match
&&
1055 strcmp(new_span
->ss
->contents
.data
+ new_span
->start
,
1056 old_span
->ss
->contents
.data
+ old_span
->start
) == 0) {
1059 debug1(newsbfd
, "Unmatching %s and %s due to %s\n",
1060 old_span
->label
, new_span
->label
, reason
);
1061 unmatch_span(old_span
);
1064 if (unchangeable_section(new_span
->ss
))
1065 err(newsbfd
, "warning: ignoring change to nonpatchable "
1066 "section %s\n", new_span
->ss
->name
);
1069 static void compare_matched_spans(struct superbfd
*newsbfd
)
1072 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1073 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1075 for (span
= ss
->spans
.data
;
1076 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1077 if (span
->match
== NULL
)
1079 compare_spans(span
->match
, span
);
1084 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
1085 struct superbfd
*newsbfd
)
1089 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1090 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1091 for (span
= ss
->spans
.data
;
1092 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1093 if (span
->match
== NULL
)
1095 if (strcmp(span
->label
, span
->match
->label
) == 0)
1097 if (strcmp(span
->orig_label
, span
->label
) != 0 &&
1098 strcmp(span
->label
, span
->match
->label
) != 0)
1100 if (span
->symbol
!= NULL
)
1101 label_map_set(newsbfd
, span
->label
,
1102 span
->match
->label
);
1103 span
->label
= span
->match
->label
;
1108 static void copy_patched_entry_points(struct superbfd
*oldsbfd
,
1109 struct superbfd
*newsbfd
)
1113 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1114 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1115 for (span
= ss
->spans
.data
;
1116 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1119 assert(span
->match
!= NULL
);
1120 vec_init(&span
->pre_entry_points
);
1122 struct entry_point
*entry
;
1123 for (entry
= span
->match
->entry_points
.data
;
1124 entry
< span
->match
->entry_points
.data
+
1125 span
->match
->entry_points
.size
;
1127 struct entry_point
*e
=
1128 vec_grow(&span
->pre_entry_points
, 1);
1129 e
->name
= entry
->name
!= NULL
?
1130 strdup(entry
->name
) : NULL
;
1131 e
->label
= strdup(entry
->label
);
1132 e
->offset
= entry
->offset
;
1139 static int compare_entry_points(const void *va
, const void *vb
)
1141 const struct entry_point
*a
= va
, *b
= vb
;
1142 if (a
->offset
< b
->offset
)
1144 else if (a
->offset
> b
->offset
)
1150 static void compute_entry_points(struct superbfd
*sbfd
)
1153 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
1155 asymbol
*sym
= *symp
;
1156 if (bfd_is_const_section(sym
->section
))
1158 struct supersect
*old_ss
= fetch_supersect(sbfd
, sym
->section
);
1159 if ((sym
->flags
& BSF_GLOBAL
) == 0)
1161 struct span
*span
= find_span(old_ss
, sym
->value
);
1162 struct entry_point
*e
= vec_grow(&span
->entry_points
, 1);
1163 e
->label
= sym
->name
;
1164 e
->name
= sym
->name
;
1165 e
->offset
= sym
->value
- span
->start
;
1170 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1171 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1173 for (span
= ss
->spans
.data
;
1174 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1175 /* First make sure that 0 appears as an entry point */
1176 bool found_zero
= false;
1177 struct entry_point
*entry
;
1178 for (entry
= span
->entry_points
.data
;
1179 entry
< span
->entry_points
.data
+
1180 span
->entry_points
.size
;
1182 if (entry
->offset
== 0)
1186 struct entry_point
*e
=
1187 vec_grow(&span
->entry_points
, 1);
1188 e
->label
= span
->label
;
1191 e
->symbol
= span
->symbol
;
1194 qsort(span
->entry_points
.data
, span
->entry_points
.size
,
1195 sizeof(*span
->entry_points
.data
),
1196 compare_entry_points
);
1201 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
)
1204 for (relocp
= ss
->relocs
.data
;
1205 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
1206 arelent
*reloc
= *relocp
;
1207 if (addr
>= reloc
->address
&&
1208 addr
< reloc
->address
+ bfd_get_reloc_size(reloc
->howto
))
1214 static bool nonrelocs_equal(struct span
*old_span
, struct span
*new_span
)
1217 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1218 if (old_span
->contents_size
!= new_span
->contents_size
)
1220 const unsigned char *old
= old_ss
->contents
.data
+ old_span
->start
;
1221 const unsigned char *new = new_ss
->contents
.data
+ new_span
->start
;
1222 for (i
= 0; i
< old_span
->contents_size
; i
++) {
1223 if (old
[i
] != new[i
] &&
1224 !(part_of_reloc(old_ss
, i
+ old_span
->start
) &&
1225 part_of_reloc(new_ss
, i
+ new_span
->start
)))
1231 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
1232 arelent
*old_reloc
, arelent
*new_reloc
)
1234 struct superbfd
*oldsbfd
= old_src_ss
->parent
;
1235 struct superbfd
*newsbfd
= new_src_ss
->parent
;
1236 struct span
*old_addr_span
= find_span(old_src_ss
, old_reloc
->address
);
1237 struct span
*new_addr_span
= find_span(new_src_ss
, new_reloc
->address
);
1239 if (old_reloc
->address
- old_addr_span
->start
!=
1240 new_reloc
->address
- new_addr_span
->start
) {
1241 debug1(newsbfd
, "Section %s/%s has reloc address mismatch at "
1242 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1243 (unsigned long)old_reloc
->address
);
1247 if (old_reloc
->howto
!= new_reloc
->howto
) {
1248 debug1(newsbfd
, "Section %s/%s has howto type mismatch at "
1249 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1250 (unsigned long)old_reloc
->address
);
1254 if (non_dst_mask(old_src_ss
, old_reloc
) !=
1255 non_dst_mask(new_src_ss
, new_reloc
)) {
1256 debug1(newsbfd
, "Section %s/%s has contents mismatch at %lx\n",
1257 old_src_ss
->name
, new_src_ss
->name
,
1258 (unsigned long)old_reloc
->address
);
1262 asymbol
*old_sym
= *old_reloc
->sym_ptr_ptr
;
1263 asymbol
*new_sym
= *new_reloc
->sym_ptr_ptr
;
1264 asection
*old_sect
= old_sym
->section
;
1265 asection
*new_sect
= new_sym
->section
;
1267 bfd_vma old_offset
= reloc_target_offset(old_src_ss
, old_reloc
);
1268 bfd_vma new_offset
= reloc_target_offset(new_src_ss
, new_reloc
);
1270 if (bfd_is_und_section(old_sect
) || bfd_is_und_section(new_sect
)) {
1271 if (!bfd_is_und_section(new_sect
) && old_offset
!= 0 &&
1272 fetch_supersect(newsbfd
, new_sect
)->type
== SS_TYPE_TEXT
)
1275 if (!bfd_is_und_section(old_sect
) && new_offset
!= 0 &&
1276 fetch_supersect(oldsbfd
, old_sect
)->type
== SS_TYPE_TEXT
)
1279 return strcmp(old_sym
->name
, new_sym
->name
) == 0 &&
1280 old_offset
== new_offset
;
1283 if (bfd_is_abs_section(old_sect
) && bfd_is_abs_section(new_sect
)) {
1284 if (old_sym
->value
+ old_offset
== new_sym
->value
+ new_offset
)
1286 debug1(newsbfd
, "Differing relocations from %s/%s to ABS "
1287 "section: %lx/%lx\n", old_addr_span
->label
,
1288 new_addr_span
->label
,
1289 (unsigned long)(old_sym
->value
+ old_offset
),
1290 (unsigned long)(new_sym
->value
+ new_offset
));
1294 if (bfd_is_const_section(old_sect
) || bfd_is_const_section(new_sect
))
1297 struct supersect
*old_ss
= fetch_supersect(oldsbfd
, old_sect
);
1298 struct supersect
*new_ss
= fetch_supersect(newsbfd
, new_sect
);
1299 struct span
*old_span
= reloc_target_span(old_src_ss
, old_reloc
);
1300 struct span
*new_span
= reloc_target_span(new_src_ss
, new_reloc
);
1302 if (old_span
->match
!= new_span
|| new_span
->match
!= old_span
) {
1303 debug1(newsbfd
, "Nonmatching relocs from %s to %s/%s\n",
1304 new_src_ss
->name
, old_span
->label
, new_span
->label
);
1308 if (old_sym
->value
+ old_offset
- old_span
->start
!=
1309 new_sym
->value
+ new_offset
- new_span
->start
) {
1310 debug1(newsbfd
, "Offsets to %s/%s differ between %s "
1311 "and %s: %lx+%lx/%lx+%lx\n", old_ss
->name
,
1312 new_ss
->name
, old_src_ss
->name
, new_src_ss
->name
,
1313 (unsigned long)old_sym
->value
, (unsigned long)old_offset
,
1314 (unsigned long)new_sym
->value
,
1315 (unsigned long)new_offset
);
1319 if ((old_sym
->value
+ old_offset
- old_span
->start
!= 0 ||
1320 new_sym
->value
+ new_offset
- new_span
->start
!= 0) &&
1322 debug1(newsbfd
, "Relocation from %s to nonzero offsets "
1323 "%lx+%lx/%lx+%lx in changed section %s\n",
1324 new_src_ss
->name
, (unsigned long)old_sym
->value
,
1325 (unsigned long)old_offset
, (unsigned long)new_sym
->value
,
1326 (unsigned long)new_offset
, new_sym
->section
->name
);
1332 bool all_relocs_equal(struct span
*old_span
, struct span
*new_span
)
1334 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1335 arelent
**old_relocp
, **new_relocp
;
1337 for (old_relocp
= old_ss
->relocs
.data
;
1338 old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
;
1340 if (find_span(old_ss
, (*old_relocp
)->address
) == old_span
)
1344 for (new_relocp
= new_ss
->relocs
.data
;
1345 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
;
1347 if (find_span(new_ss
, (*new_relocp
)->address
) == new_span
)
1351 for (; old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1352 find_span(old_ss
, (*old_relocp
)->address
) == old_span
&&
1353 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1354 find_span(new_ss
, (*new_relocp
)->address
) == new_span
;
1355 old_relocp
++, new_relocp
++) {
1356 if (!relocs_equal(old_ss
, new_ss
, *old_relocp
, *new_relocp
))
1360 if ((old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1361 find_span(old_ss
, (*old_relocp
)->address
) == old_span
) ||
1362 (new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1363 find_span(new_ss
, (*new_relocp
)->address
) == new_span
)) {
1364 debug1(new_ss
->parent
, "Different reloc count between %s and "
1365 "%s\n", old_span
->label
, new_span
->label
);
1372 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
)
1374 int bits
= bfd_get_reloc_size(reloc
->howto
) * 8;
1375 void *address
= ss
->contents
.data
+ reloc
->address
;
1376 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1377 return x
& ~reloc
->howto
->dst_mask
;
1380 void rm_relocs(struct superbfd
*isbfd
)
1383 for (p
= isbfd
->abfd
->sections
; p
!= NULL
; p
= p
->next
) {
1384 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1385 bool remove_relocs
= ss
->keep
;
1387 if (mode("keep") && ss
->type
== SS_TYPE_SPECIAL
)
1388 remove_relocs
= false;
1390 if (ss
->type
== SS_TYPE_KSPLICE
||
1391 ss
->type
== SS_TYPE_KSPLICE_CALL
)
1392 remove_relocs
= false;
1393 if (mode("finalize") &&
1394 (strstarts(ss
->name
, ".ksplice_patches") ||
1395 strstarts(ss
->name
, ".ksplice_relocs")))
1396 remove_relocs
= true;
1403 void rm_some_relocs(struct supersect
*ss
)
1405 struct arelentp_vec orig_relocs
;
1406 vec_move(&orig_relocs
, &ss
->relocs
);
1409 for (relocp
= orig_relocs
.data
;
1410 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
1411 bool rm_reloc
= false;
1412 asymbol
*sym_ptr
= *(*relocp
)->sym_ptr_ptr
;
1414 if (mode("rmsyms") && bfd_is_und_section(sym_ptr
->section
)) {
1416 for (esymp
= extract_syms
.data
;
1417 esymp
< extract_syms
.data
+ extract_syms
.size
;
1419 if (sym_ptr
== *esymp
) {
1429 if (mode("keep-new-code")) {
1430 if (bfd_is_const_section(sym_ptr
->section
)) {
1433 bfd_vma offset
= reloc_target_offset(ss
, *relocp
);
1434 struct span
*target_span
=
1435 reloc_target_span(ss
, *relocp
);
1436 if (target_span
->new ||
1437 (target_span
->ss
->type
== SS_TYPE_TEXT
&&
1438 sym_ptr
->value
+ offset
!=
1439 target_span
->start
))
1443 const struct table_section
*ts
=
1444 get_table_section(ss
->name
);
1445 if (ts
!= NULL
&& ts
->has_addr
&&
1446 ((*relocp
)->address
% ts
->entry_size
==
1448 (*relocp
)->address
% ts
->entry_size
==
1453 if (mode("finalize") && bfd_is_und_section(sym_ptr
->section
))
1456 if (strcmp(sym_ptr
->name
, "mcount") == 0 &&
1457 bfd_is_und_section(sym_ptr
->section
))
1460 if (!find_span(ss
, (*relocp
)->address
)->keep
)
1464 write_ksplice_reloc(ss
, *relocp
);
1466 *vec_grow(&ss
->relocs
, 1) = *relocp
;
1470 struct supersect
*make_section(struct superbfd
*sbfd
, const char *fmt
, ...)
1474 char *name
= vstrprintf(fmt
, ap
);
1477 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
1479 return fetch_supersect(sbfd
, sect
);
1481 return new_supersect(sbfd
, name
);
1484 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1487 bfd_reloc_code_real_type code
;
1488 switch (bfd_arch_bits_per_address(ss
->parent
->abfd
)) {
1490 code
= BFD_RELOC_32
;
1493 code
= BFD_RELOC_64
;
1499 arelent
*reloc
= malloc(sizeof(*reloc
));
1500 reloc
->sym_ptr_ptr
= symp
;
1501 reloc
->address
= addr_offset(ss
, addr
);
1502 reloc
->howto
= bfd_reloc_type_lookup(ss
->parent
->abfd
, code
);
1503 reloc
->addend
= offset
;
1507 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1510 *vec_grow(&ss
->new_relocs
, 1) = create_reloc(ss
, addr
, symp
, offset
);
1513 void write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...)
1516 struct supersect
*str_ss
= make_section(ss
->parent
, ".ksplice_str");
1519 int len
= vasprintf(&str
, fmt
, ap
);
1523 unsigned long *str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
,
1525 if (str_offp
== NULL
) {
1526 char *buf
= sect_grow(str_ss
, len
+ 1, char);
1527 memcpy(buf
, str
, len
+ 1);
1528 str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
, TRUE
);
1529 *str_offp
= addr_offset(str_ss
, buf
);
1532 write_reloc(ss
, addr
, &str_ss
->symbol
, *str_offp
);
1535 void lookup_system_map(struct addr_vec
*addrs
, const char *name
, long offset
)
1537 struct addr_vec
*map_addrs
=
1538 addr_vec_hash_lookup(&system_map
, name
, FALSE
);
1539 if (map_addrs
== NULL
)
1542 unsigned long *addr
, *map_addr
;
1543 for (map_addr
= map_addrs
->data
;
1544 map_addr
< map_addrs
->data
+ map_addrs
->size
; map_addr
++) {
1545 for (addr
= addrs
->data
; addr
< addrs
->data
+ addrs
->size
;
1547 if (*addr
== *map_addr
+ offset
)
1550 if (addr
< addrs
->data
+ addrs
->size
)
1552 *vec_grow(addrs
, 1) = *map_addr
+ offset
;
1556 void compute_system_map_array(struct superbfd
*sbfd
, struct addr_vec
*addrs
,
1559 if (bfd_is_abs_section(sym
->section
)) {
1560 *vec_grow(addrs
, 1) = sym
->value
;
1561 } else if (bfd_is_und_section(sym
->section
)) {
1562 lookup_system_map(addrs
, sym
->name
, 0);
1563 } else if (!bfd_is_const_section(sym
->section
)) {
1565 for (gsymp
= sbfd
->syms
.data
;
1566 gsymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; gsymp
++) {
1567 asymbol
*gsym
= *gsymp
;
1568 if ((gsym
->flags
& BSF_DEBUGGING
) == 0 &&
1569 gsym
->section
== sym
->section
)
1570 lookup_system_map(addrs
, gsym
->name
,
1571 sym
->value
- gsym
->value
);
1576 void write_ksplice_system_map(struct superbfd
*sbfd
, asymbol
*sym
,
1579 bool *done
= bool_hash_lookup(&system_map_written
, label
, TRUE
);
1584 struct addr_vec addrs
;
1587 compute_system_map_array(sbfd
, &addrs
, sym
);
1588 if (addrs
.size
!= 0) {
1589 struct supersect
*smap_ss
=
1590 make_section(sbfd
, ".ksplice_system_map");
1591 struct ksplice_system_map
*smap
=
1592 sect_grow(smap_ss
, 1, struct ksplice_system_map
);
1593 write_string(smap_ss
, &smap
->label
, "%s", label
);
1595 struct supersect
*array_ss
= make_section(sbfd
,
1597 void *buf
= sect_grow(array_ss
, addrs
.size
,
1598 typeof(*addrs
.data
));
1599 memcpy(buf
, addrs
.data
, addrs
.size
* sizeof(*addrs
.data
));
1600 smap
->nr_candidates
= addrs
.size
;
1601 write_reloc(smap_ss
, &smap
->candidates
, &array_ss
->symbol
,
1602 addr_offset(array_ss
, buf
));
1607 void write_ksplice_symbol_backend(struct supersect
*ss
,
1608 struct ksplice_symbol
*const *addr
,
1609 asymbol
*sym
, const char *label
,
1612 struct supersect
*ksymbol_ss
= make_section(ss
->parent
,
1613 ".ksplice_symbols");
1614 struct ksplice_symbol
*ksymbol
;
1615 unsigned long *ksymbol_offp
;
1617 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, FALSE
);
1618 if (ksymbol_offp
!= NULL
) {
1619 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1622 ksymbol
= sect_grow(ksymbol_ss
, 1, struct ksplice_symbol
);
1623 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
1624 *ksymbol_offp
= addr_offset(ksymbol_ss
, ksymbol
);
1626 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1627 write_string(ksymbol_ss
, &ksymbol
->label
, "%s", label
);
1629 write_string(ksymbol_ss
, &ksymbol
->name
, "%s", name
);
1630 write_ksplice_system_map(ksymbol_ss
->parent
, sym
, label
);
1634 void write_ksplice_symbol(struct supersect
*ss
,
1635 struct ksplice_symbol
*const *addr
,
1636 asymbol
*sym
, struct span
*span
,
1637 const char *addstr_sect
)
1639 const char *label
, *name
;
1640 if (span
!= NULL
&& span
->start
!= 0)
1641 label
= span
->label
;
1643 label
= label_lookup(ss
->parent
, sym
);
1645 asymbol
*gsym
= canonical_symbol(ss
->parent
, sym
);
1646 if (strcmp(addstr_sect
, "") != 0)
1648 else if (bfd_is_und_section(sym
->section
))
1650 else if (bfd_is_const_section(sym
->section
))
1652 else if (span
!= NULL
&& span
->symbol
== NULL
)
1654 else if (gsym
== NULL
|| (gsym
->flags
& BSF_SECTION_SYM
) != 0)
1659 write_ksplice_symbol_backend(ss
, addr
, sym
,
1660 strprintf("%s%s", addstr_sect
, label
),
1664 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
)
1666 asymbol
*sym_ptr
= *orig_reloc
->sym_ptr_ptr
;
1667 bfd_vma reloc_addend
= reloc_offset(ss
, orig_reloc
);
1668 bfd_vma target_addend
= reloc_target_offset(ss
, orig_reloc
);
1669 unsigned long *repladdr
= ss
->contents
.data
+ orig_reloc
->address
;
1671 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_patches")) {
1675 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_relocs")) {
1676 assert(strstarts(sym_ptr
->name
, KSPLICE_SYMBOL_STR
));
1678 fake_sym
.name
= sym_ptr
->name
+ strlen(KSPLICE_SYMBOL_STR
);
1679 fake_sym
.section
= bfd_und_section_ptr
;
1683 write_ksplice_symbol_backend
1684 (ss
, (struct ksplice_symbol
**)repladdr
, &fake_sym
,
1685 fake_sym
.name
, fake_sym
.name
);
1689 struct span
*span
= reloc_target_span(ss
, orig_reloc
);
1690 if (span
== ss
->spans
.data
&& span
->start
!= target_addend
)
1692 write_canary(ss
, orig_reloc
->address
,
1693 bfd_get_reloc_size(orig_reloc
->howto
),
1694 orig_reloc
->howto
->dst_mask
);
1696 struct supersect
*kreloc_ss
=
1697 make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1698 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1699 struct ksplice_reloc
);
1701 struct span
*address_span
= find_span(ss
, orig_reloc
->address
);
1702 write_reloc(kreloc_ss
, &kreloc
->blank_addr
,
1703 &ss
->symbol
, orig_reloc
->address
+ address_span
->shift
);
1704 if (bfd_is_und_section(sym_ptr
->section
) && mode("keep")) {
1705 char *name
= strprintf(KSPLICE_SYMBOL_STR
"%s", sym_ptr
->name
);
1706 asymbol
**symp
= make_undefined_symbolp(ss
->parent
, name
);
1707 write_reloc(kreloc_ss
, &kreloc
->symbol
, symp
, 0);
1709 write_ksplice_symbol(kreloc_ss
, &kreloc
->symbol
, sym_ptr
, span
,
1712 if (span
!= NULL
&& span
->start
!= 0) {
1713 reloc_addend
+= sym_ptr
->value
- span
->start
;
1714 target_addend
+= sym_ptr
->value
- span
->start
;
1716 kreloc
->insn_addend
= reloc_addend
- target_addend
;
1717 kreloc
->target_addend
= target_addend
;
1718 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, orig_reloc
->howto
,
1719 KSPLICE_HOWTO_RELOC
);
1722 static void write_ksplice_reloc_howto(struct supersect
*ss
, const
1723 struct ksplice_reloc_howto
*const *addr
,
1724 reloc_howto_type
*howto
,
1725 enum ksplice_reloc_howto_type type
)
1727 struct supersect
*khowto_ss
= make_section(ss
->parent
,
1728 ".ksplice_reloc_howtos");
1729 struct ksplice_reloc_howto
*khowto
;
1730 unsigned long *khowto_offp
;
1732 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1734 if (khowto_offp
!= NULL
) {
1735 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1738 khowto
= sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1739 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1741 *khowto_offp
= addr_offset(khowto_ss
, khowto
);
1743 khowto
->type
= type
;
1744 khowto
->pcrel
= howto
->pc_relative
;
1745 khowto
->size
= bfd_get_reloc_size(howto
);
1746 khowto
->dst_mask
= howto
->dst_mask
;
1747 khowto
->rightshift
= howto
->rightshift
;
1748 khowto
->signed_addend
=
1749 (howto
->complain_on_overflow
== complain_overflow_signed
) ||
1750 (howto
->complain_on_overflow
== complain_overflow_bitfield
);
1751 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1754 #define CANARY(x, canary) ((x & ~howto->dst_mask) | (canary & howto->dst_mask))
1756 void write_canary(struct supersect
*ss
, int offset
, bfd_size_type size
,
1759 int bits
= size
* 8;
1760 void *address
= ss
->contents
.data
+ offset
;
1761 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1762 x
= (x
& ~dst_mask
) | ((bfd_vma
)KSPLICE_CANARY
& dst_mask
);
1763 bfd_put(bits
, ss
->parent
->abfd
, x
, address
);
1766 static void write_date_relocs(struct superbfd
*sbfd
, const char *str
,
1767 enum ksplice_reloc_howto_type type
)
1770 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1771 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1772 if (ss
->type
!= SS_TYPE_STRING
&& ss
->type
!= SS_TYPE_RODATA
)
1776 for (span
= ss
->spans
.data
;
1777 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1780 for (ptr
= ss
->contents
.data
+ span
->start
;
1781 ptr
+ strlen(str
) < ss
->contents
.data
+
1782 span
->start
+ span
->contents_size
; ptr
++) {
1783 if (strcmp((const char *)ptr
, str
) == 0)
1784 write_ksplice_date_reloc
1785 (ss
, addr_offset(ss
, ptr
), str
,
1792 static void write_ksplice_date_reloc(struct supersect
*ss
, unsigned long offset
,
1794 enum ksplice_reloc_howto_type type
)
1796 struct supersect
*kreloc_ss
;
1797 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1798 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1799 struct ksplice_reloc
);
1801 const char *filename
= ss
->parent
->abfd
->filename
;
1802 char *c
= strstr(filename
, ".KSPLICE");
1803 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
1805 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1806 strprintf("%s<%.*s>", str
, flen
, filename
),
1809 struct span
*span
= find_span(ss
, offset
);
1810 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1811 offset
+ span
->shift
);
1812 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
,
1816 static void write_table_relocs(struct superbfd
*sbfd
, const char *sectname
,
1817 enum ksplice_reloc_howto_type type
)
1819 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, sectname
);
1822 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1824 const struct table_section
*s
= get_table_section(sectname
);
1829 for (entry
= ss
->contents
.data
;
1830 entry
< ss
->contents
.data
+ ss
->contents
.size
;
1831 entry
+= s
->entry_size
) {
1832 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
1833 assert(span
!= NULL
);
1837 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
1838 assert(reloc
!= NULL
);
1839 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
1840 assert(!bfd_is_const_section(sym
->section
));
1841 struct supersect
*sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1842 unsigned long addr
= sym
->value
+
1843 reloc_target_offset(ss
, reloc
);
1844 write_ksplice_table_reloc(sym_ss
, addr
, span
->label
, type
);
1848 static void write_ksplice_table_reloc(struct supersect
*ss
,
1849 unsigned long address
,
1851 enum ksplice_reloc_howto_type type
)
1853 struct supersect
*kreloc_ss
;
1854 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1855 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1856 struct ksplice_reloc
);
1857 struct span
*span
= find_span(ss
, address
);
1858 assert(span
!= NULL
);
1860 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1862 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1863 address
+ span
->shift
);
1864 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
, 0);
1867 static void write_ksplice_nonreloc_howto(struct supersect
*ss
,
1868 const struct ksplice_reloc_howto
1870 enum ksplice_reloc_howto_type type
,
1873 struct supersect
*khowto_ss
=
1874 make_section(ss
->parent
, ".ksplice_reloc_howtos");
1875 struct ksplice_reloc_howto
*khowto
=
1876 sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1878 khowto
->type
= type
;
1879 khowto
->size
= size
;
1881 khowto
->dst_mask
= 0;
1882 khowto
->rightshift
= 0;
1883 khowto
->signed_addend
= 0;
1884 write_reloc(ss
, addr
, &khowto_ss
->symbol
,
1885 addr_offset(khowto_ss
, khowto
));
1888 static void write_ksplice_symbol_reloc(struct supersect
*ss
,
1889 const char *sectname
,
1890 unsigned long *addr
, asymbol
*sym
,
1891 const char *label
, const char *name
)
1893 struct supersect
*kreloc_ss
;
1894 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1895 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1896 struct ksplice_reloc
);
1898 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, sym
, label
,
1900 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1901 addr_offset(ss
, addr
));
1902 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
,
1903 KSPLICE_HOWTO_SYMBOL
, 0);
1906 static void write_ksplice_section(struct span
*span
)
1908 struct supersect
*ss
= span
->ss
;
1909 const char *sectname
= span
->ss
->name
;
1910 const struct table_section
*ts
= get_table_section(ss
->name
);
1912 if (ts
!= NULL
&& ts
->has_addr
) {
1913 arelent
*reloc
= find_reloc(ss
, ss
->contents
.data
+ span
->start
1915 assert(reloc
!= NULL
);
1916 asymbol
*rsym
= *reloc
->sym_ptr_ptr
;
1917 assert(!bfd_is_const_section(rsym
->section
));
1918 sectname
= rsym
->section
->name
;
1921 struct supersect
*ksect_ss
=
1922 make_section(ss
->parent
, ".ksplice_sections%s", sectname
);
1923 struct ksplice_section
*ksect
= sect_grow(ksect_ss
, 1,
1924 struct ksplice_section
);
1925 asymbol
*sym
= span
->symbol
== NULL
? ss
->symbol
: span
->symbol
;
1927 write_ksplice_symbol(ksect_ss
, &ksect
->symbol
, sym
, span
,
1928 mode("keep-new-code") ? "(post)" : "");
1929 ksect
->size
= span
->size
;
1932 if (ss
->type
== SS_TYPE_RODATA
|| ss
->type
== SS_TYPE_STRING
||
1933 ss
->type
== SS_TYPE_EXPORT
|| ss
->type
== SS_TYPE_BUGTABLE
)
1934 ksect
->flags
|= KSPLICE_SECTION_RODATA
;
1935 if (ss
->type
== SS_TYPE_DATA
)
1936 ksect
->flags
|= KSPLICE_SECTION_DATA
;
1937 if (ss
->type
== SS_TYPE_TEXT
)
1938 ksect
->flags
|= KSPLICE_SECTION_TEXT
;
1939 assert(ksect
->flags
!= 0);
1941 if (ss
->type
== SS_TYPE_STRING
)
1942 ksect
->flags
|= KSPLICE_SECTION_STRING
;
1944 write_reloc(ksect_ss
, &ksect
->address
, &ss
->symbol
,
1945 span
->start
+ span
->shift
);
1947 if (mode("keep-old-code")) {
1948 /* Write ksplice_symbols for all the entry points */
1949 struct entry_point
*entry
;
1950 for (entry
= span
->entry_points
.data
;
1951 entry
< span
->entry_points
.data
+ span
->entry_points
.size
;
1953 write_ksplice_symbol_reloc
1954 (span
->ss
, sectname
, span
->ss
->contents
.data
+
1955 span
->start
+ span
->shift
+ entry
->offset
,
1956 entry
->symbol
, entry
->label
, entry
->name
);
1960 static void write_ksplice_patch_reloc(struct supersect
*ss
,
1961 const char *sectname
, unsigned long *addr
,
1962 bfd_size_type size
, const char *label
,
1965 struct supersect
*kreloc_ss
;
1966 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1967 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1968 struct ksplice_reloc
);
1970 write_canary(ss
, addr_offset(ss
, addr
), size
, -1);
1971 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1973 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1974 addr_offset(ss
, addr
));
1975 reloc_howto_type
*howto
=
1976 bfd_reloc_type_lookup(ss
->parent
->abfd
,
1977 PASTE(BFD_RELOC_
, LONG_BIT
));
1978 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, howto
,
1979 KSPLICE_HOWTO_RELOC
);
1980 kreloc
->target_addend
= addend
;
1981 kreloc
->insn_addend
= 0;
1984 /* Assumes symbol is global, aka only one symbol of that name */
1985 static asymbol
*name_to_symbol(struct superbfd
*sbfd
, const char *name
)
1991 for (symp
= sbfd
->syms
.data
;
1992 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
1993 asymbol
*sym
= *symp
;
1994 if (strcmp(name
, sym
->name
) == 0 &&
1995 ((sym
->flags
& BSF_GLOBAL
) != 0 ||
1996 bfd_is_und_section(sym
->section
)))
2002 void write_ksplice_patches(struct superbfd
*sbfd
, struct span
*span
)
2004 if (span
->datapatch
) {
2005 write_ksplice_patch(sbfd
, span
, span
->label
, 0);
2009 assert(span
->patch
);
2011 long prev_offset
= LONG_MIN
;
2012 asymbol
*prev_sym
= NULL
;
2013 const char *prev_label
= NULL
;
2014 struct entry_point
*entry
;
2015 for (entry
= span
->pre_entry_points
.data
;
2016 entry
< span
->pre_entry_points
.data
+ span
->pre_entry_points
.size
;
2018 asymbol
*sym
= name_to_symbol(sbfd
, entry
->name
);
2019 if (sym
== NULL
&& entry
->offset
!= 0) {
2020 /* Since it was global, name and label are the same */
2021 write_ksplice_deleted_patch
2022 (sbfd
, entry
->label
, entry
->label
, span
->ss
->name
,
2024 } else if (entry
->offset
!= prev_offset
) {
2025 debug1(sbfd
, "entry point: %s(%s) %lx\n", entry
->label
,
2026 entry
->name
, entry
->offset
);
2028 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> entry
->offset
) {
2030 "Overlapping trampolines: %s %lx/%lx\n",
2031 span
->label
, prev_offset
, entry
->offset
);
2035 long target_offset
= 0;
2037 target_offset
= sym
->value
- span
->start
;
2038 write_ksplice_patch(sbfd
, span
, entry
->label
,
2040 prev_offset
= entry
->offset
;
2044 if (prev_sym
== NULL
) {
2046 prev_label
= entry
->label
;
2047 } else if (sym
!= NULL
&&
2048 (prev_sym
->section
!= sym
->section
||
2049 prev_sym
->value
!= sym
->value
)) {
2050 err(sbfd
, "Splitting global symbols in the middle of a "
2051 "span: %s+%lx != %s+%lx!\n",
2052 prev_label
, (unsigned long)prev_sym
->value
,
2053 entry
->label
, (unsigned long)sym
->value
);
2058 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> span
->size
) {
2059 err(sbfd
, "Trampoline ends outside span: %s %lx/%lx\n",
2060 span
->label
, prev_offset
, (unsigned long)span
->size
);
2065 void write_ksplice_patch(struct superbfd
*sbfd
, struct span
*span
,
2066 const char *label
, long offset
)
2068 struct supersect
*kpatch_ss
=
2069 make_section(sbfd
, ".ksplice_patches%s", span
->ss
->name
);
2070 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2071 struct ksplice_patch
);
2073 write_ksplice_patch_reloc(kpatch_ss
, span
->ss
->name
, &kpatch
->oldaddr
,
2074 sizeof(kpatch
->oldaddr
), label
, 0);
2075 if (span
->ss
->type
== SS_TYPE_TEXT
) {
2076 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2077 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
,
2080 kpatch
->type
= KSPLICE_PATCH_DATA
;
2081 kpatch
->size
= span
->contents_size
;
2082 struct supersect
*data_ss
=
2083 make_section(sbfd
, ".ksplice_patch_data");
2084 write_reloc(kpatch_ss
, &kpatch
->contents
, &span
->ss
->symbol
,
2085 span
->start
+ span
->shift
);
2086 char *saved
= sect_do_grow(data_ss
, 1, span
->contents_size
, 1);
2087 write_reloc(kpatch_ss
, &kpatch
->saved
, &data_ss
->symbol
,
2088 addr_offset(data_ss
, saved
));
2090 write_reloc(kpatch_ss
, &kpatch
->repladdr
, &span
->ss
->symbol
,
2091 span
->start
+ span
->shift
+ offset
);
2094 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
)
2097 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
2099 asymbol
*sym
= *symp
;
2100 if (strcmp(name
, sym
->name
) == 0 &&
2101 bfd_is_und_section(sym
->section
))
2105 for (sympp
= sbfd
->new_syms
.data
;
2106 sympp
< sbfd
->new_syms
.data
+ sbfd
->new_syms
.size
; sympp
++) {
2107 asymbol
**symp
= *sympp
;
2108 asymbol
*sym
= *symp
;
2109 if (strcmp(name
, sym
->name
) == 0 &&
2110 bfd_is_und_section(sym
->section
))
2114 symp
= malloc(sizeof(*symp
));
2115 *symp
= bfd_make_empty_symbol(sbfd
->abfd
);
2116 asymbol
*sym
= *symp
;
2118 sym
->section
= bfd_und_section_ptr
;
2121 *vec_grow(&sbfd
->new_syms
, 1) = symp
;
2125 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
2126 const char *label
, const char *sectname
,
2129 struct supersect
*kpatch_ss
=
2130 make_section(sbfd
, ".ksplice_patches%s", sectname
);
2131 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2132 struct ksplice_patch
);
2134 write_ksplice_patch_reloc(kpatch_ss
, sectname
, &kpatch
->oldaddr
,
2135 sizeof(kpatch
->oldaddr
), label
, 0);
2136 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2137 asymbol
**symp
= make_undefined_symbolp(sbfd
, strdup(name
));
2138 write_reloc(kpatch_ss
, &kpatch
->repladdr
, symp
, offset
);
2139 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
, NULL
);
2142 void write_ksplice_export(struct superbfd
*sbfd
, struct span
*span
, bool del
)
2144 struct supersect
*kpatch_ss
= make_section(sbfd
, ".ksplice_patches");
2145 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2146 struct ksplice_patch
);
2147 struct supersect
*data_ss
;
2149 const struct table_section
*ts
= get_table_section(span
->ss
->name
);
2152 span
->ss
->contents
.data
+ span
->start
+ ts
->other_offset
;
2153 const char *symname
= read_string(span
->ss
, addr
);
2155 char *oldname
, *newname
;
2157 oldname
= strprintf("%s:%s", span
->ss
->name
, symname
);
2158 newname
= strprintf("DISABLED_%s_%s", symname
, kid
);
2160 oldname
= strprintf("%s:DISABLED_%s_%s", span
->ss
->name
,
2162 newname
= strprintf("%s", symname
);
2163 write_string(span
->ss
, addr
, "DISABLED_%s_%s", symname
, kid
);
2166 write_ksplice_patch_reloc(kpatch_ss
, "", &kpatch
->oldaddr
,
2167 sizeof(kpatch
->oldaddr
), oldname
,
2169 kpatch
->type
= KSPLICE_PATCH_EXPORT
;
2170 const char **namep
= write_patch_storage(kpatch_ss
, kpatch
,
2171 sizeof(newname
), &data_ss
);
2172 write_string(data_ss
, namep
, "%s", newname
);
2175 void filter_table_sections(struct superbfd
*isbfd
)
2177 struct supersect
*tables_ss
=
2178 fetch_supersect(offsets_sbfd
,
2179 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2180 ".ksplice_table_sections"));
2181 const struct table_section
*ts
;
2182 for (ts
= tables_ss
->contents
.data
;
2183 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2185 struct table_section s
= *ts
;
2186 s
.sect
= read_string(tables_ss
, &ts
->sect
);
2187 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
2188 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2189 filter_table_section(isbfd
, &s
);
2193 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
)
2195 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
2196 if (isection
== NULL
)
2198 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2201 for (entry
= ss
->contents
.data
;
2202 entry
< ss
->contents
.data
+ ss
->contents
.size
;
2203 entry
+= s
->entry_size
) {
2204 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
2205 assert(span
!= NULL
);
2208 struct span
*sym_span
=
2209 span_offset_target_span(span
, s
->addr_offset
);
2210 assert(sym_span
!= NULL
);
2215 if (s
->other_sect
!= NULL
) {
2216 struct span
*sym_span
=
2217 span_offset_target_span(span
, s
->other_offset
);
2218 assert(sym_span
!= NULL
);
2220 keep_span(sym_span
);
2223 if (s
->crc_sect
!= NULL
) {
2224 struct span
*crc_span
= get_crc_span(span
, s
);
2225 assert(crc_span
!= NULL
);
2226 if (span
->keep
&& mode("keep-new-code"))
2227 keep_span(crc_span
);
2232 static void match_other_spans(struct span
*old_span
, struct span
*new_span
)
2234 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2238 if (old_span
->match
== new_span
&& new_span
->match
== old_span
&&
2239 ts
->other_sect
!= NULL
) {
2240 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2241 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2242 arelent
*old_reloc
=
2243 find_reloc(old_span
->ss
, old_entry
+ ts
->other_offset
);
2244 arelent
*new_reloc
=
2245 find_reloc(new_span
->ss
, new_entry
+ ts
->other_offset
);
2246 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2247 struct span
*old_other_span
=
2248 reloc_target_span(old_span
->ss
, old_reloc
);
2249 struct span
*new_other_span
=
2250 reloc_target_span(new_span
->ss
, new_reloc
);
2251 assert(old_other_span
!= NULL
&& new_other_span
!= NULL
);
2252 match_spans(old_other_span
, new_other_span
);
2256 static void match_table_spans(struct span
*old_span
, struct span
*new_span
)
2258 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2260 if (strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
2262 if (ts
== NULL
|| old_span
->ss
->type
!= SS_TYPE_SPECIAL
||
2263 new_span
->ss
->type
!= SS_TYPE_SPECIAL
)
2265 if (old_span
->match
!= NULL
|| new_span
->match
!= NULL
)
2269 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2270 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2271 arelent
*old_reloc
=
2272 find_reloc(old_span
->ss
, old_entry
+ ts
->addr_offset
);
2273 arelent
*new_reloc
=
2274 find_reloc(new_span
->ss
, new_entry
+ ts
->addr_offset
);
2275 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2276 struct span
*old_sym_span
=
2277 reloc_target_span(old_span
->ss
, old_reloc
);
2278 struct span
*new_sym_span
=
2279 reloc_target_span(new_span
->ss
, new_reloc
);
2280 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
2281 if (old_sym_span
->match
== new_sym_span
&&
2282 new_sym_span
->match
== old_sym_span
&&
2283 old_reloc
->address
- old_sym_span
->start
==
2284 new_reloc
->address
- new_sym_span
->start
)
2285 match_spans(old_span
, new_span
);
2289 static struct span
*get_crc_span(struct span
*span
,
2290 const struct table_section
*ts
)
2292 void *entry
= span
->ss
->contents
.data
+ span
->start
;
2293 asection
*crc_sect
= bfd_get_section_by_name(span
->ss
->parent
->abfd
,
2295 if (crc_sect
== NULL
)
2297 struct supersect
*crc_ss
= fetch_supersect(span
->ss
->parent
, crc_sect
);
2300 struct span
*crc_span
= find_span(crc_ss
, addr_offset(span
->ss
, entry
) /
2301 ts
->entry_size
* ts
->crc_size
);
2305 void mark_precallable_spans(struct superbfd
*sbfd
)
2308 struct supersect
*ss
, *sym_ss
;
2309 struct span
*address_span
, *target_span
;
2310 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2311 ss
= fetch_supersect(sbfd
, sect
);
2313 if (ss
->type
== SS_TYPE_SPECIAL
)
2315 for (relocp
= ss
->relocs
.data
;
2316 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2317 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2318 address_span
= find_span(ss
, (*relocp
)->address
);
2319 if (!address_span
->precallable
)
2321 target_span
= reloc_target_span(ss
, *relocp
);
2322 if (target_span
== NULL
|| target_span
->keep
)
2324 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2325 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2327 target_span
->precallable
= true;
2333 void keep_referenced_sections(struct superbfd
*sbfd
)
2336 struct supersect
*ss
, *sym_ss
;
2337 struct span
*address_span
, *target_span
;
2338 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2339 ss
= fetch_supersect(sbfd
, sect
);
2341 if (ss
->type
== SS_TYPE_SPECIAL
)
2343 for (relocp
= ss
->relocs
.data
;
2344 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2345 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2346 address_span
= find_span(ss
, (*relocp
)->address
);
2347 if (!address_span
->keep
)
2349 target_span
= reloc_target_span(ss
, *relocp
);
2350 if (target_span
== NULL
|| target_span
->keep
)
2352 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2353 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2355 keep_span(target_span
);
2361 void copy_symbols(struct asymbolp_vec
*osyms
, struct asymbolpp_vec
*isyms
)
2364 for (sympp
= isyms
->data
; sympp
< isyms
->data
+ isyms
->size
; sympp
++)
2365 *vec_grow(osyms
, 1) = **sympp
;
2368 /* Modified function from GNU Binutils objcopy.c */
2369 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
)
2371 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2373 bfd_vma start
= bfd_get_start_address(ibfd
);
2375 flagword flags
= bfd_get_file_flags(ibfd
);
2376 flags
&= bfd_applicable_file_flags(obfd
);
2378 assert(bfd_set_start_address(obfd
, start
)
2379 && bfd_set_file_flags(obfd
, flags
));
2381 enum bfd_architecture iarch
= bfd_get_arch(ibfd
);
2382 unsigned int imach
= bfd_get_mach(ibfd
);
2383 assert(bfd_set_arch_mach(obfd
, iarch
, imach
));
2384 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2386 /* BFD mandates that all output sections be created and sizes set before
2387 any output is done. Thus, we traverse all sections multiple times. */
2388 bfd_map_over_sections(ibfd
, setup_section
, obfd
);
2390 struct supersect
*new_supersects
= fetch_superbfd(ibfd
)->new_supersects
;
2391 struct supersect
*ss
;
2392 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2393 setup_new_section(obfd
, ss
);
2395 /* Mark symbols used in output relocations so that they
2396 are kept, even if they are local labels or static symbols.
2398 Note we iterate over the input sections examining their
2399 relocations since the relocations for the output sections
2400 haven't been set yet. mark_symbols_used_in_relocations will
2401 ignore input sections which have no corresponding output
2404 bfd_map_over_sections(ibfd
, mark_symbols_used_in_relocations
, NULL
);
2405 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2406 ss_mark_symbols_used_in_relocations(ss
);
2407 struct asymbolp_vec osyms
;
2409 filter_symbols(ibfd
, obfd
, &osyms
, &fetch_superbfd(ibfd
)->syms
);
2410 copy_symbols(&osyms
, &fetch_superbfd(ibfd
)->new_syms
);
2412 bfd_set_symtab(obfd
, osyms
.data
, osyms
.size
);
2414 /* This has to happen after the symbol table has been set. */
2415 bfd_map_over_sections(obfd
, write_section
, NULL
);
2417 /* Allow the BFD backend to copy any private data it understands
2418 from the input BFD to the output BFD. This is done last to
2419 permit the routine to look at the filtered symbol table, which is
2420 important for the ECOFF code at least. */
2421 assert(bfd_copy_private_bfd_data(ibfd
, obfd
));
2426 /* Modified function from GNU Binutils objcopy.c */
2427 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
)
2429 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
2430 struct supersect
*ss
= fetch_supersect(isbfd
, isection
);
2431 bfd
*obfd
= obfdarg
;
2437 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2438 assert(osection
!= NULL
);
2440 osection
->userdata
= ss
;
2441 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2442 ss
->symbol
= osection
->symbol
;
2443 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2445 vma
= bfd_section_vma(ibfd
, isection
);
2446 assert(bfd_set_section_vma(obfd
, osection
, vma
));
2448 osection
->lma
= isection
->lma
;
2449 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2450 osection
->entsize
= ss
->entsize
;
2451 osection
->output_section
= osection
;
2452 osection
->output_offset
= 0;
2453 isection
->output_section
= osection
;
2454 isection
->output_offset
= 0;
2458 void setup_new_section(bfd
*obfd
, struct supersect
*ss
)
2460 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2461 assert(osection
!= NULL
);
2462 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2464 osection
->userdata
= ss
;
2465 ss
->symbol
= osection
->symbol
;
2466 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2467 assert(bfd_set_section_vma(obfd
, osection
, 0));
2470 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2471 osection
->entsize
= ss
->entsize
;
2472 osection
->output_section
= osection
;
2473 osection
->output_offset
= 0;
2476 static int compare_reloc_addresses(const void *aptr
, const void *bptr
)
2478 const arelent
*const *a
= aptr
, *const *b
= bptr
;
2479 return (*a
)->address
- (*b
)->address
;
2482 static void delete_obsolete_relocs(struct supersect
*ss
)
2484 if (ss
->new_relocs
.size
== 0)
2487 qsort(ss
->relocs
.data
, ss
->relocs
.size
, sizeof(*ss
->relocs
.data
),
2488 compare_reloc_addresses
);
2489 qsort(ss
->new_relocs
.data
, ss
->new_relocs
.size
,
2490 sizeof(*ss
->new_relocs
.data
), compare_reloc_addresses
);
2492 struct arelentp_vec orig_relocs
;
2493 vec_move(&orig_relocs
, &ss
->relocs
);
2495 arelent
**relocp
, **new_relocp
= ss
->new_relocs
.data
;
2496 for (relocp
= orig_relocs
.data
;
2497 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
2498 while (new_relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
&&
2499 (*new_relocp
)->address
< (*relocp
)->address
)
2501 arelent
*reloc
= *relocp
, *new_reloc
= *new_relocp
;
2502 if (new_relocp
== ss
->new_relocs
.data
+ ss
->new_relocs
.size
||
2503 reloc
->address
!= new_reloc
->address
)
2504 *vec_grow(&ss
->relocs
, 1) = reloc
;
2508 void write_section(bfd
*obfd
, asection
*osection
, void *arg
)
2510 struct supersect
*ss
= osection
->userdata
;
2512 if ((ss
->flags
& SEC_GROUP
) != 0 || ss
->contents
.size
== 0)
2515 delete_obsolete_relocs(ss
);
2518 char *error_message
;
2519 for (relocp
= ss
->new_relocs
.data
;
2520 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2522 if (bfd_get_arch(obfd
) == bfd_arch_arm
)
2523 val
= osection
->use_rela_p
? 0 : (*relocp
)->addend
;
2526 bfd_put(bfd_get_reloc_size((*relocp
)->howto
) * 8, obfd
, val
,
2527 ss
->contents
.data
+ (*relocp
)->address
);
2528 if (bfd_install_relocation(obfd
, *relocp
, ss
->contents
.data
,
2529 0, osection
, &error_message
) !=
2531 err(ss
->parent
, "ksplice: error installing reloc: %s",
2535 if (mode("finalize")) {
2536 /* Check that all our sections will be allocated */
2537 asymbol
*sym
= *((*relocp
)->sym_ptr_ptr
);
2538 if (!bfd_is_const_section(sym
->section
)) {
2539 struct supersect
*sym_ss
=
2540 fetch_supersect(ss
->parent
, sym
->section
);
2541 assert((sym_ss
->flags
& SEC_ALLOC
) != 0);
2545 memcpy(vec_grow(&ss
->relocs
, ss
->new_relocs
.size
), ss
->new_relocs
.data
,
2546 ss
->new_relocs
.size
* sizeof(*ss
->new_relocs
.data
));
2548 bfd_set_reloc(obfd
, osection
,
2549 ss
->relocs
.size
== 0 ? NULL
: ss
->relocs
.data
,
2552 if (ss
->flags
& SEC_HAS_CONTENTS
)
2553 assert(bfd_set_section_contents
2554 (obfd
, osection
, ss
->contents
.data
, 0,
2555 ss
->contents
.size
));
2558 /* Modified function from GNU Binutils objcopy.c
2560 * Mark all the symbols which will be used in output relocations with
2561 * the BSF_KEEP flag so that those symbols will not be stripped.
2563 * Ignore relocations which will not appear in the output file.
2565 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
2568 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2569 if (isection
->output_section
== NULL
)
2572 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2573 ss_mark_symbols_used_in_relocations(ss
);
2576 void ss_mark_symbols_used_in_relocations(struct supersect
*ss
)
2578 /* Examine each symbol used in a relocation. If it's not one of the
2579 special bfd section symbols, then mark it with BSF_KEEP. */
2581 for (relocp
= ss
->relocs
.data
;
2582 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2583 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2584 if (!(bfd_is_const_section(sym
->section
) &&
2585 sym
== sym
->section
->symbol
))
2586 sym
->flags
|= BSF_KEEP
;
2588 for (relocp
= ss
->new_relocs
.data
;
2589 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2590 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2591 if (!(bfd_is_const_section(sym
->section
) &&
2592 sym
== sym
->section
->symbol
))
2593 sym
->flags
|= BSF_KEEP
;
2597 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
)
2599 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2600 if (bfd_is_const_section(sym
->section
))
2602 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
2605 for (symp
= ss
->syms
.data
; symp
< ss
->syms
.data
+ ss
->syms
.size
; symp
++) {
2609 return symp
>= ss
->syms
.data
+ ss
->syms
.size
&&
2610 (sym
->flags
& BSF_SECTION_SYM
) == 0;
2613 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
2614 struct asymbolp_vec
*isyms
)
2617 struct superbfd
*sbfd
= fetch_superbfd(ibfd
);
2618 for (symp
= isyms
->data
; symp
< isyms
->data
+ isyms
->size
; symp
++) {
2619 asymbol
*sym
= *symp
;
2620 struct supersect
*sym_ss
= NULL
;
2621 struct span
*sym_span
= NULL
;
2622 if (!bfd_is_const_section(sym
->section
)) {
2623 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2624 sym_span
= find_span(sym_ss
, sym
->value
);
2627 if (mode("keep") && (sym
->flags
& BSF_GLOBAL
) != 0 &&
2628 !(mode("keep-new-code") && sym_span
!= NULL
&&
2630 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2632 if (mode("finalize") && (sym
->flags
& BSF_GLOBAL
) != 0)
2633 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2635 bool keep
= bfd_is_const_section(sym
->section
) ||
2636 (sym_ss
->keep
&& (sym
->flags
& BSF_SECTION_SYM
) != 0) ||
2637 (sym_span
!= NULL
&& sym_span
->keep
);
2638 if (bfd_is_und_section(sym
->section
) &&
2639 (sym
->flags
& BSF_KEEP
) == 0)
2641 if (bfd_is_abs_section(sym
->section
) &&
2642 (sym
->flags
& BSF_KEEP
) == 0 &&
2643 (sym
->flags
& BSF_FILE
) == 0)
2645 if (deleted_table_section_symbol(ibfd
, sym
))
2648 if (mode("keep-old-code") && sym_ss
!= NULL
&&
2649 sym_ss
->type
== SS_TYPE_EXPORT
)
2653 if (sym_ss
!= NULL
&& !sym_ss
->keep
) {
2654 err(sbfd
, "Kept symbol %s in unkept section "
2655 "%s\n", sym
->name
, sym
->section
->name
);
2658 *vec_grow(osyms
, 1) = sym
;
2663 static bool is_table_section(const char *name
, bool consider_other
,
2666 struct supersect
*tables_ss
=
2667 fetch_supersect(offsets_sbfd
,
2668 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2669 ".ksplice_table_sections"));
2670 const struct table_section
*ts
;
2671 for (ts
= tables_ss
->contents
.data
;
2672 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2674 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0)
2676 const char *osect_name
= read_string(tables_ss
,
2678 if (consider_other
&& osect_name
!= NULL
&&
2679 strcmp(name
, osect_name
) == 0)
2681 const char *crc_name
= read_string(tables_ss
, &ts
->crc_sect
);
2682 if (consider_crc
&& crc_name
!= NULL
&&
2683 strcmp(name
, crc_name
) == 0)
2689 const struct table_section
*get_table_section(const char *name
)
2691 struct supersect
*tables_ss
=
2692 fetch_supersect(offsets_sbfd
,
2693 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2694 ".ksplice_table_sections"));
2695 const struct table_section
*ts
;
2696 for (ts
= tables_ss
->contents
.data
;
2697 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2699 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0) {
2700 if (ts
->entry_contents_size
!= 0)
2701 assert(align(ts
->entry_contents_size
,
2704 struct table_section
*ns
= malloc(sizeof(*ns
));
2706 ns
->sect
= read_string(tables_ss
, &ts
->sect
);
2707 ns
->crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2709 read_string(tables_ss
, &ts
->other_sect
);
2716 enum supersect_type
supersect_type(struct supersect
*ss
)
2718 if (mode("finalize") &&
2719 strcmp(finalize_target
, "vmlinux") == 0 &&
2720 (strstarts(ss
->name
, ".ksplice_relocs.exit") ||
2721 strstarts(ss
->name
, ".ksplice_sections.exit") ||
2722 strstarts(ss
->name
, ".ksplice_patches.exit")))
2723 return SS_TYPE_EXIT
;
2724 if (strstarts(ss
->name
, ".ksplice_call"))
2725 return SS_TYPE_KSPLICE_CALL
;
2726 if (strstarts(ss
->name
, ".ksplice_extract"))
2727 return SS_TYPE_KSPLICE_EXTRACT
;
2728 if (strstarts(ss
->name
, ".ksplice_options"))
2729 return SS_TYPE_SPECIAL
;
2730 if (strstarts(ss
->name
, ".ksplice"))
2731 return SS_TYPE_KSPLICE
;
2733 if (strstarts(ss
->name
, ".init"))
2734 return SS_TYPE_IGNORED
;
2735 if (strstarts(ss
->name
, ".security_initcall.init"))
2736 return SS_TYPE_IGNORED
;
2737 if (strstarts(ss
->name
, ".con_initcall.init"))
2738 return SS_TYPE_IGNORED
;
2739 if (strstarts(ss
->name
, ".x86cpuvendor.init"))
2740 return SS_TYPE_IGNORED
;
2741 if (strstarts(ss
->name
, ".early_param.init"))
2742 return SS_TYPE_IGNORED
;
2743 if (strstarts(ss
->name
, ".taglist.init"))
2744 return SS_TYPE_IGNORED
;
2745 if (strstarts(ss
->name
, ".x86_cpu_dev.init"))
2746 return SS_TYPE_IGNORED
;
2747 if (strstarts(ss
->name
, ".arch.info.init"))
2748 return SS_TYPE_IGNORED
;
2749 if (strstarts(ss
->name
, ".proc.info.init"))
2750 return SS_TYPE_IGNORED
;
2751 /* .pci_fixup_* sections really should be treated as global rodata
2752 referenced only from quirks.c */
2753 if (strstarts(ss
->name
, ".pci_fixup_"))
2754 return SS_TYPE_IGNORED
;
2755 /* .builtin_fw sections are similar to .pci_fixup */
2756 if (strstarts(ss
->name
, ".builtin_fw"))
2757 return SS_TYPE_IGNORED
;
2758 /* same for .tracedata */
2759 if (strstarts(ss
->name
, ".tracedata"))
2760 return SS_TYPE_IGNORED
;
2761 if (strstarts(ss
->name
, ".debug"))
2762 return SS_TYPE_IGNORED
;
2763 /* .eh_frame should probably be discarded, not ignored */
2764 if (strstarts(ss
->name
, ".eh_frame"))
2765 return SS_TYPE_IGNORED
;
2766 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devinit"))
2767 return SS_TYPE_IGNORED
;
2768 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".meminit"))
2769 return SS_TYPE_IGNORED
;
2770 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuinit"))
2771 return SS_TYPE_IGNORED
;
2772 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devexit"))
2773 return SS_TYPE_IGNORED
;
2774 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".memexit"))
2775 return SS_TYPE_IGNORED
;
2776 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuexit"))
2777 return SS_TYPE_IGNORED
;
2778 if (strstarts(ss
->name
, ".vgetcpu_mode") ||
2779 strstarts(ss
->name
, ".jiffies") ||
2780 strstarts(ss
->name
, ".wall_jiffies") ||
2781 strstarts(ss
->name
, ".vxtime") ||
2782 strstarts(ss
->name
, ".sys_tz") ||
2783 strstarts(ss
->name
, ".sysctl_vsyscall") ||
2784 strstarts(ss
->name
, ".xtime") ||
2785 strstarts(ss
->name
, ".xtime_lock") ||
2786 strstarts(ss
->name
, ".vsyscall"))
2787 return SS_TYPE_IGNORED
;
2788 if (strstarts(ss
->name
, ".vdso"))
2789 return SS_TYPE_IGNORED
;
2791 if (strstarts(ss
->name
, ".exit.text"))
2792 return SS_TYPE_TEXT
;
2793 if (strstarts(ss
->name
, ".exit.data"))
2794 return SS_TYPE_DATA
;
2796 if (strstarts(ss
->name
, ".text") ||
2797 strstarts(ss
->name
, ".kernel.text") ||
2798 strstarts(ss
->name
, ".devinit.text") ||
2799 strstarts(ss
->name
, ".meminit.text") ||
2800 strstarts(ss
->name
, ".cpuinit.text") ||
2801 strstarts(ss
->name
, ".devexit.text") ||
2802 strstarts(ss
->name
, ".memexit.text") ||
2803 strstarts(ss
->name
, ".cpuexit.text") ||
2804 strstarts(ss
->name
, ".ref.text") ||
2805 strstarts(ss
->name
, ".spinlock.text") ||
2806 strstarts(ss
->name
, ".kprobes.text") ||
2807 strstarts(ss
->name
, ".sched.text") ||
2808 strstarts(ss
->name
, ".entry.text") || /* OpenVZ */
2809 (mode("keep-old-code") && strstarts(ss
->name
, ".fixup")))
2810 return SS_TYPE_TEXT
;
2813 if (sscanf(ss
->name
, ".rodata.str%*u.%*u%n", &n
) >= 0 &&
2814 n
== strlen(ss
->name
))
2815 return ss
->entsize
== 1 ? SS_TYPE_STRING
: SS_TYPE_RODATA
;
2817 if (strstarts(ss
->name
, ".rodata") ||
2818 strstarts(ss
->name
, ".kernel.rodata") ||
2819 strstarts(ss
->name
, ".devinit.rodata") ||
2820 strstarts(ss
->name
, ".meminit.rodata") ||
2821 strstarts(ss
->name
, ".cpuinit.rodata") ||
2822 strstarts(ss
->name
, ".devexit.rodata") ||
2823 strstarts(ss
->name
, ".memexit.rodata") ||
2824 strstarts(ss
->name
, ".cpuexit.rodata") ||
2825 strstarts(ss
->name
, ".ref.rodata") ||
2826 strstarts(ss
->name
, "__tracepoints_strings") ||
2827 strstarts(ss
->name
, "__markers_strings") ||
2828 (mode("keep-old-code") && strstarts(ss
->name
, "__ex_table")))
2829 return SS_TYPE_RODATA
;
2831 if (strstarts(ss
->name
, ".bss"))
2832 return SS_TYPE_DATA
;
2834 /* Ignore .data.percpu sections */
2835 if (strstarts(ss
->name
, ".data.percpu") ||
2836 strstarts(ss
->name
, ".kernel.data.percpu") ||
2837 strstarts(ss
->name
, ".data..percpu"))
2838 return SS_TYPE_IGNORED
;
2839 if (strstarts(ss
->name
, ".data") ||
2840 strstarts(ss
->name
, ".kernel.data") ||
2841 strstarts(ss
->name
, ".devinit.data") ||
2842 strstarts(ss
->name
, ".cpuinit.data") ||
2843 strstarts(ss
->name
, ".meminit.data") ||
2844 strstarts(ss
->name
, ".devexit.data") ||
2845 strstarts(ss
->name
, ".memexit.data") ||
2846 strstarts(ss
->name
, ".cpuexit.data") ||
2847 strstarts(ss
->name
, ".ref.data") ||
2848 strstarts(ss
->name
, "__tracepoints") ||
2849 strstarts(ss
->name
, "__markers"))
2850 return SS_TYPE_DATA
;
2852 /* We replace all the ksymtab strings, so delete them */
2853 if (strcmp(ss
->name
, "__ksymtab_strings") == 0)
2854 return SS_TYPE_STRING
;
2855 if (strstarts(ss
->name
, "__ksymtab"))
2856 return SS_TYPE_EXPORT
;
2858 if (strstarts(ss
->name
, "__bug_table"))
2859 return SS_TYPE_BUGTABLE
;
2861 if (is_table_section(ss
->name
, true, true))
2862 return SS_TYPE_SPECIAL
;
2864 if (strstarts(ss
->name
, ".ARM."))
2865 return SS_TYPE_SPECIAL
;
2867 if (strstarts(ss
->name
, ".note"))
2868 return SS_TYPE_IGNORED
;
2869 if (strstarts(ss
->name
, ".comment"))
2870 return SS_TYPE_IGNORED
;
2871 if (strstarts(ss
->name
, "__param"))
2872 return SS_TYPE_IGNORED
;
2873 if (strstarts(ss
->name
, "__obsparm"))
2874 return SS_TYPE_IGNORED
;
2875 if (strstarts(ss
->name
, ".exitcall.exit"))
2876 return SS_TYPE_IGNORED
;
2877 if (strstarts(ss
->name
, ".modinfo"))
2878 return SS_TYPE_IGNORED
;
2880 return SS_TYPE_UNKNOWN
;
2883 void initialize_supersect_types(struct superbfd
*sbfd
)
2886 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2887 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2888 ss
->type
= supersect_type(ss
);
2889 ss
->orig_type
= ss
->type
;
2890 if (ss
->type
== SS_TYPE_UNKNOWN
) {
2891 err(sbfd
, "Unknown section type: %s\n", ss
->name
);
2897 static void init_label_map(struct superbfd
*sbfd
)
2899 struct label_map
*map
;
2901 vec_init(&sbfd
->maps
);
2905 struct symbol_hash csyms
;
2906 symbol_hash_init(&csyms
);
2909 for (symp
= sbfd
->syms
.data
;
2910 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2911 asymbol
*csym
= canonical_symbol(sbfd
, *symp
);
2914 char *key
= strprintf("%p", csym
);
2915 asymbol
**csymp
= symbol_hash_lookup(&csyms
, key
, TRUE
);
2921 map
= vec_grow(&sbfd
->maps
, 1);
2924 map
->label
= symbol_label(sbfd
, csym
);
2927 struct label_mapp_hash label_maps
;
2928 label_mapp_hash_init(&label_maps
);
2929 for (map
= sbfd
->maps
.data
;
2930 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2931 struct label_map
**mapp
=
2932 label_mapp_hash_lookup(&label_maps
, map
->label
, TRUE
);
2933 if (*mapp
== NULL
) {
2938 struct label_map
*first_map
= *mapp
;
2939 if (first_map
->count
== 0)
2940 first_map
->label
= strprintf("%s~%d", map
->label
, 0);
2941 map
->label
= strprintf("%s~%d", map
->label
, ++first_map
->count
);
2944 label_mapp_hash_init(&sbfd
->maps_hash
);
2945 for (map
= sbfd
->maps
.data
;
2946 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2947 char *key
= strprintf("%p", map
->csym
);
2948 struct label_map
**mapp
=
2949 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, TRUE
);
2952 map
->orig_label
= map
->label
;
2956 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
)
2958 asymbol
*csym
= canonical_symbol(sbfd
, sym
);
2959 char *key
= strprintf("%p", csym
);
2960 struct label_map
**mapp
=
2961 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2965 return (*mapp
)->label
;
2968 static void print_label_changes(struct superbfd
*sbfd
)
2972 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2973 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2974 for (span
= ss
->spans
.data
;
2975 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
2976 if (strcmp(span
->label
, span
->orig_label
) != 0)
2977 debug1(sbfd
, "Label change: %s -> %s\n",
2978 span
->label
, span
->orig_label
);
2983 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
2986 struct label_map
*map
;
2987 for (map
= sbfd
->maps
.data
;
2988 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2989 if (strcmp(map
->orig_label
, oldlabel
) == 0) {
2990 if (strcmp(map
->orig_label
, map
->label
) != 0 &&
2991 strcmp(map
->label
, label
) != 0)
3000 static void change_initial_label(struct span
*span
, const char *label
)
3002 struct superbfd
*sbfd
= span
->ss
->parent
;
3003 span
->label
= label
;
3004 span
->orig_label
= label
;
3006 asymbol
*csym
= canonical_symbol(sbfd
, span
->symbol
);
3007 char *key
= strprintf("%p", csym
);
3008 struct label_map
**mapp
=
3009 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
3012 (*mapp
)->label
= span
->label
;
3013 (*mapp
)->orig_label
= span
->orig_label
;
3014 span
->symbol
= NULL
;
3018 static void init_callers(struct superbfd
*sbfd
)
3020 string_hash_init(&sbfd
->callers
);
3022 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3023 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3025 for (relocp
= ss
->relocs
.data
;
3026 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3027 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
3029 sym
->value
+ reloc_target_offset(ss
, *relocp
);
3030 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3032 const char **ret
= string_hash_lookup(&sbfd
->callers
,
3035 asymbol
*csym
= canonical_symbol(sbfd
, sect
->symbol
);
3037 *ret
= "*multiple_callers*";
3038 else if (static_local_symbol(sbfd
, csym
))
3039 *ret
= static_local_symbol(sbfd
, csym
);
3046 static const char *find_caller(struct supersect
*ss
, asymbol
*sym
)
3048 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3049 (unsigned long)sym
->value
);
3050 const char **ret
= string_hash_lookup(&ss
->parent
->callers
, key
, FALSE
);
3054 return "*no_caller*";
3058 static void init_csyms(struct superbfd
*sbfd
)
3060 asymbolpp_hash_init(&sbfd
->csyms
);
3063 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
3065 asymbol
*sym
= *symp
;
3066 if ((sym
->flags
& BSF_DEBUGGING
) != 0)
3068 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3069 (unsigned long)sym
->value
);
3070 asymbol
***csympp
= asymbolpp_hash_lookup(&sbfd
->csyms
, key
,
3073 if (*csympp
== NULL
) {
3077 asymbol
*csym
= **csympp
;
3078 if ((csym
->flags
& BSF_GLOBAL
) != 0)
3080 if ((sym
->flags
& BSF_GLOBAL
) != 0)
3085 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
)
3087 char *key
= strprintf("%s+%lx", ss
->name
, (unsigned long)value
);
3089 asymbolpp_hash_lookup(&ss
->parent
->csyms
, key
, FALSE
);
3094 /* For section symbols of sections containing no symbols, return the
3095 section symbol that relocations are generated against */
3101 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
)
3103 if (bfd_is_const_section(sym
->section
)) {
3105 for (csymp
= sbfd
->syms
.data
;
3106 csymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; csymp
++) {
3112 return symbolp_scan(fetch_supersect(sbfd
, sym
->section
), sym
->value
);
3115 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3117 if (bfd_is_const_section(sym
->section
))
3119 asymbol
**symp
= canonical_symbolp(sbfd
, sym
);
3120 return symp
!= NULL
? *symp
: NULL
;
3123 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3125 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
3126 if ((sym
->flags
& BSF_LOCAL
) == 0 || (sym
->flags
& BSF_OBJECT
) == 0)
3128 char *dot
= strrchr(sym
->name
, '.');
3129 if (dot
== NULL
|| dot
[1 + strspn(dot
+ 1, "0123546789")] != '\0')
3131 char *basename
= strndup(sym
->name
, dot
- sym
->name
);
3133 /* Handle C.123.12345 symbols */
3134 dot
= strrchr(basename
, '.');
3135 if (dot
!= NULL
&& dot
[1 + strspn(dot
+ 1, "0123546789")] == '\0')
3136 basename
= strndup(basename
, dot
- basename
);
3138 if (strcmp(basename
, "__func__") == 0 ||
3139 strcmp(basename
, "__PRETTY_FUNCTION__") == 0)
3140 caller
= (const char *)ss
->contents
.data
+ sym
->value
;
3142 caller
= find_caller(ss
, sym
);
3143 return strprintf("%s<%s>", basename
, caller
);
3146 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
)
3148 const char *filename
= sbfd
->abfd
->filename
;
3149 char *c
= strstr(filename
, ".KSPLICE");
3150 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
3153 if (bfd_is_und_section(sym
->section
) || (sym
->flags
& BSF_GLOBAL
) != 0) {
3154 label
= strdup(sym
->name
);
3155 } else if (bfd_is_const_section(sym
->section
)) {
3156 label
= strprintf("%s<%.*s>", sym
->name
, flen
, filename
);
3158 asymbol
*gsym
= canonical_symbol(sbfd
, sym
);
3161 label
= strprintf("%s+%lx<%.*s>",
3163 (unsigned long)sym
->value
,
3165 else if ((gsym
->flags
& BSF_GLOBAL
) != 0)
3166 label
= strdup(gsym
->name
);
3167 else if (static_local_symbol(sbfd
, gsym
))
3168 label
= strprintf("%s+%lx<%.*s>",
3169 static_local_symbol(sbfd
, gsym
),
3170 (unsigned long)sym
->value
,
3173 label
= strprintf("%s<%.*s>",
3174 gsym
->name
, flen
, filename
);
3180 static void keep_span(struct span
*span
)
3183 span
->ss
->keep
= true;
3186 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
)
3188 struct span
*span
= vec_grow(&ss
->spans
, 1);
3190 span
->contents_size
= size
;
3191 span
->start
= start
;
3195 span
->patch
= false;
3196 span
->bugpatch
= false;
3197 span
->datapatch
= false;
3198 span
->precallable
= strstarts(ss
->name
, ".ksplice_call_pre_apply") ||
3199 strstarts(ss
->name
, ".ksplice_call_check_apply") ||
3200 strstarts(ss
->name
, ".ksplice_call_fail_apply") ||
3201 strstarts(ss
->name
, ".ksplice_call_post_remove");
3203 vec_init(&span
->entry_points
);
3205 asymbol
**symp
= symbolp_scan(ss
, span
->start
);
3207 span
->symbol
= *symp
;
3208 span
->label
= label_lookup(ss
->parent
, span
->symbol
);
3210 span
->symbol
= NULL
;
3211 const char *label
= label_lookup(ss
->parent
, ss
->symbol
);
3212 if (span
->start
!= 0)
3213 span
->label
= strprintf("%s<span:%lx>", label
,
3214 (unsigned long)span
->start
);
3216 span
->label
= label
;
3218 span
->orig_label
= span
->label
;
3222 static void initialize_string_spans(struct supersect
*ss
)
3225 for (str
= ss
->contents
.data
;
3226 (void *)str
< ss
->contents
.data
+ ss
->contents
.size
;) {
3227 bfd_vma start
= (unsigned long)str
-
3228 (unsigned long)ss
->contents
.data
;
3229 bfd_vma size
= strlen(str
) + 1;
3230 bfd_vma contents_size
= size
;
3231 while ((start
+ size
) % (1 << ss
->alignment
) != 0 &&
3232 start
+ size
< ss
->contents
.size
) {
3233 /* Some string sections, like __ksymtab_strings, only
3234 align some strings with the declared alignment */
3235 if (str
[size
] != '\0')
3239 struct span
*span
= new_span(ss
, start
, size
);
3240 span
->contents_size
= contents_size
;
3245 static int compare_ulongs(const void *va
, const void *vb
)
3247 const unsigned long *a
= va
, *b
= vb
;
3251 static void initialize_table_spans(struct superbfd
*sbfd
,
3252 struct table_section
*s
)
3254 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
3255 if (isection
== NULL
)
3257 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
3258 if (ss
->alignment
< ffs(s
->entry_align
) - 1)
3259 ss
->alignment
= ffs(s
->entry_align
) - 1;
3261 asection
*other_sect
= NULL
;
3262 if (s
->other_sect
!= NULL
)
3263 other_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->other_sect
);
3264 struct supersect
*other_ss
= NULL
;
3265 if (other_sect
!= NULL
)
3266 other_ss
= fetch_supersect(sbfd
, other_sect
);
3268 asection
*crc_sect
= NULL
;
3269 if (s
->crc_sect
!= NULL
)
3270 crc_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->crc_sect
);
3271 struct supersect
*crc_ss
= NULL
;
3272 if (crc_sect
!= NULL
)
3273 crc_ss
= fetch_supersect(sbfd
, crc_sect
);
3275 struct ulong_vec offsets
;
3279 for (entry
= ss
->contents
.data
;
3280 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3281 entry
+= s
->entry_size
) {
3282 struct span
*span
= new_span(ss
, addr_offset(ss
, entry
),
3284 if (s
->entry_contents_size
!= 0)
3285 span
->contents_size
= s
->entry_contents_size
;
3286 if ((span
->symbol
== NULL
||
3287 (span
->symbol
->flags
& BSF_SECTION_SYM
) != 0) &&
3289 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
3291 struct span
*target_span
= reloc_target_span(ss
, reloc
);
3292 assert(target_span
);
3293 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3294 unsigned long val
= sym
->value
+
3295 reloc_target_offset(ss
, reloc
) -
3296 (target_span
->start
+ target_span
->shift
);
3297 char *label
= strprintf("%s<target:%s+%lx>", ss
->name
,
3298 target_span
->label
, val
);
3299 change_initial_label(span
, label
);
3302 if (other_sect
!= NULL
) {
3304 bfd_vma offset
= read_reloc(ss
, entry
+ s
->other_offset
,
3305 sizeof(void *), &sym
);
3306 if (sym
->section
== other_sect
) {
3307 assert(offset
>= 0 &&
3308 offset
< other_ss
->contents
.size
);
3309 *vec_grow(&offsets
, 1) = offset
;
3313 if (crc_sect
!= NULL
)
3314 new_span(crc_ss
, addr_offset(ss
, entry
) / s
->entry_size
3315 * s
->crc_size
, s
->crc_size
);
3317 if (ss
->type
== SS_TYPE_EXPORT
) {
3318 const char *symname
= read_string(ss
, entry
+
3320 char *label
= strprintf("%s:%s", ss
->name
, symname
);
3321 change_initial_label(span
, label
);
3325 if (other_sect
== NULL
)
3328 *vec_grow(&offsets
, 1) = 0;
3329 qsort(offsets
.data
, offsets
.size
, sizeof(*offsets
.data
),
3331 *vec_grow(&offsets
, 1) = other_ss
->contents
.size
;
3334 for (off
= offsets
.data
; off
< offsets
.data
+ offsets
.size
- 1; off
++) {
3335 if (*off
!= *(off
+ 1))
3336 new_span(other_ss
, *off
, *(off
+ 1) - *off
);
3340 static void initialize_table_section_spans(struct superbfd
*sbfd
)
3342 struct supersect
*tables_ss
=
3343 fetch_supersect(offsets_sbfd
,
3344 bfd_get_section_by_name(offsets_sbfd
->abfd
,
3345 ".ksplice_table_sections"));
3346 const struct table_section
*ts
;
3347 struct table_section s
;
3348 for (ts
= tables_ss
->contents
.data
;
3349 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
3352 s
.sect
= read_string(tables_ss
, &ts
->sect
);
3353 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
3354 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
3355 initialize_table_spans(sbfd
, &s
);
3359 static void initialize_ksplice_call_spans(struct supersect
*ss
)
3362 for (relocp
= ss
->relocs
.data
;
3363 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3364 arelent
*reloc
= *relocp
;
3365 new_span(ss
, reloc
->address
, bfd_get_reloc_size(reloc
->howto
));
3366 /* the span labels should already be unique */
3370 static void initialize_spans(struct superbfd
*sbfd
)
3373 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3374 if (is_table_section(sect
->name
, true, true) && mode("keep"))
3377 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3378 if (ss
->type
== SS_TYPE_STRING
)
3379 initialize_string_spans(ss
);
3380 else if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
3381 initialize_ksplice_call_spans(ss
);
3383 new_span(ss
, 0, ss
->contents
.size
);
3386 initialize_table_section_spans(sbfd
);
3389 /* Returns the span pointed to by the relocation at span->start + offset */
3390 static struct span
*span_offset_target_span(struct span
*span
, int offset
)
3392 void *entry
= span
->ss
->contents
.data
+ span
->start
;
3393 arelent
*reloc
= find_reloc(span
->ss
, entry
+ offset
);
3396 return reloc_target_span(span
->ss
, reloc
);
3399 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
)
3401 asymbol
*sym_ptr
= *reloc
->sym_ptr_ptr
;
3402 if (bfd_is_const_section(sym_ptr
->section
))
3405 bfd_vma addend
= sym_ptr
->value
;
3406 if ((sym_ptr
->flags
& BSF_SECTION_SYM
) != 0)
3407 addend
+= reloc_target_offset(ss
, reloc
);
3409 struct supersect
*sym_ss
=
3410 fetch_supersect(ss
->parent
, sym_ptr
->section
);
3411 struct span
*span
, *target_span
= sym_ss
->spans
.data
;
3412 for (span
= sym_ss
->spans
.data
;
3413 span
< sym_ss
->spans
.data
+ sym_ss
->spans
.size
; span
++) {
3414 if (addend
>= span
->start
&& addend
< span
->start
+ span
->size
)
3420 static bfd_vma
reloc_target_offset(struct supersect
*ss
, arelent
*reloc
)
3422 bfd_vma offset
= reloc_offset(ss
, reloc
);
3423 if (reloc
->howto
->pc_relative
) {
3424 if ((ss
->flags
& SEC_CODE
) != 0)
3425 return offset
+ bfd_get_reloc_size(reloc
->howto
);
3427 const struct table_section
*ts
= get_table_section(ss
->name
);
3428 if (ts
!= NULL
&& ts
->relative_addr
&&
3429 reloc
->address
% ts
->entry_size
== ts
->addr_offset
)
3430 return offset
- ts
->addr_offset
;
3431 if (ts
!= NULL
&& ts
->relative_other
&&
3432 reloc
->address
% ts
->entry_size
== ts
->other_offset
)
3433 return offset
- ts
->other_offset
;
3440 struct span
*find_span(struct supersect
*ss
, bfd_size_type address
)
3443 for (span
= ss
->spans
.data
; span
< ss
->spans
.data
+ ss
->spans
.size
;
3445 if (address
>= span
->start
&&
3446 address
< span
->start
+ span
->size
)
3449 /* Deal with empty BSS sections */
3450 if (ss
->contents
.size
== 0 && ss
->spans
.size
> 0)
3451 return ss
->spans
.data
;
3452 /* Deal with section end pointers */
3453 if (address
== ss
->contents
.size
&& ss
->spans
.size
== 1)
3454 return ss
->spans
.data
;
3458 void compute_span_shifts(struct superbfd
*sbfd
)
3462 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3463 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3466 bfd_size_type offset
= 0;
3467 for (span
= ss
->spans
.data
;
3468 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
3471 span
->shift
= offset
- span
->start
;
3472 offset
+= span
->size
;
3477 void remove_unkept_spans(struct superbfd
*sbfd
)
3481 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3482 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3483 delete_obsolete_relocs(ss
);
3484 struct arelentp_vec orig_relocs
;
3485 vec_move(&orig_relocs
, &ss
->relocs
);
3486 arelent
**relocp
, *reloc
;
3487 for (relocp
= orig_relocs
.data
;
3488 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
3490 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3491 span
= reloc_target_span(ss
, reloc
);
3492 if ((span
!= NULL
&& span
->keep
&& span
->shift
== 0) ||
3493 bfd_is_const_section(sym
->section
)) {
3494 *vec_grow(&ss
->relocs
, 1) = reloc
;
3497 struct supersect
*sym_ss
=
3498 fetch_supersect(sbfd
, sym
->section
);
3499 if (span
!= NULL
&& (sym
->flags
& BSF_SECTION_SYM
) == 0
3500 && find_span(sym_ss
, sym
->value
) != span
) {
3501 err(sbfd
, "Spans for symbol %s and relocation "
3502 "target do not match in sect %s\n",
3503 sym
->name
, sym_ss
->name
);
3506 if (span
!= NULL
&& span
->keep
) {
3507 arelent
*new_reloc
= malloc(sizeof(*new_reloc
));
3508 *new_reloc
= *reloc
;
3509 new_reloc
->addend
= reloc_offset(ss
, reloc
);
3510 new_reloc
->addend
+= span
->shift
;
3511 *vec_grow(&ss
->new_relocs
, 1) = new_reloc
;
3516 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3517 struct supersect
*ss
= fetch_supersect(sbfd
, sect
), orig_ss
;
3520 supersect_move(&orig_ss
, ss
);
3521 vec_init(&ss
->spans
);
3522 for (span
= orig_ss
.spans
.data
;
3523 span
< orig_ss
.spans
.data
+ orig_ss
.spans
.size
; span
++) {
3526 struct span
*new_span
= vec_grow(&ss
->spans
, 1);
3528 new_span
->start
= span
->start
+ span
->shift
;
3529 new_span
->shift
= 0;
3530 sect_copy(ss
, sect_do_grow(ss
, 1, span
->size
, 1),
3531 &orig_ss
, orig_ss
.contents
.data
+ span
->start
,
3537 static void init_objmanip_superbfd(struct superbfd
*sbfd
)
3539 init_label_map(sbfd
);
3540 initialize_supersect_types(sbfd
);
3541 initialize_spans(sbfd
);
3543 compute_entry_points(sbfd
);
3546 void mangle_section_name(struct superbfd
*sbfd
, const char *name
)
3548 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
3551 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3552 ss
->name
= strprintf(".ksplice_pre.%s", ss
->name
);
3555 static void write_bugline_patches(struct superbfd
*sbfd
)
3557 const struct table_section
*ts
= get_table_section("__bug_table");
3558 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, "__bug_table");
3561 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3565 for (entry
= ss
->contents
.data
;
3566 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3567 entry
+= ts
->entry_size
) {
3568 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
3569 assert(span
!= NULL
);
3570 if (!span
->bugpatch
)
3572 arelent
*reloc
= find_reloc(ss
, entry
+ ts
->addr_offset
);
3573 assert(reloc
!= NULL
);
3574 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3575 assert(!bfd_is_const_section(sym
->section
));
3576 struct supersect
*kpatch_ss
=
3577 make_section(sbfd
, ".ksplice_patches%s",
3578 sym
->section
->name
);
3580 bfd_vma offset
, start
= 0;
3581 for (offset
= 0; offset
<= span
->size
; offset
++) {
3582 if (offset
!= span
->size
&&
3583 !part_of_reloc(ss
, span
->start
+ offset
))
3585 if (start
== offset
) {
3589 /* an interval of non-relocations just passed */
3590 struct ksplice_patch
*kpatch
=
3591 sect_grow(kpatch_ss
, 1, struct ksplice_patch
);
3592 write_ksplice_patch_reloc
3593 (kpatch_ss
, sym
->section
->name
, &kpatch
->oldaddr
,
3594 sizeof(kpatch
->oldaddr
), span
->label
, start
);
3596 char *data
= write_patch_storage(kpatch_ss
, kpatch
,
3597 offset
- start
, NULL
);
3598 memcpy(data
, entry
+ start
, offset
- start
);
3599 kpatch
->type
= KSPLICE_PATCH_DATA
;
3605 void *write_patch_storage(struct supersect
*ss
, struct ksplice_patch
*kpatch
,
3606 size_t size
, struct supersect
**data_ssp
)
3608 struct supersect
*data_ss
= make_section(ss
->parent
,
3609 ".ksplice_patch_data");
3610 char *saved
= sect_do_grow(data_ss
, 1, size
, 1);
3611 write_reloc(ss
, &kpatch
->saved
, &data_ss
->symbol
,
3612 addr_offset(data_ss
, saved
));
3613 char *data
= sect_do_grow(data_ss
, 1, size
, 1);
3614 write_reloc(ss
, &kpatch
->contents
, &data_ss
->symbol
,
3615 addr_offset(data_ss
, data
));
3616 kpatch
->size
= size
;
3617 if (data_ssp
!= NULL
)
3618 *data_ssp
= data_ss
;