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
);
155 static void write_bugline_patches(struct superbfd
*sbfd
);
156 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
);
157 void filter_table_sections(struct superbfd
*isbfd
);
158 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
);
159 void keep_referenced_sections(struct superbfd
*sbfd
);
160 void mark_precallable_spans(struct superbfd
*sbfd
);
161 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
);
162 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
);
163 static void setup_new_section(bfd
*obfd
, struct supersect
*ss
);
164 static void write_section(bfd
*obfd
, asection
*osection
, void *arg
);
165 static void delete_obsolete_relocs(struct supersect
*ss
);
166 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
168 static void ss_mark_symbols_used_in_relocations(struct supersect
*ss
);
169 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
170 struct asymbolp_vec
*isyms
);
171 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
);
172 struct supersect
*__attribute((format(printf
, 2, 3)))
173 make_section(struct superbfd
*sbfd
, const char *fmt
, ...);
174 void __attribute__((format(printf
, 3, 4)))
175 write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...);
176 void write_ksplice_export(struct superbfd
*sbfd
, struct span
*span
, bool del
);
177 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
179 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
181 static void foreach_symbol_pair(struct superbfd
*oldsbfd
, struct superbfd
*newsbfd
,
182 void (*fn
)(struct span
*old_span
,
184 struct span
*new_span
,
186 static void check_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
187 struct span
*new_span
, asymbol
*newsym
);
188 static void match_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
189 struct span
*new_span
, asymbol
*newsym
);
190 static void match_symbol_spans(struct span
*old_span
, asymbol
*oldsym
,
191 struct span
*new_span
, asymbol
*newsym
);
192 static void match_table_spans(struct span
*old_span
, struct span
*new_span
);
194 static struct span
*get_crc_span(struct span
*span
,
195 const struct table_section
*ts
);
196 static void foreach_span_pair(struct superbfd
*oldsbfd
,
197 struct superbfd
*newsbfd
,
198 void (*fn
)(struct span
*old_span
,
199 struct span
*new_span
));
200 static void match_spans_by_label(struct span
*old_span
, struct span
*new_span
);
201 static void match_string_spans(struct span
*old_span
, struct span
*new_span
);
202 static void mark_new_spans(struct superbfd
*sbfd
);
203 static void handle_deleted_spans(struct superbfd
*oldsbfd
,
204 struct superbfd
*newsbfd
);
205 static void unmatch_addr_spans(struct span
*old_span
, struct span
*new_span
,
206 const struct table_section
*ts
);
207 static void compare_matched_spans(struct superbfd
*newsbfd
);
208 static void compare_spans(struct span
*old_span
, struct span
*new_span
);
209 static void update_nonzero_offsets(struct superbfd
*sbfd
);
210 static void handle_nonzero_offset_relocs(struct supersect
*ss
);
211 static void keep_span(struct span
*span
);
213 static void init_objmanip_superbfd(struct superbfd
*sbfd
);
214 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
);
215 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
217 static void print_label_changes(struct superbfd
*sbfd
);
218 static void init_label_map(struct superbfd
*sbfd
);
219 static void change_initial_label(struct span
*span
, const char *label
);
220 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
);
221 static void init_csyms(struct superbfd
*sbfd
);
222 static void init_callers(struct superbfd
*sbfd
);
223 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
);
224 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
);
225 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
);
226 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
);
229 #define debug_(sbfd, level, fmt, ...) \
231 if (verbose >= (level)) \
232 printf("%s: " fmt, (sbfd)->abfd->filename, \
235 #define debug0(sbfd, fmt, ...) debug_(sbfd, 0, fmt, ## __VA_ARGS__)
236 #define debug1(sbfd, fmt, ...) debug_(sbfd, 1, fmt, ## __VA_ARGS__)
237 #define err(sbfd, fmt, ...) \
239 fprintf(stderr, "%s: " fmt, (sbfd)->abfd->filename, \
243 struct str_vec delsects
;
244 struct asymbolp_vec extract_syms
;
247 struct ksplice_config
*config
;
249 const char *modestr
, *kid
, *finalize_target
= NULL
;
250 bool write_output
= true;
252 struct superbfd
*offsets_sbfd
= NULL
;
254 #define mode(str) strstarts(modestr, str)
256 DECLARE_VEC_TYPE(unsigned long, addr_vec
);
257 DEFINE_HASH_TYPE(struct addr_vec
, addr_vec_hash
,
258 addr_vec_hash_init
, addr_vec_hash_free
, addr_vec_hash_lookup
,
260 struct addr_vec_hash system_map
;
262 struct bool_hash system_map_written
;
263 struct ulong_hash ksplice_symbol_offset
;
264 struct ulong_hash ksplice_howto_offset
;
265 struct ulong_hash ksplice_string_offset
;
267 void load_system_map()
269 const char *config_dir
= getenv("KSPLICE_CONFIG_DIR");
271 FILE *fp
= fopen(strprintf("%s/System.map", config_dir
), "r");
273 addr_vec_hash_init(&system_map
);
277 while (fscanf(fp
, "%lx %c %as\n", &addr
, &type
, &sym
) == 3)
278 *vec_grow(addr_vec_hash_lookup(&system_map
, sym
, TRUE
),
283 void load_ksplice_symbol_offsets(struct superbfd
*sbfd
)
285 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
,
289 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
291 struct ksplice_symbol
*ksym
;
292 for (ksym
= ss
->contents
.data
;
293 (void *)ksym
< ss
->contents
.data
+ ss
->contents
.size
; ksym
++) {
294 const char *label
= read_string(ss
, &ksym
->label
);
295 unsigned long *ksymbol_offp
=
296 ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
297 *ksymbol_offp
= addr_offset(ss
, ksym
);
303 char *kmodsrc
= getenv("KSPLICE_KMODSRC");
304 assert(kmodsrc
!= NULL
);
305 bfd
*offsets_bfd
= bfd_openr(strprintf("%s/offsets.o", kmodsrc
), NULL
);
306 assert(offsets_bfd
!= NULL
);
308 assert(bfd_check_format_matches(offsets_bfd
, bfd_object
, &matching
));
309 offsets_sbfd
= fetch_superbfd(offsets_bfd
);
311 asection
*config_sect
= bfd_get_section_by_name(offsets_sbfd
->abfd
,
313 struct supersect
*config_ss
=
314 fetch_supersect(offsets_sbfd
, config_sect
);
316 config
= config_ss
->contents
.data
;
319 void load_options(struct superbfd
*sbfd
)
321 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
,
325 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
326 const struct ksplice_option
*opt
;
327 for (opt
= ss
->contents
.data
;
328 (void *)opt
< ss
->contents
.data
+ ss
->contents
.size
; opt
++) {
329 if (opt
->type
== KSPLICE_OPTION_ASSUME_RODATA
) {
330 arelent
*reloc
= find_reloc(ss
, &opt
->target
);
331 assert(reloc
!= NULL
);
332 struct span
*span
= reloc_target_span(ss
, reloc
);
333 assert(span
!= NULL
);
334 assert(span
->ss
->type
== SS_TYPE_DATA
);
335 assert(span
->start
== 0 &&
336 span
->size
== span
->ss
->contents
.size
);
337 span
->ss
->type
= SS_TYPE_RODATA
;
340 err(sbfd
, "Unrecognized Ksplice option %d\n",
347 bool matchable_data_section(struct supersect
*ss
)
349 if (ss
->type
== SS_TYPE_STRING
)
351 if (ss
->type
== SS_TYPE_RODATA
)
353 if (ss
->type
== SS_TYPE_DATA
&& ss
->relocs
.size
!= 0)
355 if (ss
->type
== SS_TYPE_EXPORT
)
357 if (ss
->type
== SS_TYPE_BUGTABLE
)
362 bool unchangeable_section(struct supersect
*ss
)
364 if (ss
->type
== SS_TYPE_DATA
)
366 if (ss
->type
== SS_TYPE_IGNORED
&& !strstarts(ss
->name
, ".debug") &&
367 strcmp(ss
->name
, "__ksymtab_strings") != 0)
372 int main(int argc
, char *argv
[])
374 if (getenv("KSPLICE_VERBOSE") != NULL
)
375 verbose
= atoi(getenv("KSPLICE_VERBOSE"));
378 bfd
*ibfd
= bfd_openr(argv
[1], NULL
);
382 if (bfd_check_format_matches(ibfd
, bfd_archive
, &matching
) &&
383 bfd_openr_next_archived_file(ibfd
, NULL
) == NULL
)
384 return 66; /* empty archive */
385 assert(bfd_check_format_matches(ibfd
, bfd_object
, &matching
));
387 const char *output_target
= bfd_get_target(ibfd
);
392 bool_hash_init(&system_map_written
);
393 ulong_hash_init(&ksplice_symbol_offset
);
394 ulong_hash_init(&ksplice_howto_offset
);
395 ulong_hash_init(&ksplice_string_offset
);
397 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
400 if (mode("finalize"))
401 finalize_target
= argv
[4];
402 init_objmanip_superbfd(isbfd
);
403 if (mode("keep-new-code")) {
405 do_keep_new_code(isbfd
, argv
[4]);
406 } else if (mode("keep-old-code")) {
407 do_keep_old_code(isbfd
);
408 } else if (mode("finalize")) {
410 } else if (mode("rmsyms")) {
415 bfd
*obfd
= bfd_openw(argv
[2], output_target
);
417 copy_object(ibfd
, obfd
);
418 assert(bfd_close(obfd
));
421 if (offsets_sbfd
!= NULL
)
422 assert(bfd_close(offsets_sbfd
->abfd
));
423 assert(bfd_close(ibfd
));
427 void do_keep_new_code(struct superbfd
*isbfd
, const char *pre
)
429 struct bfd
*prebfd
= bfd_openr(pre
, NULL
);
430 assert(prebfd
!= NULL
);
432 assert(bfd_check_format_matches(prebfd
, bfd_object
, &matching
));
434 struct superbfd
*presbfd
= fetch_superbfd(prebfd
);
435 init_objmanip_superbfd(presbfd
);
437 foreach_symbol_pair(presbfd
, isbfd
, match_global_symbols
);
438 debug1(isbfd
, "Matched global\n");
439 foreach_span_pair(presbfd
, isbfd
, match_string_spans
);
440 debug1(isbfd
, "Matched string spans\n");
441 foreach_symbol_pair(presbfd
, isbfd
, match_symbol_spans
);
442 debug1(isbfd
, "Matched by name\n");
443 foreach_span_pair(presbfd
, isbfd
, match_spans_by_label
);
444 debug1(isbfd
, "Matched by label\n");
445 foreach_span_pair(presbfd
, isbfd
, match_table_spans
);
446 debug1(isbfd
, "Matched table spans\n");
450 compare_matched_spans(isbfd
);
451 update_nonzero_offsets(isbfd
);
452 mark_new_spans(isbfd
);
456 foreach_symbol_pair(presbfd
, isbfd
, check_global_symbols
);
458 handle_deleted_spans(presbfd
, isbfd
);
459 handle_section_symbol_renames(presbfd
, isbfd
);
461 copy_patched_entry_points(presbfd
, isbfd
);
463 assert(bfd_close(prebfd
));
467 mark_precallable_spans(isbfd
);
471 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
472 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
475 for (span
= ss
->spans
.data
;
476 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
477 if (strstarts(ss
->name
, ".ksplice_options"))
479 else if (span
->new || span
->patch
|| span
->datapatch
)
483 if (span
->patch
&& span
->precallable
) {
484 err(isbfd
, "Patched span %s can be reached "
485 "by a precall function\n", span
->label
);
491 print_label_changes(isbfd
);
493 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
494 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
496 for (span
= ss
->spans
.data
;
497 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
498 if (span
->patch
|| span
->bugpatch
|| span
->datapatch
)
499 debug0(isbfd
, "Patching span %s\n",
504 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
505 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
507 for (span
= ss
->spans
.data
;
508 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
510 debug0(isbfd
, "New span %s\n", span
->label
);
514 write_output
= false;
515 const char **sectname
;
516 for (sectname
= delsects
.data
;
517 sectname
< delsects
.data
+ delsects
.size
; sectname
++) {
519 debug0(isbfd
, "Deleted section: %s\n", *sectname
);
522 filter_table_sections(isbfd
);
524 compute_span_shifts(isbfd
);
526 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
527 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
528 if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
531 for (span
= ss
->spans
.data
;
532 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
535 if (span
->patch
|| span
->new || span
->datapatch
)
536 write_ksplice_section(span
);
537 if (span
->patch
|| span
->datapatch
)
538 write_ksplice_patches(isbfd
, span
);
539 if (ss
->type
== SS_TYPE_EXPORT
&& span
->new)
540 write_ksplice_export(isbfd
, span
, false);
544 write_bugline_patches(isbfd
);
546 remove_unkept_spans(isbfd
);
549 void do_keep_old_code(struct superbfd
*isbfd
)
552 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
553 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
556 for (span
= ss
->spans
.data
;
557 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
559 if (ss
->type
== SS_TYPE_TEXT
&&
560 !strstarts(ss
->name
, ".fixup"))
562 if (ss
->type
== SS_TYPE_EXPORT
)
568 for (symp
= isbfd
->syms
.data
;
569 symp
< isbfd
->syms
.data
+ isbfd
->syms
.size
; symp
++) {
570 asymbol
*sym
= *symp
;
571 if (!bfd_is_const_section(sym
->section
) &&
572 (sym
->flags
& BSF_GLOBAL
) != 0) {
573 struct supersect
*sym_ss
=
574 fetch_supersect(isbfd
, sym
->section
);
575 if (sym
->value
== sym_ss
->contents
.size
)
577 struct span
*span
= find_span(sym_ss
, sym
->value
);
578 assert(span
!= NULL
);
579 if (sym_ss
->type
!= SS_TYPE_IGNORED
)
586 keep_referenced_sections(isbfd
);
589 filter_table_sections(isbfd
);
590 compute_span_shifts(isbfd
);
592 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
593 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
594 asymbol
*sym
= canonical_symbol(isbfd
, sect
->symbol
);
597 if ((sym
->flags
& BSF_WEAK
) != 0)
599 if (bfd_get_section_size(sect
) == 0)
603 if (ss
->type
!= SS_TYPE_TEXT
&& !matchable_data_section(ss
))
607 for (span
= ss
->spans
.data
;
608 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
610 write_ksplice_section(span
);
614 write_table_relocs(isbfd
, "__bug_table", KSPLICE_HOWTO_BUG
);
615 write_table_relocs(isbfd
, "__ex_table", KSPLICE_HOWTO_EXTABLE
);
617 remove_unkept_spans(isbfd
);
619 mangle_section_name(isbfd
, "__markers");
620 mangle_section_name(isbfd
, "__ex_table");
621 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
622 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
623 if (ss
->type
== SS_TYPE_EXPORT
)
624 mangle_section_name(isbfd
, ss
->name
);
628 void do_finalize(struct superbfd
*isbfd
)
630 load_ksplice_symbol_offsets(isbfd
);
632 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
633 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
634 if (ss
->type
== SS_TYPE_EXIT
) {
636 for (span
= ss
->spans
.data
;
637 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
642 write_date_relocs(isbfd
, "<{DATE...}>", KSPLICE_HOWTO_DATE
);
643 write_date_relocs(isbfd
, "<{TIME}>", KSPLICE_HOWTO_TIME
);
647 void do_rmsyms(struct superbfd
*isbfd
)
649 asection
*extract_sect
= bfd_get_section_by_name(isbfd
->abfd
,
651 if (extract_sect
!= NULL
) {
652 struct supersect
*extract_ss
= fetch_supersect(isbfd
,
655 for (relocp
= extract_ss
->relocs
.data
;
656 relocp
< extract_ss
->relocs
.data
+ extract_ss
->relocs
.size
;
658 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
659 if (bfd_is_und_section(sym
->section
)) {
660 debug1(isbfd
, "extracting symbol %s\n",
662 *vec_grow(&extract_syms
, 1) = sym
;
670 void match_spans(struct span
*old_span
, struct span
*new_span
)
672 struct superbfd
*sbfd
= new_span
->ss
->parent
;
673 if (old_span
->match
== new_span
&& new_span
->match
== old_span
)
675 if (old_span
->match
!= NULL
) {
676 err(sbfd
, "Matching conflict: old %s: %s != %s\n",
677 old_span
->label
, old_span
->match
->label
, new_span
->label
);
680 if (new_span
->match
!= NULL
) {
681 err(sbfd
, "Matching conflict: new %s: %s != %s\n",
682 new_span
->label
, new_span
->match
->label
, old_span
->label
);
685 old_span
->match
= new_span
;
686 new_span
->match
= old_span
;
687 debug1(sbfd
, "Matched old %s to new %s\n", old_span
->label
,
689 if (old_span
->ss
->type
!= new_span
->ss
->type
&&
690 old_span
->ss
->type
== new_span
->ss
->orig_type
)
691 old_span
->ss
->type
= new_span
->ss
->type
;
693 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
694 if (ts
== NULL
|| !ts
->has_addr
|| ts
->other_sect
== NULL
)
696 struct span
*old_sym_span
=
697 span_offset_target_span(old_span
, ts
->other_offset
);
698 struct span
*new_sym_span
=
699 span_offset_target_span(new_span
, ts
->other_offset
);
700 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
701 match_spans(old_sym_span
, new_sym_span
);
704 void unmatch_span(struct span
*old_span
)
706 struct span
*new_span
= old_span
->match
;
707 old_span
->match
= NULL
;
708 new_span
->match
= NULL
;
710 new_span
->bugpatch
= false;
712 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
) {
713 const struct table_section
*ts
=
714 get_table_section(old_span
->ss
->name
);
715 if (ts
!= NULL
&& ts
->has_addr
)
716 unmatch_addr_spans(old_span
, new_span
, ts
);
719 new_span
->patch
= false;
720 new_span
->bugpatch
= false;
721 new_span
->datapatch
= false;
726 static void match_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
727 struct span
*new_span
, asymbol
*newsym
)
729 if ((oldsym
->flags
& BSF_GLOBAL
) == 0 ||
730 (newsym
->flags
& BSF_GLOBAL
) == 0)
732 match_spans(old_span
, new_span
);
735 static void check_global_symbols(struct span
*old_span
, asymbol
*oldsym
,
736 struct span
*new_span
, asymbol
*newsym
)
738 if ((oldsym
->flags
& BSF_GLOBAL
) == 0 ||
739 (newsym
->flags
& BSF_GLOBAL
) == 0)
741 if (old_span
->ss
->type
== SS_TYPE_IGNORED
)
743 if (old_span
->match
!= new_span
|| new_span
->match
!= old_span
) {
744 err(new_span
->ss
->parent
, "Global symbol span mismatch: %s "
745 "%s/%s\n", oldsym
->name
, old_span
->label
, new_span
->label
);
750 static void foreach_symbol_pair(struct superbfd
*oldsbfd
, struct superbfd
*newsbfd
,
751 void (*fn
)(struct span
*old_span
,
753 struct span
*new_span
,
756 asymbol
**oldsymp
, **newsymp
;
757 for (oldsymp
= oldsbfd
->syms
.data
;
758 oldsymp
< oldsbfd
->syms
.data
+ oldsbfd
->syms
.size
; oldsymp
++) {
759 asymbol
*oldsym
= *oldsymp
;
760 if ((oldsym
->flags
& BSF_DEBUGGING
) != 0 ||
761 bfd_is_const_section(oldsym
->section
))
764 struct supersect
*old_ss
=
765 fetch_supersect(oldsbfd
, oldsym
->section
);
766 if (old_ss
->type
== SS_TYPE_SPECIAL
||
767 old_ss
->type
== SS_TYPE_EXPORT
)
770 struct span
*old_span
= find_span(old_ss
, oldsym
->value
);
771 if (old_span
== NULL
) {
772 err(oldsbfd
, "Could not find span for %s\n",
777 for (newsymp
= newsbfd
->syms
.data
;
778 newsymp
< newsbfd
->syms
.data
+ newsbfd
->syms
.size
;
780 asymbol
*newsym
= *newsymp
;
781 if ((newsym
->flags
& BSF_DEBUGGING
) != 0 ||
782 bfd_is_const_section(newsym
->section
))
784 if (strcmp(oldsym
->name
, newsym
->name
) != 0)
787 struct supersect
*new_ss
=
788 fetch_supersect(newsbfd
, newsym
->section
);
789 if (old_ss
->type
!= new_ss
->type
&&
790 old_ss
->type
!= new_ss
->orig_type
)
793 struct span
*new_span
=
794 find_span(new_ss
, newsym
->value
);
795 if (new_span
== NULL
) {
796 err(newsbfd
, "Could not find span for %s\n",
800 fn(old_span
, oldsym
, new_span
, newsym
);
805 static void match_symbol_spans(struct span
*old_span
, asymbol
*oldsym
,
806 struct span
*new_span
, asymbol
*newsym
)
808 if (old_span
->ss
->type
== SS_TYPE_SPECIAL
)
810 if (static_local_symbol(old_span
->ss
->parent
, oldsym
) ||
811 static_local_symbol(new_span
->ss
->parent
, newsym
))
813 if (old_span
->match
== NULL
&& new_span
->match
== NULL
)
814 match_spans(old_span
, new_span
);
817 static void match_spans_by_label(struct span
*old_span
, struct span
*new_span
)
819 if (old_span
->ss
->type
== SS_TYPE_STRING
||
820 (is_table_section(old_span
->ss
->name
, true, false) &&
821 !is_table_section(old_span
->ss
->name
, false, false)))
823 if (strcmp(old_span
->label
, new_span
->label
) == 0)
824 match_spans(old_span
, new_span
);
827 static void match_string_spans(struct span
*old_span
, struct span
*new_span
)
829 if (old_span
->ss
->type
!= SS_TYPE_STRING
||
830 strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
832 if (strcmp((char *)old_span
->ss
->contents
.data
+ old_span
->start
,
833 (char *)new_span
->ss
->contents
.data
+ new_span
->start
) == 0)
834 match_spans(old_span
, new_span
);
837 static void foreach_span_pair(struct superbfd
*oldsbfd
,
838 struct superbfd
*newsbfd
,
839 void (*fn
)(struct span
*old_span
,
840 struct span
*new_span
))
842 asection
*oldsect
, *newsect
;
843 struct supersect
*oldss
, *newss
;
844 struct span
*old_span
, *new_span
;
845 for (newsect
= newsbfd
->abfd
->sections
; newsect
!= NULL
;
846 newsect
= newsect
->next
) {
847 newss
= fetch_supersect(newsbfd
, newsect
);
848 for (oldsect
= oldsbfd
->abfd
->sections
; oldsect
!= NULL
;
849 oldsect
= oldsect
->next
) {
850 oldss
= fetch_supersect(oldsbfd
, oldsect
);
851 if (oldss
->type
!= newss
->type
)
853 for (new_span
= newss
->spans
.data
;
854 new_span
< newss
->spans
.data
+ newss
->spans
.size
;
856 for (old_span
= oldss
->spans
.data
;
857 old_span
< oldss
->spans
.data
+
858 oldss
->spans
.size
; old_span
++)
859 fn(old_span
, new_span
);
865 static void mark_new_spans(struct superbfd
*sbfd
)
868 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
869 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
870 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
873 for (span
= ss
->spans
.data
;
874 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
875 if (span
->match
== NULL
)
881 static void handle_deleted_spans(struct superbfd
*oldsbfd
,
882 struct superbfd
*newsbfd
)
885 for (sect
= oldsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
886 struct supersect
*ss
= fetch_supersect(oldsbfd
, sect
);
888 for (span
= ss
->spans
.data
;
889 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
890 if (span
->match
!= NULL
)
892 if (ss
->type
== SS_TYPE_EXPORT
) {
893 *vec_grow(&delsects
, 1) = span
->label
;
894 write_ksplice_export(newsbfd
, span
, true);
895 } else if (ss
->type
== SS_TYPE_TEXT
) {
896 *vec_grow(&delsects
, 1) = span
->label
;
897 if (span
->symbol
== NULL
)
899 write_ksplice_deleted_patch
900 (newsbfd
, span
->symbol
->name
, span
->label
,
907 static void handle_nonzero_offset_relocs(struct supersect
*ss
)
909 struct span
*address_span
, *target_span
;
911 for (relocp
= ss
->relocs
.data
;
912 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
913 arelent
*reloc
= *relocp
;
914 address_span
= find_span(ss
, reloc
->address
);
915 if (!address_span
->new && !address_span
->patch
)
918 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
919 if (bfd_is_const_section(sym
->section
))
921 bfd_vma offset
= reloc_target_offset(ss
, reloc
);
922 target_span
= reloc_target_span(ss
, reloc
);
923 if (sym
->value
+ offset
== target_span
->start
)
926 if (target_span
->ss
->type
!= SS_TYPE_TEXT
)
928 if (target_span
->patch
)
931 target_span
->patch
= true;
933 debug1(ss
->parent
, "Changing %s because a relocation from sect "
934 "%s has a nonzero offset %lx+%lx into it\n",
935 target_span
->label
, ss
->name
, (unsigned long)sym
->value
,
936 (unsigned long)offset
);
940 static void update_nonzero_offsets(struct superbfd
*sbfd
)
943 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
944 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
945 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_IGNORED
)
947 handle_nonzero_offset_relocs(ss
);
951 static void unmatch_addr_spans(struct span
*old_span
, struct span
*new_span
,
952 const struct table_section
*ts
)
954 struct span
*old_sym_span
=
955 span_offset_target_span(old_span
, ts
->addr_offset
);
956 struct span
*new_sym_span
=
957 span_offset_target_span(new_span
, ts
->addr_offset
);
958 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
959 if (old_sym_span
->match
== new_sym_span
&&
960 new_sym_span
->match
== old_sym_span
&&
961 !(new_sym_span
->patch
&& new_sym_span
->ss
->type
== SS_TYPE_TEXT
)) {
962 if (old_sym_span
->ss
->type
== SS_TYPE_TEXT
) {
963 debug1(new_span
->ss
->parent
, "Patching %s due "
964 "to relocations from special section %s\n",
965 new_sym_span
->label
, new_span
->label
);
966 new_sym_span
->patch
= true;
968 debug1(new_span
->ss
->parent
, "Unmatching %s and %s due "
969 "to relocations from special section %s/%s\n",
970 old_sym_span
->label
, new_sym_span
->label
,
971 old_span
->label
, new_span
->label
);
972 unmatch_span(old_sym_span
);
978 static void compare_spans(struct span
*old_span
, struct span
*new_span
)
980 struct superbfd
*newsbfd
= new_span
->ss
->parent
;
982 bool nonrelocs_match
= nonrelocs_equal(old_span
, new_span
);
983 bool relocs_match
= all_relocs_equal(old_span
, new_span
);
984 if (nonrelocs_match
&& relocs_match
) {
985 const struct table_section
*ts
=
986 get_table_section(old_span
->ss
->name
);
987 if (ts
!= NULL
&& ts
->crc_sect
!= NULL
) {
988 struct span
*old_crc_span
= get_crc_span(old_span
, ts
);
989 struct span
*new_crc_span
= get_crc_span(new_span
, ts
);
990 assert(old_crc_span
!= NULL
);
991 assert(new_crc_span
!= NULL
);
992 if (old_crc_span
->match
!= new_crc_span
||
993 new_crc_span
->match
!= old_crc_span
) {
994 debug1(newsbfd
, "Unmatching %s and %s due to "
995 "nonmatching CRCs\n", old_span
->label
,
997 unmatch_span(old_span
);
1004 if (new_span
->contents_size
!= old_span
->contents_size
)
1005 reason
= "differing sizes";
1006 else if (!nonrelocs_match
)
1007 reason
= "differing contents";
1009 reason
= "differing relocations";
1011 if (new_span
->ss
->type
== SS_TYPE_TEXT
) {
1012 if (new_span
->patch
)
1014 new_span
->patch
= true;
1015 debug1(newsbfd
, "Changing %s due to %s\n", new_span
->label
,
1017 } else if (old_span
->ss
->type
== SS_TYPE_BUGTABLE
&&
1018 new_span
->ss
->type
== SS_TYPE_BUGTABLE
&& relocs_match
) {
1019 if (new_span
->bugpatch
)
1021 debug1(newsbfd
, "Changing %s due to %s\n",
1022 new_span
->label
, reason
);
1023 new_span
->bugpatch
= true;
1024 } else if (new_span
->ss
->type
== SS_TYPE_RODATA
&&
1025 new_span
->contents_size
== old_span
->contents_size
) {
1026 if (new_span
->datapatch
)
1028 new_span
->datapatch
= true;
1029 debug1(newsbfd
, "Changing %s in-place due to %s\n",
1030 new_span
->label
, reason
);
1031 } else if (new_span
->ss
->type
== SS_TYPE_STRING
&&
1032 old_span
->ss
->type
== SS_TYPE_STRING
&& relocs_match
&&
1033 strcmp(new_span
->ss
->contents
.data
+ new_span
->start
,
1034 old_span
->ss
->contents
.data
+ old_span
->start
) == 0) {
1037 debug1(newsbfd
, "Unmatching %s and %s due to %s\n",
1038 old_span
->label
, new_span
->label
, reason
);
1039 unmatch_span(old_span
);
1042 if (unchangeable_section(new_span
->ss
))
1043 err(newsbfd
, "warning: ignoring change to nonpatchable "
1044 "section %s\n", new_span
->ss
->name
);
1047 static void compare_matched_spans(struct superbfd
*newsbfd
)
1050 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1051 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1053 for (span
= ss
->spans
.data
;
1054 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1055 if (span
->match
== NULL
)
1057 compare_spans(span
->match
, span
);
1062 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
1063 struct superbfd
*newsbfd
)
1067 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1068 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1069 for (span
= ss
->spans
.data
;
1070 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1071 if (span
->match
== NULL
)
1073 if (strcmp(span
->label
, span
->match
->label
) == 0)
1075 if (strcmp(span
->orig_label
, span
->label
) != 0 &&
1076 strcmp(span
->label
, span
->match
->label
) != 0)
1078 if (span
->symbol
!= NULL
)
1079 label_map_set(newsbfd
, span
->label
,
1080 span
->match
->label
);
1081 span
->label
= span
->match
->label
;
1086 static void copy_patched_entry_points(struct superbfd
*oldsbfd
,
1087 struct superbfd
*newsbfd
)
1091 for (sect
= newsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1092 struct supersect
*ss
= fetch_supersect(newsbfd
, sect
);
1093 for (span
= ss
->spans
.data
;
1094 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1097 assert(span
->match
!= NULL
);
1098 vec_init(&span
->pre_entry_points
);
1100 struct entry_point
*entry
;
1101 for (entry
= span
->match
->entry_points
.data
;
1102 entry
< span
->match
->entry_points
.data
+
1103 span
->match
->entry_points
.size
;
1105 struct entry_point
*e
=
1106 vec_grow(&span
->pre_entry_points
, 1);
1107 e
->name
= entry
->name
!= NULL
?
1108 strdup(entry
->name
) : NULL
;
1109 e
->label
= strdup(entry
->label
);
1110 e
->offset
= entry
->offset
;
1117 static int compare_entry_points(const void *va
, const void *vb
)
1119 const struct entry_point
*a
= va
, *b
= vb
;
1120 if (a
->offset
< b
->offset
)
1122 else if (a
->offset
> b
->offset
)
1128 static void compute_entry_points(struct superbfd
*sbfd
)
1131 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
1133 asymbol
*sym
= *symp
;
1134 if (bfd_is_const_section(sym
->section
))
1136 struct supersect
*old_ss
= fetch_supersect(sbfd
, sym
->section
);
1137 if ((sym
->flags
& BSF_GLOBAL
) == 0)
1139 struct span
*span
= find_span(old_ss
, sym
->value
);
1140 struct entry_point
*e
= vec_grow(&span
->entry_points
, 1);
1141 e
->label
= sym
->name
;
1142 e
->name
= sym
->name
;
1143 e
->offset
= sym
->value
- span
->start
;
1148 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1149 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1151 for (span
= ss
->spans
.data
;
1152 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1153 /* First make sure that 0 appears as an entry point */
1154 bool found_zero
= false;
1155 struct entry_point
*entry
;
1156 for (entry
= span
->entry_points
.data
;
1157 entry
< span
->entry_points
.data
+
1158 span
->entry_points
.size
;
1160 if (entry
->offset
== 0)
1164 struct entry_point
*e
=
1165 vec_grow(&span
->entry_points
, 1);
1166 e
->label
= span
->label
;
1169 e
->symbol
= span
->symbol
;
1172 qsort(span
->entry_points
.data
, span
->entry_points
.size
,
1173 sizeof(*span
->entry_points
.data
),
1174 compare_entry_points
);
1179 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
)
1182 for (relocp
= ss
->relocs
.data
;
1183 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
1184 arelent
*reloc
= *relocp
;
1185 if (addr
>= reloc
->address
&&
1186 addr
< reloc
->address
+ bfd_get_reloc_size(reloc
->howto
))
1192 static bool nonrelocs_equal(struct span
*old_span
, struct span
*new_span
)
1195 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1196 if (old_span
->contents_size
!= new_span
->contents_size
)
1198 const unsigned char *old
= old_ss
->contents
.data
+ old_span
->start
;
1199 const unsigned char *new = new_ss
->contents
.data
+ new_span
->start
;
1200 for (i
= 0; i
< old_span
->contents_size
; i
++) {
1201 if (old
[i
] != new[i
] &&
1202 !(part_of_reloc(old_ss
, i
+ old_span
->start
) &&
1203 part_of_reloc(new_ss
, i
+ new_span
->start
)))
1209 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
1210 arelent
*old_reloc
, arelent
*new_reloc
)
1212 struct superbfd
*oldsbfd
= old_src_ss
->parent
;
1213 struct superbfd
*newsbfd
= new_src_ss
->parent
;
1214 struct span
*old_addr_span
= find_span(old_src_ss
, old_reloc
->address
);
1215 struct span
*new_addr_span
= find_span(new_src_ss
, new_reloc
->address
);
1217 if (old_reloc
->address
- old_addr_span
->start
!=
1218 new_reloc
->address
- new_addr_span
->start
) {
1219 debug1(newsbfd
, "Section %s/%s has reloc address mismatch at "
1220 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1221 (unsigned long)old_reloc
->address
);
1225 if (old_reloc
->howto
!= new_reloc
->howto
) {
1226 debug1(newsbfd
, "Section %s/%s has howto type mismatch at "
1227 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
1228 (unsigned long)old_reloc
->address
);
1232 if (non_dst_mask(old_src_ss
, old_reloc
) !=
1233 non_dst_mask(new_src_ss
, new_reloc
)) {
1234 debug1(newsbfd
, "Section %s/%s has contents mismatch at %lx\n",
1235 old_src_ss
->name
, new_src_ss
->name
,
1236 (unsigned long)old_reloc
->address
);
1240 asymbol
*old_sym
= *old_reloc
->sym_ptr_ptr
;
1241 asymbol
*new_sym
= *new_reloc
->sym_ptr_ptr
;
1242 asection
*old_sect
= old_sym
->section
;
1243 asection
*new_sect
= new_sym
->section
;
1245 bfd_vma old_offset
= reloc_target_offset(old_src_ss
, old_reloc
);
1246 bfd_vma new_offset
= reloc_target_offset(new_src_ss
, new_reloc
);
1248 if (bfd_is_und_section(old_sect
) || bfd_is_und_section(new_sect
)) {
1249 if (!bfd_is_und_section(new_sect
) && old_offset
!= 0 &&
1250 fetch_supersect(newsbfd
, new_sect
)->type
== SS_TYPE_TEXT
)
1253 if (!bfd_is_und_section(new_sect
) && new_offset
!= 0 &&
1254 fetch_supersect(oldsbfd
, old_sect
)->type
== SS_TYPE_TEXT
)
1257 return strcmp(old_sym
->name
, new_sym
->name
) == 0 &&
1258 old_offset
== new_offset
;
1261 if (bfd_is_abs_section(old_sect
) && bfd_is_abs_section(new_sect
)) {
1262 if (old_sym
->value
+ old_offset
== new_sym
->value
+ new_offset
)
1264 debug1(newsbfd
, "Differing relocations from %s/%s to ABS "
1265 "section: %lx/%lx\n", old_addr_span
->label
,
1266 new_addr_span
->label
,
1267 (unsigned long)(old_sym
->value
+ old_offset
),
1268 (unsigned long)(new_sym
->value
+ new_offset
));
1272 if (bfd_is_const_section(old_sect
) || bfd_is_const_section(new_sect
))
1275 struct supersect
*old_ss
= fetch_supersect(oldsbfd
, old_sect
);
1276 struct supersect
*new_ss
= fetch_supersect(newsbfd
, new_sect
);
1277 struct span
*old_span
= reloc_target_span(old_src_ss
, old_reloc
);
1278 struct span
*new_span
= reloc_target_span(new_src_ss
, new_reloc
);
1280 if (old_span
->match
!= new_span
|| new_span
->match
!= old_span
) {
1281 debug1(newsbfd
, "Nonmatching relocs from %s to %s/%s\n",
1282 new_src_ss
->name
, old_span
->label
, new_span
->label
);
1286 if (old_sym
->value
+ old_offset
- old_span
->start
!=
1287 new_sym
->value
+ new_offset
- new_span
->start
) {
1288 debug1(newsbfd
, "Offsets to %s/%s differ between %s "
1289 "and %s: %lx+%lx/%lx+%lx\n", old_ss
->name
,
1290 new_ss
->name
, old_src_ss
->name
, new_src_ss
->name
,
1291 (unsigned long)old_sym
->value
, (unsigned long)old_offset
,
1292 (unsigned long)new_sym
->value
,
1293 (unsigned long)new_offset
);
1297 if ((old_sym
->value
+ old_offset
- old_span
->start
!= 0 ||
1298 new_sym
->value
+ new_offset
- new_span
->start
!= 0) &&
1300 debug1(newsbfd
, "Relocation from %s to nonzero offsets "
1301 "%lx+%lx/%lx+%lx in changed section %s\n",
1302 new_src_ss
->name
, (unsigned long)old_sym
->value
,
1303 (unsigned long)old_offset
, (unsigned long)new_sym
->value
,
1304 (unsigned long)new_offset
, new_sym
->section
->name
);
1310 bool all_relocs_equal(struct span
*old_span
, struct span
*new_span
)
1312 struct supersect
*old_ss
= old_span
->ss
, *new_ss
= new_span
->ss
;
1313 arelent
**old_relocp
, **new_relocp
;
1315 for (old_relocp
= old_ss
->relocs
.data
;
1316 old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
;
1318 if (find_span(old_ss
, (*old_relocp
)->address
) == old_span
)
1322 for (new_relocp
= new_ss
->relocs
.data
;
1323 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
;
1325 if (find_span(new_ss
, (*new_relocp
)->address
) == new_span
)
1329 for (; old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1330 find_span(old_ss
, (*old_relocp
)->address
) == old_span
&&
1331 new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1332 find_span(new_ss
, (*new_relocp
)->address
) == new_span
;
1333 old_relocp
++, new_relocp
++) {
1334 if (!relocs_equal(old_ss
, new_ss
, *old_relocp
, *new_relocp
))
1338 if ((old_relocp
< old_ss
->relocs
.data
+ old_ss
->relocs
.size
&&
1339 find_span(old_ss
, (*old_relocp
)->address
) == old_span
) ||
1340 (new_relocp
< new_ss
->relocs
.data
+ new_ss
->relocs
.size
&&
1341 find_span(new_ss
, (*new_relocp
)->address
) == new_span
)) {
1342 debug1(new_ss
->parent
, "Different reloc count between %s and "
1343 "%s\n", old_span
->label
, new_span
->label
);
1350 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
)
1352 int bits
= bfd_get_reloc_size(reloc
->howto
) * 8;
1353 void *address
= ss
->contents
.data
+ reloc
->address
;
1354 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1355 return x
& ~reloc
->howto
->dst_mask
;
1358 void rm_relocs(struct superbfd
*isbfd
)
1361 for (p
= isbfd
->abfd
->sections
; p
!= NULL
; p
= p
->next
) {
1362 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1363 bool remove_relocs
= ss
->keep
;
1365 if (mode("keep") && ss
->type
== SS_TYPE_SPECIAL
)
1366 remove_relocs
= false;
1368 if (ss
->type
== SS_TYPE_KSPLICE
||
1369 ss
->type
== SS_TYPE_KSPLICE_CALL
)
1370 remove_relocs
= false;
1371 if (mode("finalize") &&
1372 (strstarts(ss
->name
, ".ksplice_patches") ||
1373 strstarts(ss
->name
, ".ksplice_relocs")))
1374 remove_relocs
= true;
1381 void rm_some_relocs(struct supersect
*ss
)
1383 struct arelentp_vec orig_relocs
;
1384 vec_move(&orig_relocs
, &ss
->relocs
);
1387 for (relocp
= orig_relocs
.data
;
1388 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
1389 bool rm_reloc
= false;
1390 asymbol
*sym_ptr
= *(*relocp
)->sym_ptr_ptr
;
1392 if (mode("rmsyms") && bfd_is_und_section(sym_ptr
->section
)) {
1394 for (esymp
= extract_syms
.data
;
1395 esymp
< extract_syms
.data
+ extract_syms
.size
;
1397 if (sym_ptr
== *esymp
) {
1407 if (mode("keep-new-code")) {
1408 if (bfd_is_const_section(sym_ptr
->section
)) {
1411 bfd_vma offset
= reloc_target_offset(ss
, *relocp
);
1412 struct span
*target_span
=
1413 reloc_target_span(ss
, *relocp
);
1414 if (target_span
->new ||
1415 (target_span
->ss
->type
== SS_TYPE_TEXT
&&
1416 sym_ptr
->value
+ offset
!=
1417 target_span
->start
))
1421 const struct table_section
*ts
=
1422 get_table_section(ss
->name
);
1423 if (ts
!= NULL
&& ts
->has_addr
&&
1424 ((*relocp
)->address
% ts
->entry_size
==
1426 (*relocp
)->address
% ts
->entry_size
==
1431 if (mode("finalize") && bfd_is_und_section(sym_ptr
->section
))
1434 if (strcmp(sym_ptr
->name
, "mcount") == 0 &&
1435 bfd_is_und_section(sym_ptr
->section
))
1438 if (!find_span(ss
, (*relocp
)->address
)->keep
)
1442 write_ksplice_reloc(ss
, *relocp
);
1444 *vec_grow(&ss
->relocs
, 1) = *relocp
;
1448 struct supersect
*make_section(struct superbfd
*sbfd
, const char *fmt
, ...)
1452 char *name
= vstrprintf(fmt
, ap
);
1455 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
1457 return fetch_supersect(sbfd
, sect
);
1459 return new_supersect(sbfd
, name
);
1462 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1465 bfd_reloc_code_real_type code
;
1466 switch (bfd_arch_bits_per_address(ss
->parent
->abfd
)) {
1468 code
= BFD_RELOC_32
;
1471 code
= BFD_RELOC_64
;
1477 arelent
*reloc
= malloc(sizeof(*reloc
));
1478 reloc
->sym_ptr_ptr
= symp
;
1479 reloc
->address
= addr_offset(ss
, addr
);
1480 reloc
->howto
= bfd_reloc_type_lookup(ss
->parent
->abfd
, code
);
1481 reloc
->addend
= offset
;
1485 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1488 *vec_grow(&ss
->new_relocs
, 1) = create_reloc(ss
, addr
, symp
, offset
);
1491 void write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...)
1494 struct supersect
*str_ss
= make_section(ss
->parent
, ".ksplice_str");
1497 int len
= vasprintf(&str
, fmt
, ap
);
1501 unsigned long *str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
,
1503 if (str_offp
== NULL
) {
1504 char *buf
= sect_grow(str_ss
, len
+ 1, char);
1505 memcpy(buf
, str
, len
+ 1);
1506 str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
, TRUE
);
1507 *str_offp
= addr_offset(str_ss
, buf
);
1510 write_reloc(ss
, addr
, &str_ss
->symbol
, *str_offp
);
1513 void lookup_system_map(struct addr_vec
*addrs
, const char *name
, long offset
)
1515 struct addr_vec
*map_addrs
=
1516 addr_vec_hash_lookup(&system_map
, name
, FALSE
);
1517 if (map_addrs
== NULL
)
1520 unsigned long *addr
, *map_addr
;
1521 for (map_addr
= map_addrs
->data
;
1522 map_addr
< map_addrs
->data
+ map_addrs
->size
; map_addr
++) {
1523 for (addr
= addrs
->data
; addr
< addrs
->data
+ addrs
->size
;
1525 if (*addr
== *map_addr
+ offset
)
1528 if (addr
< addrs
->data
+ addrs
->size
)
1530 *vec_grow(addrs
, 1) = *map_addr
+ offset
;
1534 void compute_system_map_array(struct superbfd
*sbfd
, struct addr_vec
*addrs
,
1537 if (bfd_is_abs_section(sym
->section
)) {
1538 *vec_grow(addrs
, 1) = sym
->value
;
1539 } else if (bfd_is_und_section(sym
->section
)) {
1540 lookup_system_map(addrs
, sym
->name
, 0);
1541 } else if (!bfd_is_const_section(sym
->section
)) {
1543 for (gsymp
= sbfd
->syms
.data
;
1544 gsymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; gsymp
++) {
1545 asymbol
*gsym
= *gsymp
;
1546 if ((gsym
->flags
& BSF_DEBUGGING
) == 0 &&
1547 gsym
->section
== sym
->section
)
1548 lookup_system_map(addrs
, gsym
->name
,
1549 sym
->value
- gsym
->value
);
1554 void write_ksplice_system_map(struct superbfd
*sbfd
, asymbol
*sym
,
1557 bool *done
= bool_hash_lookup(&system_map_written
, label
, TRUE
);
1562 struct addr_vec addrs
;
1565 compute_system_map_array(sbfd
, &addrs
, sym
);
1566 if (addrs
.size
!= 0) {
1567 struct supersect
*smap_ss
=
1568 make_section(sbfd
, ".ksplice_system_map");
1569 struct ksplice_system_map
*smap
=
1570 sect_grow(smap_ss
, 1, struct ksplice_system_map
);
1571 write_string(smap_ss
, &smap
->label
, "%s", label
);
1573 struct supersect
*array_ss
= make_section(sbfd
,
1575 void *buf
= sect_grow(array_ss
, addrs
.size
,
1576 typeof(*addrs
.data
));
1577 memcpy(buf
, addrs
.data
, addrs
.size
* sizeof(*addrs
.data
));
1578 smap
->nr_candidates
= addrs
.size
;
1579 write_reloc(smap_ss
, &smap
->candidates
, &array_ss
->symbol
,
1580 addr_offset(array_ss
, buf
));
1585 void write_ksplice_symbol_backend(struct supersect
*ss
,
1586 struct ksplice_symbol
*const *addr
,
1587 asymbol
*sym
, const char *label
,
1590 struct supersect
*ksymbol_ss
= make_section(ss
->parent
,
1591 ".ksplice_symbols");
1592 struct ksplice_symbol
*ksymbol
;
1593 unsigned long *ksymbol_offp
;
1595 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, FALSE
);
1596 if (ksymbol_offp
!= NULL
) {
1597 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1600 ksymbol
= sect_grow(ksymbol_ss
, 1, struct ksplice_symbol
);
1601 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
1602 *ksymbol_offp
= addr_offset(ksymbol_ss
, ksymbol
);
1604 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1605 write_string(ksymbol_ss
, &ksymbol
->label
, "%s", label
);
1607 write_string(ksymbol_ss
, &ksymbol
->name
, "%s", name
);
1608 write_ksplice_system_map(ksymbol_ss
->parent
, sym
, label
);
1612 void write_ksplice_symbol(struct supersect
*ss
,
1613 struct ksplice_symbol
*const *addr
,
1614 asymbol
*sym
, struct span
*span
,
1615 const char *addstr_sect
)
1617 const char *label
, *name
;
1618 if (span
!= NULL
&& span
->start
!= 0)
1619 label
= span
->label
;
1621 label
= label_lookup(ss
->parent
, sym
);
1623 asymbol
*gsym
= canonical_symbol(ss
->parent
, sym
);
1624 if (strcmp(addstr_sect
, "") != 0)
1626 else if (bfd_is_und_section(sym
->section
))
1628 else if (bfd_is_const_section(sym
->section
))
1630 else if (span
!= NULL
&& span
->symbol
== NULL
)
1632 else if (gsym
== NULL
|| (gsym
->flags
& BSF_SECTION_SYM
) != 0)
1637 write_ksplice_symbol_backend(ss
, addr
, sym
,
1638 strprintf("%s%s", addstr_sect
, label
),
1642 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
)
1644 asymbol
*sym_ptr
= *orig_reloc
->sym_ptr_ptr
;
1645 bfd_vma reloc_addend
= reloc_offset(ss
, orig_reloc
);
1646 bfd_vma target_addend
= reloc_target_offset(ss
, orig_reloc
);
1647 unsigned long *repladdr
= ss
->contents
.data
+ orig_reloc
->address
;
1649 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_patches")) {
1653 if (mode("finalize") && strstarts(ss
->name
, ".ksplice_relocs")) {
1654 assert(strstarts(sym_ptr
->name
, KSPLICE_SYMBOL_STR
));
1656 fake_sym
.name
= sym_ptr
->name
+ strlen(KSPLICE_SYMBOL_STR
);
1657 fake_sym
.section
= bfd_und_section_ptr
;
1661 write_ksplice_symbol_backend
1662 (ss
, (struct ksplice_symbol
**)repladdr
, &fake_sym
,
1663 fake_sym
.name
, fake_sym
.name
);
1667 struct span
*span
= reloc_target_span(ss
, orig_reloc
);
1668 if (span
== ss
->spans
.data
&& span
->start
!= target_addend
)
1670 write_canary(ss
, orig_reloc
->address
,
1671 bfd_get_reloc_size(orig_reloc
->howto
),
1672 orig_reloc
->howto
->dst_mask
);
1674 struct supersect
*kreloc_ss
=
1675 make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1676 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1677 struct ksplice_reloc
);
1679 struct span
*address_span
= find_span(ss
, orig_reloc
->address
);
1680 write_reloc(kreloc_ss
, &kreloc
->blank_addr
,
1681 &ss
->symbol
, orig_reloc
->address
+ address_span
->shift
);
1682 if (bfd_is_und_section(sym_ptr
->section
) && mode("keep")) {
1683 char *name
= strprintf(KSPLICE_SYMBOL_STR
"%s", sym_ptr
->name
);
1684 asymbol
**symp
= make_undefined_symbolp(ss
->parent
, name
);
1685 write_reloc(kreloc_ss
, &kreloc
->symbol
, symp
, 0);
1687 write_ksplice_symbol(kreloc_ss
, &kreloc
->symbol
, sym_ptr
, span
,
1690 if (span
!= NULL
&& span
->start
!= 0) {
1691 reloc_addend
+= sym_ptr
->value
- span
->start
;
1692 target_addend
+= sym_ptr
->value
- span
->start
;
1694 kreloc
->insn_addend
= reloc_addend
- target_addend
;
1695 kreloc
->target_addend
= target_addend
;
1696 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, orig_reloc
->howto
,
1697 KSPLICE_HOWTO_RELOC
);
1700 static void write_ksplice_reloc_howto(struct supersect
*ss
, const
1701 struct ksplice_reloc_howto
*const *addr
,
1702 reloc_howto_type
*howto
,
1703 enum ksplice_reloc_howto_type type
)
1705 struct supersect
*khowto_ss
= make_section(ss
->parent
,
1706 ".ksplice_reloc_howtos");
1707 struct ksplice_reloc_howto
*khowto
;
1708 unsigned long *khowto_offp
;
1710 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1712 if (khowto_offp
!= NULL
) {
1713 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1716 khowto
= sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1717 khowto_offp
= ulong_hash_lookup(&ksplice_howto_offset
, howto
->name
,
1719 *khowto_offp
= addr_offset(khowto_ss
, khowto
);
1721 khowto
->type
= type
;
1722 khowto
->pcrel
= howto
->pc_relative
;
1723 khowto
->size
= bfd_get_reloc_size(howto
);
1724 khowto
->dst_mask
= howto
->dst_mask
;
1725 khowto
->rightshift
= howto
->rightshift
;
1726 khowto
->signed_addend
=
1727 (howto
->complain_on_overflow
== complain_overflow_signed
) ||
1728 (howto
->complain_on_overflow
== complain_overflow_bitfield
);
1729 write_reloc(ss
, addr
, &khowto_ss
->symbol
, *khowto_offp
);
1732 #define CANARY(x, canary) ((x & ~howto->dst_mask) | (canary & howto->dst_mask))
1734 void write_canary(struct supersect
*ss
, int offset
, bfd_size_type size
,
1737 int bits
= size
* 8;
1738 void *address
= ss
->contents
.data
+ offset
;
1739 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1740 x
= (x
& ~dst_mask
) | ((bfd_vma
)KSPLICE_CANARY
& dst_mask
);
1741 bfd_put(bits
, ss
->parent
->abfd
, x
, address
);
1744 static void write_date_relocs(struct superbfd
*sbfd
, const char *str
,
1745 enum ksplice_reloc_howto_type type
)
1748 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1749 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1750 if (ss
->type
!= SS_TYPE_STRING
&& ss
->type
!= SS_TYPE_RODATA
)
1754 for (span
= ss
->spans
.data
;
1755 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
1758 for (ptr
= ss
->contents
.data
+ span
->start
;
1759 ptr
+ strlen(str
) < ss
->contents
.data
+
1760 span
->start
+ span
->contents_size
; ptr
++) {
1761 if (strcmp((const char *)ptr
, str
) == 0)
1762 write_ksplice_date_reloc
1763 (ss
, addr_offset(ss
, ptr
), str
,
1770 static void write_ksplice_date_reloc(struct supersect
*ss
, unsigned long offset
,
1772 enum ksplice_reloc_howto_type type
)
1774 struct supersect
*kreloc_ss
;
1775 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1776 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1777 struct ksplice_reloc
);
1779 const char *filename
= ss
->parent
->abfd
->filename
;
1780 char *c
= strstr(filename
, ".KSPLICE");
1781 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
1783 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1784 strprintf("%s<%.*s>", str
, flen
, filename
),
1787 struct span
*span
= find_span(ss
, offset
);
1788 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1789 offset
+ span
->shift
);
1790 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
,
1794 static void write_table_relocs(struct superbfd
*sbfd
, const char *sectname
,
1795 enum ksplice_reloc_howto_type type
)
1797 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, sectname
);
1800 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
1802 const struct table_section
*s
= get_table_section(sectname
);
1807 for (entry
= ss
->contents
.data
;
1808 entry
< ss
->contents
.data
+ ss
->contents
.size
;
1809 entry
+= s
->entry_size
) {
1810 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
1811 assert(span
!= NULL
);
1815 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
1816 assert(reloc
!= NULL
);
1817 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
1818 assert(!bfd_is_const_section(sym
->section
));
1819 struct supersect
*sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1820 unsigned long addr
= sym
->value
+
1821 reloc_target_offset(ss
, reloc
);
1822 write_ksplice_table_reloc(sym_ss
, addr
, span
->label
, type
);
1826 static void write_ksplice_table_reloc(struct supersect
*ss
,
1827 unsigned long address
,
1829 enum ksplice_reloc_howto_type type
)
1831 struct supersect
*kreloc_ss
;
1832 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", ss
->name
);
1833 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1834 struct ksplice_reloc
);
1835 struct span
*span
= find_span(ss
, address
);
1836 assert(span
!= NULL
);
1838 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1840 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1841 address
+ span
->shift
);
1842 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
, type
, 0);
1845 static void write_ksplice_nonreloc_howto(struct supersect
*ss
,
1846 const struct ksplice_reloc_howto
1848 enum ksplice_reloc_howto_type type
,
1851 struct supersect
*khowto_ss
=
1852 make_section(ss
->parent
, ".ksplice_reloc_howtos");
1853 struct ksplice_reloc_howto
*khowto
=
1854 sect_grow(khowto_ss
, 1, struct ksplice_reloc_howto
);
1856 khowto
->type
= type
;
1857 khowto
->size
= size
;
1859 khowto
->dst_mask
= 0;
1860 khowto
->rightshift
= 0;
1861 khowto
->signed_addend
= 0;
1862 write_reloc(ss
, addr
, &khowto_ss
->symbol
,
1863 addr_offset(khowto_ss
, khowto
));
1866 static void write_ksplice_symbol_reloc(struct supersect
*ss
,
1867 const char *sectname
,
1868 unsigned long *addr
, asymbol
*sym
,
1869 const char *label
, const char *name
)
1871 struct supersect
*kreloc_ss
;
1872 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1873 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1874 struct ksplice_reloc
);
1876 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, sym
, label
,
1878 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1879 addr_offset(ss
, addr
));
1880 write_ksplice_nonreloc_howto(kreloc_ss
, &kreloc
->howto
,
1881 KSPLICE_HOWTO_SYMBOL
, 0);
1884 static void write_ksplice_section(struct span
*span
)
1886 struct supersect
*ss
= span
->ss
;
1887 const char *sectname
= span
->ss
->name
;
1888 const struct table_section
*ts
= get_table_section(ss
->name
);
1890 if (ts
!= NULL
&& ts
->has_addr
) {
1891 arelent
*reloc
= find_reloc(ss
, ss
->contents
.data
+ span
->start
1893 assert(reloc
!= NULL
);
1894 asymbol
*rsym
= *reloc
->sym_ptr_ptr
;
1895 assert(!bfd_is_const_section(rsym
->section
));
1896 sectname
= rsym
->section
->name
;
1899 struct supersect
*ksect_ss
=
1900 make_section(ss
->parent
, ".ksplice_sections%s", sectname
);
1901 struct ksplice_section
*ksect
= sect_grow(ksect_ss
, 1,
1902 struct ksplice_section
);
1903 asymbol
*sym
= span
->symbol
== NULL
? ss
->symbol
: span
->symbol
;
1905 write_ksplice_symbol(ksect_ss
, &ksect
->symbol
, sym
, span
,
1906 mode("keep-new-code") ? "(post)" : "");
1907 ksect
->size
= span
->size
;
1910 if (ss
->type
== SS_TYPE_RODATA
|| ss
->type
== SS_TYPE_STRING
||
1911 ss
->type
== SS_TYPE_EXPORT
|| ss
->type
== SS_TYPE_BUGTABLE
)
1912 ksect
->flags
|= KSPLICE_SECTION_RODATA
;
1913 if (ss
->type
== SS_TYPE_DATA
)
1914 ksect
->flags
|= KSPLICE_SECTION_DATA
;
1915 if (ss
->type
== SS_TYPE_TEXT
)
1916 ksect
->flags
|= KSPLICE_SECTION_TEXT
;
1917 assert(ksect
->flags
!= 0);
1919 if (ss
->type
== SS_TYPE_STRING
)
1920 ksect
->flags
|= KSPLICE_SECTION_STRING
;
1922 write_reloc(ksect_ss
, &ksect
->address
, &ss
->symbol
,
1923 span
->start
+ span
->shift
);
1925 if (mode("keep-old-code")) {
1926 /* Write ksplice_symbols for all the entry points */
1927 struct entry_point
*entry
;
1928 for (entry
= span
->entry_points
.data
;
1929 entry
< span
->entry_points
.data
+ span
->entry_points
.size
;
1931 write_ksplice_symbol_reloc
1932 (span
->ss
, sectname
, span
->ss
->contents
.data
+
1933 span
->start
+ span
->shift
+ entry
->offset
,
1934 entry
->symbol
, entry
->label
, entry
->name
);
1938 static void write_ksplice_patch_reloc(struct supersect
*ss
,
1939 const char *sectname
, unsigned long *addr
,
1940 bfd_size_type size
, const char *label
,
1943 struct supersect
*kreloc_ss
;
1944 kreloc_ss
= make_section(ss
->parent
, ".ksplice_relocs%s", sectname
);
1945 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1946 struct ksplice_reloc
);
1948 write_canary(ss
, addr_offset(ss
, addr
), size
, -1);
1949 write_ksplice_symbol_backend(kreloc_ss
, &kreloc
->symbol
, NULL
,
1951 write_reloc(kreloc_ss
, &kreloc
->blank_addr
, &ss
->symbol
,
1952 addr_offset(ss
, addr
));
1953 reloc_howto_type
*howto
=
1954 bfd_reloc_type_lookup(ss
->parent
->abfd
,
1955 PASTE(BFD_RELOC_
, LONG_BIT
));
1956 write_ksplice_reloc_howto(kreloc_ss
, &kreloc
->howto
, howto
,
1957 KSPLICE_HOWTO_RELOC
);
1958 kreloc
->target_addend
= addend
;
1959 kreloc
->insn_addend
= 0;
1962 /* Assumes symbol is global, aka only one symbol of that name */
1963 static asymbol
*name_to_symbol(struct superbfd
*sbfd
, const char *name
)
1969 for (symp
= sbfd
->syms
.data
;
1970 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
1971 asymbol
*sym
= *symp
;
1972 if (strcmp(name
, sym
->name
) == 0 &&
1973 ((sym
->flags
& BSF_GLOBAL
) != 0 ||
1974 bfd_is_und_section(sym
->section
)))
1980 void write_ksplice_patches(struct superbfd
*sbfd
, struct span
*span
)
1982 if (span
->datapatch
) {
1983 write_ksplice_patch(sbfd
, span
, span
->label
, 0);
1987 assert(span
->patch
);
1989 long prev_offset
= LONG_MIN
;
1990 asymbol
*prev_sym
= NULL
;
1991 const char *prev_label
= NULL
;
1992 struct entry_point
*entry
;
1993 for (entry
= span
->pre_entry_points
.data
;
1994 entry
< span
->pre_entry_points
.data
+ span
->pre_entry_points
.size
;
1996 asymbol
*sym
= name_to_symbol(sbfd
, entry
->name
);
1998 if (entry
->offset
!= prev_offset
) {
1999 debug1(sbfd
, "entry point: %s(%s) %lx\n", entry
->label
,
2000 entry
->name
, entry
->offset
);
2002 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> entry
->offset
) {
2004 "Overlapping trampolines: %s %lx/%lx\n",
2005 span
->label
, prev_offset
, entry
->offset
);
2009 long target_offset
= 0;
2011 target_offset
= sym
->value
- span
->start
;
2012 write_ksplice_patch(sbfd
, span
, entry
->label
,
2014 prev_offset
= entry
->offset
;
2018 if (prev_sym
== NULL
) {
2020 prev_label
= entry
->label
;
2021 } else if (sym
!= NULL
&&
2022 (prev_sym
->section
!= sym
->section
||
2023 prev_sym
->value
!= sym
->value
)) {
2024 err(sbfd
, "Splitting global symbols in the middle of a "
2025 "span: %s+%lx != %s+%lx!\n",
2026 prev_label
, (unsigned long)prev_sym
->value
,
2027 entry
->label
, (unsigned long)sym
->value
);
2032 if (prev_offset
+ MAX_TRAMPOLINE_SIZE
> span
->size
) {
2033 err(sbfd
, "Trampoline ends outside span: %s %lx/%lx\n",
2034 span
->label
, prev_offset
, (unsigned long)span
->size
);
2039 void write_ksplice_patch(struct superbfd
*sbfd
, struct span
*span
,
2040 const char *label
, long offset
)
2042 struct supersect
*kpatch_ss
=
2043 make_section(sbfd
, ".ksplice_patches%s", span
->ss
->name
);
2044 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2045 struct ksplice_patch
);
2047 write_ksplice_patch_reloc(kpatch_ss
, span
->ss
->name
, &kpatch
->oldaddr
,
2048 sizeof(kpatch
->oldaddr
), label
, 0);
2049 if (span
->ss
->type
== SS_TYPE_TEXT
) {
2050 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2051 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
,
2054 kpatch
->type
= KSPLICE_PATCH_DATA
;
2055 kpatch
->size
= span
->contents_size
;
2056 struct supersect
*data_ss
=
2057 make_section(sbfd
, ".ksplice_patch_data");
2058 write_reloc(kpatch_ss
, &kpatch
->contents
, &span
->ss
->symbol
,
2059 span
->start
+ span
->shift
);
2060 char *saved
= sect_do_grow(data_ss
, 1, span
->contents_size
, 1);
2061 write_reloc(kpatch_ss
, &kpatch
->saved
, &data_ss
->symbol
,
2062 addr_offset(data_ss
, saved
));
2064 write_reloc(kpatch_ss
, &kpatch
->repladdr
, &span
->ss
->symbol
,
2065 span
->start
+ span
->shift
+ offset
);
2068 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
)
2071 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
2073 asymbol
*sym
= *symp
;
2074 if (strcmp(name
, sym
->name
) == 0 &&
2075 bfd_is_und_section(sym
->section
))
2079 for (sympp
= sbfd
->new_syms
.data
;
2080 sympp
< sbfd
->new_syms
.data
+ sbfd
->new_syms
.size
; sympp
++) {
2081 asymbol
**symp
= *sympp
;
2082 asymbol
*sym
= *symp
;
2083 if (strcmp(name
, sym
->name
) == 0 &&
2084 bfd_is_und_section(sym
->section
))
2088 symp
= malloc(sizeof(*symp
));
2089 *symp
= bfd_make_empty_symbol(sbfd
->abfd
);
2090 asymbol
*sym
= *symp
;
2092 sym
->section
= bfd_und_section_ptr
;
2095 *vec_grow(&sbfd
->new_syms
, 1) = symp
;
2099 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
2100 const char *label
, const char *sectname
)
2102 struct supersect
*kpatch_ss
=
2103 make_section(sbfd
, ".ksplice_patches%s", sectname
);
2104 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2105 struct ksplice_patch
);
2107 write_ksplice_patch_reloc(kpatch_ss
, sectname
, &kpatch
->oldaddr
,
2108 sizeof(kpatch
->oldaddr
), label
, 0);
2109 kpatch
->type
= KSPLICE_PATCH_TEXT
;
2110 asymbol
**symp
= make_undefined_symbolp(sbfd
, strdup(name
));
2111 write_reloc(kpatch_ss
, &kpatch
->repladdr
, symp
, 0);
2112 write_patch_storage(kpatch_ss
, kpatch
, MAX_TRAMPOLINE_SIZE
, NULL
);
2115 void write_ksplice_export(struct superbfd
*sbfd
, struct span
*span
, bool del
)
2117 struct supersect
*kpatch_ss
= make_section(sbfd
, ".ksplice_patches");
2118 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
2119 struct ksplice_patch
);
2120 struct supersect
*data_ss
;
2122 const struct table_section
*ts
= get_table_section(span
->ss
->name
);
2125 span
->ss
->contents
.data
+ span
->start
+ ts
->other_offset
;
2126 const char *symname
= read_string(span
->ss
, addr
);
2128 char *oldname
, *newname
;
2130 oldname
= strprintf("%s:%s", span
->ss
->name
, symname
);
2131 newname
= strprintf("DISABLED_%s_%s", symname
, kid
);
2133 oldname
= strprintf("%s:DISABLED_%s_%s", span
->ss
->name
,
2135 newname
= strprintf("%s", symname
);
2136 write_string(span
->ss
, addr
, "DISABLED_%s_%s", symname
, kid
);
2139 write_ksplice_patch_reloc(kpatch_ss
, "", &kpatch
->oldaddr
,
2140 sizeof(kpatch
->oldaddr
), oldname
,
2142 kpatch
->type
= KSPLICE_PATCH_EXPORT
;
2143 const char **namep
= write_patch_storage(kpatch_ss
, kpatch
,
2144 sizeof(newname
), &data_ss
);
2145 write_string(data_ss
, namep
, "%s", newname
);
2148 void filter_table_sections(struct superbfd
*isbfd
)
2150 struct supersect
*tables_ss
=
2151 fetch_supersect(offsets_sbfd
,
2152 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2153 ".ksplice_table_sections"));
2154 const struct table_section
*ts
;
2155 for (ts
= tables_ss
->contents
.data
;
2156 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2158 struct table_section s
= *ts
;
2159 s
.sect
= read_string(tables_ss
, &ts
->sect
);
2160 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
2161 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2162 filter_table_section(isbfd
, &s
);
2166 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
)
2168 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
2169 if (isection
== NULL
)
2171 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2174 for (entry
= ss
->contents
.data
;
2175 entry
< ss
->contents
.data
+ ss
->contents
.size
;
2176 entry
+= s
->entry_size
) {
2177 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
2178 assert(span
!= NULL
);
2181 struct span
*sym_span
=
2182 span_offset_target_span(span
, s
->addr_offset
);
2183 assert(sym_span
!= NULL
);
2188 if (s
->other_sect
!= NULL
) {
2189 struct span
*sym_span
=
2190 span_offset_target_span(span
, s
->other_offset
);
2191 assert(sym_span
!= NULL
);
2193 keep_span(sym_span
);
2196 if (s
->crc_sect
!= NULL
) {
2197 struct span
*crc_span
= get_crc_span(span
, s
);
2198 assert(crc_span
!= NULL
);
2199 if (span
->keep
&& mode("keep-new-code"))
2200 keep_span(crc_span
);
2205 static void match_table_spans(struct span
*old_span
, struct span
*new_span
)
2207 const struct table_section
*ts
= get_table_section(old_span
->ss
->name
);
2209 if (strcmp(old_span
->ss
->name
, new_span
->ss
->name
) != 0)
2211 if (ts
== NULL
|| old_span
->ss
->type
!= SS_TYPE_SPECIAL
||
2212 new_span
->ss
->type
!= SS_TYPE_SPECIAL
)
2214 if (old_span
->match
!= NULL
|| new_span
->match
!= NULL
)
2218 void *old_entry
= old_span
->ss
->contents
.data
+ old_span
->start
;
2219 void *new_entry
= new_span
->ss
->contents
.data
+ new_span
->start
;
2220 arelent
*old_reloc
=
2221 find_reloc(old_span
->ss
, old_entry
+ ts
->addr_offset
);
2222 arelent
*new_reloc
=
2223 find_reloc(new_span
->ss
, new_entry
+ ts
->addr_offset
);
2224 assert(old_reloc
!= NULL
&& new_reloc
!= NULL
);
2225 struct span
*old_sym_span
=
2226 reloc_target_span(old_span
->ss
, old_reloc
);
2227 struct span
*new_sym_span
=
2228 reloc_target_span(new_span
->ss
, new_reloc
);
2229 assert(old_sym_span
!= NULL
&& new_sym_span
!= NULL
);
2230 if (old_sym_span
->match
== new_sym_span
&&
2231 new_sym_span
->match
== old_sym_span
&&
2232 old_reloc
->address
- old_sym_span
->start
==
2233 new_reloc
->address
- new_sym_span
->start
)
2234 match_spans(old_span
, new_span
);
2238 static struct span
*get_crc_span(struct span
*span
,
2239 const struct table_section
*ts
)
2241 void *entry
= span
->ss
->contents
.data
+ span
->start
;
2242 asection
*crc_sect
= bfd_get_section_by_name(span
->ss
->parent
->abfd
,
2244 if (crc_sect
== NULL
)
2246 struct supersect
*crc_ss
= fetch_supersect(span
->ss
->parent
, crc_sect
);
2249 struct span
*crc_span
= find_span(crc_ss
, addr_offset(span
->ss
, entry
) /
2250 ts
->entry_size
* ts
->crc_size
);
2254 void mark_precallable_spans(struct superbfd
*sbfd
)
2257 struct supersect
*ss
, *sym_ss
;
2258 struct span
*address_span
, *target_span
;
2259 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2260 ss
= fetch_supersect(sbfd
, sect
);
2262 if (ss
->type
== SS_TYPE_SPECIAL
)
2264 for (relocp
= ss
->relocs
.data
;
2265 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2266 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2267 address_span
= find_span(ss
, (*relocp
)->address
);
2268 if (!address_span
->precallable
)
2270 target_span
= reloc_target_span(ss
, *relocp
);
2271 if (target_span
== NULL
|| target_span
->keep
)
2273 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2274 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2276 target_span
->precallable
= true;
2282 void keep_referenced_sections(struct superbfd
*sbfd
)
2285 struct supersect
*ss
, *sym_ss
;
2286 struct span
*address_span
, *target_span
;
2287 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2288 ss
= fetch_supersect(sbfd
, sect
);
2290 if (ss
->type
== SS_TYPE_SPECIAL
)
2292 for (relocp
= ss
->relocs
.data
;
2293 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2294 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2295 address_span
= find_span(ss
, (*relocp
)->address
);
2296 if (!address_span
->keep
)
2298 target_span
= reloc_target_span(ss
, *relocp
);
2299 if (target_span
== NULL
|| target_span
->keep
)
2301 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2302 if (sym_ss
->type
== SS_TYPE_IGNORED
)
2304 keep_span(target_span
);
2310 void copy_symbols(struct asymbolp_vec
*osyms
, struct asymbolpp_vec
*isyms
)
2313 for (sympp
= isyms
->data
; sympp
< isyms
->data
+ isyms
->size
; sympp
++)
2314 *vec_grow(osyms
, 1) = **sympp
;
2317 /* Modified function from GNU Binutils objcopy.c */
2318 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
)
2320 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2322 bfd_vma start
= bfd_get_start_address(ibfd
);
2324 flagword flags
= bfd_get_file_flags(ibfd
);
2325 flags
&= bfd_applicable_file_flags(obfd
);
2327 assert(bfd_set_start_address(obfd
, start
)
2328 && bfd_set_file_flags(obfd
, flags
));
2330 enum bfd_architecture iarch
= bfd_get_arch(ibfd
);
2331 unsigned int imach
= bfd_get_mach(ibfd
);
2332 assert(bfd_set_arch_mach(obfd
, iarch
, imach
));
2333 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
2335 /* BFD mandates that all output sections be created and sizes set before
2336 any output is done. Thus, we traverse all sections multiple times. */
2337 bfd_map_over_sections(ibfd
, setup_section
, obfd
);
2339 struct supersect
*new_supersects
= fetch_superbfd(ibfd
)->new_supersects
;
2340 struct supersect
*ss
;
2341 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2342 setup_new_section(obfd
, ss
);
2344 /* Mark symbols used in output relocations so that they
2345 are kept, even if they are local labels or static symbols.
2347 Note we iterate over the input sections examining their
2348 relocations since the relocations for the output sections
2349 haven't been set yet. mark_symbols_used_in_relocations will
2350 ignore input sections which have no corresponding output
2353 bfd_map_over_sections(ibfd
, mark_symbols_used_in_relocations
, NULL
);
2354 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
2355 ss_mark_symbols_used_in_relocations(ss
);
2356 struct asymbolp_vec osyms
;
2358 filter_symbols(ibfd
, obfd
, &osyms
, &fetch_superbfd(ibfd
)->syms
);
2359 copy_symbols(&osyms
, &fetch_superbfd(ibfd
)->new_syms
);
2361 bfd_set_symtab(obfd
, osyms
.data
, osyms
.size
);
2363 /* This has to happen after the symbol table has been set. */
2364 bfd_map_over_sections(obfd
, write_section
, NULL
);
2366 /* Allow the BFD backend to copy any private data it understands
2367 from the input BFD to the output BFD. This is done last to
2368 permit the routine to look at the filtered symbol table, which is
2369 important for the ECOFF code at least. */
2370 assert(bfd_copy_private_bfd_data(ibfd
, obfd
));
2375 /* Modified function from GNU Binutils objcopy.c */
2376 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
)
2378 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
2379 struct supersect
*ss
= fetch_supersect(isbfd
, isection
);
2380 bfd
*obfd
= obfdarg
;
2386 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2387 assert(osection
!= NULL
);
2389 osection
->userdata
= ss
;
2390 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2391 ss
->symbol
= osection
->symbol
;
2392 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2394 vma
= bfd_section_vma(ibfd
, isection
);
2395 assert(bfd_set_section_vma(obfd
, osection
, vma
));
2397 osection
->lma
= isection
->lma
;
2398 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2399 osection
->entsize
= ss
->entsize
;
2400 osection
->output_section
= osection
;
2401 osection
->output_offset
= 0;
2402 isection
->output_section
= osection
;
2403 isection
->output_offset
= 0;
2407 void setup_new_section(bfd
*obfd
, struct supersect
*ss
)
2409 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
2410 assert(osection
!= NULL
);
2411 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
2413 osection
->userdata
= ss
;
2414 ss
->symbol
= osection
->symbol
;
2415 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
2416 assert(bfd_set_section_vma(obfd
, osection
, 0));
2419 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
2420 osection
->entsize
= ss
->entsize
;
2421 osection
->output_section
= osection
;
2422 osection
->output_offset
= 0;
2425 static int compare_reloc_addresses(const void *aptr
, const void *bptr
)
2427 const arelent
*const *a
= aptr
, *const *b
= bptr
;
2428 return (*a
)->address
- (*b
)->address
;
2431 static void delete_obsolete_relocs(struct supersect
*ss
)
2433 if (ss
->new_relocs
.size
== 0)
2436 qsort(ss
->relocs
.data
, ss
->relocs
.size
, sizeof(*ss
->relocs
.data
),
2437 compare_reloc_addresses
);
2438 qsort(ss
->new_relocs
.data
, ss
->new_relocs
.size
,
2439 sizeof(*ss
->new_relocs
.data
), compare_reloc_addresses
);
2441 struct arelentp_vec orig_relocs
;
2442 vec_move(&orig_relocs
, &ss
->relocs
);
2444 arelent
**relocp
, **new_relocp
= ss
->new_relocs
.data
;
2445 for (relocp
= orig_relocs
.data
;
2446 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
2447 while (new_relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
&&
2448 (*new_relocp
)->address
< (*relocp
)->address
)
2450 arelent
*reloc
= *relocp
, *new_reloc
= *new_relocp
;
2451 if (new_relocp
== ss
->new_relocs
.data
+ ss
->new_relocs
.size
||
2452 reloc
->address
!= new_reloc
->address
)
2453 *vec_grow(&ss
->relocs
, 1) = reloc
;
2457 void write_section(bfd
*obfd
, asection
*osection
, void *arg
)
2459 struct supersect
*ss
= osection
->userdata
;
2461 if ((ss
->flags
& SEC_GROUP
) != 0 || ss
->contents
.size
== 0)
2464 delete_obsolete_relocs(ss
);
2467 char *error_message
;
2468 for (relocp
= ss
->new_relocs
.data
;
2469 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2471 if (bfd_get_arch(obfd
) == bfd_arch_arm
)
2472 val
= osection
->use_rela_p
? 0 : (*relocp
)->addend
;
2475 bfd_put(bfd_get_reloc_size((*relocp
)->howto
) * 8, obfd
, val
,
2476 ss
->contents
.data
+ (*relocp
)->address
);
2477 if (bfd_install_relocation(obfd
, *relocp
, ss
->contents
.data
,
2478 0, osection
, &error_message
) !=
2480 err(ss
->parent
, "ksplice: error installing reloc: %s",
2484 if (mode("finalize")) {
2485 /* Check that all our sections will be allocated */
2486 asymbol
*sym
= *((*relocp
)->sym_ptr_ptr
);
2487 if (!bfd_is_const_section(sym
->section
)) {
2488 struct supersect
*sym_ss
=
2489 fetch_supersect(ss
->parent
, sym
->section
);
2490 assert((sym_ss
->flags
& SEC_ALLOC
) != 0);
2494 memcpy(vec_grow(&ss
->relocs
, ss
->new_relocs
.size
), ss
->new_relocs
.data
,
2495 ss
->new_relocs
.size
* sizeof(*ss
->new_relocs
.data
));
2497 bfd_set_reloc(obfd
, osection
,
2498 ss
->relocs
.size
== 0 ? NULL
: ss
->relocs
.data
,
2501 if (ss
->flags
& SEC_HAS_CONTENTS
)
2502 assert(bfd_set_section_contents
2503 (obfd
, osection
, ss
->contents
.data
, 0,
2504 ss
->contents
.size
));
2507 /* Modified function from GNU Binutils objcopy.c
2509 * Mark all the symbols which will be used in output relocations with
2510 * the BSF_KEEP flag so that those symbols will not be stripped.
2512 * Ignore relocations which will not appear in the output file.
2514 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
2517 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2518 if (isection
->output_section
== NULL
)
2521 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
2522 ss_mark_symbols_used_in_relocations(ss
);
2525 void ss_mark_symbols_used_in_relocations(struct supersect
*ss
)
2527 /* Examine each symbol used in a relocation. If it's not one of the
2528 special bfd section symbols, then mark it with BSF_KEEP. */
2530 for (relocp
= ss
->relocs
.data
;
2531 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2532 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2533 if (!(bfd_is_const_section(sym
->section
) &&
2534 sym
== sym
->section
->symbol
))
2535 sym
->flags
|= BSF_KEEP
;
2537 for (relocp
= ss
->new_relocs
.data
;
2538 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
2539 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2540 if (!(bfd_is_const_section(sym
->section
) &&
2541 sym
== sym
->section
->symbol
))
2542 sym
->flags
|= BSF_KEEP
;
2546 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
)
2548 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
2549 if (bfd_is_const_section(sym
->section
))
2551 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
2554 for (symp
= ss
->syms
.data
; symp
< ss
->syms
.data
+ ss
->syms
.size
; symp
++) {
2558 return symp
>= ss
->syms
.data
+ ss
->syms
.size
&&
2559 (sym
->flags
& BSF_SECTION_SYM
) == 0;
2562 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
2563 struct asymbolp_vec
*isyms
)
2566 struct superbfd
*sbfd
= fetch_superbfd(ibfd
);
2567 for (symp
= isyms
->data
; symp
< isyms
->data
+ isyms
->size
; symp
++) {
2568 asymbol
*sym
= *symp
;
2569 struct supersect
*sym_ss
= NULL
;
2570 struct span
*sym_span
= NULL
;
2571 if (!bfd_is_const_section(sym
->section
)) {
2572 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
2573 sym_span
= find_span(sym_ss
, sym
->value
);
2576 if (mode("keep") && (sym
->flags
& BSF_GLOBAL
) != 0 &&
2577 !(mode("keep-new-code") && sym_span
!= NULL
&&
2579 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2581 if (mode("finalize") && (sym
->flags
& BSF_GLOBAL
) != 0)
2582 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
2584 bool keep
= bfd_is_const_section(sym
->section
) ||
2585 (sym_ss
->keep
&& (sym
->flags
& BSF_SECTION_SYM
) != 0) ||
2586 (sym_span
!= NULL
&& sym_span
->keep
);
2587 if (bfd_is_und_section(sym
->section
) &&
2588 (sym
->flags
& BSF_KEEP
) == 0)
2590 if (bfd_is_abs_section(sym
->section
) &&
2591 (sym
->flags
& BSF_KEEP
) == 0 &&
2592 (sym
->flags
& BSF_FILE
) == 0)
2594 if (deleted_table_section_symbol(ibfd
, sym
))
2597 if (mode("keep-old-code") && sym_ss
!= NULL
&&
2598 sym_ss
->type
== SS_TYPE_EXPORT
)
2602 if (sym_ss
!= NULL
&& !sym_ss
->keep
) {
2603 err(sbfd
, "Kept symbol %s in unkept section "
2604 "%s\n", sym
->name
, sym
->section
->name
);
2607 *vec_grow(osyms
, 1) = sym
;
2612 static bool is_table_section(const char *name
, bool consider_other
,
2615 struct supersect
*tables_ss
=
2616 fetch_supersect(offsets_sbfd
,
2617 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2618 ".ksplice_table_sections"));
2619 const struct table_section
*ts
;
2620 for (ts
= tables_ss
->contents
.data
;
2621 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2623 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0)
2625 const char *osect_name
= read_string(tables_ss
,
2627 if (consider_other
&& osect_name
!= NULL
&&
2628 strcmp(name
, osect_name
) == 0)
2630 const char *crc_name
= read_string(tables_ss
, &ts
->crc_sect
);
2631 if (consider_crc
&& crc_name
!= NULL
&&
2632 strcmp(name
, crc_name
) == 0)
2638 const struct table_section
*get_table_section(const char *name
)
2640 struct supersect
*tables_ss
=
2641 fetch_supersect(offsets_sbfd
,
2642 bfd_get_section_by_name(offsets_sbfd
->abfd
,
2643 ".ksplice_table_sections"));
2644 const struct table_section
*ts
;
2645 for (ts
= tables_ss
->contents
.data
;
2646 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
2648 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0) {
2649 if (ts
->entry_contents_size
!= 0)
2650 assert(align(ts
->entry_contents_size
,
2653 struct table_section
*ns
= malloc(sizeof(*ns
));
2655 ns
->sect
= read_string(tables_ss
, &ts
->sect
);
2656 ns
->crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
2658 read_string(tables_ss
, &ts
->other_sect
);
2665 enum supersect_type
supersect_type(struct supersect
*ss
)
2667 if (mode("finalize") &&
2668 strcmp(finalize_target
, "vmlinux") == 0 &&
2669 (strstarts(ss
->name
, ".ksplice_relocs.exit") ||
2670 strstarts(ss
->name
, ".ksplice_sections.exit") ||
2671 strstarts(ss
->name
, ".ksplice_patches.exit")))
2672 return SS_TYPE_EXIT
;
2673 if (strstarts(ss
->name
, ".ksplice_call"))
2674 return SS_TYPE_KSPLICE_CALL
;
2675 if (strstarts(ss
->name
, ".ksplice_extract"))
2676 return SS_TYPE_KSPLICE_EXTRACT
;
2677 if (strstarts(ss
->name
, ".ksplice_options"))
2678 return SS_TYPE_SPECIAL
;
2679 if (strstarts(ss
->name
, ".ksplice"))
2680 return SS_TYPE_KSPLICE
;
2682 if (strstarts(ss
->name
, ".init"))
2683 return SS_TYPE_IGNORED
;
2684 if (strstarts(ss
->name
, ".security_initcall.init"))
2685 return SS_TYPE_IGNORED
;
2686 if (strstarts(ss
->name
, ".con_initcall.init"))
2687 return SS_TYPE_IGNORED
;
2688 if (strstarts(ss
->name
, ".x86cpuvendor.init"))
2689 return SS_TYPE_IGNORED
;
2690 if (strstarts(ss
->name
, ".early_param.init"))
2691 return SS_TYPE_IGNORED
;
2692 if (strstarts(ss
->name
, ".taglist.init"))
2693 return SS_TYPE_IGNORED
;
2694 if (strstarts(ss
->name
, ".arch.info.init"))
2695 return SS_TYPE_IGNORED
;
2696 if (strstarts(ss
->name
, ".proc.info.init"))
2697 return SS_TYPE_IGNORED
;
2698 /* .pci_fixup_* sections really should be treated as global rodata
2699 referenced only from quirks.c */
2700 if (strstarts(ss
->name
, ".pci_fixup_"))
2701 return SS_TYPE_IGNORED
;
2702 /* .builtin_fw sections are similar to .pci_fixup */
2703 if (strstarts(ss
->name
, ".builtin_fw"))
2704 return SS_TYPE_IGNORED
;
2705 /* same for .tracedata */
2706 if (strstarts(ss
->name
, ".tracedata"))
2707 return SS_TYPE_IGNORED
;
2708 if (strstarts(ss
->name
, ".debug"))
2709 return SS_TYPE_IGNORED
;
2710 /* .eh_frame should probably be discarded, not ignored */
2711 if (strstarts(ss
->name
, ".eh_frame"))
2712 return SS_TYPE_IGNORED
;
2713 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devinit"))
2714 return SS_TYPE_IGNORED
;
2715 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".meminit"))
2716 return SS_TYPE_IGNORED
;
2717 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuinit"))
2718 return SS_TYPE_IGNORED
;
2719 if (config
->ignore_devinit
&& strstarts(ss
->name
, ".devexit"))
2720 return SS_TYPE_IGNORED
;
2721 if (config
->ignore_meminit
&& strstarts(ss
->name
, ".memexit"))
2722 return SS_TYPE_IGNORED
;
2723 if (config
->ignore_cpuinit
&& strstarts(ss
->name
, ".cpuexit"))
2724 return SS_TYPE_IGNORED
;
2725 if (strstarts(ss
->name
, ".vgetcpu_mode") ||
2726 strstarts(ss
->name
, ".jiffies") ||
2727 strstarts(ss
->name
, ".wall_jiffies") ||
2728 strstarts(ss
->name
, ".vxtime") ||
2729 strstarts(ss
->name
, ".sys_tz") ||
2730 strstarts(ss
->name
, ".sysctl_vsyscall") ||
2731 strstarts(ss
->name
, ".xtime") ||
2732 strstarts(ss
->name
, ".xtime_lock") ||
2733 strstarts(ss
->name
, ".vsyscall"))
2734 return SS_TYPE_IGNORED
;
2735 if (strstarts(ss
->name
, ".vdso"))
2736 return SS_TYPE_IGNORED
;
2738 if (strstarts(ss
->name
, ".exit.text"))
2739 return SS_TYPE_TEXT
;
2740 if (strstarts(ss
->name
, ".exit.data"))
2741 return SS_TYPE_DATA
;
2743 if (strstarts(ss
->name
, ".text") ||
2744 strstarts(ss
->name
, ".kernel.text") ||
2745 strstarts(ss
->name
, ".devinit.text") ||
2746 strstarts(ss
->name
, ".meminit.text") ||
2747 strstarts(ss
->name
, ".cpuinit.text") ||
2748 strstarts(ss
->name
, ".devexit.text") ||
2749 strstarts(ss
->name
, ".memexit.text") ||
2750 strstarts(ss
->name
, ".cpuexit.text") ||
2751 strstarts(ss
->name
, ".ref.text") ||
2752 strstarts(ss
->name
, ".spinlock.text") ||
2753 strstarts(ss
->name
, ".kprobes.text") ||
2754 strstarts(ss
->name
, ".sched.text") ||
2755 strstarts(ss
->name
, ".entry.text") || /* OpenVZ */
2756 (mode("keep-old-code") && strstarts(ss
->name
, ".fixup")))
2757 return SS_TYPE_TEXT
;
2760 if (sscanf(ss
->name
, ".rodata.str%*u.%*u%n", &n
) >= 0 &&
2761 n
== strlen(ss
->name
))
2762 return ss
->entsize
== 1 ? SS_TYPE_STRING
: SS_TYPE_RODATA
;
2764 if (strstarts(ss
->name
, ".rodata") ||
2765 strstarts(ss
->name
, ".kernel.rodata") ||
2766 strstarts(ss
->name
, ".devinit.rodata") ||
2767 strstarts(ss
->name
, ".meminit.rodata") ||
2768 strstarts(ss
->name
, ".cpuinit.rodata") ||
2769 strstarts(ss
->name
, ".devexit.rodata") ||
2770 strstarts(ss
->name
, ".memexit.rodata") ||
2771 strstarts(ss
->name
, ".cpuexit.rodata") ||
2772 strstarts(ss
->name
, ".ref.rodata") ||
2773 strstarts(ss
->name
, "__markers_strings") ||
2774 (mode("keep-old-code") && strstarts(ss
->name
, "__ex_table")))
2775 return SS_TYPE_RODATA
;
2777 if (strstarts(ss
->name
, ".bss"))
2778 return SS_TYPE_DATA
;
2780 /* Ignore .data.percpu sections */
2781 if (strstarts(ss
->name
, ".data.percpu") ||
2782 strstarts(ss
->name
, ".kernel.data.percpu") ||
2783 strstarts(ss
->name
, ".data..percpu"))
2784 return SS_TYPE_IGNORED
;
2785 if (strstarts(ss
->name
, ".data") ||
2786 strstarts(ss
->name
, ".kernel.data") ||
2787 strstarts(ss
->name
, ".devinit.data") ||
2788 strstarts(ss
->name
, ".cpuinit.data") ||
2789 strstarts(ss
->name
, ".meminit.data") ||
2790 strstarts(ss
->name
, ".devexit.data") ||
2791 strstarts(ss
->name
, ".memexit.data") ||
2792 strstarts(ss
->name
, ".cpuexit.data") ||
2793 strstarts(ss
->name
, ".ref.data") ||
2794 strstarts(ss
->name
, "__markers"))
2795 return SS_TYPE_DATA
;
2797 /* We replace all the ksymtab strings, so delete them */
2798 if (strcmp(ss
->name
, "__ksymtab_strings") == 0)
2799 return SS_TYPE_STRING
;
2800 if (strstarts(ss
->name
, "__ksymtab"))
2801 return SS_TYPE_EXPORT
;
2803 if (strstarts(ss
->name
, "__bug_table"))
2804 return SS_TYPE_BUGTABLE
;
2806 if (is_table_section(ss
->name
, true, true))
2807 return SS_TYPE_SPECIAL
;
2809 if (strstarts(ss
->name
, ".ARM."))
2810 return SS_TYPE_SPECIAL
;
2812 if (strstarts(ss
->name
, ".note"))
2813 return SS_TYPE_IGNORED
;
2814 if (strstarts(ss
->name
, ".comment"))
2815 return SS_TYPE_IGNORED
;
2816 if (strstarts(ss
->name
, "__param"))
2817 return SS_TYPE_IGNORED
;
2818 if (strstarts(ss
->name
, "__obsparm"))
2819 return SS_TYPE_IGNORED
;
2820 if (strstarts(ss
->name
, ".exitcall.exit"))
2821 return SS_TYPE_IGNORED
;
2822 if (strstarts(ss
->name
, ".modinfo"))
2823 return SS_TYPE_IGNORED
;
2825 return SS_TYPE_UNKNOWN
;
2828 void initialize_supersect_types(struct superbfd
*sbfd
)
2831 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2832 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2833 ss
->type
= supersect_type(ss
);
2834 ss
->orig_type
= ss
->type
;
2835 if (ss
->type
== SS_TYPE_UNKNOWN
) {
2836 err(sbfd
, "Unknown section type: %s\n", ss
->name
);
2842 static void init_label_map(struct superbfd
*sbfd
)
2844 struct label_map
*map
;
2846 vec_init(&sbfd
->maps
);
2850 struct symbol_hash csyms
;
2851 symbol_hash_init(&csyms
);
2854 for (symp
= sbfd
->syms
.data
;
2855 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2856 asymbol
*csym
= canonical_symbol(sbfd
, *symp
);
2859 char *key
= strprintf("%p", csym
);
2860 asymbol
**csymp
= symbol_hash_lookup(&csyms
, key
, TRUE
);
2866 map
= vec_grow(&sbfd
->maps
, 1);
2869 map
->label
= symbol_label(sbfd
, csym
);
2872 struct label_mapp_hash label_maps
;
2873 label_mapp_hash_init(&label_maps
);
2874 for (map
= sbfd
->maps
.data
;
2875 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2876 struct label_map
**mapp
=
2877 label_mapp_hash_lookup(&label_maps
, map
->label
, TRUE
);
2878 if (*mapp
== NULL
) {
2883 struct label_map
*first_map
= *mapp
;
2884 if (first_map
->count
== 0)
2885 first_map
->label
= strprintf("%s~%d", map
->label
, 0);
2886 map
->label
= strprintf("%s~%d", map
->label
, ++first_map
->count
);
2889 label_mapp_hash_init(&sbfd
->maps_hash
);
2890 for (map
= sbfd
->maps
.data
;
2891 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2892 char *key
= strprintf("%p", map
->csym
);
2893 struct label_map
**mapp
=
2894 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, TRUE
);
2897 map
->orig_label
= map
->label
;
2901 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
)
2903 asymbol
*csym
= canonical_symbol(sbfd
, sym
);
2904 char *key
= strprintf("%p", csym
);
2905 struct label_map
**mapp
=
2906 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2910 return (*mapp
)->label
;
2913 static void print_label_changes(struct superbfd
*sbfd
)
2917 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2918 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2919 for (span
= ss
->spans
.data
;
2920 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
2921 if (strcmp(span
->label
, span
->orig_label
) != 0)
2922 debug1(sbfd
, "Label change: %s -> %s\n",
2923 span
->label
, span
->orig_label
);
2928 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
2931 struct label_map
*map
;
2932 for (map
= sbfd
->maps
.data
;
2933 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2934 if (strcmp(map
->orig_label
, oldlabel
) == 0) {
2935 if (strcmp(map
->orig_label
, map
->label
) != 0 &&
2936 strcmp(map
->label
, label
) != 0)
2945 static void change_initial_label(struct span
*span
, const char *label
)
2947 struct superbfd
*sbfd
= span
->ss
->parent
;
2948 span
->label
= label
;
2949 span
->orig_label
= label
;
2951 asymbol
*csym
= canonical_symbol(sbfd
, span
->symbol
);
2952 char *key
= strprintf("%p", csym
);
2953 struct label_map
**mapp
=
2954 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2957 (*mapp
)->label
= span
->label
;
2958 (*mapp
)->orig_label
= span
->orig_label
;
2959 span
->symbol
= NULL
;
2963 static void init_callers(struct superbfd
*sbfd
)
2965 string_hash_init(&sbfd
->callers
);
2967 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2968 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2970 for (relocp
= ss
->relocs
.data
;
2971 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2972 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2974 sym
->value
+ reloc_target_offset(ss
, *relocp
);
2975 char *key
= strprintf("%s+%lx", sym
->section
->name
,
2977 const char **ret
= string_hash_lookup(&sbfd
->callers
,
2980 asymbol
*csym
= canonical_symbol(sbfd
, sect
->symbol
);
2982 *ret
= "*multiple_callers*";
2983 else if (static_local_symbol(sbfd
, csym
))
2984 *ret
= static_local_symbol(sbfd
, csym
);
2991 static const char *find_caller(struct supersect
*ss
, asymbol
*sym
)
2993 char *key
= strprintf("%s+%lx", sym
->section
->name
,
2994 (unsigned long)sym
->value
);
2995 const char **ret
= string_hash_lookup(&ss
->parent
->callers
, key
, FALSE
);
2999 return "*no_caller*";
3003 static void init_csyms(struct superbfd
*sbfd
)
3005 asymbolpp_hash_init(&sbfd
->csyms
);
3008 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
3010 asymbol
*sym
= *symp
;
3011 if ((sym
->flags
& BSF_DEBUGGING
) != 0)
3013 char *key
= strprintf("%s+%lx", sym
->section
->name
,
3014 (unsigned long)sym
->value
);
3015 asymbol
***csympp
= asymbolpp_hash_lookup(&sbfd
->csyms
, key
,
3018 if (*csympp
== NULL
) {
3022 asymbol
*csym
= **csympp
;
3023 if ((csym
->flags
& BSF_GLOBAL
) != 0)
3025 if ((sym
->flags
& BSF_GLOBAL
) != 0)
3030 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
)
3032 char *key
= strprintf("%s+%lx", ss
->name
, (unsigned long)value
);
3034 asymbolpp_hash_lookup(&ss
->parent
->csyms
, key
, FALSE
);
3039 /* For section symbols of sections containing no symbols, return the
3040 section symbol that relocations are generated against */
3046 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
)
3048 if (bfd_is_const_section(sym
->section
)) {
3050 for (csymp
= sbfd
->syms
.data
;
3051 csymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; csymp
++) {
3057 return symbolp_scan(fetch_supersect(sbfd
, sym
->section
), sym
->value
);
3060 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3062 if (bfd_is_const_section(sym
->section
))
3064 asymbol
**symp
= canonical_symbolp(sbfd
, sym
);
3065 return symp
!= NULL
? *symp
: NULL
;
3068 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
3070 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
3071 if ((sym
->flags
& BSF_LOCAL
) == 0 || (sym
->flags
& BSF_OBJECT
) == 0)
3073 char *dot
= strrchr(sym
->name
, '.');
3074 if (dot
== NULL
|| dot
[1 + strspn(dot
+ 1, "0123546789")] != '\0')
3076 char *basename
= strndup(sym
->name
, dot
- sym
->name
);
3078 /* Handle C.123.12345 symbols */
3079 dot
= strrchr(basename
, '.');
3080 if (dot
!= NULL
&& dot
[1 + strspn(dot
+ 1, "0123546789")] == '\0')
3081 basename
= strndup(basename
, dot
- basename
);
3083 if (strcmp(basename
, "__func__") == 0 ||
3084 strcmp(basename
, "__PRETTY_FUNCTION__") == 0)
3085 caller
= (const char *)ss
->contents
.data
+ sym
->value
;
3087 caller
= find_caller(ss
, sym
);
3088 return strprintf("%s<%s>", basename
, caller
);
3091 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
)
3093 const char *filename
= sbfd
->abfd
->filename
;
3094 char *c
= strstr(filename
, ".KSPLICE");
3095 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
3098 if (bfd_is_und_section(sym
->section
) || (sym
->flags
& BSF_GLOBAL
) != 0) {
3099 label
= strdup(sym
->name
);
3100 } else if (bfd_is_const_section(sym
->section
)) {
3101 label
= strprintf("%s<%.*s>", sym
->name
, flen
, filename
);
3103 asymbol
*gsym
= canonical_symbol(sbfd
, sym
);
3106 label
= strprintf("%s+%lx<%.*s>",
3108 (unsigned long)sym
->value
,
3110 else if ((gsym
->flags
& BSF_GLOBAL
) != 0)
3111 label
= strdup(gsym
->name
);
3112 else if (static_local_symbol(sbfd
, gsym
))
3113 label
= strprintf("%s+%lx<%.*s>",
3114 static_local_symbol(sbfd
, gsym
),
3115 (unsigned long)sym
->value
,
3118 label
= strprintf("%s<%.*s>",
3119 gsym
->name
, flen
, filename
);
3125 static void keep_span(struct span
*span
)
3128 span
->ss
->keep
= true;
3131 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
)
3133 struct span
*span
= vec_grow(&ss
->spans
, 1);
3135 span
->contents_size
= size
;
3136 span
->start
= start
;
3140 span
->patch
= false;
3141 span
->bugpatch
= false;
3142 span
->datapatch
= false;
3143 span
->precallable
= strstarts(ss
->name
, ".ksplice_call_pre_apply") ||
3144 strstarts(ss
->name
, ".ksplice_call_check_apply") ||
3145 strstarts(ss
->name
, ".ksplice_call_fail_apply") ||
3146 strstarts(ss
->name
, ".ksplice_call_post_remove");
3148 vec_init(&span
->entry_points
);
3150 asymbol
**symp
= symbolp_scan(ss
, span
->start
);
3152 span
->symbol
= *symp
;
3153 span
->label
= label_lookup(ss
->parent
, span
->symbol
);
3155 span
->symbol
= NULL
;
3156 const char *label
= label_lookup(ss
->parent
, ss
->symbol
);
3157 if (span
->start
!= 0)
3158 span
->label
= strprintf("%s<span:%lx>", label
,
3159 (unsigned long)span
->start
);
3161 span
->label
= label
;
3163 span
->orig_label
= span
->label
;
3167 static void initialize_string_spans(struct supersect
*ss
)
3170 for (str
= ss
->contents
.data
;
3171 (void *)str
< ss
->contents
.data
+ ss
->contents
.size
;) {
3172 bfd_vma start
= (unsigned long)str
-
3173 (unsigned long)ss
->contents
.data
;
3174 bfd_vma size
= strlen(str
) + 1;
3175 bfd_vma contents_size
= size
;
3176 while ((start
+ size
) % (1 << ss
->alignment
) != 0 &&
3177 start
+ size
< ss
->contents
.size
) {
3178 /* Some string sections, like __ksymtab_strings, only
3179 align some strings with the declared alignment */
3180 if (str
[size
] != '\0')
3184 struct span
*span
= new_span(ss
, start
, size
);
3185 span
->contents_size
= contents_size
;
3190 static int compare_ulongs(const void *va
, const void *vb
)
3192 const unsigned long *a
= va
, *b
= vb
;
3196 static void initialize_table_spans(struct superbfd
*sbfd
,
3197 struct table_section
*s
)
3199 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
3200 if (isection
== NULL
)
3202 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
3203 if (ss
->alignment
< ffs(s
->entry_align
) - 1)
3204 ss
->alignment
= ffs(s
->entry_align
) - 1;
3206 asection
*other_sect
= NULL
;
3207 if (s
->other_sect
!= NULL
)
3208 other_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->other_sect
);
3209 struct supersect
*other_ss
= NULL
;
3210 if (other_sect
!= NULL
)
3211 other_ss
= fetch_supersect(sbfd
, other_sect
);
3213 asection
*crc_sect
= NULL
;
3214 if (s
->crc_sect
!= NULL
)
3215 crc_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->crc_sect
);
3216 struct supersect
*crc_ss
= NULL
;
3217 if (crc_sect
!= NULL
)
3218 crc_ss
= fetch_supersect(sbfd
, crc_sect
);
3220 struct ulong_vec offsets
;
3224 for (entry
= ss
->contents
.data
;
3225 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3226 entry
+= s
->entry_size
) {
3227 struct span
*span
= new_span(ss
, addr_offset(ss
, entry
),
3229 if (s
->entry_contents_size
!= 0)
3230 span
->contents_size
= s
->entry_contents_size
;
3231 if ((span
->symbol
== NULL
||
3232 (span
->symbol
->flags
& BSF_SECTION_SYM
) != 0) &&
3234 arelent
*reloc
= find_reloc(ss
, entry
+ s
->addr_offset
);
3236 struct span
*target_span
= reloc_target_span(ss
, reloc
);
3237 assert(target_span
);
3238 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3239 unsigned long val
= sym
->value
+
3240 reloc_target_offset(ss
, reloc
) -
3241 (target_span
->start
+ target_span
->shift
);
3242 char *label
= strprintf("%s<target:%s+%lx>", ss
->name
,
3243 target_span
->label
, val
);
3244 change_initial_label(span
, label
);
3247 if (other_sect
!= NULL
) {
3249 bfd_vma offset
= read_reloc(ss
, entry
+ s
->other_offset
,
3250 sizeof(void *), &sym
);
3251 if (sym
->section
== other_sect
) {
3252 assert(offset
>= 0 &&
3253 offset
< other_ss
->contents
.size
);
3254 *vec_grow(&offsets
, 1) = offset
;
3258 if (crc_sect
!= NULL
)
3259 new_span(crc_ss
, addr_offset(ss
, entry
) / s
->entry_size
3260 * s
->crc_size
, s
->crc_size
);
3262 if (ss
->type
== SS_TYPE_EXPORT
) {
3263 const char *symname
= read_string(ss
, entry
+
3265 char *label
= strprintf("%s:%s", ss
->name
, symname
);
3266 change_initial_label(span
, label
);
3270 if (other_sect
== NULL
)
3273 *vec_grow(&offsets
, 1) = 0;
3274 qsort(offsets
.data
, offsets
.size
, sizeof(*offsets
.data
),
3276 *vec_grow(&offsets
, 1) = other_ss
->contents
.size
;
3279 for (off
= offsets
.data
; off
< offsets
.data
+ offsets
.size
- 1; off
++) {
3280 if (*off
!= *(off
+ 1))
3281 new_span(other_ss
, *off
, *(off
+ 1) - *off
);
3285 static void initialize_table_section_spans(struct superbfd
*sbfd
)
3287 struct supersect
*tables_ss
=
3288 fetch_supersect(offsets_sbfd
,
3289 bfd_get_section_by_name(offsets_sbfd
->abfd
,
3290 ".ksplice_table_sections"));
3291 const struct table_section
*ts
;
3292 struct table_section s
;
3293 for (ts
= tables_ss
->contents
.data
;
3294 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
3297 s
.sect
= read_string(tables_ss
, &ts
->sect
);
3298 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
3299 s
.crc_sect
= read_string(tables_ss
, &ts
->crc_sect
);
3300 initialize_table_spans(sbfd
, &s
);
3304 static void initialize_ksplice_call_spans(struct supersect
*ss
)
3307 for (relocp
= ss
->relocs
.data
;
3308 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
3309 arelent
*reloc
= *relocp
;
3310 new_span(ss
, reloc
->address
, bfd_get_reloc_size(reloc
->howto
));
3311 /* the span labels should already be unique */
3315 static void initialize_spans(struct superbfd
*sbfd
)
3318 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3319 if (is_table_section(sect
->name
, true, true) && mode("keep"))
3322 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3323 if (ss
->type
== SS_TYPE_STRING
)
3324 initialize_string_spans(ss
);
3325 else if (ss
->type
== SS_TYPE_KSPLICE_CALL
)
3326 initialize_ksplice_call_spans(ss
);
3328 new_span(ss
, 0, ss
->contents
.size
);
3331 initialize_table_section_spans(sbfd
);
3334 /* Returns the span pointed to by the relocation at span->start + offset */
3335 static struct span
*span_offset_target_span(struct span
*span
, int offset
)
3337 void *entry
= span
->ss
->contents
.data
+ span
->start
;
3338 arelent
*reloc
= find_reloc(span
->ss
, entry
+ offset
);
3341 return reloc_target_span(span
->ss
, reloc
);
3344 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
)
3346 asymbol
*sym_ptr
= *reloc
->sym_ptr_ptr
;
3347 if (bfd_is_const_section(sym_ptr
->section
))
3350 bfd_vma addend
= sym_ptr
->value
+ reloc_target_offset(ss
, reloc
);
3351 struct supersect
*sym_ss
=
3352 fetch_supersect(ss
->parent
, sym_ptr
->section
);
3353 struct span
*span
, *target_span
= sym_ss
->spans
.data
;
3354 for (span
= sym_ss
->spans
.data
;
3355 span
< sym_ss
->spans
.data
+ sym_ss
->spans
.size
; span
++) {
3356 if (addend
>= span
->start
&& addend
< span
->start
+ span
->size
)
3362 static bfd_vma
reloc_target_offset(struct supersect
*ss
, arelent
*reloc
)
3364 bfd_vma offset
= reloc_offset(ss
, reloc
);
3365 if (reloc
->howto
->pc_relative
) {
3366 if ((ss
->flags
& SEC_CODE
) != 0)
3367 return offset
+ bfd_get_reloc_size(reloc
->howto
);
3369 const struct table_section
*ts
= get_table_section(ss
->name
);
3370 if (ts
!= NULL
&& ts
->relative_addr
&&
3371 reloc
->address
% ts
->entry_size
== ts
->addr_offset
)
3372 return offset
- ts
->addr_offset
;
3373 if (ts
!= NULL
&& ts
->relative_other
&&
3374 reloc
->address
% ts
->entry_size
== ts
->other_offset
)
3375 return offset
- ts
->other_offset
;
3382 struct span
*find_span(struct supersect
*ss
, bfd_size_type address
)
3385 for (span
= ss
->spans
.data
; span
< ss
->spans
.data
+ ss
->spans
.size
;
3387 if (address
>= span
->start
&&
3388 address
< span
->start
+ span
->size
)
3391 /* Deal with empty BSS sections */
3392 if (ss
->contents
.size
== 0 && ss
->spans
.size
> 0)
3393 return ss
->spans
.data
;
3394 /* Deal with section end pointers */
3395 if (address
== ss
->contents
.size
&& ss
->spans
.size
== 1)
3396 return ss
->spans
.data
;
3400 void compute_span_shifts(struct superbfd
*sbfd
)
3404 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3405 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3408 bfd_size_type offset
= 0;
3409 for (span
= ss
->spans
.data
;
3410 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
3413 span
->shift
= offset
- span
->start
;
3414 offset
+= span
->size
;
3419 void remove_unkept_spans(struct superbfd
*sbfd
)
3423 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3424 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3425 delete_obsolete_relocs(ss
);
3426 struct arelentp_vec orig_relocs
;
3427 vec_move(&orig_relocs
, &ss
->relocs
);
3428 arelent
**relocp
, *reloc
;
3429 for (relocp
= orig_relocs
.data
;
3430 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
3432 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3433 span
= reloc_target_span(ss
, reloc
);
3434 if ((span
!= NULL
&& span
->keep
&& span
->shift
== 0) ||
3435 bfd_is_const_section(sym
->section
)) {
3436 *vec_grow(&ss
->relocs
, 1) = reloc
;
3439 struct supersect
*sym_ss
=
3440 fetch_supersect(sbfd
, sym
->section
);
3441 if (span
!= NULL
&& (sym
->flags
& BSF_SECTION_SYM
) == 0
3442 && find_span(sym_ss
, sym
->value
) != span
) {
3443 err(sbfd
, "Spans for symbol %s and relocation "
3444 "target do not match in sect %s\n",
3445 sym
->name
, sym_ss
->name
);
3448 if (span
!= NULL
&& span
->keep
) {
3449 arelent
*new_reloc
= malloc(sizeof(*new_reloc
));
3450 *new_reloc
= *reloc
;
3451 new_reloc
->addend
= reloc_offset(ss
, reloc
);
3452 new_reloc
->addend
+= span
->shift
;
3453 *vec_grow(&ss
->new_relocs
, 1) = new_reloc
;
3458 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
3459 struct supersect
*ss
= fetch_supersect(sbfd
, sect
), orig_ss
;
3462 supersect_move(&orig_ss
, ss
);
3463 vec_init(&ss
->spans
);
3464 for (span
= orig_ss
.spans
.data
;
3465 span
< orig_ss
.spans
.data
+ orig_ss
.spans
.size
; span
++) {
3468 struct span
*new_span
= vec_grow(&ss
->spans
, 1);
3470 new_span
->start
= span
->start
+ span
->shift
;
3471 new_span
->shift
= 0;
3472 sect_copy(ss
, sect_do_grow(ss
, 1, span
->size
, 1),
3473 &orig_ss
, orig_ss
.contents
.data
+ span
->start
,
3479 static void init_objmanip_superbfd(struct superbfd
*sbfd
)
3481 init_label_map(sbfd
);
3482 initialize_supersect_types(sbfd
);
3483 initialize_spans(sbfd
);
3485 compute_entry_points(sbfd
);
3488 void mangle_section_name(struct superbfd
*sbfd
, const char *name
)
3490 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
3493 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3494 ss
->name
= strprintf(".ksplice_pre.%s", ss
->name
);
3497 static void write_bugline_patches(struct superbfd
*sbfd
)
3499 const struct table_section
*ts
= get_table_section("__bug_table");
3500 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, "__bug_table");
3503 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
3507 for (entry
= ss
->contents
.data
;
3508 entry
< ss
->contents
.data
+ ss
->contents
.size
;
3509 entry
+= ts
->entry_size
) {
3510 struct span
*span
= find_span(ss
, addr_offset(ss
, entry
));
3511 assert(span
!= NULL
);
3512 if (!span
->bugpatch
)
3514 arelent
*reloc
= find_reloc(ss
, entry
+ ts
->addr_offset
);
3515 assert(reloc
!= NULL
);
3516 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
3517 assert(!bfd_is_const_section(sym
->section
));
3518 struct supersect
*kpatch_ss
=
3519 make_section(sbfd
, ".ksplice_patches%s",
3520 sym
->section
->name
);
3522 bfd_vma offset
, start
= 0;
3523 for (offset
= 0; offset
<= span
->size
; offset
++) {
3524 if (offset
!= span
->size
&&
3525 !part_of_reloc(ss
, span
->start
+ offset
))
3527 if (start
== offset
) {
3531 /* an interval of non-relocations just passed */
3532 struct ksplice_patch
*kpatch
=
3533 sect_grow(kpatch_ss
, 1, struct ksplice_patch
);
3534 write_ksplice_patch_reloc
3535 (kpatch_ss
, sym
->section
->name
, &kpatch
->oldaddr
,
3536 sizeof(kpatch
->oldaddr
), span
->label
, start
);
3538 char *data
= write_patch_storage(kpatch_ss
, kpatch
,
3539 offset
- start
, NULL
);
3540 memcpy(data
, entry
+ start
, offset
- start
);
3541 kpatch
->type
= KSPLICE_PATCH_DATA
;
3547 void *write_patch_storage(struct supersect
*ss
, struct ksplice_patch
*kpatch
,
3548 size_t size
, struct supersect
**data_ssp
)
3550 struct supersect
*data_ss
= make_section(ss
->parent
,
3551 ".ksplice_patch_data");
3552 char *saved
= sect_do_grow(data_ss
, 1, size
, 1);
3553 write_reloc(ss
, &kpatch
->saved
, &data_ss
->symbol
,
3554 addr_offset(data_ss
, saved
));
3555 char *data
= sect_do_grow(data_ss
, 1, size
, 1);
3556 write_reloc(ss
, &kpatch
->contents
, &data_ss
->symbol
,
3557 addr_offset(data_ss
, data
));
3558 kpatch
->size
= size
;
3559 if (data_ssp
!= NULL
)
3560 *data_ssp
= data_ss
;