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
++) {
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(new_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
, ".arch.info.init"))
2746 return SS_TYPE_IGNORED
;
2747 if (strstarts(ss
->name
, ".proc.info.init"))
2748 return SS_TYPE_IGNORED
;
2749 /* .pci_fixup_* sections really should be treated as global rodata
2750 referenced only from quirks.c */
2751 if (strstarts(ss
->name
, ".pci_fixup_"))
2752 return SS_TYPE_IGNORED
;
2753 /* .builtin_fw sections are similar to .pci_fixup */
2754 if (strstarts(ss
->name
, ".builtin_fw"))
2755 return SS_TYPE_IGNORED
;
2756 /* same for .tracedata */
2757 if (strstarts(ss
->name
, ".tracedata"))
2758 return SS_TYPE_IGNORED
;
2759 if (strstarts(ss
->name
, ".debug"))
2760 return SS_TYPE_IGNORED
;
2761 /* .eh_frame should probably be discarded, not ignored */
2762 if (strstarts(ss
->name
, ".eh_frame"))
2763 return SS_TYPE_IGNORED
;
2764 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devinit"))
2765 return SS_TYPE_IGNORED
;
2766 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".meminit"))
2767 return SS_TYPE_IGNORED
;
2768 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuinit"))
2769 return SS_TYPE_IGNORED
;
2770 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devexit"))
2771 return SS_TYPE_IGNORED
;
2772 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".memexit"))
2773 return SS_TYPE_IGNORED
;
2774 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuexit"))
2775 return SS_TYPE_IGNORED
;
2776 if (strstarts(ss
->name
, ".vgetcpu_mode") ||
2777 strstarts(ss
->name
, ".jiffies") ||
2778 strstarts(ss
->name
, ".wall_jiffies") ||
2779 strstarts(ss
->name
, ".vxtime") ||
2780 strstarts(ss
->name
, ".sys_tz") ||
2781 strstarts(ss
->name
, ".sysctl_vsyscall") ||
2782 strstarts(ss
->name
, ".xtime") ||
2783 strstarts(ss
->name
, ".xtime_lock") ||
2784 strstarts(ss
->name
, ".vsyscall"))
2785 return SS_TYPE_IGNORED
;
2786 if (strstarts(ss
->name
, ".vdso"))
2787 return SS_TYPE_IGNORED
;
2789 if (strstarts(ss
->name
, ".exit.text"))
2790 return SS_TYPE_TEXT
;
2791 if (strstarts(ss
->name
, ".exit.data"))
2792 return SS_TYPE_DATA
;
2794 if (strstarts(ss
->name
, ".text") ||
2795 strstarts(ss
->name
, ".kernel.text") ||
2796 strstarts(ss
->name
, ".devinit.text") ||
2797 strstarts(ss
->name
, ".meminit.text") ||
2798 strstarts(ss
->name
, ".cpuinit.text") ||
2799 strstarts(ss
->name
, ".devexit.text") ||
2800 strstarts(ss
->name
, ".memexit.text") ||
2801 strstarts(ss
->name
, ".cpuexit.text") ||
2802 strstarts(ss
->name
, ".ref.text") ||
2803 strstarts(ss
->name
, ".spinlock.text") ||
2804 strstarts(ss
->name
, ".kprobes.text") ||
2805 strstarts(ss
->name
, ".sched.text") ||
2806 strstarts(ss
->name
, ".entry.text") || /* OpenVZ */
2807 (mode("keep-old-code") && strstarts(ss
->name
, ".fixup")))
2808 return SS_TYPE_TEXT
;
2811 if (sscanf(ss
->name
, ".rodata.str%*u.%*u%n", &n
) >= 0 &&
2812 n
== strlen(ss
->name
))
2813 return ss
->entsize
== 1 ? SS_TYPE_STRING
: SS_TYPE_RODATA
;
2815 if (strstarts(ss
->name
, ".rodata") ||
2816 strstarts(ss
->name
, ".kernel.rodata") ||
2817 strstarts(ss
->name
, ".devinit.rodata") ||
2818 strstarts(ss
->name
, ".meminit.rodata") ||
2819 strstarts(ss
->name
, ".cpuinit.rodata") ||
2820 strstarts(ss
->name
, ".devexit.rodata") ||
2821 strstarts(ss
->name
, ".memexit.rodata") ||
2822 strstarts(ss
->name
, ".cpuexit.rodata") ||
2823 strstarts(ss
->name
, ".ref.rodata") ||
2824 strstarts(ss
->name
, "__tracepoints_strings") ||
2825 strstarts(ss
->name
, "__markers_strings") ||
2826 (mode("keep-old-code") && strstarts(ss
->name
, "__ex_table")))
2827 return SS_TYPE_RODATA
;
2829 if (strstarts(ss
->name
, ".bss"))
2830 return SS_TYPE_DATA
;
2832 /* Ignore .data.percpu sections */
2833 if (strstarts(ss
->name
, ".data.percpu") ||
2834 strstarts(ss
->name
, ".kernel.data.percpu") ||
2835 strstarts(ss
->name
, ".data..percpu"))
2836 return SS_TYPE_IGNORED
;
2837 if (strstarts(ss
->name
, ".data") ||
2838 strstarts(ss
->name
, ".kernel.data") ||
2839 strstarts(ss
->name
, ".devinit.data") ||
2840 strstarts(ss
->name
, ".cpuinit.data") ||
2841 strstarts(ss
->name
, ".meminit.data") ||
2842 strstarts(ss
->name
, ".devexit.data") ||
2843 strstarts(ss
->name
, ".memexit.data") ||
2844 strstarts(ss
->name
, ".cpuexit.data") ||
2845 strstarts(ss
->name
, ".ref.data") ||
2846 strstarts(ss
->name
, "__tracepoints") ||
2847 strstarts(ss
->name
, "__markers"))
2848 return SS_TYPE_DATA
;
2850 /* We replace all the ksymtab strings, so delete them */
2851 if (strcmp(ss
->name
, "__ksymtab_strings") == 0)
2852 return SS_TYPE_STRING
;
2853 if (strstarts(ss
->name
, "__ksymtab"))
2854 return SS_TYPE_EXPORT
;
2856 if (strstarts(ss
->name
, "__bug_table"))
2857 return SS_TYPE_BUGTABLE
;
2859 if (is_table_section(ss
->name
, true, true))
2860 return SS_TYPE_SPECIAL
;
2862 if (strstarts(ss
->name
, ".ARM."))
2863 return SS_TYPE_SPECIAL
;
2865 if (strstarts(ss
->name
, ".note"))
2866 return SS_TYPE_IGNORED
;
2867 if (strstarts(ss
->name
, ".comment"))
2868 return SS_TYPE_IGNORED
;
2869 if (strstarts(ss
->name
, "__param"))
2870 return SS_TYPE_IGNORED
;
2871 if (strstarts(ss
->name
, "__obsparm"))
2872 return SS_TYPE_IGNORED
;
2873 if (strstarts(ss
->name
, ".exitcall.exit"))
2874 return SS_TYPE_IGNORED
;
2875 if (strstarts(ss
->name
, ".modinfo"))
2876 return SS_TYPE_IGNORED
;
2878 return SS_TYPE_UNKNOWN
;
2881 void initialize_supersect_types(struct superbfd
*sbfd
)
2884 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2885 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2886 ss
->type
= supersect_type(ss
);
2887 ss
->orig_type
= ss
->type
;
2888 if (ss
->type
== SS_TYPE_UNKNOWN
) {
2889 err(sbfd
, "Unknown section type: %s\n", ss
->name
);
2895 static void init_label_map(struct superbfd
*sbfd
)
2897 struct label_map
*map
;
2899 vec_init(&sbfd
->maps
);
2903 struct symbol_hash csyms
;
2904 symbol_hash_init(&csyms
);
2907 for (symp
= sbfd
->syms
.data
;
2908 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2909 asymbol
*csym
= canonical_symbol(sbfd
, *symp
);
2912 char *key
= strprintf("%p", csym
);
2913 asymbol
**csymp
= symbol_hash_lookup(&csyms
, key
, TRUE
);
2919 map
= vec_grow(&sbfd
->maps
, 1);
2922 map
->label
= symbol_label(sbfd
, csym
);
2925 struct label_mapp_hash label_maps
;
2926 label_mapp_hash_init(&label_maps
);
2927 for (map
= sbfd
->maps
.data
;
2928 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2929 struct label_map
**mapp
=
2930 label_mapp_hash_lookup(&label_maps
, map
->label
, TRUE
);
2931 if (*mapp
== NULL
) {
2936 struct label_map
*first_map
= *mapp
;
2937 if (first_map
->count
== 0)
2938 first_map
->label
= strprintf("%s~%d", map
->label
, 0);
2939 map
->label
= strprintf("%s~%d", map
->label
, ++first_map
->count
);
2942 label_mapp_hash_init(&sbfd
->maps_hash
);
2943 for (map
= sbfd
->maps
.data
;
2944 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2945 char *key
= strprintf("%p", map
->csym
);
2946 struct label_map
**mapp
=
2947 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, TRUE
);
2950 map
->orig_label
= map
->label
;
2954 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
)
2956 asymbol
*csym
= canonical_symbol(sbfd
, sym
);
2957 char *key
= strprintf("%p", csym
);
2958 struct label_map
**mapp
=
2959 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2963 return (*mapp
)->label
;
2966 static void print_label_changes(struct superbfd
*sbfd
)
2970 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2971 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2972 for (span
= ss
->spans
.data
;
2973 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
2974 if (strcmp(span
->label
, span
->orig_label
) != 0)
2975 debug1(sbfd
, "Label change: %s -> %s\n",
2976 span
->label
, span
->orig_label
);
2981 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
2984 struct label_map
*map
;
2985 for (map
= sbfd
->maps
.data
;
2986 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2987 if (strcmp(map
->orig_label
, oldlabel
) == 0) {
2988 if (strcmp(map
->orig_label
, map
->label
) != 0 &&
2989 strcmp(map
->label
, label
) != 0)
2998 static void change_initial_label(struct span
*span
, const char *label
)
3000 struct superbfd
*sbfd
= span
->ss
->parent
;
3001 span
->label
= label
;
3002 span
->orig_label
= label
;
3004 asymbol
*csym
= canonical_symbol(sbfd
, span
->symbol
);
3005 char *key
= strprintf("%p", csym
);
3006 struct label_map
**mapp
=
3007 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
3010 (*mapp
)->label
= span
->label
;
3011 (*mapp
)->orig_label
= span
->orig_label
;
3012 span
->symbol
= NULL
;
3016 static void init_callers(struct superbfd
*sbfd
)
3018 string_hash_init(&sbfd
->callers
);
3020 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3021 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3023 for (relocp
= ss
->relocs
.data
;
3024 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3025 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
3027 sym
->value
+ reloc_target_offset(ss
, *relocp
);
3028 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3030 const char **ret
= string_hash_lookup(&sbfd
->callers
,
3033 asymbol
*csym
= canonical_symbol(sbfd
, sect
->symbol
);
3035 *ret
= "*multiple_callers*";
3036 else if (static_local_symbol(sbfd
, csym
))
3037 *ret
= static_local_symbol(sbfd
, csym
);
3044 static const char *find_caller(struct supersect
*ss
, asymbol
*sym
)
3046 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3047 (unsigned long)sym
->value
);
3048 const char **ret
= string_hash_lookup(&ss
->parent
->callers
, key
, FALSE
);
3052 return "*no_caller*";
3056 static void init_csyms(struct superbfd
*sbfd
)
3058 asymbolpp_hash_init(&sbfd
->csyms
);
3061 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
3063 asymbol
*sym
= *symp
;
3064 if ((sym
->flags
& BSF_DEBUGGING
) != 0)
3066 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3067 (unsigned long)sym
->value
);
3068 asymbol
***csympp
= asymbolpp_hash_lookup(&sbfd
->csyms
, key
,
3071 if (*csympp
== NULL
) {
3075 asymbol
*csym
= **csympp
;
3076 if ((csym
->flags
& BSF_GLOBAL
) != 0)
3078 if ((sym
->flags
& BSF_GLOBAL
) != 0)
3083 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
)
3085 char *key
= strprintf("%s+%lx", ss
->name
, (unsigned long)value
);
3087 asymbolpp_hash_lookup(&ss
->parent
->csyms
, key
, FALSE
);
3092 /* For section symbols of sections containing no symbols, return the
3093 section symbol that relocations are generated against */
3099 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
)
3101 if (bfd_is_const_section(sym
->section
)) {
3103 for (csymp
= sbfd
->syms
.data
;
3104 csymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; csymp
++) {
3110 return symbolp_scan(fetch_supersect(sbfd
, sym
->section
), sym
->value
);
3113 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3115 if (bfd_is_const_section(sym
->section
))
3117 asymbol
**symp
= canonical_symbolp(sbfd
, sym
);
3118 return symp
!= NULL
? *symp
: NULL
;
3121 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3123 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
3124 if ((sym
->flags
& BSF_LOCAL
) == 0 || (sym
->flags
& BSF_OBJECT
) == 0)
3126 char *dot
= strrchr(sym
->name
, '.');
3127 if (dot
== NULL
|| dot
[1 + strspn(dot
+ 1, "0123546789")] != '\0')
3129 char *basename
= strndup(sym
->name
, dot
- sym
->name
);
3131 /* Handle C.123.12345 symbols */
3132 dot
= strrchr(basename
, '.');
3133 if (dot
!= NULL
&& dot
[1 + strspn(dot
+ 1, "0123546789")] == '\0')
3134 basename
= strndup(basename
, dot
- basename
);
3136 if (strcmp(basename
, "__func__") == 0 ||
3137 strcmp(basename
, "__PRETTY_FUNCTION__") == 0)
3138 caller
= (const char *)ss
->contents
.data
+ sym
->value
;
3140 caller
= find_caller(ss
, sym
);
3141 return strprintf("%s<%s>", basename
, caller
);
3144 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
)
3146 const char *filename
= sbfd
->abfd
->filename
;
3147 char *c
= strstr(filename
, ".KSPLICE");
3148 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
3151 if (bfd_is_und_section(sym
->section
) || (sym
->flags
& BSF_GLOBAL
) != 0) {
3152 label
= strdup(sym
->name
);
3153 } else if (bfd_is_const_section(sym
->section
)) {
3154 label
= strprintf("%s<%.*s>", sym
->name
, flen
, filename
);
3156 asymbol
*gsym
= canonical_symbol(sbfd
, sym
);
3159 label
= strprintf("%s+%lx<%.*s>",
3161 (unsigned long)sym
->value
,
3163 else if ((gsym
->flags
& BSF_GLOBAL
) != 0)
3164 label
= strdup(gsym
->name
);
3165 else if (static_local_symbol(sbfd
, gsym
))
3166 label
= strprintf("%s+%lx<%.*s>",
3167 static_local_symbol(sbfd
, gsym
),
3168 (unsigned long)sym
->value
,
3171 label
= strprintf("%s<%.*s>",
3172 gsym
->name
, flen
, filename
);
3178 static void keep_span(struct span
*span
)
3181 span
->ss
->keep
= true;
3184 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
)
3186 struct span
*span
= vec_grow(&ss
->spans
, 1);
3188 span
->contents_size
= size
;
3189 span
->start
= start
;
3193 span
->patch
= false;
3194 span
->bugpatch
= false;
3195 span
->datapatch
= false;
3196 span
->precallable
= strstarts(ss
->name
, ".ksplice_call_pre_apply") ||
3197 strstarts(ss
->name
, ".ksplice_call_check_apply") ||
3198 strstarts(ss
->name
, ".ksplice_call_fail_apply") ||
3199 strstarts(ss
->name
, ".ksplice_call_post_remove");
3201 vec_init(&span
->entry_points
);
3203 asymbol
**symp
= symbolp_scan(ss
, span
->start
);
3205 span
->symbol
= *symp
;
3206 span
->label
= label_lookup(ss
->parent
, span
->symbol
);
3208 span
->symbol
= NULL
;
3209 const char *label
= label_lookup(ss
->parent
, ss
->symbol
);
3210 if (span
->start
!= 0)
3211 span
->label
= strprintf("%s<span:%lx>", label
,
3212 (unsigned long)span
->start
);
3214 span
->label
= label
;
3216 span
->orig_label
= span
->label
;
3220 static void initialize_string_spans(struct supersect
*ss
)
3223 for (str
= ss
->contents
.data
;
3224 (void *)str
< ss
->contents
.data
+ ss
->contents
.size
;) {
3225 bfd_vma start
= (unsigned long)str
-
3226 (unsigned long)ss
->contents
.data
;
3227 bfd_vma size
= strlen(str
) + 1;
3228 bfd_vma contents_size
= size
;
3229 while ((start
+ size
) % (1 << ss
->alignment
) != 0 &&
3230 start
+ size
< ss
->contents
.size
) {
3231 /* Some string sections, like __ksymtab_strings, only
3232 align some strings with the declared alignment */
3233 if (str
[size
] != '\0')
3237 struct span
*span
= new_span(ss
, start
, size
);
3238 span
->contents_size
= contents_size
;
3243 static int compare_ulongs(const void *va
, const void *vb
)
3245 const unsigned long *a
= va
, *b
= vb
;
3249 static void initialize_table_spans(struct superbfd
*sbfd
,
3250 struct table_section
*s
)
3252 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
3253 if (isection
== NULL
)
3255 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
3256 if (ss
->alignment
< ffs(s
->entry_align
) - 1)
3257 ss
->alignment
= ffs(s
->entry_align
) - 1;
3259 asection
*other_sect
= NULL
;
3260 if (s
->other_sect
!= NULL
)
3261 other_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->other_sect
);
3262 struct supersect
*other_ss
= NULL
;
3263 if (other_sect
!= NULL
)
3264 other_ss
= fetch_supersect(sbfd
, other_sect
);
3266 asection
*crc_sect
= NULL
;
3267 if (s
->crc_sect
!= NULL
)
3268 crc_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->crc_sect
);
3269 struct supersect
*crc_ss
= NULL
;
3270 if (crc_sect
!= NULL
)
3271 crc_ss
= fetch_supersect(sbfd
, crc_sect
);
3273 struct ulong_vec offsets
;
3277 for (entry
= ss
->contents
.data
;
3278 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3279 entry
+= s
->entry_size
) {
3280 struct span
*span
= new_span(ss
, addr_offset(ss
, entry
),
3282 if (s
->entry_contents_size
!= 0)
3283 span
->contents_size
= s
->entry_contents_size
;
3284 if ((span
->symbol
== NULL
||
3285 (span
->symbol
->flags
& BSF_SECTION_SYM
) != 0) &&
3287 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
3289 struct span
*target_span
= reloc_target_span(ss
, reloc
);
3290 assert(target_span
);
3291 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3292 unsigned long val
= sym
->value
+
3293 reloc_target_offset(ss
, reloc
) -
3294 (target_span
->start
+ target_span
->shift
);
3295 char *label
= strprintf("%s<target:%s+%lx>", ss
->name
,
3296 target_span
->label
, val
);
3297 change_initial_label(span
, label
);
3300 if (other_sect
!= NULL
) {
3302 bfd_vma offset
= read_reloc(ss
, entry
+ s
->other_offset
,
3303 sizeof(void *), &sym
);
3304 if (sym
->section
== other_sect
) {
3305 assert(offset
>= 0 &&
3306 offset
< other_ss
->contents
.size
);
3307 *vec_grow(&offsets
, 1) = offset
;
3311 if (crc_sect
!= NULL
)
3312 new_span(crc_ss
, addr_offset(ss
, entry
) / s
->entry_size
3313 * s
->crc_size
, s
->crc_size
);
3315 if (ss
->type
== SS_TYPE_EXPORT
) {
3316 const char *symname
= read_string(ss
, entry
+
3318 char *label
= strprintf("%s:%s", ss
->name
, symname
);
3319 change_initial_label(span
, label
);
3323 if (other_sect
== NULL
)
3326 *vec_grow(&offsets
, 1) = 0;
3327 qsort(offsets
.data
, offsets
.size
, sizeof(*offsets
.data
),
3329 *vec_grow(&offsets
, 1) = other_ss
->contents
.size
;
3332 for (off
= offsets
.data
; off
< offsets
.data
+ offsets
.size
- 1; off
++) {
3333 if (*off
!= *(off
+ 1))
3334 new_span(other_ss
, *off
, *(off
+ 1) - *off
);
3338 static void initialize_table_section_spans(struct superbfd
*sbfd
)
3340 struct supersect
*tables_ss
=
3341 fetch_supersect(offsets_sbfd
,
3342 bfd_get_section_by_name(offsets_sbfd
->abfd
,
3343 ".ksplice_table_sections"));
3344 const struct table_section
*ts
;
3345 struct table_section s
;
3346 for (ts
= tables_ss
->contents
.data
;
3347 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
3350 s
.sect
= read_string(tables_ss
, &ts
->sect
);
3351 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
3352 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
3353 initialize_table_spans(sbfd
, &s
);
3357 static void initialize_ksplice_call_spans(struct supersect
*ss
)
3360 for (relocp
= ss
->relocs
.data
;
3361 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3362 arelent
*reloc
= *relocp
;
3363 new_span(ss
, reloc
->address
, bfd_get_reloc_size(reloc
->howto
));
3364 /* the span labels should already be unique */
3368 static void initialize_spans(struct superbfd
*sbfd
)
3371 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3372 if (is_table_section(sect
->name
, true, true) && mode("keep"))
3375 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3376 if (ss
->type
== SS_TYPE_STRING
)
3377 initialize_string_spans(ss
);
3378 else if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
3379 initialize_ksplice_call_spans(ss
);
3381 new_span(ss
, 0, ss
->contents
.size
);
3384 initialize_table_section_spans(sbfd
);
3387 /* Returns the span pointed to by the relocation at span->start + offset */
3388 static struct span
*span_offset_target_span(struct span
*span
, int offset
)
3390 void *entry
= span
->ss
->contents
.data
+ span
->start
;
3391 arelent
*reloc
= find_reloc(span
->ss
, entry
+ offset
);
3394 return reloc_target_span(span
->ss
, reloc
);
3397 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
)
3399 asymbol
*sym_ptr
= *reloc
->sym_ptr_ptr
;
3400 if (bfd_is_const_section(sym_ptr
->section
))
3403 bfd_vma addend
= sym_ptr
->value
+ reloc_target_offset(ss
, reloc
);
3404 struct supersect
*sym_ss
=
3405 fetch_supersect(ss
->parent
, sym_ptr
->section
);
3406 struct span
*span
, *target_span
= sym_ss
->spans
.data
;
3407 for (span
= sym_ss
->spans
.data
;
3408 span
< sym_ss
->spans
.data
+ sym_ss
->spans
.size
; span
++) {
3409 if (addend
>= span
->start
&& addend
< span
->start
+ span
->size
)
3415 static bfd_vma
reloc_target_offset(struct supersect
*ss
, arelent
*reloc
)
3417 bfd_vma offset
= reloc_offset(ss
, reloc
);
3418 if (reloc
->howto
->pc_relative
) {
3419 if ((ss
->flags
& SEC_CODE
) != 0)
3420 return offset
+ bfd_get_reloc_size(reloc
->howto
);
3422 const struct table_section
*ts
= get_table_section(ss
->name
);
3423 if (ts
!= NULL
&& ts
->relative_addr
&&
3424 reloc
->address
% ts
->entry_size
== ts
->addr_offset
)
3425 return offset
- ts
->addr_offset
;
3426 if (ts
!= NULL
&& ts
->relative_other
&&
3427 reloc
->address
% ts
->entry_size
== ts
->other_offset
)
3428 return offset
- ts
->other_offset
;
3435 struct span
*find_span(struct supersect
*ss
, bfd_size_type address
)
3438 for (span
= ss
->spans
.data
; span
< ss
->spans
.data
+ ss
->spans
.size
;
3440 if (address
>= span
->start
&&
3441 address
< span
->start
+ span
->size
)
3444 /* Deal with empty BSS sections */
3445 if (ss
->contents
.size
== 0 && ss
->spans
.size
> 0)
3446 return ss
->spans
.data
;
3447 /* Deal with section end pointers */
3448 if (address
== ss
->contents
.size
&& ss
->spans
.size
== 1)
3449 return ss
->spans
.data
;
3453 void compute_span_shifts(struct superbfd
*sbfd
)
3457 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3458 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3461 bfd_size_type offset
= 0;
3462 for (span
= ss
->spans
.data
;
3463 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
3466 span
->shift
= offset
- span
->start
;
3467 offset
+= span
->size
;
3472 void remove_unkept_spans(struct superbfd
*sbfd
)
3476 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3477 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3478 delete_obsolete_relocs(ss
);
3479 struct arelentp_vec orig_relocs
;
3480 vec_move(&orig_relocs
, &ss
->relocs
);
3481 arelent
**relocp
, *reloc
;
3482 for (relocp
= orig_relocs
.data
;
3483 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
3485 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3486 span
= reloc_target_span(ss
, reloc
);
3487 if ((span
!= NULL
&& span
->keep
&& span
->shift
== 0) ||
3488 bfd_is_const_section(sym
->section
)) {
3489 *vec_grow(&ss
->relocs
, 1) = reloc
;
3492 struct supersect
*sym_ss
=
3493 fetch_supersect(sbfd
, sym
->section
);
3494 if (span
!= NULL
&& (sym
->flags
& BSF_SECTION_SYM
) == 0
3495 && find_span(sym_ss
, sym
->value
) != span
) {
3496 err(sbfd
, "Spans for symbol %s and relocation "
3497 "target do not match in sect %s\n",
3498 sym
->name
, sym_ss
->name
);
3501 if (span
!= NULL
&& span
->keep
) {
3502 arelent
*new_reloc
= malloc(sizeof(*new_reloc
));
3503 *new_reloc
= *reloc
;
3504 new_reloc
->addend
= reloc_offset(ss
, reloc
);
3505 new_reloc
->addend
+= span
->shift
;
3506 *vec_grow(&ss
->new_relocs
, 1) = new_reloc
;
3511 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3512 struct supersect
*ss
= fetch_supersect(sbfd
, sect
), orig_ss
;
3515 supersect_move(&orig_ss
, ss
);
3516 vec_init(&ss
->spans
);
3517 for (span
= orig_ss
.spans
.data
;
3518 span
< orig_ss
.spans
.data
+ orig_ss
.spans
.size
; span
++) {
3521 struct span
*new_span
= vec_grow(&ss
->spans
, 1);
3523 new_span
->start
= span
->start
+ span
->shift
;
3524 new_span
->shift
= 0;
3525 sect_copy(ss
, sect_do_grow(ss
, 1, span
->size
, 1),
3526 &orig_ss
, orig_ss
.contents
.data
+ span
->start
,
3532 static void init_objmanip_superbfd(struct superbfd
*sbfd
)
3534 init_label_map(sbfd
);
3535 initialize_supersect_types(sbfd
);
3536 initialize_spans(sbfd
);
3538 compute_entry_points(sbfd
);
3541 void mangle_section_name(struct superbfd
*sbfd
, const char *name
)
3543 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
3546 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3547 ss
->name
= strprintf(".ksplice_pre.%s", ss
->name
);
3550 static void write_bugline_patches(struct superbfd
*sbfd
)
3552 const struct table_section
*ts
= get_table_section("__bug_table");
3553 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, "__bug_table");
3556 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3560 for (entry
= ss
->contents
.data
;
3561 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3562 entry
+= ts
->entry_size
) {
3563 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
3564 assert(span
!= NULL
);
3565 if (!span
->bugpatch
)
3567 arelent
*reloc
= find_reloc(ss
, entry
+ ts
->addr_offset
);
3568 assert(reloc
!= NULL
);
3569 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3570 assert(!bfd_is_const_section(sym
->section
));
3571 struct supersect
*kpatch_ss
=
3572 make_section(sbfd
, ".ksplice_patches%s",
3573 sym
->section
->name
);
3575 bfd_vma offset
, start
= 0;
3576 for (offset
= 0; offset
<= span
->size
; offset
++) {
3577 if (offset
!= span
->size
&&
3578 !part_of_reloc(ss
, span
->start
+ offset
))
3580 if (start
== offset
) {
3584 /* an interval of non-relocations just passed */
3585 struct ksplice_patch
*kpatch
=
3586 sect_grow(kpatch_ss
, 1, struct ksplice_patch
);
3587 write_ksplice_patch_reloc
3588 (kpatch_ss
, sym
->section
->name
, &kpatch
->oldaddr
,
3589 sizeof(kpatch
->oldaddr
), span
->label
, start
);
3591 char *data
= write_patch_storage(kpatch_ss
, kpatch
,
3592 offset
- start
, NULL
);
3593 memcpy(data
, entry
+ start
, offset
- start
);
3594 kpatch
->type
= KSPLICE_PATCH_DATA
;
3600 void *write_patch_storage(struct supersect
*ss
, struct ksplice_patch
*kpatch
,
3601 size_t size
, struct supersect
**data_ssp
)
3603 struct supersect
*data_ss
= make_section(ss
->parent
,
3604 ".ksplice_patch_data");
3605 char *saved
= sect_do_grow(data_ss
, 1, size
, 1);
3606 write_reloc(ss
, &kpatch
->saved
, &data_ss
->symbol
,
3607 addr_offset(data_ss
, saved
));
3608 char *data
= sect_do_grow(data_ss
, 1, size
, 1);
3609 write_reloc(ss
, &kpatch
->contents
, &data_ss
->symbol
,
3610 addr_offset(data_ss
, data
));
3611 kpatch
->size
= size
;
3612 if (data_ssp
!= NULL
)
3613 *data_ssp
= data_ss
;