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
;
340 } else if (opt
->type
== KSPLICE_OPTION_MATCH_DATA_EARLY
) {
341 arelent
*reloc
= find_reloc(ss
, &opt
->target
);
342 assert(reloc
!= NULL
);
343 struct span
*span
= reloc_target_span(ss
, reloc
);
344 assert(span
!= NULL
);
345 assert(span
->ss
->type
== SS_TYPE_DATA
);
346 assert(span
->start
== 0 &&
347 span
->size
== span
->ss
->contents
.size
);
348 span
->ss
->match_data_early
= true;
350 err(sbfd
, "Unrecognized Ksplice option %d\n",
357 bool matchable_data_section(struct supersect
*ss
)
359 if (ss
->type
== SS_TYPE_STRING
)
361 if (ss
->type
== SS_TYPE_RODATA
)
363 if (ss
->type
== SS_TYPE_DATA
&& ss
->relocs
.size
!= 0)
365 if (ss
->type
== SS_TYPE_EXPORT
)
367 if (ss
->type
== SS_TYPE_BUGTABLE
)
372 bool unchangeable_section(struct supersect
*ss
)
374 if (ss
->type
== SS_TYPE_DATA
)
376 if (ss
->type
== SS_TYPE_IGNORED
&& !strstarts(ss
->name
, ".debug") &&
377 strcmp(ss
->name
, "__ksymtab_strings") != 0)
382 int main(int argc
, char *argv
[])
384 if (getenv("KSPLICE_VERBOSE") != NULL
)
385 verbose
= atoi(getenv("KSPLICE_VERBOSE"));
388 bfd
*ibfd
= bfd_openr(argv
[1], NULL
);
392 if (bfd_check_format_matches(ibfd
, bfd_archive
, &matching
) &&
393 bfd_openr_next_archived_file(ibfd
, NULL
) == NULL
)
394 return 66; /* empty archive */
395 assert(bfd_check_format_matches(ibfd
, bfd_object
, &matching
));
397 const char *output_target
= bfd_get_target(ibfd
);
402 bool_hash_init(&system_map_written
);
403 ulong_hash_init(&ksplice_symbol_offset
);
404 ulong_hash_init(&ksplice_howto_offset
);
405 ulong_hash_init(&ksplice_string_offset
);
407 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
410 if (mode("finalize"))
411 finalize_target
= argv
[4];
412 init_objmanip_superbfd(isbfd
);
413 if (mode("keep-new-code")) {
415 do_keep_new_code(isbfd
, argv
[4]);
416 } else if (mode("keep-old-code")) {
417 do_keep_old_code(isbfd
);
418 } else if (mode("finalize")) {
420 } else if (mode("rmsyms")) {
425 bfd
*obfd
= bfd_openw(argv
[2], output_target
);
427 copy_object(ibfd
, obfd
);
428 assert(bfd_close(obfd
));
431 if (offsets_sbfd
!= NULL
)
432 assert(bfd_close(offsets_sbfd
->abfd
));
433 assert(bfd_close(ibfd
));
437 void do_keep_new_code(struct superbfd
*isbfd
, const char *pre
)
439 struct bfd
*prebfd
= bfd_openr(pre
, NULL
);
440 assert(prebfd
!= NULL
);
442 assert(bfd_check_format_matches(prebfd
, bfd_object
, &matching
));
444 struct superbfd
*presbfd
= fetch_superbfd(prebfd
);
445 init_objmanip_superbfd(presbfd
);
447 foreach_symbol_pair(presbfd
, isbfd
, match_global_symbols
);
448 debug1(isbfd
, "Matched global\n");
449 foreach_span_pair(presbfd
, isbfd
, match_string_spans
);
450 debug1(isbfd
, "Matched string spans\n");
451 foreach_symbol_pair(presbfd
, isbfd
, match_symbol_spans
);
452 debug1(isbfd
, "Matched by name\n");
453 foreach_span_pair(presbfd
, isbfd
, match_spans_by_label
);
454 debug1(isbfd
, "Matched by label\n");
455 foreach_span_pair(presbfd
, isbfd
, match_table_spans
);
456 debug1(isbfd
, "Matched table spans\n");
457 foreach_span_pair(presbfd
, isbfd
, match_other_spans
);
458 debug1(isbfd
, "Matched other spans\n");
462 compare_matched_spans(isbfd
);
463 update_nonzero_offsets(isbfd
);
464 mark_new_spans(isbfd
);
468 foreach_symbol_pair(presbfd
, isbfd
, check_global_symbols
);
470 handle_deleted_spans(presbfd
, isbfd
);
471 handle_section_symbol_renames(presbfd
, isbfd
);
473 copy_patched_entry_points(presbfd
, isbfd
);
475 assert(bfd_close(prebfd
));
479 mark_precallable_spans(isbfd
);
483 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
484 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
487 for (span
= ss
->spans
.data
;
488 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
489 if (strstarts(ss
->name
, ".ksplice_options"))
491 else if (span
->new || span
->patch
|| span
->datapatch
)
495 if (span
->patch
&& span
->precallable
) {
496 err(isbfd
, "Patched span %s can be reached "
497 "by a precall function\n", span
->label
);
503 print_label_changes(isbfd
);
505 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
506 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
508 for (span
= ss
->spans
.data
;
509 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
510 if (span
->patch
|| span
->bugpatch
|| span
->datapatch
)
511 debug0(isbfd
, "Patching span %s\n",
516 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
517 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
519 for (span
= ss
->spans
.data
;
520 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
522 debug0(isbfd
, "New span %s\n", span
->label
);
526 write_output
= false;
527 const char **sectname
;
528 for (sectname
= delsects
.data
;
529 sectname
< delsects
.data
+ delsects
.size
; sectname
++) {
531 debug0(isbfd
, "Deleted section: %s\n", *sectname
);
534 filter_table_sections(isbfd
);
536 compute_span_shifts(isbfd
);
538 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
539 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
540 if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
543 for (span
= ss
->spans
.data
;
544 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
545 if (span
->keep
|| span
->bugpatch
)
547 if (span
->patch
|| span
->new || span
->datapatch
)
548 write_ksplice_section(span
);
549 if (span
->patch
|| span
->datapatch
)
550 write_ksplice_patches(isbfd
, span
);
551 if (ss
->type
== SS_TYPE_EXPORT
&& span
->new)
552 write_ksplice_export(isbfd
, span
, false);
556 write_bugline_patches(isbfd
);
558 remove_unkept_spans(isbfd
);
561 void do_keep_old_code(struct superbfd
*isbfd
)
564 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
565 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
568 for (span
= ss
->spans
.data
;
569 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
571 if (ss
->type
== SS_TYPE_TEXT
&&
572 !strstarts(ss
->name
, ".fixup"))
574 if (ss
->type
== SS_TYPE_EXPORT
)
580 for (symp
= isbfd
->syms
.data
;
581 symp
< isbfd
->syms
.data
+ isbfd
->syms
.size
; symp
++) {
582 asymbol
*sym
= *symp
;
583 if (!bfd_is_const_section(sym
->section
) &&
584 (sym
->flags
& BSF_GLOBAL
) != 0) {
585 struct supersect
*sym_ss
=
586 fetch_supersect(isbfd
, sym
->section
);
587 if (sym
->value
== sym_ss
->contents
.size
)
589 struct span
*span
= find_span(sym_ss
, sym
->value
);
590 assert(span
!= NULL
);
591 if (sym_ss
->type
!= SS_TYPE_IGNORED
)
598 keep_referenced_sections(isbfd
);
601 filter_table_sections(isbfd
);
602 compute_span_shifts(isbfd
);
604 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
605 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
606 asymbol
*sym
= canonical_symbol(isbfd
, sect
->symbol
);
609 if ((sym
->flags
& BSF_WEAK
) != 0)
611 if (bfd_get_section_size(sect
) == 0)
615 if (ss
->type
!= SS_TYPE_TEXT
&& !matchable_data_section(ss
))
619 for (span
= ss
->spans
.data
;
620 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
622 write_ksplice_section(span
);
626 write_table_relocs(isbfd
, "__bug_table", KSPLICE_HOWTO_BUG
);
627 write_table_relocs(isbfd
, "__ex_table", KSPLICE_HOWTO_EXTABLE
);
629 remove_unkept_spans(isbfd
);
631 mangle_section_name(isbfd
, "__markers");
632 mangle_section_name(isbfd
, "__tracepoints");
633 mangle_section_name(isbfd
, "__ex_table");
634 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
635 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
636 if (ss
->type
== SS_TYPE_EXPORT
)
637 mangle_section_name(isbfd
, ss
->name
);
641 void do_finalize(struct superbfd
*isbfd
)
643 load_ksplice_symbol_offsets(isbfd
);
645 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
646 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
647 if (ss
->type
== SS_TYPE_EXIT
) {
649 for (span
= ss
->spans
.data
;
650 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
655 write_date_relocs(isbfd
, "<{DATE...}>", KSPLICE_HOWTO_DATE
);
656 write_date_relocs(isbfd
, "<{TIME}>", KSPLICE_HOWTO_TIME
);
660 void do_rmsyms(struct superbfd
*isbfd
)
662 asection
*extract_sect
= bfd_get_section_by_name(isbfd
->abfd
,
664 if (extract_sect
!= NULL
) {
665 struct supersect
*extract_ss
= fetch_supersect(isbfd
,
668 for (relocp
= extract_ss
->relocs
.data
;
669 relocp
< extract_ss
->relocs
.data
+ extract_ss
->relocs
.size
;
671 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
672 if (bfd_is_und_section(sym
->section
)) {
673 debug1(isbfd
, "extracting symbol %s\n",
675 *vec_grow(&extract_syms
, 1) = sym
;
683 void match_spans(struct span
*old_span
, struct span
*new_span
)
685 struct superbfd
*sbfd
= new_span
->ss
->parent
;
686 if (old_span
->match
== new_span
&& new_span
->match
== old_span
)
688 if (old_span
->match
!= NULL
) {
689 err(sbfd
, "Matching conflict: old %s: %s != %s\n",
690 old_span
->label
, old_span
->match
->label
, new_span
->label
);
693 if (new_span
->match
!= NULL
) {
694 err(sbfd
, "Matching conflict: new %s: %s != %s\n",
695 new_span
->label
, new_span
->match
->label
, old_span
->label
);
698 old_span
->match
= new_span
;
699 new_span
->match
= old_span
;
700 debug1(sbfd
, "Matched old %s to new %s\n", old_span
->label
,
702 if (old_span
->ss
->type
!= new_span
->ss
->type
&&
703 old_span
->ss
->type
== new_span
->ss
->orig_type
)
704 old_span
->ss
->type
= new_span
->ss
->type
;
706 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
707 if (ts
== NULL
|| !ts
->has_addr
|| ts
->other_sect
== NULL
)
709 struct span
*old_sym_span
=
710 span_offset_target_span(old_span
, ts
->other_offset
);
711 struct span
*new_sym_span
=
712 span_offset_target_span(new_span
, ts
->other_offset
);
713 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
714 match_spans(old_sym_span
, new_sym_span
);
717 void unmatch_span(struct span
*old_span
)
719 struct span
*new_span
= old_span
->match
;
720 old_span
->match
= NULL
;
721 new_span
->match
= NULL
;
723 new_span
->bugpatch
= false;
725 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
) {
726 const struct table_section
*ts
=
727 get_table_section(old_span
->ss
->name
);
728 if (ts
!= NULL
&& ts
->has_addr
)
729 unmatch_addr_spans(old_span
, new_span
, ts
);
732 new_span
->patch
= false;
733 new_span
->bugpatch
= false;
734 new_span
->datapatch
= false;
739 static void match_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
740 struct span
*new_span
, asymbol
*newsym
)
742 if (newsym
== NULL
||
743 (oldsym
->flags
& BSF_GLOBAL
) == 0 ||
744 (newsym
->flags
& BSF_GLOBAL
) == 0)
746 match_spans(old_span
, new_span
);
749 static void check_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
750 struct span
*new_span
, asymbol
*newsym
)
752 if ((oldsym
->flags
& BSF_GLOBAL
) == 0 ||
753 (newsym
!= NULL
&& (newsym
->flags
& BSF_GLOBAL
) == 0))
755 if (old_span
->ss
->type
== SS_TYPE_IGNORED
)
757 if (old_span
->match
!= new_span
) {
758 if (new_span
!= NULL
)
759 err(new_span
->ss
->parent
,
760 "Global symbol span mismatch: %s %s/%s\n",
761 oldsym
->name
, old_span
->label
, new_span
->label
);
763 err(old_span
->ss
->parent
,
764 "Global symbol span mismatch: %s %s/NULL\n",
765 oldsym
->name
, old_span
->label
);
770 static void foreach_symbol_pair(struct superbfd
*oldsbfd
, struct superbfd
*newsbfd
,
771 void (*fn
)(struct span
*old_span
,
773 struct span
*new_span
,
776 asymbol
**oldsymp
, **newsymp
;
777 for (oldsymp
= oldsbfd
->syms
.data
;
778 oldsymp
< oldsbfd
->syms
.data
+ oldsbfd
->syms
.size
; oldsymp
++) {
779 asymbol
*oldsym
= *oldsymp
;
780 if ((oldsym
->flags
& BSF_DEBUGGING
) != 0 ||
781 bfd_is_const_section(oldsym
->section
))
784 struct supersect
*old_ss
=
785 fetch_supersect(oldsbfd
, oldsym
->section
);
786 if (old_ss
->type
== SS_TYPE_SPECIAL
||
787 old_ss
->type
== SS_TYPE_EXPORT
)
790 struct span
*old_span
= find_span(old_ss
, oldsym
->value
);
791 if (old_span
== NULL
) {
792 err(oldsbfd
, "Could not find span for %s\n",
799 for (newsymp
= newsbfd
->syms
.data
;
800 newsymp
< newsbfd
->syms
.data
+ newsbfd
->syms
.size
;
802 asymbol
*newsym
= *newsymp
;
803 if ((newsym
->flags
& BSF_DEBUGGING
) != 0 ||
804 bfd_is_const_section(newsym
->section
))
806 if (strcmp(oldsym
->name
, newsym
->name
) != 0)
809 struct supersect
*new_ss
=
810 fetch_supersect(newsbfd
, newsym
->section
);
811 if (old_ss
->type
!= new_ss
->type
&&
812 old_ss
->type
!= new_ss
->orig_type
)
818 struct span
*new_span
=
819 find_span(new_ss
, newsym
->value
);
820 if (new_span
== NULL
) {
821 err(newsbfd
, "Could not find span for %s\n",
825 fn(old_span
, oldsym
, new_span
, newsym
);
829 fn(old_span
, oldsym
, NULL
, NULL
);
833 static void match_symbol_spans(struct span
*old_span
, asymbol
*oldsym
,
834 struct span
*new_span
, asymbol
*newsym
)
838 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
)
840 if (static_local_symbol(old_span
->ss
->parent
, oldsym
) ||
841 static_local_symbol(new_span
->ss
->parent
, newsym
))
843 if (old_span
->match
== NULL
&& new_span
->match
== NULL
)
844 match_spans(old_span
, new_span
);
847 static void match_spans_by_label(struct span
*old_span
, struct span
*new_span
)
849 if (old_span
->ss
->type
== SS_TYPE_STRING
||
850 (is_table_section(old_span
->ss
->name
, true, false) &&
851 !is_table_section(old_span
->ss
->name
, false, false)))
853 if (strcmp(old_span
->label
, new_span
->label
) == 0)
854 match_spans(old_span
, new_span
);
857 static void match_string_spans(struct span
*old_span
, struct span
*new_span
)
859 if (old_span
->ss
->type
!= SS_TYPE_STRING
||
860 strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
862 if (strcmp((char *)old_span
->ss
->contents
.data
+ old_span
->start
,
863 (char *)new_span
->ss
->contents
.data
+ new_span
->start
) == 0)
864 match_spans(old_span
, new_span
);
867 static void foreach_span_pair(struct superbfd
*oldsbfd
,
868 struct superbfd
*newsbfd
,
869 void (*fn
)(struct span
*old_span
,
870 struct span
*new_span
))
872 asection
*oldsect
, *newsect
;
873 struct supersect
*oldss
, *newss
;
874 struct span
*old_span
, *new_span
;
875 for (newsect
= newsbfd
->abfd
->sections
; newsect
!= NULL
;
876 newsect
= newsect
->next
) {
877 newss
= fetch_supersect(newsbfd
, newsect
);
878 for (oldsect
= oldsbfd
->abfd
->sections
; oldsect
!= NULL
;
879 oldsect
= oldsect
->next
) {
880 oldss
= fetch_supersect(oldsbfd
, oldsect
);
881 if (oldss
->type
!= newss
->type
)
883 for (new_span
= newss
->spans
.data
;
884 new_span
< newss
->spans
.data
+ newss
->spans
.size
;
886 for (old_span
= oldss
->spans
.data
;
887 old_span
< oldss
->spans
.data
+
888 oldss
->spans
.size
; old_span
++)
889 fn(old_span
, new_span
);
895 static void mark_new_spans(struct superbfd
*sbfd
)
898 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
899 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
900 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
903 for (span
= ss
->spans
.data
;
904 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
905 if (span
->match
== NULL
)
911 static void handle_deleted_spans(struct superbfd
*oldsbfd
,
912 struct superbfd
*newsbfd
)
915 for (sect
= oldsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
916 struct supersect
*ss
= fetch_supersect(oldsbfd
, sect
);
918 for (span
= ss
->spans
.data
;
919 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
920 if (span
->match
!= NULL
)
922 if (ss
->type
== SS_TYPE_EXPORT
) {
923 *vec_grow(&delsects
, 1) = span
->label
;
924 write_ksplice_export(newsbfd
, span
, true);
925 } else if (ss
->type
== SS_TYPE_TEXT
) {
926 *vec_grow(&delsects
, 1) = span
->label
;
927 if (span
->symbol
== NULL
)
929 write_ksplice_deleted_patch
930 (newsbfd
, span
->symbol
->name
, span
->label
,
937 static void handle_nonzero_offset_relocs(struct supersect
*ss
)
939 struct span
*address_span
, *target_span
;
941 for (relocp
= ss
->relocs
.data
;
942 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
943 arelent
*reloc
= *relocp
;
944 address_span
= find_span(ss
, reloc
->address
);
945 if (!address_span
->new && !address_span
->patch
)
948 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
949 if (bfd_is_const_section(sym
->section
))
951 bfd_vma offset
= reloc_target_offset(ss
, reloc
);
952 target_span
= reloc_target_span(ss
, reloc
);
953 if (sym
->value
+ offset
== target_span
->start
)
956 if (target_span
->ss
->type
!= SS_TYPE_TEXT
)
958 if (target_span
->patch
)
961 target_span
->patch
= true;
963 debug1(ss
->parent
, "Changing %s because a relocation from sect "
964 "%s has a nonzero offset %lx+%lx into it\n",
965 target_span
->label
, ss
->name
, (unsigned long)sym
->value
,
966 (unsigned long)offset
);
970 static void update_nonzero_offsets(struct superbfd
*sbfd
)
973 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
974 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
975 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
977 handle_nonzero_offset_relocs(ss
);
981 static void unmatch_addr_spans(struct span
*old_span
, struct span
*new_span
,
982 const struct table_section
*ts
)
984 struct span
*old_sym_span
=
985 span_offset_target_span(old_span
, ts
->addr_offset
);
986 struct span
*new_sym_span
=
987 span_offset_target_span(new_span
, ts
->addr_offset
);
988 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
989 if (old_sym_span
->match
== new_sym_span
&&
990 new_sym_span
->match
== old_sym_span
&&
991 !(new_sym_span
->patch
&& new_sym_span
->ss
->type
== SS_TYPE_TEXT
)) {
992 if (old_sym_span
->ss
->type
== SS_TYPE_TEXT
) {
993 debug1(new_span
->ss
->parent
, "Patching %s due "
994 "to relocations from special section %s\n",
995 new_sym_span
->label
, new_span
->label
);
996 new_sym_span
->patch
= true;
998 debug1(new_span
->ss
->parent
, "Unmatching %s and %s due "
999 "to relocations from special section %s/%s\n",
1000 old_sym_span
->label
, new_sym_span
->label
,
1001 old_span
->label
, new_span
->label
);
1002 unmatch_span(old_sym_span
);
1008 static void compare_spans(struct span
*old_span
, struct span
*new_span
)
1010 struct superbfd
*newsbfd
= new_span
->ss
->parent
;
1012 bool nonrelocs_match
= nonrelocs_equal(old_span
, new_span
);
1013 bool relocs_match
= all_relocs_equal(old_span
, new_span
);
1014 if (nonrelocs_match
&& relocs_match
) {
1015 const struct table_section
*ts
=
1016 get_table_section(old_span
->ss
->name
);
1017 if (ts
!= NULL
&& ts
->crc_sect
!= NULL
) {
1018 struct span
*old_crc_span
= get_crc_span(old_span
, ts
);
1019 struct span
*new_crc_span
= get_crc_span(new_span
, ts
);
1020 assert(old_crc_span
!= NULL
);
1021 assert(new_crc_span
!= NULL
);
1022 if (old_crc_span
->match
!= new_crc_span
||
1023 new_crc_span
->match
!= old_crc_span
) {
1024 debug1(newsbfd
, "Unmatching %s and %s due to "
1025 "nonmatching CRCs\n", old_span
->label
,
1027 unmatch_span(old_span
);
1034 if (new_span
->contents_size
!= old_span
->contents_size
)
1035 reason
= "differing sizes";
1036 else if (!nonrelocs_match
)
1037 reason
= "differing contents";
1039 reason
= "differing relocations";
1041 if (new_span
->ss
->type
== SS_TYPE_TEXT
) {
1042 if (new_span
->patch
)
1044 new_span
->patch
= true;
1045 debug1(newsbfd
, "Changing %s due to %s\n", new_span
->label
,
1047 } else if (old_span
->ss
->type
== SS_TYPE_BUGTABLE
&&
1048 new_span
->ss
->type
== SS_TYPE_BUGTABLE
&& relocs_match
) {
1049 if (new_span
->bugpatch
)
1051 debug1(newsbfd
, "Changing %s due to %s\n",
1052 new_span
->label
, reason
);
1053 new_span
->bugpatch
= true;
1054 } else if (new_span
->ss
->type
== SS_TYPE_RODATA
&&
1055 new_span
->contents_size
== old_span
->contents_size
) {
1056 if (new_span
->datapatch
)
1058 new_span
->datapatch
= true;
1059 debug1(newsbfd
, "Changing %s in-place due to %s\n",
1060 new_span
->label
, reason
);
1061 } else if (new_span
->ss
->type
== SS_TYPE_STRING
&&
1062 old_span
->ss
->type
== SS_TYPE_STRING
&& relocs_match
&&
1063 strcmp(new_span
->ss
->contents
.data
+ new_span
->start
,
1064 old_span
->ss
->contents
.data
+ old_span
->start
) == 0) {
1067 debug1(newsbfd
, "Unmatching %s and %s due to %s\n",
1068 old_span
->label
, new_span
->label
, reason
);
1069 unmatch_span(old_span
);
1072 if (unchangeable_section(new_span
->ss
))
1073 err(newsbfd
, "warning: ignoring change to nonpatchable "
1074 "section %s\n", new_span
->ss
->name
);
1077 static void compare_matched_spans(struct superbfd
*newsbfd
)
1080 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1081 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1083 for (span
= ss
->spans
.data
;
1084 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1085 if (span
->match
== NULL
)
1087 compare_spans(span
->match
, span
);
1092 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
1093 struct superbfd
*newsbfd
)
1097 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1098 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1099 for (span
= ss
->spans
.data
;
1100 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1101 if (span
->match
== NULL
)
1103 if (strcmp(span
->label
, span
->match
->label
) == 0)
1105 if (strcmp(span
->orig_label
, span
->label
) != 0 &&
1106 strcmp(span
->label
, span
->match
->label
) != 0)
1108 if (span
->symbol
!= NULL
)
1109 label_map_set(newsbfd
, span
->label
,
1110 span
->match
->label
);
1111 span
->label
= span
->match
->label
;
1116 static void copy_patched_entry_points(struct superbfd
*oldsbfd
,
1117 struct superbfd
*newsbfd
)
1121 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1122 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1123 for (span
= ss
->spans
.data
;
1124 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1127 assert(span
->match
!= NULL
);
1128 vec_init(&span
->pre_entry_points
);
1130 struct entry_point
*entry
;
1131 for (entry
= span
->match
->entry_points
.data
;
1132 entry
< span
->match
->entry_points
.data
+
1133 span
->match
->entry_points
.size
;
1135 struct entry_point
*e
=
1136 vec_grow(&span
->pre_entry_points
, 1);
1137 e
->name
= entry
->name
!= NULL
?
1138 strdup(entry
->name
) : NULL
;
1139 e
->label
= strdup(entry
->label
);
1140 e
->offset
= entry
->offset
;
1147 static int compare_entry_points(const void *va
, const void *vb
)
1149 const struct entry_point
*a
= va
, *b
= vb
;
1150 if (a
->offset
< b
->offset
)
1152 else if (a
->offset
> b
->offset
)
1158 static void compute_entry_points(struct superbfd
*sbfd
)
1161 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
1163 asymbol
*sym
= *symp
;
1164 if (bfd_is_const_section(sym
->section
))
1166 struct supersect
*old_ss
= fetch_supersect(sbfd
, sym
->section
);
1167 if ((sym
->flags
& BSF_GLOBAL
) == 0)
1169 struct span
*span
= find_span(old_ss
, sym
->value
);
1170 struct entry_point
*e
= vec_grow(&span
->entry_points
, 1);
1171 e
->label
= sym
->name
;
1172 e
->name
= sym
->name
;
1173 e
->offset
= sym
->value
- span
->start
;
1178 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1179 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1181 for (span
= ss
->spans
.data
;
1182 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1183 /* First make sure that 0 appears as an entry point */
1184 bool found_zero
= false;
1185 struct entry_point
*entry
;
1186 for (entry
= span
->entry_points
.data
;
1187 entry
< span
->entry_points
.data
+
1188 span
->entry_points
.size
;
1190 if (entry
->offset
== 0)
1194 struct entry_point
*e
=
1195 vec_grow(&span
->entry_points
, 1);
1196 e
->label
= span
->label
;
1199 e
->symbol
= span
->symbol
;
1202 qsort(span
->entry_points
.data
, span
->entry_points
.size
,
1203 sizeof(*span
->entry_points
.data
),
1204 compare_entry_points
);
1209 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
)
1212 for (relocp
= ss
->relocs
.data
;
1213 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
1214 arelent
*reloc
= *relocp
;
1215 if (addr
>= reloc
->address
&&
1216 addr
< reloc
->address
+ bfd_get_reloc_size(reloc
->howto
))
1222 static bool nonrelocs_equal(struct span
*old_span
, struct span
*new_span
)
1225 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1226 if (old_span
->contents_size
!= new_span
->contents_size
)
1228 const unsigned char *old
= old_ss
->contents
.data
+ old_span
->start
;
1229 const unsigned char *new = new_ss
->contents
.data
+ new_span
->start
;
1230 for (i
= 0; i
< old_span
->contents_size
; i
++) {
1231 if (old
[i
] != new[i
] &&
1232 !(part_of_reloc(old_ss
, i
+ old_span
->start
) &&
1233 part_of_reloc(new_ss
, i
+ new_span
->start
)))
1239 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
1240 arelent
*old_reloc
, arelent
*new_reloc
)
1242 struct superbfd
*oldsbfd
= old_src_ss
->parent
;
1243 struct superbfd
*newsbfd
= new_src_ss
->parent
;
1244 struct span
*old_addr_span
= find_span(old_src_ss
, old_reloc
->address
);
1245 struct span
*new_addr_span
= find_span(new_src_ss
, new_reloc
->address
);
1247 if (old_reloc
->address
- old_addr_span
->start
!=
1248 new_reloc
->address
- new_addr_span
->start
) {
1249 debug1(newsbfd
, "Section %s/%s has reloc address mismatch at "
1250 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1251 (unsigned long)old_reloc
->address
);
1255 if (old_reloc
->howto
!= new_reloc
->howto
) {
1256 debug1(newsbfd
, "Section %s/%s has howto type mismatch at "
1257 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1258 (unsigned long)old_reloc
->address
);
1262 if (non_dst_mask(old_src_ss
, old_reloc
) !=
1263 non_dst_mask(new_src_ss
, new_reloc
)) {
1264 debug1(newsbfd
, "Section %s/%s has contents mismatch at %lx\n",
1265 old_src_ss
->name
, new_src_ss
->name
,
1266 (unsigned long)old_reloc
->address
);
1270 asymbol
*old_sym
= *old_reloc
->sym_ptr_ptr
;
1271 asymbol
*new_sym
= *new_reloc
->sym_ptr_ptr
;
1272 asection
*old_sect
= old_sym
->section
;
1273 asection
*new_sect
= new_sym
->section
;
1275 bfd_vma old_offset
= reloc_target_offset(old_src_ss
, old_reloc
);
1276 bfd_vma new_offset
= reloc_target_offset(new_src_ss
, new_reloc
);
1278 if (bfd_is_und_section(old_sect
) || bfd_is_und_section(new_sect
)) {
1279 if (!bfd_is_und_section(new_sect
) && old_offset
!= 0 &&
1280 fetch_supersect(newsbfd
, new_sect
)->type
== SS_TYPE_TEXT
)
1283 if (!bfd_is_und_section(old_sect
) && new_offset
!= 0 &&
1284 fetch_supersect(oldsbfd
, old_sect
)->type
== SS_TYPE_TEXT
)
1287 return strcmp(old_sym
->name
, new_sym
->name
) == 0 &&
1288 old_offset
== new_offset
;
1291 if (bfd_is_abs_section(old_sect
) && bfd_is_abs_section(new_sect
)) {
1292 if (old_sym
->value
+ old_offset
== new_sym
->value
+ new_offset
)
1294 debug1(newsbfd
, "Differing relocations from %s/%s to ABS "
1295 "section: %lx/%lx\n", old_addr_span
->label
,
1296 new_addr_span
->label
,
1297 (unsigned long)(old_sym
->value
+ old_offset
),
1298 (unsigned long)(new_sym
->value
+ new_offset
));
1302 if (bfd_is_const_section(old_sect
) || bfd_is_const_section(new_sect
))
1305 struct supersect
*old_ss
= fetch_supersect(oldsbfd
, old_sect
);
1306 struct supersect
*new_ss
= fetch_supersect(newsbfd
, new_sect
);
1307 struct span
*old_span
= reloc_target_span(old_src_ss
, old_reloc
);
1308 struct span
*new_span
= reloc_target_span(new_src_ss
, new_reloc
);
1310 if (old_span
->match
!= new_span
|| new_span
->match
!= old_span
) {
1311 debug1(newsbfd
, "Nonmatching relocs from %s to %s/%s\n",
1312 new_src_ss
->name
, old_span
->label
, new_span
->label
);
1316 if (old_sym
->value
+ old_offset
- old_span
->start
!=
1317 new_sym
->value
+ new_offset
- new_span
->start
) {
1318 debug1(newsbfd
, "Offsets to %s/%s differ between %s "
1319 "and %s: %lx+%lx/%lx+%lx\n", old_ss
->name
,
1320 new_ss
->name
, old_src_ss
->name
, new_src_ss
->name
,
1321 (unsigned long)old_sym
->value
, (unsigned long)old_offset
,
1322 (unsigned long)new_sym
->value
,
1323 (unsigned long)new_offset
);
1327 if ((old_sym
->value
+ old_offset
- old_span
->start
!= 0 ||
1328 new_sym
->value
+ new_offset
- new_span
->start
!= 0) &&
1330 debug1(newsbfd
, "Relocation from %s to nonzero offsets "
1331 "%lx+%lx/%lx+%lx in changed section %s\n",
1332 new_src_ss
->name
, (unsigned long)old_sym
->value
,
1333 (unsigned long)old_offset
, (unsigned long)new_sym
->value
,
1334 (unsigned long)new_offset
, new_sym
->section
->name
);
1340 bool all_relocs_equal(struct span
*old_span
, struct span
*new_span
)
1342 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1343 arelent
**old_relocp
, **new_relocp
;
1345 for (old_relocp
= old_ss
->relocs
.data
;
1346 old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
;
1348 if (find_span(old_ss
, (*old_relocp
)->address
) == old_span
)
1352 for (new_relocp
= new_ss
->relocs
.data
;
1353 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
;
1355 if (find_span(new_ss
, (*new_relocp
)->address
) == new_span
)
1359 for (; old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1360 find_span(old_ss
, (*old_relocp
)->address
) == old_span
&&
1361 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1362 find_span(new_ss
, (*new_relocp
)->address
) == new_span
;
1363 old_relocp
++, new_relocp
++) {
1364 if (!relocs_equal(old_ss
, new_ss
, *old_relocp
, *new_relocp
))
1368 if ((old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1369 find_span(old_ss
, (*old_relocp
)->address
) == old_span
) ||
1370 (new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1371 find_span(new_ss
, (*new_relocp
)->address
) == new_span
)) {
1372 debug1(new_ss
->parent
, "Different reloc count between %s and "
1373 "%s\n", old_span
->label
, new_span
->label
);
1380 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
)
1382 int bits
= bfd_get_reloc_size(reloc
->howto
) * 8;
1383 void *address
= ss
->contents
.data
+ reloc
->address
;
1384 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1385 return x
& ~reloc
->howto
->dst_mask
;
1388 void rm_relocs(struct superbfd
*isbfd
)
1391 for (p
= isbfd
->abfd
->sections
; p
!= NULL
; p
= p
->next
) {
1392 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1393 bool remove_relocs
= ss
->keep
;
1395 if (mode("keep") && ss
->type
== SS_TYPE_SPECIAL
)
1396 remove_relocs
= false;
1398 if (ss
->type
== SS_TYPE_KSPLICE
||
1399 ss
->type
== SS_TYPE_KSPLICE_CALL
)
1400 remove_relocs
= false;
1401 if (mode("finalize") &&
1402 (strstarts(ss
->name
, ".ksplice_patches") ||
1403 strstarts(ss
->name
, ".ksplice_relocs")))
1404 remove_relocs
= true;
1411 void rm_some_relocs(struct supersect
*ss
)
1413 struct arelentp_vec orig_relocs
;
1414 vec_move(&orig_relocs
, &ss
->relocs
);
1417 for (relocp
= orig_relocs
.data
;
1418 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
1419 bool rm_reloc
= false;
1420 asymbol
*sym_ptr
= *(*relocp
)->sym_ptr_ptr
;
1422 if (mode("rmsyms") && bfd_is_und_section(sym_ptr
->section
)) {
1424 for (esymp
= extract_syms
.data
;
1425 esymp
< extract_syms
.data
+ extract_syms
.size
;
1427 if (sym_ptr
== *esymp
) {
1437 if (mode("keep-new-code")) {
1438 if (bfd_is_const_section(sym_ptr
->section
)) {
1441 bfd_vma offset
= reloc_target_offset(ss
, *relocp
);
1442 struct span
*target_span
=
1443 reloc_target_span(ss
, *relocp
);
1444 if (target_span
->new ||
1445 (target_span
->ss
->type
== SS_TYPE_TEXT
&&
1446 sym_ptr
->value
+ offset
!=
1447 target_span
->start
))
1451 const struct table_section
*ts
=
1452 get_table_section(ss
->name
);
1453 if (ts
!= NULL
&& ts
->has_addr
&&
1454 ((*relocp
)->address
% ts
->entry_size
==
1456 (*relocp
)->address
% ts
->entry_size
==
1461 if (mode("finalize") && bfd_is_und_section(sym_ptr
->section
))
1464 if (strcmp(sym_ptr
->name
, "mcount") == 0 &&
1465 bfd_is_und_section(sym_ptr
->section
))
1468 if (!find_span(ss
, (*relocp
)->address
)->keep
)
1472 write_ksplice_reloc(ss
, *relocp
);
1474 *vec_grow(&ss
->relocs
, 1) = *relocp
;
1478 struct supersect
*make_section(struct superbfd
*sbfd
, const char *fmt
, ...)
1482 char *name
= vstrprintf(fmt
, ap
);
1485 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
1487 return fetch_supersect(sbfd
, sect
);
1489 return new_supersect(sbfd
, name
);
1492 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1495 bfd_reloc_code_real_type code
;
1496 switch (bfd_arch_bits_per_address(ss
->parent
->abfd
)) {
1498 code
= BFD_RELOC_32
;
1501 code
= BFD_RELOC_64
;
1507 arelent
*reloc
= malloc(sizeof(*reloc
));
1508 reloc
->sym_ptr_ptr
= symp
;
1509 reloc
->address
= addr_offset(ss
, addr
);
1510 reloc
->howto
= bfd_reloc_type_lookup(ss
->parent
->abfd
, code
);
1511 reloc
->addend
= offset
;
1515 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1518 *vec_grow(&ss
->new_relocs
, 1) = create_reloc(ss
, addr
, symp
, offset
);
1521 void write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...)
1524 struct supersect
*str_ss
= make_section(ss
->parent
, ".ksplice_str");
1527 int len
= vasprintf(&str
, fmt
, ap
);
1531 unsigned long *str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
,
1533 if (str_offp
== NULL
) {
1534 char *buf
= sect_grow(str_ss
, len
+ 1, char);
1535 memcpy(buf
, str
, len
+ 1);
1536 str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
, TRUE
);
1537 *str_offp
= addr_offset(str_ss
, buf
);
1540 write_reloc(ss
, addr
, &str_ss
->symbol
, *str_offp
);
1543 void lookup_system_map(struct addr_vec
*addrs
, const char *name
, long offset
)
1545 struct addr_vec
*map_addrs
=
1546 addr_vec_hash_lookup(&system_map
, name
, FALSE
);
1547 if (map_addrs
== NULL
)
1550 unsigned long *addr
, *map_addr
;
1551 for (map_addr
= map_addrs
->data
;
1552 map_addr
< map_addrs
->data
+ map_addrs
->size
; map_addr
++) {
1553 for (addr
= addrs
->data
; addr
< addrs
->data
+ addrs
->size
;
1555 if (*addr
== *map_addr
+ offset
)
1558 if (addr
< addrs
->data
+ addrs
->size
)
1560 *vec_grow(addrs
, 1) = *map_addr
+ offset
;
1564 void compute_system_map_array(struct superbfd
*sbfd
, struct addr_vec
*addrs
,
1567 if (bfd_is_abs_section(sym
->section
)) {
1568 *vec_grow(addrs
, 1) = sym
->value
;
1569 } else if (bfd_is_und_section(sym
->section
)) {
1570 lookup_system_map(addrs
, sym
->name
, 0);
1571 } else if (!bfd_is_const_section(sym
->section
)) {
1573 for (gsymp
= sbfd
->syms
.data
;
1574 gsymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; gsymp
++) {
1575 asymbol
*gsym
= *gsymp
;
1576 if ((gsym
->flags
& BSF_DEBUGGING
) == 0 &&
1577 gsym
->section
== sym
->section
)
1578 lookup_system_map(addrs
, gsym
->name
,
1579 sym
->value
- gsym
->value
);
1584 void write_ksplice_system_map(struct superbfd
*sbfd
, asymbol
*sym
,
1587 bool *done
= bool_hash_lookup(&system_map_written
, label
, TRUE
);
1592 struct addr_vec addrs
;
1595 compute_system_map_array(sbfd
, &addrs
, sym
);
1596 if (addrs
.size
!= 0) {
1597 struct supersect
*smap_ss
=
1598 make_section(sbfd
, ".ksplice_system_map");
1599 struct ksplice_system_map
*smap
=
1600 sect_grow(smap_ss
, 1, struct ksplice_system_map
);
1601 write_string(smap_ss
, &smap
->label
, "%s", label
);
1603 struct supersect
*array_ss
= make_section(sbfd
,
1605 void *buf
= sect_grow(array_ss
, addrs
.size
,
1606 typeof(*addrs
.data
));
1607 memcpy(buf
, addrs
.data
, addrs
.size
* sizeof(*addrs
.data
));
1608 smap
->nr_candidates
= addrs
.size
;
1609 write_reloc(smap_ss
, &smap
->candidates
, &array_ss
->symbol
,
1610 addr_offset(array_ss
, buf
));
1615 void write_ksplice_symbol_backend(struct supersect
*ss
,
1616 struct ksplice_symbol
*const *addr
,
1617 asymbol
*sym
, const char *label
,
1620 struct supersect
*ksymbol_ss
= make_section(ss
->parent
,
1621 ".ksplice_symbols");
1622 struct ksplice_symbol
*ksymbol
;
1623 unsigned long *ksymbol_offp
;
1625 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, FALSE
);
1626 if (ksymbol_offp
!= NULL
) {
1627 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1630 ksymbol
= sect_grow(ksymbol_ss
, 1, struct ksplice_symbol
);
1631 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
1632 *ksymbol_offp
= addr_offset(ksymbol_ss
, ksymbol
);
1634 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1635 write_string(ksymbol_ss
, &ksymbol
->label
, "%s", label
);
1637 write_string(ksymbol_ss
, &ksymbol
->name
, "%s", name
);
1638 write_ksplice_system_map(ksymbol_ss
->parent
, sym
, label
);
1642 void write_ksplice_symbol(struct supersect
*ss
,
1643 struct ksplice_symbol
*const *addr
,
1644 asymbol
*sym
, struct span
*span
,
1645 const char *addstr_sect
)
1647 const char *label
, *name
;
1648 if (span
!= NULL
&& span
->start
!= 0)
1649 label
= span
->label
;
1651 label
= label_lookup(ss
->parent
, sym
);
1653 asymbol
*gsym
= canonical_symbol(ss
->parent
, sym
);
1654 if (strcmp(addstr_sect
, "") != 0)
1656 else if (bfd_is_und_section(sym
->section
))
1658 else if (bfd_is_const_section(sym
->section
))
1660 else if (span
!= NULL
&& span
->symbol
== NULL
)
1662 else if (gsym
== NULL
|| (gsym
->flags
& BSF_SECTION_SYM
) != 0)
1667 write_ksplice_symbol_backend(ss
, addr
, sym
,
1668 strprintf("%s%s", addstr_sect
, label
),
1672 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
)
1674 asymbol
*sym_ptr
= *orig_reloc
->sym_ptr_ptr
;
1675 bfd_vma reloc_addend
= reloc_offset(ss
, orig_reloc
);
1676 bfd_vma target_addend
= reloc_target_offset(ss
, orig_reloc
);
1677 unsigned long *repladdr
= ss
->contents
.data
+ orig_reloc
->address
;
1679 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_patches")) {
1683 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_relocs")) {
1684 assert(strstarts(sym_ptr
->name
, KSPLICE_SYMBOL_STR
));
1686 fake_sym
.name
= sym_ptr
->name
+ strlen(KSPLICE_SYMBOL_STR
);
1687 fake_sym
.section
= bfd_und_section_ptr
;
1691 write_ksplice_symbol_backend
1692 (ss
, (struct ksplice_symbol
**)repladdr
, &fake_sym
,
1693 fake_sym
.name
, fake_sym
.name
);
1697 struct span
*span
= reloc_target_span(ss
, orig_reloc
);
1698 if (span
== ss
->spans
.data
&& span
->start
!= target_addend
)
1700 write_canary(ss
, orig_reloc
->address
,
1701 bfd_get_reloc_size(orig_reloc
->howto
),
1702 orig_reloc
->howto
->dst_mask
);
1704 struct supersect
*kreloc_ss
=
1705 make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1706 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1707 struct ksplice_reloc
);
1709 struct span
*address_span
= find_span(ss
, orig_reloc
->address
);
1710 write_reloc(kreloc_ss
, &kreloc
->blank_addr
,
1711 &ss
->symbol
, orig_reloc
->address
+ address_span
->shift
);
1712 if (bfd_is_und_section(sym_ptr
->section
) && mode("keep")) {
1713 char *name
= strprintf(KSPLICE_SYMBOL_STR
"%s", sym_ptr
->name
);
1714 asymbol
**symp
= make_undefined_symbolp(ss
->parent
, name
);
1715 write_reloc(kreloc_ss
, &kreloc
->symbol
, symp
, 0);
1717 write_ksplice_symbol(kreloc_ss
, &kreloc
->symbol
, sym_ptr
, span
,
1720 if (span
!= NULL
&& span
->start
!= 0) {
1721 reloc_addend
+= sym_ptr
->value
- span
->start
;
1722 target_addend
+= sym_ptr
->value
- span
->start
;
1724 kreloc
->insn_addend
= reloc_addend
- target_addend
;
1725 kreloc
->target_addend
= target_addend
;
1726 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, orig_reloc
->howto
,
1727 KSPLICE_HOWTO_RELOC
);
1730 static void write_ksplice_reloc_howto(struct supersect
*ss
, const
1731 struct ksplice_reloc_howto
*const *addr
,
1732 reloc_howto_type
*howto
,
1733 enum ksplice_reloc_howto_type type
)
1735 struct supersect
*khowto_ss
= make_section(ss
->parent
,
1736 ".ksplice_reloc_howtos");
1737 struct ksplice_reloc_howto
*khowto
;
1738 unsigned long *khowto_offp
;
1740 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1742 if (khowto_offp
!= NULL
) {
1743 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1746 khowto
= sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1747 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1749 *khowto_offp
= addr_offset(khowto_ss
, khowto
);
1751 khowto
->type
= type
;
1752 khowto
->pcrel
= howto
->pc_relative
;
1753 khowto
->size
= bfd_get_reloc_size(howto
);
1754 khowto
->dst_mask
= howto
->dst_mask
;
1755 khowto
->rightshift
= howto
->rightshift
;
1756 khowto
->signed_addend
=
1757 (howto
->complain_on_overflow
== complain_overflow_signed
) ||
1758 (howto
->complain_on_overflow
== complain_overflow_bitfield
);
1759 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1762 #define CANARY(x, canary) ((x & ~howto->dst_mask) | (canary & howto->dst_mask))
1764 void write_canary(struct supersect
*ss
, int offset
, bfd_size_type size
,
1767 int bits
= size
* 8;
1768 void *address
= ss
->contents
.data
+ offset
;
1769 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1770 x
= (x
& ~dst_mask
) | ((bfd_vma
)KSPLICE_CANARY
& dst_mask
);
1771 bfd_put(bits
, ss
->parent
->abfd
, x
, address
);
1774 static void write_date_relocs(struct superbfd
*sbfd
, const char *str
,
1775 enum ksplice_reloc_howto_type type
)
1778 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1779 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1780 if (ss
->type
!= SS_TYPE_STRING
&& ss
->type
!= SS_TYPE_RODATA
)
1784 for (span
= ss
->spans
.data
;
1785 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1788 for (ptr
= ss
->contents
.data
+ span
->start
;
1789 ptr
+ strlen(str
) < ss
->contents
.data
+
1790 span
->start
+ span
->contents_size
; ptr
++) {
1791 if (strcmp((const char *)ptr
, str
) == 0)
1792 write_ksplice_date_reloc
1793 (ss
, addr_offset(ss
, ptr
), str
,
1800 static void write_ksplice_date_reloc(struct supersect
*ss
, unsigned long offset
,
1802 enum ksplice_reloc_howto_type type
)
1804 struct supersect
*kreloc_ss
;
1805 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1806 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1807 struct ksplice_reloc
);
1809 const char *filename
= ss
->parent
->abfd
->filename
;
1810 char *c
= strstr(filename
, ".KSPLICE");
1811 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
1813 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1814 strprintf("%s<%.*s>", str
, flen
, filename
),
1817 struct span
*span
= find_span(ss
, offset
);
1818 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1819 offset
+ span
->shift
);
1820 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
,
1824 static void write_table_relocs(struct superbfd
*sbfd
, const char *sectname
,
1825 enum ksplice_reloc_howto_type type
)
1827 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, sectname
);
1830 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1832 const struct table_section
*s
= get_table_section(sectname
);
1837 for (entry
= ss
->contents
.data
;
1838 entry
< ss
->contents
.data
+ ss
->contents
.size
;
1839 entry
+= s
->entry_size
) {
1840 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
1841 assert(span
!= NULL
);
1845 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
1846 assert(reloc
!= NULL
);
1847 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
1848 assert(!bfd_is_const_section(sym
->section
));
1849 struct supersect
*sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1850 unsigned long addr
= sym
->value
+
1851 reloc_target_offset(ss
, reloc
);
1852 write_ksplice_table_reloc(sym_ss
, addr
, span
->label
, type
);
1856 static void write_ksplice_table_reloc(struct supersect
*ss
,
1857 unsigned long address
,
1859 enum ksplice_reloc_howto_type type
)
1861 struct supersect
*kreloc_ss
;
1862 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1863 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1864 struct ksplice_reloc
);
1865 struct span
*span
= find_span(ss
, address
);
1866 assert(span
!= NULL
);
1868 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1870 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1871 address
+ span
->shift
);
1872 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
, 0);
1875 static void write_ksplice_nonreloc_howto(struct supersect
*ss
,
1876 const struct ksplice_reloc_howto
1878 enum ksplice_reloc_howto_type type
,
1881 struct supersect
*khowto_ss
=
1882 make_section(ss
->parent
, ".ksplice_reloc_howtos");
1883 struct ksplice_reloc_howto
*khowto
=
1884 sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1886 khowto
->type
= type
;
1887 khowto
->size
= size
;
1889 khowto
->dst_mask
= 0;
1890 khowto
->rightshift
= 0;
1891 khowto
->signed_addend
= 0;
1892 write_reloc(ss
, addr
, &khowto_ss
->symbol
,
1893 addr_offset(khowto_ss
, khowto
));
1896 static void write_ksplice_symbol_reloc(struct supersect
*ss
,
1897 const char *sectname
,
1898 unsigned long *addr
, asymbol
*sym
,
1899 const char *label
, const char *name
)
1901 struct supersect
*kreloc_ss
;
1902 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1903 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1904 struct ksplice_reloc
);
1906 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, sym
, label
,
1908 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1909 addr_offset(ss
, addr
));
1910 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
,
1911 KSPLICE_HOWTO_SYMBOL
, 0);
1914 static void write_ksplice_section(struct span
*span
)
1916 struct supersect
*ss
= span
->ss
;
1917 const char *sectname
= span
->ss
->name
;
1918 const struct table_section
*ts
= get_table_section(ss
->name
);
1920 if (ts
!= NULL
&& ts
->has_addr
) {
1921 arelent
*reloc
= find_reloc(ss
, ss
->contents
.data
+ span
->start
1923 assert(reloc
!= NULL
);
1924 asymbol
*rsym
= *reloc
->sym_ptr_ptr
;
1925 assert(!bfd_is_const_section(rsym
->section
));
1926 sectname
= rsym
->section
->name
;
1929 struct supersect
*ksect_ss
=
1930 make_section(ss
->parent
, ".ksplice_sections%s", sectname
);
1931 struct ksplice_section
*ksect
= sect_grow(ksect_ss
, 1,
1932 struct ksplice_section
);
1933 asymbol
*sym
= span
->symbol
== NULL
? ss
->symbol
: span
->symbol
;
1935 write_ksplice_symbol(ksect_ss
, &ksect
->symbol
, sym
, span
,
1936 mode("keep-new-code") ? "(post)" : "");
1937 ksect
->size
= span
->size
;
1940 if (ss
->type
== SS_TYPE_RODATA
|| ss
->type
== SS_TYPE_STRING
||
1941 ss
->type
== SS_TYPE_EXPORT
|| ss
->type
== SS_TYPE_BUGTABLE
)
1942 ksect
->flags
|= KSPLICE_SECTION_RODATA
;
1943 if (ss
->type
== SS_TYPE_DATA
)
1944 ksect
->flags
|= KSPLICE_SECTION_DATA
;
1945 if (ss
->type
== SS_TYPE_TEXT
)
1946 ksect
->flags
|= KSPLICE_SECTION_TEXT
;
1947 assert(ksect
->flags
!= 0);
1949 if (ss
->type
== SS_TYPE_STRING
)
1950 ksect
->flags
|= KSPLICE_SECTION_STRING
;
1951 if (ss
->match_data_early
)
1952 ksect
->flags
|= KSPLICE_SECTION_MATCH_DATA_EARLY
;
1954 write_reloc(ksect_ss
, &ksect
->address
, &ss
->symbol
,
1955 span
->start
+ span
->shift
);
1957 if (mode("keep-old-code")) {
1958 /* Write ksplice_symbols for all the entry points */
1959 struct entry_point
*entry
;
1960 for (entry
= span
->entry_points
.data
;
1961 entry
< span
->entry_points
.data
+ span
->entry_points
.size
;
1963 write_ksplice_symbol_reloc
1964 (span
->ss
, sectname
, span
->ss
->contents
.data
+
1965 span
->start
+ span
->shift
+ entry
->offset
,
1966 entry
->symbol
, entry
->label
, entry
->name
);
1970 static void write_ksplice_patch_reloc(struct supersect
*ss
,
1971 const char *sectname
, unsigned long *addr
,
1972 bfd_size_type size
, const char *label
,
1975 struct supersect
*kreloc_ss
;
1976 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1977 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1978 struct ksplice_reloc
);
1980 write_canary(ss
, addr_offset(ss
, addr
), size
, -1);
1981 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1983 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1984 addr_offset(ss
, addr
));
1985 reloc_howto_type
*howto
=
1986 bfd_reloc_type_lookup(ss
->parent
->abfd
,
1987 PASTE(BFD_RELOC_
, LONG_BIT
));
1988 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, howto
,
1989 KSPLICE_HOWTO_RELOC
);
1990 kreloc
->target_addend
= addend
;
1991 kreloc
->insn_addend
= 0;
1994 /* Assumes symbol is global, aka only one symbol of that name */
1995 static asymbol
*name_to_symbol(struct superbfd
*sbfd
, const char *name
)
2001 for (symp
= sbfd
->syms
.data
;
2002 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2003 asymbol
*sym
= *symp
;
2004 if (strcmp(name
, sym
->name
) == 0 &&
2005 ((sym
->flags
& BSF_GLOBAL
) != 0 ||
2006 bfd_is_und_section(sym
->section
)))
2012 void write_ksplice_patches(struct superbfd
*sbfd
, struct span
*span
)
2014 if (span
->datapatch
) {
2015 write_ksplice_patch(sbfd
, span
, span
->label
, 0);
2019 assert(span
->patch
);
2021 long prev_offset
= LONG_MIN
;
2022 asymbol
*prev_sym
= NULL
;
2023 const char *prev_label
= NULL
;
2024 struct entry_point
*entry
;
2025 for (entry
= span
->pre_entry_points
.data
;
2026 entry
< span
->pre_entry_points
.data
+ span
->pre_entry_points
.size
;
2028 asymbol
*sym
= name_to_symbol(sbfd
, entry
->name
);
2029 if (sym
== NULL
&& entry
->offset
!= 0) {
2030 /* Since it was global, name and label are the same */
2031 write_ksplice_deleted_patch
2032 (sbfd
, entry
->label
, entry
->label
, span
->ss
->name
,
2034 } else if (entry
->offset
!= prev_offset
) {
2035 debug1(sbfd
, "entry point: %s(%s) %lx\n", entry
->label
,
2036 entry
->name
, entry
->offset
);
2038 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> entry
->offset
) {
2040 "Overlapping trampolines: %s %lx/%lx\n",
2041 span
->label
, prev_offset
, entry
->offset
);
2045 long target_offset
= 0;
2047 target_offset
= sym
->value
- span
->start
;
2048 write_ksplice_patch(sbfd
, span
, entry
->label
,
2050 prev_offset
= entry
->offset
;
2054 if (prev_sym
== NULL
) {
2056 prev_label
= entry
->label
;
2057 } else if (sym
!= NULL
&&
2058 (prev_sym
->section
!= sym
->section
||
2059 prev_sym
->value
!= sym
->value
)) {
2060 err(sbfd
, "Splitting global symbols in the middle of a "
2061 "span: %s+%lx != %s+%lx!\n",
2062 prev_label
, (unsigned long)prev_sym
->value
,
2063 entry
->label
, (unsigned long)sym
->value
);
2068 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> span
->size
) {
2069 err(sbfd
, "Trampoline ends outside span: %s %lx/%lx\n",
2070 span
->label
, prev_offset
, (unsigned long)span
->size
);
2075 void write_ksplice_patch(struct superbfd
*sbfd
, struct span
*span
,
2076 const char *label
, long offset
)
2078 struct supersect
*kpatch_ss
=
2079 make_section(sbfd
, ".ksplice_patches%s", span
->ss
->name
);
2080 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2081 struct ksplice_patch
);
2083 write_ksplice_patch_reloc(kpatch_ss
, span
->ss
->name
, &kpatch
->oldaddr
,
2084 sizeof(kpatch
->oldaddr
), label
, 0);
2085 if (span
->ss
->type
== SS_TYPE_TEXT
) {
2086 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2087 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
,
2090 kpatch
->type
= KSPLICE_PATCH_DATA
;
2091 kpatch
->size
= span
->contents_size
;
2092 struct supersect
*data_ss
=
2093 make_section(sbfd
, ".ksplice_patch_data");
2094 write_reloc(kpatch_ss
, &kpatch
->contents
, &span
->ss
->symbol
,
2095 span
->start
+ span
->shift
);
2096 char *saved
= sect_do_grow(data_ss
, 1, span
->contents_size
, 1);
2097 write_reloc(kpatch_ss
, &kpatch
->saved
, &data_ss
->symbol
,
2098 addr_offset(data_ss
, saved
));
2100 write_reloc(kpatch_ss
, &kpatch
->repladdr
, &span
->ss
->symbol
,
2101 span
->start
+ span
->shift
+ offset
);
2104 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
)
2107 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
2109 asymbol
*sym
= *symp
;
2110 if (strcmp(name
, sym
->name
) == 0 &&
2111 bfd_is_und_section(sym
->section
))
2115 for (sympp
= sbfd
->new_syms
.data
;
2116 sympp
< sbfd
->new_syms
.data
+ sbfd
->new_syms
.size
; sympp
++) {
2117 asymbol
**symp
= *sympp
;
2118 asymbol
*sym
= *symp
;
2119 if (strcmp(name
, sym
->name
) == 0 &&
2120 bfd_is_und_section(sym
->section
))
2124 symp
= malloc(sizeof(*symp
));
2125 *symp
= bfd_make_empty_symbol(sbfd
->abfd
);
2126 asymbol
*sym
= *symp
;
2128 sym
->section
= bfd_und_section_ptr
;
2131 *vec_grow(&sbfd
->new_syms
, 1) = symp
;
2135 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
2136 const char *label
, const char *sectname
,
2139 struct supersect
*kpatch_ss
=
2140 make_section(sbfd
, ".ksplice_patches%s", sectname
);
2141 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2142 struct ksplice_patch
);
2144 write_ksplice_patch_reloc(kpatch_ss
, sectname
, &kpatch
->oldaddr
,
2145 sizeof(kpatch
->oldaddr
), label
, 0);
2146 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2147 asymbol
**symp
= make_undefined_symbolp(sbfd
, strdup(name
));
2148 write_reloc(kpatch_ss
, &kpatch
->repladdr
, symp
, offset
);
2149 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
, NULL
);
2152 void write_ksplice_export(struct superbfd
*sbfd
, struct span
*span
, bool del
)
2154 struct supersect
*kpatch_ss
= make_section(sbfd
, ".ksplice_patches");
2155 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2156 struct ksplice_patch
);
2157 struct supersect
*data_ss
;
2159 const struct table_section
*ts
= get_table_section(span
->ss
->name
);
2162 span
->ss
->contents
.data
+ span
->start
+ ts
->other_offset
;
2163 const char *symname
= read_string(span
->ss
, addr
);
2165 char *oldname
, *newname
;
2167 oldname
= strprintf("%s:%s", span
->ss
->name
, symname
);
2168 newname
= strprintf("DISABLED_%s_%s", symname
, kid
);
2170 oldname
= strprintf("%s:DISABLED_%s_%s", span
->ss
->name
,
2172 newname
= strprintf("%s", symname
);
2173 write_string(span
->ss
, addr
, "DISABLED_%s_%s", symname
, kid
);
2176 write_ksplice_patch_reloc(kpatch_ss
, "", &kpatch
->oldaddr
,
2177 sizeof(kpatch
->oldaddr
), oldname
,
2179 kpatch
->type
= KSPLICE_PATCH_EXPORT
;
2180 const char **namep
= write_patch_storage(kpatch_ss
, kpatch
,
2181 sizeof(newname
), &data_ss
);
2182 write_string(data_ss
, namep
, "%s", newname
);
2185 void filter_table_sections(struct superbfd
*isbfd
)
2187 struct supersect
*tables_ss
=
2188 fetch_supersect(offsets_sbfd
,
2189 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2190 ".ksplice_table_sections"));
2191 const struct table_section
*ts
;
2192 for (ts
= tables_ss
->contents
.data
;
2193 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2195 struct table_section s
= *ts
;
2196 s
.sect
= read_string(tables_ss
, &ts
->sect
);
2197 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
2198 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2199 filter_table_section(isbfd
, &s
);
2203 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
)
2205 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
2206 if (isection
== NULL
)
2208 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2211 for (entry
= ss
->contents
.data
;
2212 entry
< ss
->contents
.data
+ ss
->contents
.size
;
2213 entry
+= s
->entry_size
) {
2214 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
2215 assert(span
!= NULL
);
2218 struct span
*sym_span
=
2219 span_offset_target_span(span
, s
->addr_offset
);
2220 assert(sym_span
!= NULL
);
2225 if (s
->other_sect
!= NULL
) {
2226 struct span
*sym_span
=
2227 span_offset_target_span(span
, s
->other_offset
);
2228 assert(sym_span
!= NULL
);
2230 keep_span(sym_span
);
2233 if (s
->crc_sect
!= NULL
) {
2234 struct span
*crc_span
= get_crc_span(span
, s
);
2235 assert(crc_span
!= NULL
);
2236 if (span
->keep
&& mode("keep-new-code"))
2237 keep_span(crc_span
);
2242 static void match_other_spans(struct span
*old_span
, struct span
*new_span
)
2244 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2248 if (old_span
->match
== new_span
&& new_span
->match
== old_span
&&
2249 ts
->other_sect
!= NULL
) {
2250 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2251 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2252 arelent
*old_reloc
=
2253 find_reloc(old_span
->ss
, old_entry
+ ts
->other_offset
);
2254 arelent
*new_reloc
=
2255 find_reloc(new_span
->ss
, new_entry
+ ts
->other_offset
);
2256 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2257 struct span
*old_other_span
=
2258 reloc_target_span(old_span
->ss
, old_reloc
);
2259 struct span
*new_other_span
=
2260 reloc_target_span(new_span
->ss
, new_reloc
);
2261 assert(old_other_span
!= NULL
&& new_other_span
!= NULL
);
2262 match_spans(old_other_span
, new_other_span
);
2266 static void match_table_spans(struct span
*old_span
, struct span
*new_span
)
2268 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2270 if (strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
2272 if (ts
== NULL
|| old_span
->ss
->type
!= SS_TYPE_SPECIAL
||
2273 new_span
->ss
->type
!= SS_TYPE_SPECIAL
)
2275 if (old_span
->match
!= NULL
|| new_span
->match
!= NULL
)
2279 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2280 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2281 arelent
*old_reloc
=
2282 find_reloc(old_span
->ss
, old_entry
+ ts
->addr_offset
);
2283 arelent
*new_reloc
=
2284 find_reloc(new_span
->ss
, new_entry
+ ts
->addr_offset
);
2285 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2286 struct span
*old_sym_span
=
2287 reloc_target_span(old_span
->ss
, old_reloc
);
2288 struct span
*new_sym_span
=
2289 reloc_target_span(new_span
->ss
, new_reloc
);
2290 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
2291 if (old_sym_span
->match
== new_sym_span
&&
2292 new_sym_span
->match
== old_sym_span
&&
2293 old_reloc
->address
- old_sym_span
->start
==
2294 new_reloc
->address
- new_sym_span
->start
)
2295 match_spans(old_span
, new_span
);
2299 static struct span
*get_crc_span(struct span
*span
,
2300 const struct table_section
*ts
)
2302 void *entry
= span
->ss
->contents
.data
+ span
->start
;
2303 asection
*crc_sect
= bfd_get_section_by_name(span
->ss
->parent
->abfd
,
2305 if (crc_sect
== NULL
)
2307 struct supersect
*crc_ss
= fetch_supersect(span
->ss
->parent
, crc_sect
);
2310 struct span
*crc_span
= find_span(crc_ss
, addr_offset(span
->ss
, entry
) /
2311 ts
->entry_size
* ts
->crc_size
);
2315 void mark_precallable_spans(struct superbfd
*sbfd
)
2318 struct supersect
*ss
, *sym_ss
;
2319 struct span
*address_span
, *target_span
;
2320 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2321 ss
= fetch_supersect(sbfd
, sect
);
2323 if (ss
->type
== SS_TYPE_SPECIAL
)
2325 for (relocp
= ss
->relocs
.data
;
2326 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2327 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2328 address_span
= find_span(ss
, (*relocp
)->address
);
2329 if (!address_span
->precallable
)
2331 target_span
= reloc_target_span(ss
, *relocp
);
2332 if (target_span
== NULL
|| target_span
->keep
)
2334 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2335 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2337 target_span
->precallable
= true;
2343 void keep_referenced_sections(struct superbfd
*sbfd
)
2346 struct supersect
*ss
, *sym_ss
;
2347 struct span
*address_span
, *target_span
;
2348 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2349 ss
= fetch_supersect(sbfd
, sect
);
2351 if (ss
->type
== SS_TYPE_SPECIAL
)
2353 for (relocp
= ss
->relocs
.data
;
2354 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2355 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2356 address_span
= find_span(ss
, (*relocp
)->address
);
2357 if (!address_span
->keep
)
2359 target_span
= reloc_target_span(ss
, *relocp
);
2360 if (target_span
== NULL
|| target_span
->keep
)
2362 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2363 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2365 keep_span(target_span
);
2371 void copy_symbols(struct asymbolp_vec
*osyms
, struct asymbolpp_vec
*isyms
)
2374 for (sympp
= isyms
->data
; sympp
< isyms
->data
+ isyms
->size
; sympp
++)
2375 *vec_grow(osyms
, 1) = **sympp
;
2378 /* Modified function from GNU Binutils objcopy.c */
2379 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
)
2381 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2383 bfd_vma start
= bfd_get_start_address(ibfd
);
2385 flagword flags
= bfd_get_file_flags(ibfd
);
2386 flags
&= bfd_applicable_file_flags(obfd
);
2388 assert(bfd_set_start_address(obfd
, start
)
2389 && bfd_set_file_flags(obfd
, flags
));
2391 enum bfd_architecture iarch
= bfd_get_arch(ibfd
);
2392 unsigned int imach
= bfd_get_mach(ibfd
);
2393 assert(bfd_set_arch_mach(obfd
, iarch
, imach
));
2394 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2396 /* BFD mandates that all output sections be created and sizes set before
2397 any output is done. Thus, we traverse all sections multiple times. */
2398 bfd_map_over_sections(ibfd
, setup_section
, obfd
);
2400 struct supersect
*new_supersects
= fetch_superbfd(ibfd
)->new_supersects
;
2401 struct supersect
*ss
;
2402 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2403 setup_new_section(obfd
, ss
);
2405 /* Mark symbols used in output relocations so that they
2406 are kept, even if they are local labels or static symbols.
2408 Note we iterate over the input sections examining their
2409 relocations since the relocations for the output sections
2410 haven't been set yet. mark_symbols_used_in_relocations will
2411 ignore input sections which have no corresponding output
2414 bfd_map_over_sections(ibfd
, mark_symbols_used_in_relocations
, NULL
);
2415 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2416 ss_mark_symbols_used_in_relocations(ss
);
2417 struct asymbolp_vec osyms
;
2419 filter_symbols(ibfd
, obfd
, &osyms
, &fetch_superbfd(ibfd
)->syms
);
2420 copy_symbols(&osyms
, &fetch_superbfd(ibfd
)->new_syms
);
2422 bfd_set_symtab(obfd
, osyms
.data
, osyms
.size
);
2424 /* This has to happen after the symbol table has been set. */
2425 bfd_map_over_sections(obfd
, write_section
, NULL
);
2427 /* Allow the BFD backend to copy any private data it understands
2428 from the input BFD to the output BFD. This is done last to
2429 permit the routine to look at the filtered symbol table, which is
2430 important for the ECOFF code at least. */
2431 assert(bfd_copy_private_bfd_data(ibfd
, obfd
));
2436 /* Modified function from GNU Binutils objcopy.c */
2437 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
)
2439 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
2440 struct supersect
*ss
= fetch_supersect(isbfd
, isection
);
2441 bfd
*obfd
= obfdarg
;
2447 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2448 assert(osection
!= NULL
);
2450 osection
->userdata
= ss
;
2451 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2452 ss
->symbol
= osection
->symbol
;
2453 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2455 vma
= bfd_section_vma(ibfd
, isection
);
2456 assert(bfd_set_section_vma(obfd
, osection
, vma
));
2458 osection
->lma
= isection
->lma
;
2459 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2460 osection
->entsize
= ss
->entsize
;
2461 osection
->output_section
= osection
;
2462 osection
->output_offset
= 0;
2463 isection
->output_section
= osection
;
2464 isection
->output_offset
= 0;
2468 void setup_new_section(bfd
*obfd
, struct supersect
*ss
)
2470 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2471 assert(osection
!= NULL
);
2472 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2474 osection
->userdata
= ss
;
2475 ss
->symbol
= osection
->symbol
;
2476 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2477 assert(bfd_set_section_vma(obfd
, osection
, 0));
2480 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2481 osection
->entsize
= ss
->entsize
;
2482 osection
->output_section
= osection
;
2483 osection
->output_offset
= 0;
2486 static int compare_reloc_addresses(const void *aptr
, const void *bptr
)
2488 const arelent
*const *a
= aptr
, *const *b
= bptr
;
2489 return (*a
)->address
- (*b
)->address
;
2492 static void delete_obsolete_relocs(struct supersect
*ss
)
2494 if (ss
->new_relocs
.size
== 0)
2497 qsort(ss
->relocs
.data
, ss
->relocs
.size
, sizeof(*ss
->relocs
.data
),
2498 compare_reloc_addresses
);
2499 qsort(ss
->new_relocs
.data
, ss
->new_relocs
.size
,
2500 sizeof(*ss
->new_relocs
.data
), compare_reloc_addresses
);
2502 struct arelentp_vec orig_relocs
;
2503 vec_move(&orig_relocs
, &ss
->relocs
);
2505 arelent
**relocp
, **new_relocp
= ss
->new_relocs
.data
;
2506 for (relocp
= orig_relocs
.data
;
2507 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
2508 while (new_relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
&&
2509 (*new_relocp
)->address
< (*relocp
)->address
)
2511 arelent
*reloc
= *relocp
, *new_reloc
= *new_relocp
;
2512 if (new_relocp
== ss
->new_relocs
.data
+ ss
->new_relocs
.size
||
2513 reloc
->address
!= new_reloc
->address
)
2514 *vec_grow(&ss
->relocs
, 1) = reloc
;
2518 void write_section(bfd
*obfd
, asection
*osection
, void *arg
)
2520 struct supersect
*ss
= osection
->userdata
;
2522 if ((ss
->flags
& SEC_GROUP
) != 0 || ss
->contents
.size
== 0)
2525 delete_obsolete_relocs(ss
);
2528 char *error_message
;
2529 for (relocp
= ss
->new_relocs
.data
;
2530 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2532 if (bfd_get_arch(obfd
) == bfd_arch_arm
)
2533 val
= osection
->use_rela_p
? 0 : (*relocp
)->addend
;
2536 bfd_put(bfd_get_reloc_size((*relocp
)->howto
) * 8, obfd
, val
,
2537 ss
->contents
.data
+ (*relocp
)->address
);
2538 if (bfd_install_relocation(obfd
, *relocp
, ss
->contents
.data
,
2539 0, osection
, &error_message
) !=
2541 err(ss
->parent
, "ksplice: error installing reloc: %s",
2545 if (mode("finalize")) {
2546 /* Check that all our sections will be allocated */
2547 asymbol
*sym
= *((*relocp
)->sym_ptr_ptr
);
2548 if (!bfd_is_const_section(sym
->section
)) {
2549 struct supersect
*sym_ss
=
2550 fetch_supersect(ss
->parent
, sym
->section
);
2551 assert((sym_ss
->flags
& SEC_ALLOC
) != 0);
2555 memcpy(vec_grow(&ss
->relocs
, ss
->new_relocs
.size
), ss
->new_relocs
.data
,
2556 ss
->new_relocs
.size
* sizeof(*ss
->new_relocs
.data
));
2558 bfd_set_reloc(obfd
, osection
,
2559 ss
->relocs
.size
== 0 ? NULL
: ss
->relocs
.data
,
2562 if (ss
->flags
& SEC_HAS_CONTENTS
)
2563 assert(bfd_set_section_contents
2564 (obfd
, osection
, ss
->contents
.data
, 0,
2565 ss
->contents
.size
));
2568 /* Modified function from GNU Binutils objcopy.c
2570 * Mark all the symbols which will be used in output relocations with
2571 * the BSF_KEEP flag so that those symbols will not be stripped.
2573 * Ignore relocations which will not appear in the output file.
2575 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
2578 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2579 if (isection
->output_section
== NULL
)
2582 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2583 ss_mark_symbols_used_in_relocations(ss
);
2586 void ss_mark_symbols_used_in_relocations(struct supersect
*ss
)
2588 /* Examine each symbol used in a relocation. If it's not one of the
2589 special bfd section symbols, then mark it with BSF_KEEP. */
2591 for (relocp
= ss
->relocs
.data
;
2592 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2593 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2594 if (!(bfd_is_const_section(sym
->section
) &&
2595 sym
== sym
->section
->symbol
))
2596 sym
->flags
|= BSF_KEEP
;
2598 for (relocp
= ss
->new_relocs
.data
;
2599 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2600 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2601 if (!(bfd_is_const_section(sym
->section
) &&
2602 sym
== sym
->section
->symbol
))
2603 sym
->flags
|= BSF_KEEP
;
2607 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
)
2609 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2610 if (bfd_is_const_section(sym
->section
))
2612 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
2615 for (symp
= ss
->syms
.data
; symp
< ss
->syms
.data
+ ss
->syms
.size
; symp
++) {
2619 return symp
>= ss
->syms
.data
+ ss
->syms
.size
&&
2620 (sym
->flags
& BSF_SECTION_SYM
) == 0;
2623 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
2624 struct asymbolp_vec
*isyms
)
2627 struct superbfd
*sbfd
= fetch_superbfd(ibfd
);
2628 for (symp
= isyms
->data
; symp
< isyms
->data
+ isyms
->size
; symp
++) {
2629 asymbol
*sym
= *symp
;
2630 struct supersect
*sym_ss
= NULL
;
2631 struct span
*sym_span
= NULL
;
2632 if (!bfd_is_const_section(sym
->section
)) {
2633 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2634 sym_span
= find_span(sym_ss
, sym
->value
);
2637 if (mode("keep") && (sym
->flags
& BSF_GLOBAL
) != 0 &&
2638 !(mode("keep-new-code") && sym_span
!= NULL
&&
2640 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2642 if (mode("finalize") && (sym
->flags
& BSF_GLOBAL
) != 0)
2643 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2645 bool keep
= bfd_is_const_section(sym
->section
) ||
2646 (sym_ss
->keep
&& (sym
->flags
& BSF_SECTION_SYM
) != 0) ||
2647 (sym_span
!= NULL
&& sym_span
->keep
);
2648 if (bfd_is_und_section(sym
->section
) &&
2649 (sym
->flags
& BSF_KEEP
) == 0)
2651 if (bfd_is_abs_section(sym
->section
) &&
2652 (sym
->flags
& BSF_KEEP
) == 0 &&
2653 (sym
->flags
& BSF_FILE
) == 0)
2655 if (deleted_table_section_symbol(ibfd
, sym
))
2658 if (mode("keep-old-code") && sym_ss
!= NULL
&&
2659 sym_ss
->type
== SS_TYPE_EXPORT
)
2663 if (sym_ss
!= NULL
&& !sym_ss
->keep
) {
2664 err(sbfd
, "Kept symbol %s in unkept section "
2665 "%s\n", sym
->name
, sym
->section
->name
);
2668 *vec_grow(osyms
, 1) = sym
;
2673 static bool is_table_section(const char *name
, bool consider_other
,
2676 struct supersect
*tables_ss
=
2677 fetch_supersect(offsets_sbfd
,
2678 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2679 ".ksplice_table_sections"));
2680 const struct table_section
*ts
;
2681 for (ts
= tables_ss
->contents
.data
;
2682 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2684 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0)
2686 const char *osect_name
= read_string(tables_ss
,
2688 if (consider_other
&& osect_name
!= NULL
&&
2689 strcmp(name
, osect_name
) == 0)
2691 const char *crc_name
= read_string(tables_ss
, &ts
->crc_sect
);
2692 if (consider_crc
&& crc_name
!= NULL
&&
2693 strcmp(name
, crc_name
) == 0)
2699 const struct table_section
*get_table_section(const char *name
)
2701 struct supersect
*tables_ss
=
2702 fetch_supersect(offsets_sbfd
,
2703 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2704 ".ksplice_table_sections"));
2705 const struct table_section
*ts
;
2706 for (ts
= tables_ss
->contents
.data
;
2707 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2709 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0) {
2710 if (ts
->entry_contents_size
!= 0)
2711 assert(align(ts
->entry_contents_size
,
2714 struct table_section
*ns
= malloc(sizeof(*ns
));
2716 ns
->sect
= read_string(tables_ss
, &ts
->sect
);
2717 ns
->crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2719 read_string(tables_ss
, &ts
->other_sect
);
2726 enum supersect_type
supersect_type(struct supersect
*ss
)
2728 if (mode("finalize") &&
2729 strcmp(finalize_target
, "vmlinux") == 0 &&
2730 (strstarts(ss
->name
, ".ksplice_relocs.exit") ||
2731 strstarts(ss
->name
, ".ksplice_sections.exit") ||
2732 strstarts(ss
->name
, ".ksplice_patches.exit")))
2733 return SS_TYPE_EXIT
;
2734 if (strstarts(ss
->name
, ".ksplice_call"))
2735 return SS_TYPE_KSPLICE_CALL
;
2736 if (strstarts(ss
->name
, ".ksplice_extract"))
2737 return SS_TYPE_KSPLICE_EXTRACT
;
2738 if (strstarts(ss
->name
, ".ksplice_options"))
2739 return SS_TYPE_SPECIAL
;
2740 if (strstarts(ss
->name
, ".ksplice"))
2741 return SS_TYPE_KSPLICE
;
2743 if (strstarts(ss
->name
, ".init"))
2744 return SS_TYPE_IGNORED
;
2745 if (strstarts(ss
->name
, ".security_initcall.init"))
2746 return SS_TYPE_IGNORED
;
2747 if (strstarts(ss
->name
, ".con_initcall.init"))
2748 return SS_TYPE_IGNORED
;
2749 if (strstarts(ss
->name
, ".x86cpuvendor.init"))
2750 return SS_TYPE_IGNORED
;
2751 if (strstarts(ss
->name
, ".early_param.init"))
2752 return SS_TYPE_IGNORED
;
2753 if (strstarts(ss
->name
, ".taglist.init"))
2754 return SS_TYPE_IGNORED
;
2755 if (strstarts(ss
->name
, ".x86_cpu_dev.init"))
2756 return SS_TYPE_IGNORED
;
2757 if (strstarts(ss
->name
, ".arch.info.init"))
2758 return SS_TYPE_IGNORED
;
2759 if (strstarts(ss
->name
, ".proc.info.init"))
2760 return SS_TYPE_IGNORED
;
2761 /* .pci_fixup_* sections really should be treated as global rodata
2762 referenced only from quirks.c */
2763 if (strstarts(ss
->name
, ".pci_fixup_"))
2764 return SS_TYPE_IGNORED
;
2765 /* .builtin_fw sections are similar to .pci_fixup */
2766 if (strstarts(ss
->name
, ".builtin_fw"))
2767 return SS_TYPE_IGNORED
;
2768 /* same for .tracedata */
2769 if (strstarts(ss
->name
, ".tracedata"))
2770 return SS_TYPE_IGNORED
;
2771 if (strstarts(ss
->name
, ".debug"))
2772 return SS_TYPE_IGNORED
;
2773 /* .eh_frame should probably be discarded, not ignored */
2774 if (strstarts(ss
->name
, ".eh_frame"))
2775 return SS_TYPE_IGNORED
;
2776 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devinit"))
2777 return SS_TYPE_IGNORED
;
2778 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".meminit"))
2779 return SS_TYPE_IGNORED
;
2780 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuinit"))
2781 return SS_TYPE_IGNORED
;
2782 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devexit"))
2783 return SS_TYPE_IGNORED
;
2784 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".memexit"))
2785 return SS_TYPE_IGNORED
;
2786 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuexit"))
2787 return SS_TYPE_IGNORED
;
2788 if (strstarts(ss
->name
, ".vgetcpu_mode") ||
2789 strstarts(ss
->name
, ".jiffies") ||
2790 strstarts(ss
->name
, ".wall_jiffies") ||
2791 strstarts(ss
->name
, ".vxtime") ||
2792 strstarts(ss
->name
, ".sys_tz") ||
2793 strstarts(ss
->name
, ".sysctl_vsyscall") ||
2794 strstarts(ss
->name
, ".xtime") ||
2795 strstarts(ss
->name
, ".xtime_lock") ||
2796 strstarts(ss
->name
, ".vsyscall"))
2797 return SS_TYPE_IGNORED
;
2798 if (strstarts(ss
->name
, ".vdso"))
2799 return SS_TYPE_IGNORED
;
2801 if (strstarts(ss
->name
, ".exit.text"))
2802 return SS_TYPE_TEXT
;
2803 if (strstarts(ss
->name
, ".exit.data"))
2804 return SS_TYPE_DATA
;
2806 if (strstarts(ss
->name
, ".text") ||
2807 strstarts(ss
->name
, ".kernel.text") ||
2808 strstarts(ss
->name
, ".devinit.text") ||
2809 strstarts(ss
->name
, ".meminit.text") ||
2810 strstarts(ss
->name
, ".cpuinit.text") ||
2811 strstarts(ss
->name
, ".devexit.text") ||
2812 strstarts(ss
->name
, ".memexit.text") ||
2813 strstarts(ss
->name
, ".cpuexit.text") ||
2814 strstarts(ss
->name
, ".ref.text") ||
2815 strstarts(ss
->name
, ".spinlock.text") ||
2816 strstarts(ss
->name
, ".kprobes.text") ||
2817 strstarts(ss
->name
, ".sched.text") ||
2818 strstarts(ss
->name
, ".entry.text") || /* OpenVZ */
2819 (mode("keep-old-code") && strstarts(ss
->name
, ".fixup")))
2820 return SS_TYPE_TEXT
;
2823 if (sscanf(ss
->name
, ".rodata.str%*u.%*u%n", &n
) >= 0 &&
2824 n
== strlen(ss
->name
))
2825 return ss
->entsize
== 1 ? SS_TYPE_STRING
: SS_TYPE_RODATA
;
2827 if (strstarts(ss
->name
, ".rodata") ||
2828 strstarts(ss
->name
, ".kernel.rodata") ||
2829 strstarts(ss
->name
, ".devinit.rodata") ||
2830 strstarts(ss
->name
, ".meminit.rodata") ||
2831 strstarts(ss
->name
, ".cpuinit.rodata") ||
2832 strstarts(ss
->name
, ".devexit.rodata") ||
2833 strstarts(ss
->name
, ".memexit.rodata") ||
2834 strstarts(ss
->name
, ".cpuexit.rodata") ||
2835 strstarts(ss
->name
, ".ref.rodata") ||
2836 strstarts(ss
->name
, "__tracepoints_strings") ||
2837 strstarts(ss
->name
, "__markers_strings") ||
2838 (mode("keep-old-code") && strstarts(ss
->name
, "__ex_table")))
2839 return SS_TYPE_RODATA
;
2841 if (strstarts(ss
->name
, ".bss"))
2842 return SS_TYPE_DATA
;
2844 /* Ignore .data.percpu sections */
2845 if (strstarts(ss
->name
, ".data.percpu") ||
2846 strstarts(ss
->name
, ".kernel.data.percpu") ||
2847 strstarts(ss
->name
, ".data..percpu"))
2848 return SS_TYPE_IGNORED
;
2849 if (strstarts(ss
->name
, ".data") ||
2850 strstarts(ss
->name
, ".kernel.data") ||
2851 strstarts(ss
->name
, ".devinit.data") ||
2852 strstarts(ss
->name
, ".cpuinit.data") ||
2853 strstarts(ss
->name
, ".meminit.data") ||
2854 strstarts(ss
->name
, ".devexit.data") ||
2855 strstarts(ss
->name
, ".memexit.data") ||
2856 strstarts(ss
->name
, ".cpuexit.data") ||
2857 strstarts(ss
->name
, ".ref.data") ||
2858 strstarts(ss
->name
, "__tracepoints") ||
2859 strstarts(ss
->name
, "__markers"))
2860 return SS_TYPE_DATA
;
2862 /* We replace all the ksymtab strings, so delete them */
2863 if (strcmp(ss
->name
, "__ksymtab_strings") == 0)
2864 return SS_TYPE_STRING
;
2865 if (strstarts(ss
->name
, "__ksymtab"))
2866 return SS_TYPE_EXPORT
;
2868 if (strstarts(ss
->name
, "__bug_table"))
2869 return SS_TYPE_BUGTABLE
;
2871 if (is_table_section(ss
->name
, true, true))
2872 return SS_TYPE_SPECIAL
;
2874 if (strstarts(ss
->name
, ".ARM."))
2875 return SS_TYPE_SPECIAL
;
2877 if (strstarts(ss
->name
, ".note"))
2878 return SS_TYPE_IGNORED
;
2879 if (strstarts(ss
->name
, ".comment"))
2880 return SS_TYPE_IGNORED
;
2881 if (strstarts(ss
->name
, "__param"))
2882 return SS_TYPE_IGNORED
;
2883 if (strstarts(ss
->name
, "__obsparm"))
2884 return SS_TYPE_IGNORED
;
2885 if (strstarts(ss
->name
, ".exitcall.exit"))
2886 return SS_TYPE_IGNORED
;
2887 if (strstarts(ss
->name
, ".modinfo"))
2888 return SS_TYPE_IGNORED
;
2890 return SS_TYPE_UNKNOWN
;
2893 void initialize_supersect_types(struct superbfd
*sbfd
)
2896 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2897 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2898 ss
->type
= supersect_type(ss
);
2899 ss
->orig_type
= ss
->type
;
2900 if (ss
->type
== SS_TYPE_UNKNOWN
) {
2901 err(sbfd
, "Unknown section type: %s\n", ss
->name
);
2907 static void init_label_map(struct superbfd
*sbfd
)
2909 struct label_map
*map
;
2911 vec_init(&sbfd
->maps
);
2915 struct symbol_hash csyms
;
2916 symbol_hash_init(&csyms
);
2919 for (symp
= sbfd
->syms
.data
;
2920 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2921 asymbol
*csym
= canonical_symbol(sbfd
, *symp
);
2924 char *key
= strprintf("%p", csym
);
2925 asymbol
**csymp
= symbol_hash_lookup(&csyms
, key
, TRUE
);
2931 map
= vec_grow(&sbfd
->maps
, 1);
2934 map
->label
= symbol_label(sbfd
, csym
);
2937 struct label_mapp_hash label_maps
;
2938 label_mapp_hash_init(&label_maps
);
2939 for (map
= sbfd
->maps
.data
;
2940 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2941 struct label_map
**mapp
=
2942 label_mapp_hash_lookup(&label_maps
, map
->label
, TRUE
);
2943 if (*mapp
== NULL
) {
2948 struct label_map
*first_map
= *mapp
;
2949 if (first_map
->count
== 0)
2950 first_map
->label
= strprintf("%s~%d", map
->label
, 0);
2951 map
->label
= strprintf("%s~%d", map
->label
, ++first_map
->count
);
2954 label_mapp_hash_init(&sbfd
->maps_hash
);
2955 for (map
= sbfd
->maps
.data
;
2956 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2957 char *key
= strprintf("%p", map
->csym
);
2958 struct label_map
**mapp
=
2959 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, TRUE
);
2962 map
->orig_label
= map
->label
;
2966 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
)
2968 asymbol
*csym
= canonical_symbol(sbfd
, sym
);
2969 char *key
= strprintf("%p", csym
);
2970 struct label_map
**mapp
=
2971 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2975 return (*mapp
)->label
;
2978 static void print_label_changes(struct superbfd
*sbfd
)
2982 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2983 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2984 for (span
= ss
->spans
.data
;
2985 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
2986 if (strcmp(span
->label
, span
->orig_label
) != 0)
2987 debug1(sbfd
, "Label change: %s -> %s\n",
2988 span
->label
, span
->orig_label
);
2993 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
2996 struct label_map
*map
;
2997 for (map
= sbfd
->maps
.data
;
2998 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2999 if (strcmp(map
->orig_label
, oldlabel
) == 0) {
3000 if (strcmp(map
->orig_label
, map
->label
) != 0 &&
3001 strcmp(map
->label
, label
) != 0)
3010 static void change_initial_label(struct span
*span
, const char *label
)
3012 struct superbfd
*sbfd
= span
->ss
->parent
;
3013 span
->label
= label
;
3014 span
->orig_label
= label
;
3016 asymbol
*csym
= canonical_symbol(sbfd
, span
->symbol
);
3017 char *key
= strprintf("%p", csym
);
3018 struct label_map
**mapp
=
3019 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
3022 (*mapp
)->label
= span
->label
;
3023 (*mapp
)->orig_label
= span
->orig_label
;
3024 span
->symbol
= NULL
;
3028 static void init_callers(struct superbfd
*sbfd
)
3030 string_hash_init(&sbfd
->callers
);
3032 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3033 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3035 for (relocp
= ss
->relocs
.data
;
3036 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3037 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
3039 sym
->value
+ reloc_target_offset(ss
, *relocp
);
3040 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3042 const char **ret
= string_hash_lookup(&sbfd
->callers
,
3045 asymbol
*csym
= canonical_symbol(sbfd
, sect
->symbol
);
3047 *ret
= "*multiple_callers*";
3048 else if (static_local_symbol(sbfd
, csym
))
3049 *ret
= static_local_symbol(sbfd
, csym
);
3056 static const char *find_caller(struct supersect
*ss
, asymbol
*sym
)
3058 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3059 (unsigned long)sym
->value
);
3060 const char **ret
= string_hash_lookup(&ss
->parent
->callers
, key
, FALSE
);
3064 return "*no_caller*";
3068 static void init_csyms(struct superbfd
*sbfd
)
3070 asymbolpp_hash_init(&sbfd
->csyms
);
3073 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
3075 asymbol
*sym
= *symp
;
3076 if ((sym
->flags
& BSF_DEBUGGING
) != 0)
3078 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3079 (unsigned long)sym
->value
);
3080 asymbol
***csympp
= asymbolpp_hash_lookup(&sbfd
->csyms
, key
,
3083 if (*csympp
== NULL
) {
3087 asymbol
*csym
= **csympp
;
3088 if ((csym
->flags
& BSF_GLOBAL
) != 0)
3090 if ((sym
->flags
& BSF_GLOBAL
) != 0)
3095 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
)
3097 char *key
= strprintf("%s+%lx", ss
->name
, (unsigned long)value
);
3099 asymbolpp_hash_lookup(&ss
->parent
->csyms
, key
, FALSE
);
3104 /* For section symbols of sections containing no symbols, return the
3105 section symbol that relocations are generated against */
3111 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
)
3113 if (bfd_is_const_section(sym
->section
)) {
3115 for (csymp
= sbfd
->syms
.data
;
3116 csymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; csymp
++) {
3122 return symbolp_scan(fetch_supersect(sbfd
, sym
->section
), sym
->value
);
3125 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3127 if (bfd_is_const_section(sym
->section
))
3129 asymbol
**symp
= canonical_symbolp(sbfd
, sym
);
3130 return symp
!= NULL
? *symp
: NULL
;
3133 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3135 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
3136 if ((sym
->flags
& BSF_LOCAL
) == 0 || (sym
->flags
& BSF_OBJECT
) == 0)
3138 char *dot
= strrchr(sym
->name
, '.');
3139 if (dot
== NULL
|| dot
[1 + strspn(dot
+ 1, "0123546789")] != '\0')
3141 char *basename
= strndup(sym
->name
, dot
- sym
->name
);
3143 /* Handle C.123.12345 symbols */
3144 dot
= strrchr(basename
, '.');
3145 if (dot
!= NULL
&& dot
[1 + strspn(dot
+ 1, "0123546789")] == '\0')
3146 basename
= strndup(basename
, dot
- basename
);
3148 if (strcmp(basename
, "__func__") == 0 ||
3149 strcmp(basename
, "__PRETTY_FUNCTION__") == 0)
3150 caller
= (const char *)ss
->contents
.data
+ sym
->value
;
3152 caller
= find_caller(ss
, sym
);
3153 return strprintf("%s<%s>", basename
, caller
);
3156 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
)
3158 const char *filename
= sbfd
->abfd
->filename
;
3159 char *c
= strstr(filename
, ".KSPLICE");
3160 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
3163 if (bfd_is_und_section(sym
->section
) || (sym
->flags
& BSF_GLOBAL
) != 0) {
3164 label
= strdup(sym
->name
);
3165 } else if (bfd_is_const_section(sym
->section
)) {
3166 label
= strprintf("%s<%.*s>", sym
->name
, flen
, filename
);
3168 asymbol
*gsym
= canonical_symbol(sbfd
, sym
);
3171 label
= strprintf("%s+%lx<%.*s>",
3173 (unsigned long)sym
->value
,
3175 else if ((gsym
->flags
& BSF_GLOBAL
) != 0)
3176 label
= strdup(gsym
->name
);
3177 else if (static_local_symbol(sbfd
, gsym
))
3178 label
= strprintf("%s+%lx<%.*s>",
3179 static_local_symbol(sbfd
, gsym
),
3180 (unsigned long)sym
->value
,
3183 label
= strprintf("%s<%.*s>",
3184 gsym
->name
, flen
, filename
);
3190 static void keep_span(struct span
*span
)
3193 span
->ss
->keep
= true;
3196 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
)
3198 struct span
*span
= vec_grow(&ss
->spans
, 1);
3200 span
->contents_size
= size
;
3201 span
->start
= start
;
3205 span
->patch
= false;
3206 span
->bugpatch
= false;
3207 span
->datapatch
= false;
3208 span
->precallable
= strstarts(ss
->name
, ".ksplice_call_pre_apply") ||
3209 strstarts(ss
->name
, ".ksplice_call_check_apply") ||
3210 strstarts(ss
->name
, ".ksplice_call_fail_apply") ||
3211 strstarts(ss
->name
, ".ksplice_call_post_remove");
3213 vec_init(&span
->entry_points
);
3215 asymbol
**symp
= symbolp_scan(ss
, span
->start
);
3217 span
->symbol
= *symp
;
3218 span
->label
= label_lookup(ss
->parent
, span
->symbol
);
3220 span
->symbol
= NULL
;
3221 const char *label
= label_lookup(ss
->parent
, ss
->symbol
);
3222 if (span
->start
!= 0)
3223 span
->label
= strprintf("%s<span:%lx>", label
,
3224 (unsigned long)span
->start
);
3226 span
->label
= label
;
3228 span
->orig_label
= span
->label
;
3232 static void initialize_string_spans(struct supersect
*ss
)
3235 for (str
= ss
->contents
.data
;
3236 (void *)str
< ss
->contents
.data
+ ss
->contents
.size
;) {
3237 bfd_vma start
= (unsigned long)str
-
3238 (unsigned long)ss
->contents
.data
;
3239 bfd_vma size
= strlen(str
) + 1;
3240 bfd_vma contents_size
= size
;
3241 while ((start
+ size
) % (1 << ss
->alignment
) != 0 &&
3242 start
+ size
< ss
->contents
.size
) {
3243 /* Some string sections, like __ksymtab_strings, only
3244 align some strings with the declared alignment */
3245 if (str
[size
] != '\0')
3249 struct span
*span
= new_span(ss
, start
, size
);
3250 span
->contents_size
= contents_size
;
3255 static int compare_ulongs(const void *va
, const void *vb
)
3257 const unsigned long *a
= va
, *b
= vb
;
3261 static void initialize_table_spans(struct superbfd
*sbfd
,
3262 struct table_section
*s
)
3264 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
3265 if (isection
== NULL
)
3267 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
3268 if (ss
->alignment
< ffs(s
->entry_align
) - 1)
3269 ss
->alignment
= ffs(s
->entry_align
) - 1;
3271 asection
*other_sect
= NULL
;
3272 if (s
->other_sect
!= NULL
)
3273 other_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->other_sect
);
3274 struct supersect
*other_ss
= NULL
;
3275 if (other_sect
!= NULL
)
3276 other_ss
= fetch_supersect(sbfd
, other_sect
);
3278 asection
*crc_sect
= NULL
;
3279 if (s
->crc_sect
!= NULL
)
3280 crc_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->crc_sect
);
3281 struct supersect
*crc_ss
= NULL
;
3282 if (crc_sect
!= NULL
)
3283 crc_ss
= fetch_supersect(sbfd
, crc_sect
);
3285 struct ulong_vec offsets
;
3289 for (entry
= ss
->contents
.data
;
3290 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3291 entry
+= s
->entry_size
) {
3292 struct span
*span
= new_span(ss
, addr_offset(ss
, entry
),
3294 if (s
->entry_contents_size
!= 0)
3295 span
->contents_size
= s
->entry_contents_size
;
3296 if ((span
->symbol
== NULL
||
3297 (span
->symbol
->flags
& BSF_SECTION_SYM
) != 0) &&
3299 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
3301 struct span
*target_span
= reloc_target_span(ss
, reloc
);
3302 assert(target_span
);
3303 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3304 unsigned long val
= sym
->value
+
3305 reloc_target_offset(ss
, reloc
) -
3306 (target_span
->start
+ target_span
->shift
);
3307 char *label
= strprintf("%s<target:%s+%lx>", ss
->name
,
3308 target_span
->label
, val
);
3309 change_initial_label(span
, label
);
3312 if (other_sect
!= NULL
) {
3314 bfd_vma offset
= read_reloc(ss
, entry
+ s
->other_offset
,
3315 sizeof(void *), &sym
);
3316 if (sym
->section
== other_sect
) {
3317 assert(offset
>= 0 &&
3318 offset
< other_ss
->contents
.size
);
3319 *vec_grow(&offsets
, 1) = offset
;
3323 if (crc_sect
!= NULL
)
3324 new_span(crc_ss
, addr_offset(ss
, entry
) / s
->entry_size
3325 * s
->crc_size
, s
->crc_size
);
3327 if (ss
->type
== SS_TYPE_EXPORT
) {
3328 const char *symname
= read_string(ss
, entry
+
3330 char *label
= strprintf("%s:%s", ss
->name
, symname
);
3331 change_initial_label(span
, label
);
3335 if (other_sect
== NULL
)
3338 *vec_grow(&offsets
, 1) = 0;
3339 qsort(offsets
.data
, offsets
.size
, sizeof(*offsets
.data
),
3341 *vec_grow(&offsets
, 1) = other_ss
->contents
.size
;
3344 for (off
= offsets
.data
; off
< offsets
.data
+ offsets
.size
- 1; off
++) {
3345 if (*off
!= *(off
+ 1))
3346 new_span(other_ss
, *off
, *(off
+ 1) - *off
);
3350 static void initialize_table_section_spans(struct superbfd
*sbfd
)
3352 struct supersect
*tables_ss
=
3353 fetch_supersect(offsets_sbfd
,
3354 bfd_get_section_by_name(offsets_sbfd
->abfd
,
3355 ".ksplice_table_sections"));
3356 const struct table_section
*ts
;
3357 struct table_section s
;
3358 for (ts
= tables_ss
->contents
.data
;
3359 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
3362 s
.sect
= read_string(tables_ss
, &ts
->sect
);
3363 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
3364 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
3365 initialize_table_spans(sbfd
, &s
);
3369 static void initialize_ksplice_call_spans(struct supersect
*ss
)
3372 for (relocp
= ss
->relocs
.data
;
3373 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3374 arelent
*reloc
= *relocp
;
3375 new_span(ss
, reloc
->address
, bfd_get_reloc_size(reloc
->howto
));
3376 /* the span labels should already be unique */
3380 static void initialize_spans(struct superbfd
*sbfd
)
3383 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3384 if (is_table_section(sect
->name
, true, true) && mode("keep"))
3387 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3388 if (ss
->type
== SS_TYPE_STRING
)
3389 initialize_string_spans(ss
);
3390 else if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
3391 initialize_ksplice_call_spans(ss
);
3393 new_span(ss
, 0, ss
->contents
.size
);
3396 initialize_table_section_spans(sbfd
);
3399 /* Returns the span pointed to by the relocation at span->start + offset */
3400 static struct span
*span_offset_target_span(struct span
*span
, int offset
)
3402 void *entry
= span
->ss
->contents
.data
+ span
->start
;
3403 arelent
*reloc
= find_reloc(span
->ss
, entry
+ offset
);
3406 return reloc_target_span(span
->ss
, reloc
);
3409 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
)
3411 asymbol
*sym_ptr
= *reloc
->sym_ptr_ptr
;
3412 if (bfd_is_const_section(sym_ptr
->section
))
3415 bfd_vma addend
= sym_ptr
->value
;
3416 if ((sym_ptr
->flags
& BSF_SECTION_SYM
) != 0)
3417 addend
+= reloc_target_offset(ss
, reloc
);
3419 struct supersect
*sym_ss
=
3420 fetch_supersect(ss
->parent
, sym_ptr
->section
);
3421 struct span
*span
, *target_span
= sym_ss
->spans
.data
;
3422 for (span
= sym_ss
->spans
.data
;
3423 span
< sym_ss
->spans
.data
+ sym_ss
->spans
.size
; span
++) {
3424 if (addend
>= span
->start
&& addend
< span
->start
+ span
->size
)
3430 static bfd_vma
reloc_target_offset(struct supersect
*ss
, arelent
*reloc
)
3432 bfd_vma offset
= reloc_offset(ss
, reloc
);
3433 if (reloc
->howto
->pc_relative
) {
3434 if ((ss
->flags
& SEC_CODE
) != 0)
3435 return offset
+ bfd_get_reloc_size(reloc
->howto
);
3437 const struct table_section
*ts
= get_table_section(ss
->name
);
3438 if (ts
!= NULL
&& ts
->relative_addr
&&
3439 reloc
->address
% ts
->entry_size
== ts
->addr_offset
)
3440 return offset
- ts
->addr_offset
;
3441 if (ts
!= NULL
&& ts
->relative_other
&&
3442 reloc
->address
% ts
->entry_size
== ts
->other_offset
)
3443 return offset
- ts
->other_offset
;
3450 struct span
*find_span(struct supersect
*ss
, bfd_size_type address
)
3453 for (span
= ss
->spans
.data
; span
< ss
->spans
.data
+ ss
->spans
.size
;
3455 if (address
>= span
->start
&&
3456 address
< span
->start
+ span
->size
)
3459 /* Deal with empty BSS sections */
3460 if (ss
->contents
.size
== 0 && ss
->spans
.size
> 0)
3461 return ss
->spans
.data
;
3462 /* Deal with section end pointers */
3463 if (address
== ss
->contents
.size
&& ss
->spans
.size
== 1)
3464 return ss
->spans
.data
;
3468 void compute_span_shifts(struct superbfd
*sbfd
)
3472 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3473 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3476 bfd_size_type offset
= 0;
3477 for (span
= ss
->spans
.data
;
3478 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
3481 span
->shift
= offset
- span
->start
;
3482 offset
+= span
->size
;
3487 void remove_unkept_spans(struct superbfd
*sbfd
)
3491 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3492 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3493 delete_obsolete_relocs(ss
);
3494 struct arelentp_vec orig_relocs
;
3495 vec_move(&orig_relocs
, &ss
->relocs
);
3496 arelent
**relocp
, *reloc
;
3497 for (relocp
= orig_relocs
.data
;
3498 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
3500 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3501 span
= reloc_target_span(ss
, reloc
);
3502 if ((span
!= NULL
&& span
->keep
&& span
->shift
== 0) ||
3503 bfd_is_const_section(sym
->section
)) {
3504 *vec_grow(&ss
->relocs
, 1) = reloc
;
3507 struct supersect
*sym_ss
=
3508 fetch_supersect(sbfd
, sym
->section
);
3509 if (span
!= NULL
&& (sym
->flags
& BSF_SECTION_SYM
) == 0
3510 && find_span(sym_ss
, sym
->value
) != span
) {
3511 err(sbfd
, "Spans for symbol %s and relocation "
3512 "target do not match in sect %s\n",
3513 sym
->name
, sym_ss
->name
);
3516 if (span
!= NULL
&& span
->keep
) {
3517 arelent
*new_reloc
= malloc(sizeof(*new_reloc
));
3518 *new_reloc
= *reloc
;
3519 new_reloc
->addend
= reloc_offset(ss
, reloc
);
3520 new_reloc
->addend
+= span
->shift
;
3521 *vec_grow(&ss
->new_relocs
, 1) = new_reloc
;
3526 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3527 struct supersect
*ss
= fetch_supersect(sbfd
, sect
), orig_ss
;
3530 supersect_move(&orig_ss
, ss
);
3531 vec_init(&ss
->spans
);
3532 for (span
= orig_ss
.spans
.data
;
3533 span
< orig_ss
.spans
.data
+ orig_ss
.spans
.size
; span
++) {
3536 struct span
*new_span
= vec_grow(&ss
->spans
, 1);
3538 new_span
->start
= span
->start
+ span
->shift
;
3539 new_span
->shift
= 0;
3540 sect_copy(ss
, sect_do_grow(ss
, 1, span
->size
, 1),
3541 &orig_ss
, orig_ss
.contents
.data
+ span
->start
,
3547 static void init_objmanip_superbfd(struct superbfd
*sbfd
)
3549 init_label_map(sbfd
);
3550 initialize_supersect_types(sbfd
);
3551 initialize_spans(sbfd
);
3553 compute_entry_points(sbfd
);
3556 void mangle_section_name(struct superbfd
*sbfd
, const char *name
)
3558 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
3561 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3562 ss
->name
= strprintf(".ksplice_pre.%s", ss
->name
);
3565 static void write_bugline_patches(struct superbfd
*sbfd
)
3567 const struct table_section
*ts
= get_table_section("__bug_table");
3568 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, "__bug_table");
3571 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3575 for (entry
= ss
->contents
.data
;
3576 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3577 entry
+= ts
->entry_size
) {
3578 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
3579 assert(span
!= NULL
);
3580 if (!span
->bugpatch
)
3582 arelent
*reloc
= find_reloc(ss
, entry
+ ts
->addr_offset
);
3583 assert(reloc
!= NULL
);
3584 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3585 assert(!bfd_is_const_section(sym
->section
));
3586 struct supersect
*kpatch_ss
=
3587 make_section(sbfd
, ".ksplice_patches%s",
3588 sym
->section
->name
);
3590 bfd_vma offset
, start
= 0;
3591 for (offset
= 0; offset
<= span
->size
; offset
++) {
3592 if (offset
!= span
->size
&&
3593 !part_of_reloc(ss
, span
->start
+ offset
))
3595 if (start
== offset
) {
3599 /* an interval of non-relocations just passed */
3600 struct ksplice_patch
*kpatch
=
3601 sect_grow(kpatch_ss
, 1, struct ksplice_patch
);
3602 write_ksplice_patch_reloc
3603 (kpatch_ss
, sym
->section
->name
, &kpatch
->oldaddr
,
3604 sizeof(kpatch
->oldaddr
), span
->label
, start
);
3606 char *data
= write_patch_storage(kpatch_ss
, kpatch
,
3607 offset
- start
, NULL
);
3608 memcpy(data
, entry
+ start
, offset
- start
);
3609 kpatch
->type
= KSPLICE_PATCH_DATA
;
3615 void *write_patch_storage(struct supersect
*ss
, struct ksplice_patch
*kpatch
,
3616 size_t size
, struct supersect
**data_ssp
)
3618 struct supersect
*data_ss
= make_section(ss
->parent
,
3619 ".ksplice_patch_data");
3620 char *saved
= sect_do_grow(data_ss
, 1, size
, 1);
3621 write_reloc(ss
, &kpatch
->saved
, &data_ss
->symbol
,
3622 addr_offset(data_ss
, saved
));
3623 char *data
= sect_do_grow(data_ss
, 1, size
, 1);
3624 write_reloc(ss
, &kpatch
->contents
, &data_ss
->symbol
,
3625 addr_offset(data_ss
, data
));
3626 kpatch
->size
= size
;
3627 if (data_ssp
!= NULL
)
3628 *data_ssp
= data_ss
;