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-2008 Jeffrey Brian Arnold <jbarnold@mit.edu>
5 * Copyright (C) 2008 Anders Kaseorg <andersk@mit.edu>,
6 * Tim Abbott <tabbott@mit.edu>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License, version 2.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 /* objmanip performs various object file manipulations for Ksplice. Its first
23 * two arguments are always an input object file and an output object file.
25 * - keep-primary: "objmanip <post.o> <out.o> keep-primary <pre.o> <kid>"
27 * This mode prepares the object file to be installed as a ksplice update. The
28 * kid argument is the ksplice id string for the ksplice update being built.
30 * - keep-helper: "objmanip <pre.o> <out.o> keep-helper"
32 * This mode prepares the object file to be used for run-pre matching. This
33 * involves replacing all ELF relocations with ksplice relocations and
34 * writing ksplice_section structures for each ELF text or data section.
36 * - rmsyms mode: "objmanip <in.o> <out.o> rmsyms
38 * In this mode, any ELF relocations involving the list of symbol names given on
39 * standard input are replaced with ksplice relocations. This is used only
40 * for KSPLICE_STANDALONE.
42 * - finalize mode: "objmanip <in.o> <out.o> finalize"
44 * In this mode, any ELF relocations to undefined symbols are replaced with
45 * ksplice relocations.
48 /* Always define KSPLICE_STANDALONE, even if you're using integrated Ksplice.
49 objmanip won't compile without it. */
50 #define KSPLICE_STANDALONE
53 #include "objcommon.h"
54 #include "kmodsrc/ksplice.h"
55 #include "kmodsrc/offsets.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
);
72 DECLARE_VEC_TYPE(struct export
, export_vec
);
74 DECLARE_VEC_TYPE(const char *, str_vec
);
77 const char *export_type
;
80 struct supersect
*sym_ss
;
81 struct supersect
*crc_ss
;
83 DECLARE_VEC_TYPE(struct export_desc
, export_desc_vec
);
85 #define bool_init(b) *(b) = false
86 DEFINE_HASH_TYPE(bool, bool_hash
, bool_hash_init
, bool_hash_free
,
87 bool_hash_lookup
, bool_init
);
89 #define ulong_init(x) *(x) = 0
90 DEFINE_HASH_TYPE(unsigned long, ulong_hash
, ulong_hash_init
,
91 ulong_hash_free
, ulong_hash_lookup
, ulong_init
);
93 void do_keep_primary(struct superbfd
*isbfd
, const char *pre
);
94 void do_keep_helper(struct superbfd
*isbfd
);
95 void do_finalize(struct superbfd
*isbfd
);
96 void do_rmsyms(struct superbfd
*isbfd
);
98 struct export_vec
*get_export_syms(struct superbfd
*sbfd
);
99 void compare_exported_symbols(struct superbfd
*oldsbfd
,
100 struct superbfd
*newsbfd
, bool deletion
);
101 struct export_desc
*new_export_desc(struct supersect
*ss
, bool deletion
);
102 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
103 arelent
*old_reloc
, arelent
*new_reloc
);
104 bool all_relocs_equal(struct supersect
*old_ss
, struct supersect
*new_ss
);
105 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
);
106 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
);
107 static bool nonrelocs_equal(struct supersect
*old_ss
, struct supersect
*new_ss
);
108 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
109 struct superbfd
*newsbfd
);
111 enum supersect_type
supersect_type(struct supersect
*ss
);
112 void initialize_supersect_types(struct superbfd
*sbfd
);
113 static void initialize_spans(struct superbfd
*sbfd
);
114 static void initialize_string_spans(struct supersect
*ss
);
115 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
);
116 struct span
*reloc_address_span(struct supersect
*ss
, arelent
*reloc
);
117 void remove_unkept_spans(struct superbfd
*sbfd
);
118 void compute_span_shifts(struct superbfd
*sbfd
);
119 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
);
120 bool is_table_section(const char *name
, bool consider_other
);
122 void rm_relocs(struct superbfd
*isbfd
);
123 void rm_some_relocs(struct supersect
*ss
);
124 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
);
125 void load_ksplice_symbol_offsets(struct superbfd
*sbfd
);
126 void blot_section(struct supersect
*ss
, int offset
, reloc_howto_type
*howto
);
127 static void write_ksplice_section(struct span
*span
);
128 void write_ksplice_patch(struct superbfd
*sbfd
, const char *sectname
);
129 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
131 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
);
132 void filter_table_sections(struct superbfd
*isbfd
);
133 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
);
134 void keep_referenced_sections(struct superbfd
*sbfd
);
135 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
);
136 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
);
137 static void setup_new_section(bfd
*obfd
, struct supersect
*ss
);
138 static void write_section(bfd
*obfd
, asection
*osection
, void *arg
);
139 static void delete_obsolete_relocs(struct supersect
*ss
);
140 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
142 static void ss_mark_symbols_used_in_relocations(struct supersect
*ss
);
143 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
144 struct asymbolp_vec
*isyms
);
145 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
);
146 void read_str_set(struct str_vec
*strs
);
147 bool str_in_set(const char *str
, const struct str_vec
*strs
);
148 struct supersect
*make_section(struct superbfd
*sbfd
, const char *name
);
149 void __attribute__((format(printf
, 3, 4)))
150 write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...);
151 void rm_some_exports(struct superbfd
*isbfd
, const struct export_desc
*ed
);
152 void write_ksplice_export(struct superbfd
*sbfd
, const char *symname
,
153 const char *export_type
, bool del
);
154 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
156 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
158 static void match_global_symbol_sections(struct superbfd
*oldsbfd
,
159 struct superbfd
*newsbfd
);
160 static void match_sections_by_name(struct superbfd
*oldsbfd
,
161 struct superbfd
*newsbfd
);
162 static void match_sections_by_label(struct superbfd
*oldsbfd
,
163 struct superbfd
*newsbfd
);
164 static void mark_new_sections(struct superbfd
*sbfd
);
165 static void handle_deleted_sections(struct superbfd
*oldsbfd
,
166 struct superbfd
*newsbfd
);
167 static void compare_matched_sections(struct superbfd
*sbfd
);
168 static void update_nonzero_offsets(struct superbfd
*sbfd
);
169 static void handle_nonzero_offset_relocs(struct supersect
*ss
);
171 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
);
172 static void print_label_map(struct superbfd
*sbfd
);
173 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
175 static void init_label_map(struct superbfd
*sbfd
);
176 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
);
177 static void init_csyms(struct superbfd
*sbfd
);
178 static void init_callers(struct superbfd
*sbfd
);
179 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
);
180 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
);
181 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
);
182 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
);
185 #define debug_(sbfd, level, fmt, ...) \
187 if (verbose >= (level)) \
188 printf("%s: " fmt, (sbfd)->abfd->filename, \
191 #define debug0(sbfd, fmt, ...) debug_(sbfd, 0, fmt, ## __VA_ARGS__)
192 #define debug1(sbfd, fmt, ...) debug_(sbfd, 1, fmt, ## __VA_ARGS__)
193 #define err(sbfd, fmt, ...) \
195 fprintf(stderr, "%s: " fmt, (sbfd)->abfd->filename, \
199 struct str_vec delsects
, rmsyms
;
200 struct export_desc_vec exports
;
203 struct ksplice_config
*config
;
205 const char *modestr
, *kid
;
207 struct superbfd
*offsets_sbfd
= NULL
;
209 #define mode(str) starts_with(modestr, str)
211 DECLARE_VEC_TYPE(unsigned long, addr_vec
);
212 DEFINE_HASH_TYPE(struct addr_vec
, addr_vec_hash
,
213 addr_vec_hash_init
, addr_vec_hash_free
, addr_vec_hash_lookup
,
215 struct addr_vec_hash system_map
;
217 struct bool_hash system_map_written
;
218 struct ulong_hash ksplice_symbol_offset
;
219 struct ulong_hash ksplice_string_offset
;
221 void load_system_map()
223 const char *config_dir
= getenv("KSPLICE_CONFIG_DIR");
226 assert(asprintf(&file
, "%s/System.map", config_dir
) >= 0);
227 FILE *fp
= fopen(file
, "r");
229 addr_vec_hash_init(&system_map
);
233 while (fscanf(fp
, "%lx %c %as\n", &addr
, &type
, &sym
) == 3)
234 *vec_grow(addr_vec_hash_lookup(&system_map
, sym
, TRUE
),
239 void load_ksplice_symbol_offsets(struct superbfd
*sbfd
)
241 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
,
245 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
247 struct ksplice_symbol
*ksym
;
248 for (ksym
= ss
->contents
.data
;
249 (void *)ksym
< ss
->contents
.data
+ ss
->contents
.size
; ksym
++) {
250 const char *label
= read_string(ss
, &ksym
->label
);
251 unsigned long *ksymbol_offp
=
252 ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
253 *ksymbol_offp
= addr_offset(ss
, ksym
);
259 char *kmodsrc
= getenv("KSPLICE_KMODSRC"), *offsets_file
;
260 assert(kmodsrc
!= NULL
);
261 assert(asprintf(&offsets_file
, "%s/offsets.o", kmodsrc
) >= 0);
262 bfd
*offsets_bfd
= bfd_openr(offsets_file
, NULL
);
263 assert(offsets_bfd
!= NULL
);
265 assert(bfd_check_format_matches(offsets_bfd
, bfd_object
, &matching
));
266 offsets_sbfd
= fetch_superbfd(offsets_bfd
);
268 asection
*config_sect
= bfd_get_section_by_name(offsets_sbfd
->abfd
,
270 struct supersect
*config_ss
=
271 fetch_supersect(offsets_sbfd
, config_sect
);
273 config
= config_ss
->contents
.data
;
276 bool matchable_data_section(struct supersect
*ss
)
278 if (ss
->type
== SS_TYPE_STRING
)
280 if (ss
->type
== SS_TYPE_RODATA
)
282 if (ss
->type
== SS_TYPE_DATA
&& ss
->relocs
.size
!= 0)
287 bool unchangeable_section(struct supersect
*ss
)
289 if (ss
->type
== SS_TYPE_DATA
)
291 if (ss
->type
== SS_TYPE_IGNORED
&& !starts_with(ss
->name
, ".debug") &&
292 strcmp(ss
->name
, "__ksymtab_strings") != 0)
297 int main(int argc
, char *argv
[])
299 if (getenv("KSPLICE_VERBOSE") != NULL
)
300 verbose
= atoi(getenv("KSPLICE_VERBOSE"));
303 bfd
*ibfd
= bfd_openr(argv
[1], NULL
);
307 assert(bfd_check_format_matches(ibfd
, bfd_object
, &matching
));
309 const char *output_target
= bfd_get_target(ibfd
);
310 bfd
*obfd
= bfd_openw(argv
[2], output_target
);
313 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
314 init_label_map(isbfd
);
316 bool_hash_init(&system_map_written
);
317 ulong_hash_init(&ksplice_symbol_offset
);
318 ulong_hash_init(&ksplice_string_offset
);
321 if (mode("keep-primary")) {
323 do_keep_primary(isbfd
, argv
[4]);
324 } else if (mode("keep-helper")) {
325 do_keep_helper(isbfd
);
326 } else if (mode("finalize")) {
328 } else if (mode("rmsyms")) {
332 copy_object(ibfd
, obfd
);
334 if (offsets_sbfd
!= NULL
)
335 assert(bfd_close(offsets_sbfd
->abfd
));
336 assert(bfd_close(obfd
));
337 assert(bfd_close(ibfd
));
341 void do_keep_primary(struct superbfd
*isbfd
, const char *pre
)
343 struct bfd
*prebfd
= bfd_openr(pre
, NULL
);
344 assert(prebfd
!= NULL
);
346 assert(bfd_check_format_matches(prebfd
, bfd_object
, &matching
));
348 struct superbfd
*presbfd
= fetch_superbfd(prebfd
);
349 init_label_map(presbfd
);
352 initialize_supersect_types(isbfd
);
353 initialize_supersect_types(presbfd
);
355 match_global_symbol_sections(presbfd
, isbfd
);
356 debug1(isbfd
, "Matched global\n");
357 match_sections_by_name(presbfd
, isbfd
);
358 debug1(isbfd
, "Matched by name\n");
359 match_sections_by_label(presbfd
, isbfd
);
360 debug1(isbfd
, "Matched by label\n");
364 compare_matched_sections(isbfd
);
365 update_nonzero_offsets(isbfd
);
366 mark_new_sections(isbfd
);
370 handle_deleted_sections(presbfd
, isbfd
);
371 handle_section_symbol_renames(presbfd
, isbfd
);
374 compare_exported_symbols(presbfd
, isbfd
, false);
375 compare_exported_symbols(isbfd
, presbfd
, true);
377 initialize_spans(isbfd
);
378 initialize_spans(presbfd
);
380 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
381 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
382 if (ss
->type
!= SS_TYPE_STRING
)
384 asection
*oldsect
= bfd_get_section_by_name(prebfd
, sect
->name
);
387 struct supersect
*old_ss
= fetch_supersect(presbfd
, oldsect
);
388 struct span
*span
, *old_span
;
389 for (span
= ss
->spans
.data
;
390 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
392 for (old_span
= old_ss
->spans
.data
;
393 old_span
< old_ss
->spans
.data
+ old_ss
->spans
.size
;
395 if (strcmp((char *)ss
->contents
.data
+
397 (char *)old_ss
->contents
.data
+
398 old_span
->start
) == 0) {
401 span
->label
= old_span
->label
;
407 assert(bfd_close(prebfd
));
409 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
410 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
412 if (ss
->type
== SS_TYPE_STRING
|| ss
->type
== SS_TYPE_SPECIAL
||
413 ss
->type
== SS_TYPE_EXPORT
)
415 if (ss
->new || ss
->patch
)
419 print_label_map(isbfd
);
421 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
422 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
424 debug0(isbfd
, "Patching section: %s\n", sect
->name
);
427 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
428 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
430 debug0(isbfd
, "New section: %s\n", sect
->name
);
433 const char **sectname
;
434 for (sectname
= delsects
.data
;
435 sectname
< delsects
.data
+ delsects
.size
; sectname
++)
436 debug0(isbfd
, "Deleted section: %s\n", *sectname
);
438 const struct export_desc
*ed
;
439 for (ed
= exports
.data
; ed
< exports
.data
+ exports
.size
; ed
++) {
440 const char **symname
;
441 for (symname
= ed
->names
.data
;
442 symname
< ed
->names
.data
+ ed
->names
.size
; symname
++)
443 debug0(isbfd
, "Export %s (%s): %s\n",
444 ed
->deletion
? "deletion" : "addition",
445 ed
->export_type
, *symname
);
449 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
450 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
451 for (span
= ss
->spans
.data
;
452 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
453 span
->keep
= ss
->keep
;
456 filter_table_sections(isbfd
);
457 for (ed
= exports
.data
; ed
< exports
.data
+ exports
.size
; ed
++) {
458 const char **symname
;
459 for (symname
= ed
->names
.data
;
460 symname
< ed
->names
.data
+ ed
->names
.size
; symname
++)
461 write_ksplice_export(isbfd
, *symname
,
462 ed
->export_type
, ed
->deletion
);
464 rm_some_exports(isbfd
, ed
);
467 compute_span_shifts(isbfd
);
469 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
470 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
471 if (!ss
->patch
&& !ss
->new)
475 for (span
= ss
->spans
.data
;
476 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
477 write_ksplice_section(span
);
480 write_ksplice_patch(isbfd
, sect
->name
);
484 remove_unkept_spans(isbfd
);
487 void do_keep_helper(struct superbfd
*isbfd
)
491 initialize_supersect_types(isbfd
);
492 initialize_spans(isbfd
);
495 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
496 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
498 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_TEXT
)
503 for (symp
= isbfd
->syms
.data
;
504 symp
< isbfd
->syms
.data
+ isbfd
->syms
.size
; symp
++) {
505 asymbol
*sym
= *symp
;
506 if (!bfd_is_const_section(sym
->section
) &&
507 (sym
->flags
& BSF_GLOBAL
) != 0) {
508 struct supersect
*sym_ss
=
509 fetch_supersect(isbfd
, sym
->section
);
510 if (sym_ss
->type
!= SS_TYPE_IGNORED
)
516 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
517 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
518 for (span
= ss
->spans
.data
;
519 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++)
520 span
->keep
= ss
->keep
;
525 keep_referenced_sections(isbfd
);
528 filter_table_sections(isbfd
);
529 compute_span_shifts(isbfd
);
531 for (sect
= isbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
532 struct supersect
*ss
= fetch_supersect(isbfd
, sect
);
533 asymbol
*sym
= canonical_symbol(isbfd
, sect
->symbol
);
536 if ((sym
->flags
& BSF_WEAK
) != 0)
538 if (bfd_get_section_size(sect
) == 0)
542 if (ss
->type
!= SS_TYPE_TEXT
&& !matchable_data_section(ss
))
546 for (span
= ss
->spans
.data
;
547 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
549 write_ksplice_section(span
);
554 remove_unkept_spans(isbfd
);
557 void do_finalize(struct superbfd
*isbfd
)
560 load_ksplice_symbol_offsets(isbfd
);
562 initialize_supersect_types(isbfd
);
563 initialize_spans(isbfd
);
567 void do_rmsyms(struct superbfd
*isbfd
)
569 read_str_set(&rmsyms
);
572 initialize_supersect_types(isbfd
);
573 initialize_spans(isbfd
);
577 struct export_vec
*get_export_syms(struct superbfd
*sbfd
)
580 struct export_vec
*exports
;
581 exports
= malloc(sizeof(*exports
));
582 assert(exports
!= NULL
);
585 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
586 if (!starts_with(sect
->name
, "__ksymtab") ||
587 ends_with(sect
->name
, "_strings"))
589 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
590 struct kernel_symbol
*sym
;
591 assert(ss
->contents
.size
* 2 == ss
->relocs
.size
*
592 sizeof(struct kernel_symbol
));
593 for (sym
= ss
->contents
.data
;
594 (void *)sym
< ss
->contents
.data
+ ss
->contents
.size
;
596 struct export
*exp
= vec_grow(exports
, 1);
598 read_string(ss
, (const char *const *)&sym
->name
);
605 struct export_desc
*new_export_desc(struct supersect
*ss
, bool deletion
)
607 struct export_desc
*ed
= vec_grow(&exports
, 1);
608 ed
->deletion
= deletion
;
609 vec_init(&ed
->names
);
610 ed
->export_type
= strdup(ss
->name
) + strlen("__ksymtab");
613 assert(asprintf(&crc_sect_name
, "__kcrctab%s", ed
->export_type
) >= 0);
615 bfd_get_section_by_name(ss
->parent
->abfd
, crc_sect_name
);
616 if (crc_sect
== NULL
)
619 ed
->crc_ss
= fetch_supersect(ss
->parent
, crc_sect
);
623 void compare_exported_symbols(struct superbfd
*oldsbfd
,
624 struct superbfd
*newsbfd
, bool deletion
)
626 struct export_vec
*new_exports
, *old_exports
;
627 new_exports
= get_export_syms(newsbfd
);
628 if (new_exports
== NULL
)
630 old_exports
= get_export_syms(oldsbfd
);
631 struct export
*old
, *new;
632 struct supersect
*last_ss
= NULL
;
633 struct export_desc
*ed
= NULL
;
634 for (new = new_exports
->data
; new < new_exports
->data
+
635 new_exports
->size
; new++) {
637 if (old_exports
!= NULL
) {
638 for (old
= old_exports
->data
; old
< old_exports
->data
+
639 old_exports
->size
; old
++) {
640 if (strcmp(new->name
, old
->name
) == 0 &&
641 strcmp(new->ss
->name
, old
->ss
->name
) == 0) {
647 if (last_ss
!= new->ss
) {
649 ed
= new_export_desc(new->ss
, deletion
);
652 *vec_grow(&ed
->names
, 1) = new->name
;
656 void match_sections(struct supersect
*oldss
, struct supersect
*newss
)
658 if (oldss
->match
== newss
&& newss
->match
== oldss
)
660 if (oldss
->match
!= NULL
) {
661 err(newss
->parent
, "Matching conflict: old %s: %s != %s\n",
662 oldss
->name
, oldss
->match
->name
, newss
->name
);
665 if (newss
->match
!= NULL
) {
666 err(newss
->parent
, "Matching conflict: new %s: %s != %s\n",
667 newss
->name
, newss
->match
->name
, oldss
->name
);
670 oldss
->match
= newss
;
671 newss
->match
= oldss
;
672 debug1(newss
->parent
, "Matched old %s to new %s\n",
673 oldss
->name
, newss
->name
);
676 static void match_global_symbol_sections(struct superbfd
*oldsbfd
,
677 struct superbfd
*newsbfd
)
679 asymbol
**oldsymp
, **newsymp
;
680 for (oldsymp
= oldsbfd
->syms
.data
;
681 oldsymp
< oldsbfd
->syms
.data
+ oldsbfd
->syms
.size
; oldsymp
++) {
682 asymbol
*oldsym
= *oldsymp
;
683 if ((oldsym
->flags
& BSF_GLOBAL
) == 0 ||
684 bfd_is_const_section(oldsym
->section
))
686 for (newsymp
= newsbfd
->syms
.data
;
687 newsymp
< newsbfd
->syms
.data
+ newsbfd
->syms
.size
;
689 asymbol
*newsym
= *newsymp
;
690 if ((newsym
->flags
& BSF_GLOBAL
) == 0 ||
691 bfd_is_const_section(oldsym
->section
))
693 if (strcmp(oldsym
->name
, newsym
->name
) != 0)
695 struct supersect
*oldss
=
696 fetch_supersect(oldsbfd
, oldsym
->section
);
697 struct supersect
*newss
=
698 fetch_supersect(newsbfd
, newsym
->section
);
699 match_sections(oldss
, newss
);
704 static void match_sections_by_name(struct superbfd
*oldsbfd
,
705 struct superbfd
*newsbfd
)
707 asection
*newp
, *oldp
;
708 for (newp
= newsbfd
->abfd
->sections
; newp
!= NULL
; newp
= newp
->next
) {
709 struct supersect
*newss
= fetch_supersect(newsbfd
, newp
);
710 oldp
= bfd_get_section_by_name(oldsbfd
->abfd
, newp
->name
);
711 if (oldp
== NULL
|| newss
->type
== SS_TYPE_STRING
||
712 newss
->type
== SS_TYPE_SPECIAL
||
713 newss
->type
== SS_TYPE_EXPORT
)
715 if (static_local_symbol(newsbfd
,
716 canonical_symbol(newsbfd
,
720 struct supersect
*oldss
= fetch_supersect(oldsbfd
, oldp
);
721 match_sections(oldss
, newss
);
725 static void match_sections_by_label(struct superbfd
*oldsbfd
,
726 struct superbfd
*newsbfd
)
728 asection
*oldsect
, *newsect
;
729 struct supersect
*oldss
, *newss
;
730 for (newsect
= newsbfd
->abfd
->sections
; newsect
!= NULL
;
731 newsect
= newsect
->next
) {
732 newss
= fetch_supersect(newsbfd
, newsect
);
733 if (newss
->type
== SS_TYPE_STRING
||
734 newss
->type
== SS_TYPE_SPECIAL
||
735 newss
->type
== SS_TYPE_EXPORT
)
737 for (oldsect
= oldsbfd
->abfd
->sections
; oldsect
!= NULL
;
738 oldsect
= oldsect
->next
) {
739 if (strcmp(label_lookup(newsbfd
, newsect
->symbol
),
740 label_lookup(oldsbfd
, oldsect
->symbol
)) != 0)
742 oldss
= fetch_supersect(oldsbfd
, oldsect
);
743 match_sections(oldss
, newss
);
748 static void mark_new_sections(struct superbfd
*sbfd
)
751 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
752 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
753 if (ss
->type
== SS_TYPE_STRING
|| ss
->type
== SS_TYPE_SPECIAL
||
754 ss
->type
== SS_TYPE_IGNORED
|| ss
->type
== SS_TYPE_EXPORT
)
756 if (ss
->match
== NULL
)
761 static void handle_deleted_sections(struct superbfd
*oldsbfd
,
762 struct superbfd
*newsbfd
)
765 for (sect
= oldsbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
766 struct supersect
*ss
= fetch_supersect(oldsbfd
, sect
);
767 if (ss
->type
!= SS_TYPE_TEXT
)
769 if (ss
->match
!= NULL
)
771 const char *label
= label_lookup(oldsbfd
, sect
->symbol
);
772 *vec_grow(&delsects
, 1) = label
;
773 asymbol
*csym
= canonical_symbol(oldsbfd
, sect
->symbol
);
774 write_ksplice_deleted_patch(newsbfd
, csym
->name
, label
);
778 static void handle_nonzero_offset_relocs(struct supersect
*ss
)
781 for (i
= 0; i
< ss
->relocs
.size
; i
++) {
782 asymbol
*sym
= *ss
->relocs
.data
[i
]->sym_ptr_ptr
;
783 bfd_vma offset
= get_reloc_offset(ss
, ss
->relocs
.data
[i
], true);
784 if (sym
->value
+ offset
== 0)
786 if (bfd_is_const_section(sym
->section
))
788 struct supersect
*sym_ss
= fetch_supersect(ss
->parent
,
790 if (sym_ss
->type
!= SS_TYPE_TEXT
)
792 if (!sym_ss
->patch
) {
795 "Changing %s because a relocation from sect %s "
796 "has a nonzero offset %lx+%lx into it\n",
797 sym_ss
->name
, ss
->name
,
798 (unsigned long)sym
->value
,
799 (unsigned long)offset
);
801 sym_ss
->patch
= true;
805 static void update_nonzero_offsets(struct superbfd
*sbfd
)
808 struct supersect
*ss
;
810 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
811 ss
= fetch_supersect(sbfd
, sect
);
812 if (ss
->new || ss
->patch
)
813 handle_nonzero_offset_relocs(ss
);
817 static void compare_matched_sections(struct superbfd
*newsbfd
)
820 struct supersect
*old_ss
, *new_ss
;
821 for (newp
= newsbfd
->abfd
->sections
; newp
!= NULL
; newp
= newp
->next
) {
822 new_ss
= fetch_supersect(newsbfd
, newp
);
823 if (new_ss
->match
== NULL
)
825 old_ss
= new_ss
->match
;
827 if (nonrelocs_equal(old_ss
, new_ss
) &&
828 all_relocs_equal(old_ss
, new_ss
))
832 if (new_ss
->contents
.size
!= old_ss
->contents
.size
)
833 reason
= "differing sizes";
834 else if (memcmp(new_ss
->contents
.data
, old_ss
->contents
.data
,
835 new_ss
->contents
.size
) != 0)
836 reason
= "differing contents";
838 reason
= "differing relocations";
839 if (new_ss
->type
== SS_TYPE_TEXT
) {
842 new_ss
->patch
= true;
843 debug1(newsbfd
, "Changing %s due to %s\n", new_ss
->name
,
846 debug1(newsbfd
, "Unmatching %s and %s due to %s\n",
847 old_ss
->name
, new_ss
->name
, reason
);
848 new_ss
->match
= NULL
;
849 old_ss
->match
= NULL
;
852 if (unchangeable_section(new_ss
))
853 err(newsbfd
, "warning: ignoring change to nonpatchable "
854 "section %s\n", new_ss
->name
);
858 static void handle_section_symbol_renames(struct superbfd
*oldsbfd
,
859 struct superbfd
*newsbfd
)
861 asection
*newp
, *oldp
;
862 for (newp
= newsbfd
->abfd
->sections
; newp
!= NULL
; newp
= newp
->next
) {
863 struct supersect
*newss
= fetch_supersect(newsbfd
, newp
);
864 if (newss
->match
== NULL
)
866 oldp
= bfd_get_section_by_name(oldsbfd
->abfd
,
871 const char *old_label
= label_lookup(oldsbfd
, oldp
->symbol
);
872 const char *new_label
= label_lookup(newsbfd
, newp
->symbol
);
874 if (strcmp(old_label
, new_label
) == 0)
876 label_map_set(newsbfd
, new_label
, old_label
);
880 static bool part_of_reloc(struct supersect
*ss
, unsigned long addr
)
883 for (relocp
= ss
->relocs
.data
;
884 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
885 arelent
*reloc
= *relocp
;
886 if (addr
>= reloc
->address
&&
887 addr
< reloc
->address
+ reloc
->howto
->size
)
893 static bool nonrelocs_equal(struct supersect
*old_ss
, struct supersect
*new_ss
)
896 if (old_ss
->contents
.size
!= new_ss
->contents
.size
)
898 const unsigned char *old
= old_ss
->contents
.data
;
899 const unsigned char *new = new_ss
->contents
.data
;
900 for (i
= 0; i
< old_ss
->contents
.size
; i
++) {
901 if (old
[i
] != new[i
] &&
902 !(part_of_reloc(old_ss
, i
) && part_of_reloc(new_ss
, i
)))
908 bool relocs_equal(struct supersect
*old_src_ss
, struct supersect
*new_src_ss
,
909 arelent
*old_reloc
, arelent
*new_reloc
)
911 struct superbfd
*oldsbfd
= old_src_ss
->parent
;
912 struct superbfd
*newsbfd
= new_src_ss
->parent
;
914 if (old_reloc
->address
!= new_reloc
->address
) {
915 debug1(newsbfd
, "Section %s/%s has reloc address mismatch at "
916 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
917 (unsigned long)old_reloc
->address
);
921 if (old_reloc
->howto
!= new_reloc
->howto
) {
922 debug1(newsbfd
, "Section %s/%s has howto type mismatch at "
923 "%lx\n", old_src_ss
->name
, new_src_ss
->name
,
924 (unsigned long)old_reloc
->address
);
928 if (non_dst_mask(old_src_ss
, old_reloc
) !=
929 non_dst_mask(new_src_ss
, new_reloc
)) {
930 debug1(newsbfd
, "Section %s/%s has contents mismatch at %lx\n",
931 old_src_ss
->name
, new_src_ss
->name
,
932 (unsigned long)old_reloc
->address
);
936 asymbol
*old_sym
= *old_reloc
->sym_ptr_ptr
;
937 asymbol
*new_sym
= *new_reloc
->sym_ptr_ptr
;
938 asection
*old_sect
= old_sym
->section
;
939 asection
*new_sect
= new_sym
->section
;
941 bfd_vma old_offset
= get_reloc_offset(old_src_ss
, old_reloc
, true);
942 bfd_vma new_offset
= get_reloc_offset(new_src_ss
, new_reloc
, true);
944 if (bfd_is_und_section(old_sect
) || bfd_is_und_section(new_sect
)) {
945 if (!bfd_is_und_section(new_sect
) && old_offset
!= 0 &&
946 fetch_supersect(newsbfd
, new_sect
)->type
== SS_TYPE_TEXT
)
949 if (!bfd_is_und_section(new_sect
) && new_offset
!= 0 &&
950 fetch_supersect(oldsbfd
, old_sect
)->type
== SS_TYPE_TEXT
)
953 return strcmp(old_sym
->name
, new_sym
->name
) == 0 &&
954 old_offset
== new_offset
;
957 if (bfd_is_const_section(old_sect
) || bfd_is_const_section(new_sect
))
960 struct supersect
*old_ss
= fetch_supersect(oldsbfd
, old_sect
);
961 struct supersect
*new_ss
= fetch_supersect(newsbfd
, new_sect
);
963 if (old_ss
->type
== SS_TYPE_STRING
&&
964 /* check it's not an out-of-range relocation to a string;
965 we'll just compare entire sections for them */
966 !(old_offset
>= old_ss
->contents
.size
||
967 new_offset
>= new_ss
->contents
.size
)) {
968 if (strcmp(old_ss
->contents
.data
+ old_sym
->value
+ old_offset
,
969 new_ss
->contents
.data
+ new_sym
->value
+ new_offset
)
971 debug0(newsbfd
, "Section %s/%s has string difference "
972 "\"%s\"/\"%s\"\n", old_src_ss
->name
,
974 (const char *)(old_ss
->contents
.data
+
975 old_sym
->value
+ old_offset
),
976 (const char *)(new_ss
->contents
.data
+
977 new_sym
->value
+ new_offset
));
978 debug1(newsbfd
, "Strings differ between %s and %s\n",
979 old_src_ss
->name
, new_src_ss
->name
);
985 if (old_ss
->match
!= new_ss
|| new_ss
->match
!= old_ss
) {
986 debug1(newsbfd
, "Nonmatching relocs from %s to %s/%s\n",
987 new_src_ss
->name
, new_ss
->name
, old_ss
->name
);
991 if (old_sym
->value
+ old_offset
!= new_sym
->value
+ new_offset
) {
992 debug1(newsbfd
, "Offsets to %s/%s differ between %s "
993 "and %s: %lx+%lx/%lx+%lx\n", old_ss
->name
,
994 new_ss
->name
, old_src_ss
->name
, new_src_ss
->name
,
995 (unsigned long)old_sym
->value
, (unsigned long)old_offset
,
996 (unsigned long)new_sym
->value
,
997 (unsigned long)new_offset
);
1001 if ((old_sym
->value
+ old_offset
!= 0 ||
1002 new_sym
->value
+ new_offset
!= 0) && new_ss
->patch
) {
1003 debug1(newsbfd
, "Relocation from %s to nonzero offsets "
1004 "%lx+%lx/%lx+%lx in changed section %s\n",
1005 new_src_ss
->name
, (unsigned long)old_sym
->value
,
1006 (unsigned long)old_offset
, (unsigned long)new_sym
->value
,
1007 (unsigned long)new_offset
, new_sym
->section
->name
);
1013 bool all_relocs_equal(struct supersect
*old_ss
, struct supersect
*new_ss
)
1015 if (old_ss
->relocs
.size
!= new_ss
->relocs
.size
) {
1016 debug1(new_ss
->parent
, "Different reloc count between %s and "
1017 "%s\n", old_ss
->name
, new_ss
->name
);
1022 for (i
= 0; i
< old_ss
->relocs
.size
; i
++) {
1023 if (!relocs_equal(old_ss
, new_ss
, old_ss
->relocs
.data
[i
],
1024 new_ss
->relocs
.data
[i
]))
1031 bfd_vma
non_dst_mask(struct supersect
*ss
, arelent
*reloc
)
1033 int bits
= bfd_get_reloc_size(reloc
->howto
) * 8;
1034 void *address
= ss
->contents
.data
+ reloc
->address
;
1035 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1036 return x
& ~reloc
->howto
->dst_mask
;
1039 void rm_some_exports(struct superbfd
*sbfd
, const struct export_desc
*ed
)
1041 struct supersect
*ss
= ed
->sym_ss
;
1042 struct supersect
*crc_ss
= ed
->crc_ss
;
1044 assert(ss
->contents
.size
* sizeof(unsigned long) ==
1045 crc_ss
->contents
.size
* sizeof(struct kernel_symbol
));
1047 struct kernel_symbol
*ksym
;
1048 unsigned long *crc
= NULL
;
1050 crc
= crc_ss
->contents
.data
;
1051 struct span
*span
, *crc_span
;
1052 for (ksym
= ss
->contents
.data
;
1053 (void *)ksym
< ss
->contents
.data
+ ss
->contents
.size
;
1056 read_reloc(ss
, &ksym
->value
, sizeof(ksym
->value
), &sym
);
1057 span
= new_span(ss
, addr_offset(ss
, ksym
), sizeof(*ksym
));
1058 span
->keep
= str_in_set(sym
->name
, &ed
->names
);
1060 if (crc_ss
!= NULL
) {
1061 crc_span
= new_span(crc_ss
, addr_offset(crc_ss
, crc
),
1063 crc_span
->keep
= span
->keep
;
1067 /* Replace name with a mangled name */
1068 write_string(ss
, (const char **)&ksym
->name
,
1069 "DISABLED_%s_%s", sym
->name
, kid
);
1074 void rm_relocs(struct superbfd
*isbfd
)
1077 for (p
= isbfd
->abfd
->sections
; p
!= NULL
; p
= p
->next
) {
1078 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1079 if ((mode("keep") && ss
->type
== SS_TYPE_SPECIAL
) ||
1080 ss
->type
== SS_TYPE_KSPLICE
)
1082 if (ss
->keep
|| mode("rmsyms"))
1085 if (mode("finalize")) {
1086 p
= bfd_get_section_by_name(isbfd
->abfd
, ".ksplice_patches");
1088 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1091 p
= bfd_get_section_by_name(isbfd
->abfd
, ".ksplice_relocs");
1093 struct supersect
*ss
= fetch_supersect(isbfd
, p
);
1099 void rm_some_relocs(struct supersect
*ss
)
1101 struct arelentp_vec orig_relocs
;
1102 vec_move(&orig_relocs
, &ss
->relocs
);
1105 for (relocp
= orig_relocs
.data
;
1106 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
1107 bool rm_reloc
= false;
1108 asymbol
*sym_ptr
= *(*relocp
)->sym_ptr_ptr
;
1110 if (mode("rmsyms") && str_in_set(sym_ptr
->name
, &rmsyms
) &&
1111 bfd_is_und_section(sym_ptr
->section
))
1117 if (mode("keep-primary") &&
1118 (bfd_is_const_section(sym_ptr
->section
) ||
1119 fetch_supersect(ss
->parent
, sym_ptr
->section
)->new ||
1120 reloc_target_span(ss
, *relocp
)->new ||
1121 !reloc_address_span(ss
, *relocp
)->keep
))
1124 if (mode("finalize") && bfd_is_und_section(sym_ptr
->section
))
1127 if (strcmp(sym_ptr
->name
, "mcount") == 0 &&
1128 bfd_is_und_section(sym_ptr
->section
))
1132 write_ksplice_reloc(ss
, *relocp
);
1134 *vec_grow(&ss
->relocs
, 1) = *relocp
;
1138 struct supersect
*make_section(struct superbfd
*sbfd
, const char *name
)
1140 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, name
);
1142 return fetch_supersect(sbfd
, sect
);
1144 return new_supersect(sbfd
, name
);
1147 arelent
*create_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1150 bfd_reloc_code_real_type code
;
1151 switch (bfd_arch_bits_per_address(ss
->parent
->abfd
)) {
1153 code
= BFD_RELOC_32
;
1156 code
= BFD_RELOC_64
;
1162 arelent
*reloc
= malloc(sizeof(*reloc
));
1163 reloc
->sym_ptr_ptr
= symp
;
1164 reloc
->address
= addr_offset(ss
, addr
);
1165 reloc
->howto
= bfd_reloc_type_lookup(ss
->parent
->abfd
, code
);
1166 reloc
->addend
= offset
;
1170 void write_reloc(struct supersect
*ss
, const void *addr
, asymbol
**symp
,
1173 *vec_grow(&ss
->new_relocs
, 1) = create_reloc(ss
, addr
, symp
, offset
);
1176 void write_string(struct supersect
*ss
, const char **addr
, const char *fmt
, ...)
1179 struct supersect
*str_ss
= make_section(ss
->parent
, ".ksplice_str");
1182 int len
= vasprintf(&str
, fmt
, ap
);
1186 unsigned long *str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
,
1188 if (str_offp
== NULL
) {
1189 char *buf
= sect_grow(str_ss
, len
+ 1, char);
1190 memcpy(buf
, str
, len
+ 1);
1191 str_offp
= ulong_hash_lookup(&ksplice_string_offset
, str
, TRUE
);
1192 *str_offp
= addr_offset(str_ss
, buf
);
1195 write_reloc(ss
, addr
, &str_ss
->symbol
, *str_offp
);
1198 void lookup_system_map(struct addr_vec
*addrs
, const char *name
, long offset
)
1200 struct addr_vec
*map_addrs
=
1201 addr_vec_hash_lookup(&system_map
, name
, FALSE
);
1202 if (map_addrs
== NULL
)
1205 unsigned long *addr
, *map_addr
;
1206 for (map_addr
= map_addrs
->data
;
1207 map_addr
< map_addrs
->data
+ map_addrs
->size
; map_addr
++) {
1208 for (addr
= addrs
->data
; addr
< addrs
->data
+ addrs
->size
;
1210 if (*addr
== *map_addr
+ offset
)
1213 if (addr
< addrs
->data
+ addrs
->size
)
1215 *vec_grow(addrs
, 1) = *map_addr
+ offset
;
1219 void compute_system_map_array(struct superbfd
*sbfd
, struct addr_vec
*addrs
,
1222 if (bfd_is_abs_section(sym
->section
)) {
1223 *vec_grow(addrs
, 1) = sym
->value
;
1224 } else if (bfd_is_und_section(sym
->section
)) {
1225 lookup_system_map(addrs
, sym
->name
, 0);
1226 } else if (!bfd_is_const_section(sym
->section
)) {
1228 for (gsymp
= sbfd
->syms
.data
;
1229 gsymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; gsymp
++) {
1230 asymbol
*gsym
= *gsymp
;
1231 if ((gsym
->flags
& BSF_DEBUGGING
) == 0 &&
1232 gsym
->section
== sym
->section
)
1233 lookup_system_map(addrs
, gsym
->name
,
1234 sym
->value
- gsym
->value
);
1239 void write_ksplice_system_map(struct superbfd
*sbfd
, asymbol
*sym
,
1242 bool *done
= bool_hash_lookup(&system_map_written
, label
, TRUE
);
1247 struct addr_vec addrs
;
1250 compute_system_map_array(sbfd
, &addrs
, sym
);
1251 if (addrs
.size
!= 0) {
1252 struct supersect
*smap_ss
=
1253 make_section(sbfd
, ".ksplice_system_map");
1254 struct ksplice_system_map
*smap
=
1255 sect_grow(smap_ss
, 1, struct ksplice_system_map
);
1256 write_string(smap_ss
, &smap
->label
, "%s", label
);
1258 struct supersect
*array_ss
= make_section(sbfd
,
1260 void *buf
= sect_grow(array_ss
, addrs
.size
,
1261 typeof(*addrs
.data
));
1262 memcpy(buf
, addrs
.data
, addrs
.size
* sizeof(*addrs
.data
));
1263 smap
->nr_candidates
= addrs
.size
;
1264 write_reloc(smap_ss
, &smap
->candidates
, &array_ss
->symbol
,
1265 addr_offset(array_ss
, buf
));
1270 void write_ksplice_symbol_backend(struct supersect
*ss
,
1271 struct ksplice_symbol
*const *addr
,
1272 asymbol
*sym
, const char *label
,
1275 struct supersect
*ksymbol_ss
= make_section(ss
->parent
,
1276 ".ksplice_symbols");
1277 struct ksplice_symbol
*ksymbol
;
1278 unsigned long *ksymbol_offp
;
1280 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, FALSE
);
1281 if (ksymbol_offp
!= NULL
) {
1282 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1285 ksymbol
= sect_grow(ksymbol_ss
, 1, struct ksplice_symbol
);
1286 ksymbol_offp
= ulong_hash_lookup(&ksplice_symbol_offset
, label
, TRUE
);
1287 *ksymbol_offp
= addr_offset(ksymbol_ss
, ksymbol
);
1289 write_reloc(ss
, addr
, &ksymbol_ss
->symbol
, *ksymbol_offp
);
1290 write_string(ksymbol_ss
, &ksymbol
->label
, "%s", label
);
1292 write_string(ksymbol_ss
, &ksymbol
->name
, "%s", name
);
1293 write_ksplice_system_map(ksymbol_ss
->parent
, sym
, label
);
1297 void write_ksplice_symbol(struct supersect
*ss
,
1298 struct ksplice_symbol
*const *addr
,
1299 asymbol
*sym
, struct span
*span
,
1300 const char *addstr_sect
)
1302 const char *label
, *name
;
1304 if (span
!= NULL
&& span
->start
!= 0)
1305 label
= span
->label
;
1307 label
= label_lookup(ss
->parent
, sym
);
1309 assert(asprintf(&output
, "%s%s", label
, addstr_sect
) >= 0);
1311 asymbol
*gsym
= canonical_symbol(ss
->parent
, sym
);
1312 if (strcmp(addstr_sect
, "") != 0)
1314 else if (bfd_is_und_section(sym
->section
))
1316 else if (bfd_is_const_section(sym
->section
))
1318 else if (span
!= NULL
&& span
->symbol
== NULL
)
1320 else if (gsym
== NULL
|| (gsym
->flags
& BSF_SECTION_SYM
) != 0)
1325 write_ksplice_symbol_backend(ss
, addr
, sym
, output
, name
);
1328 void write_ksplice_reloc(struct supersect
*ss
, arelent
*orig_reloc
)
1330 asymbol
*sym_ptr
= *orig_reloc
->sym_ptr_ptr
;
1331 reloc_howto_type
*howto
= orig_reloc
->howto
;
1332 bfd_vma addend
= get_reloc_offset(ss
, orig_reloc
, false);
1333 unsigned long *repladdr
= ss
->contents
.data
+ orig_reloc
->address
;
1335 if (mode("finalize") && strcmp(ss
->name
, ".ksplice_patches") == 0) {
1339 if (mode("finalize") && strcmp(ss
->name
, ".ksplice_relocs") == 0) {
1340 assert(starts_with(sym_ptr
->name
, KSPLICE_SYMBOL_STR
));
1342 fake_sym
.name
= sym_ptr
->name
+ strlen(KSPLICE_SYMBOL_STR
);
1343 fake_sym
.section
= bfd_und_section_ptr
;
1347 write_ksplice_symbol_backend
1348 (ss
, (struct ksplice_symbol
**)repladdr
, &fake_sym
,
1349 fake_sym
.name
, fake_sym
.name
);
1353 struct span
*span
= reloc_target_span(ss
, orig_reloc
);
1354 if (span
== ss
->spans
.data
&& span
->start
!= addend
)
1356 blot_section(ss
, orig_reloc
->address
, howto
);
1358 struct supersect
*kreloc_ss
= make_section(ss
->parent
,
1360 ".ksplice_init_relocs" :
1362 struct ksplice_reloc
*kreloc
= sect_grow(kreloc_ss
, 1,
1363 struct ksplice_reloc
);
1365 struct span
*address_span
= reloc_address_span(ss
, orig_reloc
);
1366 write_reloc(kreloc_ss
, &kreloc
->blank_addr
,
1367 &ss
->symbol
, orig_reloc
->address
+ address_span
->shift
);
1368 if (bfd_is_und_section(sym_ptr
->section
) && mode("keep")) {
1370 assert(asprintf(&name
, KSPLICE_SYMBOL_STR
"%s", sym_ptr
->name
)
1372 asymbol
**symp
= make_undefined_symbolp(ss
->parent
, name
);
1373 write_reloc(kreloc_ss
, &kreloc
->symbol
, symp
, 0);
1375 write_ksplice_symbol(kreloc_ss
, &kreloc
->symbol
, sym_ptr
, span
,
1378 kreloc
->pcrel
= howto
->pc_relative
;
1379 if (span
!= NULL
&& span
->start
!= 0)
1380 addend
+= sym_ptr
->value
- span
->start
;
1381 kreloc
->addend
= addend
;
1382 kreloc
->size
= bfd_get_reloc_size(howto
);
1383 kreloc
->dst_mask
= howto
->dst_mask
;
1384 kreloc
->rightshift
= howto
->rightshift
;
1385 kreloc
->signed_addend
=
1386 (howto
->complain_on_overflow
== complain_overflow_signed
) ||
1387 (howto
->complain_on_overflow
== complain_overflow_bitfield
);
1390 #define CANARY(x, canary) ((x & ~howto->dst_mask) | (canary & howto->dst_mask))
1392 void blot_section(struct supersect
*ss
, int offset
, reloc_howto_type
*howto
)
1394 int bits
= bfd_get_reloc_size(howto
) * 8;
1395 void *address
= ss
->contents
.data
+ offset
;
1396 bfd_vma x
= bfd_get(bits
, ss
->parent
->abfd
, address
);
1397 x
= (x
& ~howto
->dst_mask
) |
1398 ((bfd_vma
)KSPLICE_CANARY
& howto
->dst_mask
);
1399 bfd_put(bits
, ss
->parent
->abfd
, x
, address
);
1402 static void write_ksplice_section(struct span
*span
)
1404 struct supersect
*ss
= span
->ss
;
1405 struct supersect
*ksect_ss
=
1406 make_section(ss
->parent
, ".ksplice_sections");
1407 struct ksplice_section
*ksect
= sect_grow(ksect_ss
, 1,
1408 struct ksplice_section
);
1409 asymbol
*sym
= span
->symbol
== NULL
? ss
->symbol
: span
->symbol
;
1411 write_ksplice_symbol(ksect_ss
, &ksect
->symbol
, sym
, span
,
1412 mode("keep-primary") ? "(post)" : "");
1413 ksect
->size
= span
->size
;
1416 if (ss
->type
== SS_TYPE_RODATA
|| ss
->type
== SS_TYPE_STRING
)
1417 ksect
->flags
|= KSPLICE_SECTION_RODATA
;
1418 if (ss
->type
== SS_TYPE_DATA
)
1419 ksect
->flags
|= KSPLICE_SECTION_DATA
;
1420 if (ss
->type
== SS_TYPE_TEXT
)
1421 ksect
->flags
|= KSPLICE_SECTION_TEXT
;
1422 assert(ksect
->flags
!= 0);
1423 write_reloc(ksect_ss
, &ksect
->address
, &ss
->symbol
,
1424 span
->start
+ span
->shift
);
1427 void write_ksplice_patch(struct superbfd
*sbfd
, const char *sectname
)
1429 struct supersect
*kpatch_ss
= make_section(sbfd
, ".ksplice_patches");
1430 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
1431 struct ksplice_patch
);
1432 asection
*sect
= bfd_get_section_by_name(sbfd
->abfd
, sectname
);
1433 assert(sect
!= NULL
);
1435 write_string(kpatch_ss
, &kpatch
->label
, "%s",
1436 label_lookup(sbfd
, sect
->symbol
));
1437 write_reloc(kpatch_ss
, &kpatch
->repladdr
, §
->symbol
, 0);
1440 asymbol
**make_undefined_symbolp(struct superbfd
*sbfd
, const char *name
)
1443 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
1445 asymbol
*sym
= *symp
;
1446 if (strcmp(name
, sym
->name
) == 0 &&
1447 bfd_is_und_section(sym
->section
))
1451 for (sympp
= sbfd
->new_syms
.data
;
1452 sympp
< sbfd
->new_syms
.data
+ sbfd
->new_syms
.size
; sympp
++) {
1453 asymbol
**symp
= *sympp
;
1454 asymbol
*sym
= *symp
;
1455 if (strcmp(name
, sym
->name
) == 0 &&
1456 bfd_is_und_section(sym
->section
))
1460 symp
= malloc(sizeof(*symp
));
1461 *symp
= bfd_make_empty_symbol(sbfd
->abfd
);
1462 asymbol
*sym
= *symp
;
1464 sym
->section
= bfd_und_section_ptr
;
1467 *vec_grow(&sbfd
->new_syms
, 1) = symp
;
1471 void write_ksplice_deleted_patch(struct superbfd
*sbfd
, const char *name
,
1474 struct supersect
*kpatch_ss
= make_section(sbfd
, ".ksplice_patches");
1475 struct ksplice_patch
*kpatch
= sect_grow(kpatch_ss
, 1,
1476 struct ksplice_patch
);
1478 write_string(kpatch_ss
, &kpatch
->label
, "%s", label
);
1479 asymbol
**symp
= make_undefined_symbolp(sbfd
, strdup(name
));
1480 write_reloc(kpatch_ss
, &kpatch
->repladdr
, symp
, 0);
1483 void write_ksplice_export(struct superbfd
*sbfd
, const char *symname
,
1484 const char *export_type
, bool del
)
1486 struct supersect
*export_ss
= make_section(sbfd
, ".ksplice_exports");
1487 struct ksplice_export
*exp
= sect_grow(export_ss
, 1,
1488 struct ksplice_export
);
1491 write_string(export_ss
, &exp
->name
, "%s", symname
);
1492 write_string(export_ss
, &exp
->new_name
, "DISABLED_%s_%s",
1495 write_string(export_ss
, &exp
->new_name
, "%s", symname
);
1496 write_string(export_ss
, &exp
->name
, "DISABLED_%s_%s", symname
,
1501 struct fixup_entry
{
1505 DECLARE_VEC_TYPE(struct fixup_entry
, fixup_entry_vec
);
1507 int compare_fixups(const void *aptr
, const void *bptr
)
1509 const struct fixup_entry
*a
= aptr
, *b
= bptr
;
1510 if (a
->offset
< b
->offset
)
1512 else if (a
->offset
> b
->offset
)
1515 return (int)a
->used
- (int)b
->used
;
1518 void filter_table_sections(struct superbfd
*isbfd
)
1520 struct supersect
*tables_ss
=
1521 fetch_supersect(offsets_sbfd
,
1522 bfd_get_section_by_name(offsets_sbfd
->abfd
,
1523 ".ksplice_table_sections"));
1524 const struct table_section
*ts
;
1525 for (ts
= tables_ss
->contents
.data
;
1526 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
1528 struct table_section s
= *ts
;
1529 s
.sect
= read_string(tables_ss
, &ts
->sect
);
1530 s
.other_sect
= read_string(tables_ss
, &ts
->other_sect
);
1531 filter_table_section(isbfd
, &s
);
1535 void filter_table_section(struct superbfd
*sbfd
, const struct table_section
*s
)
1537 asection
*isection
= bfd_get_section_by_name(sbfd
->abfd
, s
->sect
);
1538 if (isection
== NULL
)
1540 asection
*fixup_sect
= NULL
;
1541 if (s
->other_sect
!= NULL
)
1542 fixup_sect
= bfd_get_section_by_name(sbfd
->abfd
, s
->other_sect
);
1544 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
1545 if (ss
->alignment
< ffs(s
->entry_align
) - 1)
1546 ss
->alignment
= ffs(s
->entry_align
) - 1;
1548 struct supersect
*fixup_ss
= NULL
;
1549 if (fixup_sect
!= NULL
)
1550 fixup_ss
= fetch_supersect(sbfd
, fixup_sect
);
1552 struct fixup_entry_vec fixups
;
1556 for (entry
= ss
->contents
.data
;
1557 entry
< ss
->contents
.data
+ ss
->contents
.size
;
1558 entry
+= s
->entry_size
) {
1559 asymbol
*sym
, *fixup_sym
;
1560 read_reloc(ss
, entry
+ s
->addr_offset
, sizeof(void *), &sym
);
1562 struct span
*span
= new_span(ss
, addr_offset(ss
, entry
),
1564 struct supersect
*sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1565 span
->keep
= sym_ss
->keep
;
1567 struct fixup_entry
*f
;
1568 if (fixup_sect
!= NULL
) {
1569 bfd_vma fixup_offset
=
1570 read_reloc(ss
, entry
+ s
->other_offset
,
1571 sizeof(void *), &fixup_sym
);
1572 if (fixup_sym
->section
== fixup_sect
) {
1573 assert(fixup_offset
< fixup_ss
->contents
.size
);
1574 f
= vec_grow(&fixups
, 1);
1575 f
->offset
= fixup_offset
;
1576 f
->used
= span
->keep
;
1581 if (fixup_sect
== NULL
)
1584 qsort(fixups
.data
, fixups
.size
, sizeof(*fixups
.data
), compare_fixups
);
1585 *vec_grow(&fixups
, 1) = (struct fixup_entry
)
1586 { .offset
= fixup_ss
->contents
.size
, .used
= false };
1588 struct fixup_entry
*f
;
1589 for (f
= fixups
.data
; f
< fixups
.data
+ fixups
.size
- 1; f
++) {
1590 struct span
*span
= new_span(fixup_ss
, f
->offset
,
1591 (f
+ 1)->offset
- f
->offset
);
1592 span
->keep
= f
->used
;
1596 void keep_referenced_sections(struct superbfd
*sbfd
)
1599 struct supersect
*ss
, *sym_ss
;
1600 struct span
*address_span
, *target_span
;
1601 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
1602 ss
= fetch_supersect(sbfd
, sect
);
1604 if (ss
->type
== SS_TYPE_SPECIAL
|| ss
->type
== SS_TYPE_EXPORT
)
1606 for (relocp
= ss
->relocs
.data
;
1607 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
1608 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
1609 address_span
= reloc_address_span(ss
, *relocp
);
1610 if (!address_span
->keep
)
1612 target_span
= reloc_target_span(ss
, *relocp
);
1613 if (target_span
== NULL
|| target_span
->keep
)
1615 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1616 if (sym_ss
->type
== SS_TYPE_IGNORED
)
1618 target_span
->keep
= true;
1619 sym_ss
->keep
= true;
1625 void copy_symbols(struct asymbolp_vec
*osyms
, struct asymbolpp_vec
*isyms
)
1628 for (sympp
= isyms
->data
; sympp
< isyms
->data
+ isyms
->size
; sympp
++)
1629 *vec_grow(osyms
, 1) = **sympp
;
1632 /* Modified function from GNU Binutils objcopy.c */
1633 bfd_boolean
copy_object(bfd
*ibfd
, bfd
*obfd
)
1635 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
1637 bfd_vma start
= bfd_get_start_address(ibfd
);
1639 flagword flags
= bfd_get_file_flags(ibfd
);
1640 flags
&= bfd_applicable_file_flags(obfd
);
1642 assert(bfd_set_start_address(obfd
, start
)
1643 && bfd_set_file_flags(obfd
, flags
));
1645 enum bfd_architecture iarch
= bfd_get_arch(ibfd
);
1646 unsigned int imach
= bfd_get_mach(ibfd
);
1647 assert(bfd_set_arch_mach(obfd
, iarch
, imach
));
1648 assert(bfd_set_format(obfd
, bfd_get_format(ibfd
)));
1650 /* BFD mandates that all output sections be created and sizes set before
1651 any output is done. Thus, we traverse all sections multiple times. */
1652 bfd_map_over_sections(ibfd
, setup_section
, obfd
);
1654 struct supersect
*new_supersects
= fetch_superbfd(ibfd
)->new_supersects
;
1655 struct supersect
*ss
;
1656 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
1657 setup_new_section(obfd
, ss
);
1659 /* Mark symbols used in output relocations so that they
1660 are kept, even if they are local labels or static symbols.
1662 Note we iterate over the input sections examining their
1663 relocations since the relocations for the output sections
1664 haven't been set yet. mark_symbols_used_in_relocations will
1665 ignore input sections which have no corresponding output
1668 bfd_map_over_sections(ibfd
, mark_symbols_used_in_relocations
, NULL
);
1669 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
)
1670 ss_mark_symbols_used_in_relocations(ss
);
1671 struct asymbolp_vec osyms
;
1673 filter_symbols(ibfd
, obfd
, &osyms
, &fetch_superbfd(ibfd
)->syms
);
1674 copy_symbols(&osyms
, &fetch_superbfd(ibfd
)->new_syms
);
1676 bfd_set_symtab(obfd
, osyms
.data
, osyms
.size
);
1678 /* This has to happen after the symbol table has been set. */
1679 bfd_map_over_sections(obfd
, write_section
, NULL
);
1681 /* Allow the BFD backend to copy any private data it understands
1682 from the input BFD to the output BFD. This is done last to
1683 permit the routine to look at the filtered symbol table, which is
1684 important for the ECOFF code at least. */
1685 assert(bfd_copy_private_bfd_data(ibfd
, obfd
));
1690 /* Modified function from GNU Binutils objcopy.c */
1691 void setup_section(bfd
*ibfd
, asection
*isection
, void *obfdarg
)
1693 struct superbfd
*isbfd
= fetch_superbfd(ibfd
);
1694 struct supersect
*ss
= fetch_supersect(isbfd
, isection
);
1695 bfd
*obfd
= obfdarg
;
1701 asection
*osection
= bfd_make_section_anyway(obfd
, isection
->name
);
1702 assert(osection
!= NULL
);
1704 osection
->userdata
= ss
;
1705 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
1706 ss
->symbol
= osection
->symbol
;
1707 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
1709 vma
= bfd_section_vma(ibfd
, isection
);
1710 assert(bfd_set_section_vma(obfd
, osection
, vma
));
1712 osection
->lma
= isection
->lma
;
1713 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
1714 osection
->entsize
= isection
->entsize
;
1715 osection
->output_section
= osection
;
1716 osection
->output_offset
= 0;
1717 isection
->output_section
= osection
;
1718 isection
->output_offset
= 0;
1722 void setup_new_section(bfd
*obfd
, struct supersect
*ss
)
1724 asection
*osection
= bfd_make_section_anyway(obfd
, ss
->name
);
1725 assert(osection
!= NULL
);
1726 bfd_set_section_flags(obfd
, osection
, ss
->flags
);
1728 osection
->userdata
= ss
;
1729 ss
->symbol
= osection
->symbol
;
1730 assert(bfd_set_section_size(obfd
, osection
, ss
->contents
.size
));
1731 assert(bfd_set_section_vma(obfd
, osection
, 0));
1734 assert(bfd_set_section_alignment(obfd
, osection
, ss
->alignment
));
1735 osection
->entsize
= 0;
1736 osection
->output_section
= osection
;
1737 osection
->output_offset
= 0;
1740 static int compare_reloc_addresses(const void *aptr
, const void *bptr
)
1742 const arelent
*const *a
= aptr
, *const *b
= bptr
;
1743 return (*a
)->address
- (*b
)->address
;
1746 static void delete_obsolete_relocs(struct supersect
*ss
)
1748 if (ss
->new_relocs
.size
== 0)
1751 qsort(ss
->relocs
.data
, ss
->relocs
.size
, sizeof(*ss
->relocs
.data
),
1752 compare_reloc_addresses
);
1753 qsort(ss
->new_relocs
.data
, ss
->new_relocs
.size
,
1754 sizeof(*ss
->new_relocs
.data
), compare_reloc_addresses
);
1756 struct arelentp_vec orig_relocs
;
1757 vec_move(&orig_relocs
, &ss
->relocs
);
1759 arelent
**relocp
, **new_relocp
= ss
->new_relocs
.data
;
1760 for (relocp
= orig_relocs
.data
;
1761 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
1762 while (new_relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
&&
1763 (*new_relocp
)->address
< (*relocp
)->address
)
1765 arelent
*reloc
= *relocp
, *new_reloc
= *new_relocp
;
1766 if (new_relocp
== ss
->new_relocs
.data
+ ss
->new_relocs
.size
||
1767 reloc
->address
!= new_reloc
->address
)
1768 *vec_grow(&ss
->relocs
, 1) = reloc
;
1772 void write_section(bfd
*obfd
, asection
*osection
, void *arg
)
1774 struct supersect
*ss
= osection
->userdata
;
1776 if ((ss
->flags
& SEC_GROUP
) != 0 || ss
->contents
.size
== 0)
1779 delete_obsolete_relocs(ss
);
1782 char *error_message
;
1783 for (relocp
= ss
->new_relocs
.data
;
1784 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
1786 if (bfd_get_arch(obfd
) == bfd_arch_arm
)
1787 val
= osection
->use_rela_p
? 0 : (*relocp
)->addend
;
1790 bfd_put(bfd_get_reloc_size((*relocp
)->howto
) * 8, obfd
, val
,
1791 ss
->contents
.data
+ (*relocp
)->address
);
1792 if (bfd_install_relocation(obfd
, *relocp
, ss
->contents
.data
,
1793 0, osection
, &error_message
) !=
1795 err(ss
->parent
, "ksplice: error installing reloc: %s",
1800 memcpy(vec_grow(&ss
->relocs
, ss
->new_relocs
.size
), ss
->new_relocs
.data
,
1801 ss
->new_relocs
.size
* sizeof(*ss
->new_relocs
.data
));
1803 bfd_set_reloc(obfd
, osection
,
1804 ss
->relocs
.size
== 0 ? NULL
: ss
->relocs
.data
,
1807 if (ss
->flags
& SEC_HAS_CONTENTS
)
1808 assert(bfd_set_section_contents
1809 (obfd
, osection
, ss
->contents
.data
, 0,
1810 ss
->contents
.size
));
1813 /* Modified function from GNU Binutils objcopy.c
1815 * Mark all the symbols which will be used in output relocations with
1816 * the BSF_KEEP flag so that those symbols will not be stripped.
1818 * Ignore relocations which will not appear in the output file.
1820 void mark_symbols_used_in_relocations(bfd
*abfd
, asection
*isection
,
1823 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
1824 if (isection
->output_section
== NULL
)
1827 struct supersect
*ss
= fetch_supersect(sbfd
, isection
);
1828 ss_mark_symbols_used_in_relocations(ss
);
1831 void ss_mark_symbols_used_in_relocations(struct supersect
*ss
)
1833 /* Examine each symbol used in a relocation. If it's not one of the
1834 special bfd section symbols, then mark it with BSF_KEEP. */
1836 for (relocp
= ss
->relocs
.data
;
1837 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
1838 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
1839 if (!(bfd_is_const_section(sym
->section
) &&
1840 sym
== sym
->section
->symbol
))
1841 sym
->flags
|= BSF_KEEP
;
1843 for (relocp
= ss
->new_relocs
.data
;
1844 relocp
< ss
->new_relocs
.data
+ ss
->new_relocs
.size
; relocp
++) {
1845 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
1846 if (!(bfd_is_const_section(sym
->section
) &&
1847 sym
== sym
->section
->symbol
))
1848 sym
->flags
|= BSF_KEEP
;
1852 static bool deleted_table_section_symbol(bfd
*abfd
, asymbol
*sym
)
1854 struct superbfd
*sbfd
= fetch_superbfd(abfd
);
1855 if (bfd_is_const_section(sym
->section
))
1857 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
1860 for (symp
= ss
->syms
.data
; symp
< ss
->syms
.data
+ ss
->syms
.size
; symp
++) {
1864 return symp
>= ss
->syms
.data
+ ss
->syms
.size
;
1867 /* Modified function from GNU Binutils objcopy.c
1869 * Choose which symbol entries to copy.
1870 * We don't copy in place, because that confuses the relocs.
1871 * Return the number of symbols to print.
1873 void filter_symbols(bfd
*ibfd
, bfd
*obfd
, struct asymbolp_vec
*osyms
,
1874 struct asymbolp_vec
*isyms
)
1877 struct superbfd
*sbfd
= fetch_superbfd(ibfd
);
1878 for (symp
= isyms
->data
; symp
< isyms
->data
+ isyms
->size
; symp
++) {
1879 asymbol
*sym
= *symp
;
1880 struct supersect
*sym_ss
= NULL
;
1881 if (!bfd_is_const_section(sym
->section
))
1882 sym_ss
= fetch_supersect(sbfd
, sym
->section
);
1886 if (mode("keep") && (sym
->flags
& BSF_GLOBAL
) != 0 &&
1887 !(mode("keep-primary") && sym_ss
!= NULL
&& sym_ss
->new))
1888 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
1890 if (mode("finalize") && (sym
->flags
& BSF_GLOBAL
) != 0)
1891 sym
->flags
= (sym
->flags
& ~BSF_GLOBAL
) | BSF_LOCAL
;
1893 if ((sym
->flags
& BSF_KEEP
) != 0 /* Used in relocation. */
1894 || ((sym
->flags
& BSF_SECTION_SYM
) != 0 && sym_ss
!= NULL
&&
1897 else if ((sym
->flags
& (BSF_GLOBAL
| BSF_WEAK
)) != 0 &&
1898 sym_ss
!= NULL
&& sym_ss
->keep
)
1901 if (deleted_table_section_symbol(ibfd
, sym
))
1904 if (bfd_is_com_section(sym
->section
))
1908 keep
= !str_in_set(sym
->name
, &rmsyms
);
1911 if (sym_ss
!= NULL
&& !sym_ss
->keep
) {
1912 err(sbfd
, "Kept symbol %s in unkept section "
1913 "%s\n", sym
->name
, sym
->section
->name
);
1916 *vec_grow(osyms
, 1) = sym
;
1921 void read_str_set(struct str_vec
*strs
)
1925 assert(getline(&buf
, &n
, stdin
) >= 0);
1929 char *str
= strtok_r(buf
, " \n", &saveptr
);
1933 *vec_grow(strs
, 1) = str
;
1937 bool str_in_set(const char *str
, const struct str_vec
*strs
)
1940 for (strp
= strs
->data
; strp
< strs
->data
+ strs
->size
; strp
++) {
1941 if (strcmp(str
, *strp
) == 0)
1947 bool is_table_section(const char *name
, bool consider_other
)
1949 struct supersect
*tables_ss
=
1950 fetch_supersect(offsets_sbfd
,
1951 bfd_get_section_by_name(offsets_sbfd
->abfd
,
1952 ".ksplice_table_sections"));
1953 const struct table_section
*ts
;
1954 for (ts
= tables_ss
->contents
.data
;
1955 (void *)ts
< tables_ss
->contents
.data
+ tables_ss
->contents
.size
;
1957 if (strcmp(name
, read_string(tables_ss
, &ts
->sect
)) == 0)
1959 const char *osect_name
= read_string(tables_ss
,
1961 if (consider_other
&& osect_name
!= NULL
&&
1962 strcmp(name
, osect_name
) == 0)
1968 enum supersect_type
supersect_type(struct supersect
*ss
)
1970 if (starts_with(ss
->name
, ".ksplice"))
1971 return SS_TYPE_KSPLICE
;
1973 if (starts_with(ss
->name
, ".init"))
1974 return SS_TYPE_IGNORED
;
1975 if (starts_with(ss
->name
, ".security_initcall.init"))
1976 return SS_TYPE_IGNORED
;
1977 if (starts_with(ss
->name
, ".con_initcall.init"))
1978 return SS_TYPE_IGNORED
;
1979 if (starts_with(ss
->name
, ".x86cpuvendor.init"))
1980 return SS_TYPE_IGNORED
;
1981 if (starts_with(ss
->name
, ".early_param.init"))
1982 return SS_TYPE_IGNORED
;
1983 if (starts_with(ss
->name
, ".taglist.init"))
1984 return SS_TYPE_IGNORED
;
1985 if (starts_with(ss
->name
, ".arch.info.init"))
1986 return SS_TYPE_IGNORED
;
1987 if (starts_with(ss
->name
, ".proc.info.init"))
1988 return SS_TYPE_IGNORED
;
1989 /* .pci_fixup_* sections really should be treated as global rodata
1990 referenced only from quirks.c */
1991 if (starts_with(ss
->name
, ".pci_fixup_"))
1992 return SS_TYPE_IGNORED
;
1993 /* .builtin_fw sections are similar to .pci_fixup */
1994 if (starts_with(ss
->name
, ".builtin_fw"))
1995 return SS_TYPE_IGNORED
;
1996 /* same for .tracedata */
1997 if (starts_with(ss
->name
, ".tracedata"))
1998 return SS_TYPE_IGNORED
;
1999 if (starts_with(ss
->name
, ".debug"))
2000 return SS_TYPE_IGNORED
;
2001 /* .eh_frame should probably be discarded, not ignored */
2002 if (starts_with(ss
->name
, ".eh_frame"))
2003 return SS_TYPE_IGNORED
;
2004 if (config
->ignore_devinit
&& starts_with(ss
->name
, ".devinit"))
2005 return SS_TYPE_IGNORED
;
2006 if (config
->ignore_meminit
&& starts_with(ss
->name
, ".meminit"))
2007 return SS_TYPE_IGNORED
;
2008 if (config
->ignore_cpuinit
&& starts_with(ss
->name
, ".cpuinit"))
2009 return SS_TYPE_IGNORED
;
2010 if (config
->ignore_devinit
&& starts_with(ss
->name
, ".devexit"))
2011 return SS_TYPE_IGNORED
;
2012 if (config
->ignore_meminit
&& starts_with(ss
->name
, ".memexit"))
2013 return SS_TYPE_IGNORED
;
2014 if (config
->ignore_cpuinit
&& starts_with(ss
->name
, ".cpuexit"))
2015 return SS_TYPE_IGNORED
;
2016 if (starts_with(ss
->name
, ".vgetcpu_mode") ||
2017 starts_with(ss
->name
, ".jiffies") ||
2018 starts_with(ss
->name
, ".wall_jiffies") ||
2019 starts_with(ss
->name
, ".vxtime") ||
2020 starts_with(ss
->name
, ".sys_tz") ||
2021 starts_with(ss
->name
, ".sysctl_vsyscall") ||
2022 starts_with(ss
->name
, ".xtime") ||
2023 starts_with(ss
->name
, ".xtime_lock") ||
2024 starts_with(ss
->name
, ".vsyscall"))
2025 return SS_TYPE_IGNORED
;
2026 if (starts_with(ss
->name
, ".vdso"))
2027 return SS_TYPE_IGNORED
;
2029 if (bfd_get_section_by_name(ss
->parent
->abfd
, ".exitcall.exit") == NULL
) {
2030 if (starts_with(ss
->name
, ".exit.text"))
2031 return SS_TYPE_TEXT
;
2032 if (starts_with(ss
->name
, ".exit.data"))
2033 return SS_TYPE_DATA
;
2034 } else if (starts_with(ss
->name
, ".exit.text") ||
2035 starts_with(ss
->name
, ".exit.data"))
2036 return SS_TYPE_IGNORED
;
2038 if (starts_with(ss
->name
, ".text") ||
2039 starts_with(ss
->name
, ".kernel.text") ||
2040 starts_with(ss
->name
, ".devinit.text") ||
2041 starts_with(ss
->name
, ".meminit.text") ||
2042 starts_with(ss
->name
, ".cpuinit.text") ||
2043 starts_with(ss
->name
, ".devexit.text") ||
2044 starts_with(ss
->name
, ".memexit.text") ||
2045 starts_with(ss
->name
, ".cpuexit.text") ||
2046 starts_with(ss
->name
, ".ref.text") ||
2047 starts_with(ss
->name
, ".spinlock.text") ||
2048 starts_with(ss
->name
, ".kprobes.text") ||
2049 starts_with(ss
->name
, ".sched.text"))
2050 return SS_TYPE_TEXT
;
2053 if (sscanf(ss
->name
, ".rodata.str%*u.%*u%n", &n
) >= 0 &&
2054 n
== strlen(ss
->name
))
2055 return SS_TYPE_STRING
;
2057 if (starts_with(ss
->name
, ".rodata") ||
2058 starts_with(ss
->name
, ".kernel.rodata") ||
2059 starts_with(ss
->name
, ".devinit.rodata") ||
2060 starts_with(ss
->name
, ".meminit.rodata") ||
2061 starts_with(ss
->name
, ".cpuinit.rodata") ||
2062 starts_with(ss
->name
, ".devexit.rodata") ||
2063 starts_with(ss
->name
, ".memexit.rodata") ||
2064 starts_with(ss
->name
, ".cpuexit.rodata") ||
2065 starts_with(ss
->name
, ".ref.rodata") ||
2066 starts_with(ss
->name
, "__markers_strings"))
2067 return SS_TYPE_RODATA
;
2069 if (starts_with(ss
->name
, ".bss"))
2070 return SS_TYPE_DATA
;
2072 /* Ignore .data.percpu sections */
2073 if (starts_with(ss
->name
, ".data.percpu") ||
2074 starts_with(ss
->name
, ".kernel.data.percpu"))
2075 return SS_TYPE_IGNORED
;
2076 if (starts_with(ss
->name
, ".data") ||
2077 starts_with(ss
->name
, ".kernel.data") ||
2078 starts_with(ss
->name
, ".devinit.data") ||
2079 starts_with(ss
->name
, ".cpuinit.data") ||
2080 starts_with(ss
->name
, ".meminit.data") ||
2081 starts_with(ss
->name
, ".devexit.data") ||
2082 starts_with(ss
->name
, ".memexit.data") ||
2083 starts_with(ss
->name
, ".cpuexit.data") ||
2084 starts_with(ss
->name
, ".ref.data") ||
2085 starts_with(ss
->name
, "__markers"))
2086 return SS_TYPE_DATA
;
2088 /* We replace all the ksymtab strings, so delete them */
2089 if (strcmp(ss
->name
, "__ksymtab_strings") == 0)
2090 return SS_TYPE_IGNORED
;
2091 if (starts_with(ss
->name
, "__ksymtab"))
2092 return SS_TYPE_EXPORT
;
2093 if (starts_with(ss
->name
, "__kcrctab"))
2094 return SS_TYPE_EXPORT
;
2096 if (is_table_section(ss
->name
, true))
2097 return SS_TYPE_SPECIAL
;
2099 if (starts_with(ss
->name
, ".ARM."))
2100 return SS_TYPE_SPECIAL
;
2102 if (starts_with(ss
->name
, ".note"))
2103 return SS_TYPE_IGNORED
;
2104 if (starts_with(ss
->name
, ".comment"))
2105 return SS_TYPE_IGNORED
;
2106 if (starts_with(ss
->name
, "__param"))
2107 return SS_TYPE_IGNORED
;
2108 if (starts_with(ss
->name
, ".exitcall.exit"))
2109 return SS_TYPE_IGNORED
;
2110 if (starts_with(ss
->name
, ".modinfo"))
2111 return SS_TYPE_IGNORED
;
2113 return SS_TYPE_UNKNOWN
;
2116 void initialize_supersect_types(struct superbfd
*sbfd
)
2119 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2120 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2121 ss
->type
= supersect_type(ss
);
2122 if (ss
->type
== SS_TYPE_UNKNOWN
) {
2123 err(sbfd
, "Unknown section type: %s\n", ss
->name
);
2129 static void init_label_map(struct superbfd
*sbfd
)
2131 struct label_map
*map
;
2133 vec_init(&sbfd
->maps
);
2137 struct symbol_hash csyms
;
2138 symbol_hash_init(&csyms
);
2141 for (symp
= sbfd
->syms
.data
;
2142 symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; symp
++) {
2143 asymbol
*csym
= canonical_symbol(sbfd
, *symp
);
2147 assert(asprintf(&key
, "%p", csym
) >= 0);
2148 asymbol
**csymp
= symbol_hash_lookup(&csyms
, key
, TRUE
);
2154 map
= vec_grow(&sbfd
->maps
, 1);
2157 map
->label
= symbol_label(sbfd
, csym
);
2160 struct label_mapp_hash label_maps
;
2161 label_mapp_hash_init(&label_maps
);
2162 for (map
= sbfd
->maps
.data
;
2163 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2164 struct label_map
**mapp
=
2165 label_mapp_hash_lookup(&label_maps
, map
->label
, TRUE
);
2166 if (*mapp
== NULL
) {
2171 struct label_map
*first_map
= *mapp
;
2173 if (first_map
->count
== 0) {
2174 assert(asprintf(&buf
, "%s~%d", map
->label
, 0) >= 0);
2175 first_map
->label
= buf
;
2178 assert(asprintf(&buf
, "%s~%d", map
->label
, first_map
->count
)
2183 label_mapp_hash_init(&sbfd
->maps_hash
);
2184 for (map
= sbfd
->maps
.data
;
2185 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2187 assert(asprintf(&key
, "%p", map
->csym
) >= 0);
2188 struct label_map
**mapp
=
2189 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, TRUE
);
2192 map
->orig_label
= map
->label
;
2196 static const char *label_lookup(struct superbfd
*sbfd
, asymbol
*sym
)
2198 asymbol
*csym
= canonical_symbol(sbfd
, sym
);
2200 assert(asprintf(&key
, "%p", csym
) >= 0);
2201 struct label_map
**mapp
=
2202 label_mapp_hash_lookup(&sbfd
->maps_hash
, key
, FALSE
);
2206 return (*mapp
)->label
;
2209 static void print_label_map(struct superbfd
*sbfd
)
2211 struct label_map
*map
;
2212 for (map
= sbfd
->maps
.data
;
2213 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2214 if (strcmp(map
->orig_label
, map
->label
) == 0)
2216 debug1(sbfd
, "Label change: %s -> %s\n",
2217 map
->label
, map
->orig_label
);
2221 static void label_map_set(struct superbfd
*sbfd
, const char *oldlabel
,
2224 struct label_map
*map
;
2225 for (map
= sbfd
->maps
.data
;
2226 map
< sbfd
->maps
.data
+ sbfd
->maps
.size
; map
++) {
2227 if (strcmp(map
->orig_label
, oldlabel
) == 0) {
2228 if (strcmp(map
->orig_label
, map
->label
) != 0 &&
2229 strcmp(map
->label
, label
) != 0)
2238 static void init_callers(struct superbfd
*sbfd
)
2240 string_hash_init(&sbfd
->callers
);
2242 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2243 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2245 for (relocp
= ss
->relocs
.data
;
2246 relocp
< ss
->relocs
.data
+ ss
->relocs
.size
; relocp
++) {
2247 asymbol
*sym
= *(*relocp
)->sym_ptr_ptr
;
2249 sym
->value
+ get_reloc_offset(ss
, *relocp
, true);
2251 assert(asprintf(&key
, "%s+%lx", sym
->section
->name
,
2253 const char **ret
= string_hash_lookup(&sbfd
->callers
,
2259 *ret
= "*multiple_callers*";
2264 static const char *find_caller(struct supersect
*ss
, asymbol
*sym
)
2267 assert(asprintf(&key
, "%s+%lx", sym
->section
->name
,
2268 (unsigned long)sym
->value
) >= 0);
2269 const char **ret
= string_hash_lookup(&ss
->parent
->callers
, key
, FALSE
);
2273 return "*no_caller*";
2277 static void init_csyms(struct superbfd
*sbfd
)
2279 asymbolpp_hash_init(&sbfd
->csyms
);
2282 for (symp
= sbfd
->syms
.data
; symp
< sbfd
->syms
.data
+ sbfd
->syms
.size
;
2284 asymbol
*sym
= *symp
;
2285 if ((sym
->flags
& BSF_DEBUGGING
) != 0)
2288 assert(asprintf(&key
, "%s+%lx", sym
->section
->name
,
2289 (unsigned long)sym
->value
) >= 0);
2290 asymbol
***csympp
= asymbolpp_hash_lookup(&sbfd
->csyms
, key
,
2293 if (*csympp
== NULL
) {
2297 asymbol
*csym
= **csympp
;
2298 if ((csym
->flags
& BSF_GLOBAL
) != 0)
2300 if ((sym
->flags
& BSF_GLOBAL
) != 0)
2305 static asymbol
**symbolp_scan(struct supersect
*ss
, bfd_vma value
)
2308 assert(asprintf(&key
, "%s+%lx", ss
->name
, (unsigned long)value
) >= 0);
2310 asymbolpp_hash_lookup(&ss
->parent
->csyms
, key
, FALSE
);
2315 /* For section symbols of sections containing no symbols, return the
2316 section symbol that relocations are generated against */
2322 static asymbol
**canonical_symbolp(struct superbfd
*sbfd
, asymbol
*sym
)
2324 if (bfd_is_const_section(sym
->section
)) {
2326 for (csymp
= sbfd
->syms
.data
;
2327 csymp
< sbfd
->syms
.data
+ sbfd
->syms
.size
; csymp
++) {
2333 return symbolp_scan(fetch_supersect(sbfd
, sym
->section
), sym
->value
);
2336 static asymbol
*canonical_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
2338 if (bfd_is_const_section(sym
->section
))
2340 asymbol
**symp
= canonical_symbolp(sbfd
, sym
);
2341 return symp
!= NULL
? *symp
: NULL
;
2344 static char *static_local_symbol(struct superbfd
*sbfd
, asymbol
*sym
)
2346 struct supersect
*ss
= fetch_supersect(sbfd
, sym
->section
);
2347 if ((sym
->flags
& BSF_LOCAL
) == 0 || (sym
->flags
& BSF_OBJECT
) == 0)
2349 char *dot
= strrchr(sym
->name
, '.');
2350 if (dot
== NULL
|| dot
[1 + strspn(dot
+ 1, "0123546789")] != '\0')
2352 char *basename
= strndup(sym
->name
, dot
- sym
->name
);
2354 if (strcmp(basename
, "__func__") == 0 ||
2355 strcmp(basename
, "__PRETTY_FUNCTION__") == 0)
2356 assert(asprintf(&mangled_name
, "%s<%s>", basename
,
2357 (char *)ss
->contents
.data
+ sym
->value
) >= 0);
2359 assert(asprintf(&mangled_name
, "%s<%s>", basename
,
2360 find_caller(ss
, sym
)) >= 0);
2361 return mangled_name
;
2364 static char *symbol_label(struct superbfd
*sbfd
, asymbol
*sym
)
2366 const char *filename
= sbfd
->abfd
->filename
;
2367 char *c
= strstr(filename
, ".KSPLICE");
2368 int flen
= (c
== NULL
? strlen(filename
) : c
- filename
);
2371 if (bfd_is_und_section(sym
->section
) || (sym
->flags
& BSF_GLOBAL
) != 0) {
2372 label
= strdup(sym
->name
);
2373 } else if (bfd_is_const_section(sym
->section
)) {
2374 assert(asprintf(&label
, "%s<%.*s>",
2375 sym
->name
, flen
, filename
) >= 0);
2377 asymbol
*gsym
= canonical_symbol(sbfd
, sym
);
2380 assert(asprintf(&label
, "%s+%lx<%.*s>",
2382 (unsigned long)sym
->value
,
2383 flen
, filename
) >= 0);
2384 else if ((gsym
->flags
& BSF_GLOBAL
) != 0)
2385 label
= strdup(gsym
->name
);
2386 else if (static_local_symbol(sbfd
, gsym
))
2387 assert(asprintf(&label
, "%s+%lx<%.*s>",
2388 static_local_symbol(sbfd
, gsym
),
2389 (unsigned long)sym
->value
,
2390 flen
, filename
) >= 0);
2392 assert(asprintf(&label
, "%s<%.*s>",
2393 gsym
->name
, flen
, filename
) >= 0);
2399 static struct span
*new_span(struct supersect
*ss
, bfd_vma start
, bfd_vma size
)
2401 struct span
*span
= vec_grow(&ss
->spans
, 1);
2403 span
->start
= start
;
2408 asymbol
**symp
= symbolp_scan(ss
, span
->start
);
2410 span
->symbol
= *symp
;
2411 span
->label
= label_lookup(ss
->parent
, span
->symbol
);
2413 span
->symbol
= NULL
;
2414 const char *label
= label_lookup(ss
->parent
, ss
->symbol
);
2415 if (span
->start
!= 0) {
2417 assert(asprintf(&buf
, "%s<span:%lx>", label
,
2418 (unsigned long)span
->start
) >= 0);
2421 span
->label
= label
;
2427 static void initialize_string_spans(struct supersect
*ss
)
2430 for (str
= ss
->contents
.data
;
2431 (void *)str
< ss
->contents
.data
+ ss
->contents
.size
;) {
2432 bfd_vma start
= (unsigned long)str
-
2433 (unsigned long)ss
->contents
.data
;
2434 bfd_vma size
= strlen(str
) + 1;
2435 while ((start
+ size
) % (1 << ss
->alignment
) != 0 &&
2436 start
+ size
< ss
->contents
.size
) {
2437 if (str
[size
] != '\0')
2441 new_span(ss
, start
, size
);
2446 static void initialize_spans(struct superbfd
*sbfd
)
2449 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2450 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2451 if (ss
->type
== SS_TYPE_STRING
)
2452 initialize_string_spans(ss
);
2453 else if (!mode("keep") || (ss
->type
!= SS_TYPE_SPECIAL
&&
2454 ss
->type
!= SS_TYPE_EXPORT
))
2455 new_span(ss
, 0, ss
->contents
.size
);
2459 struct span
*reloc_target_span(struct supersect
*ss
, arelent
*reloc
)
2461 asymbol
*sym_ptr
= *reloc
->sym_ptr_ptr
;
2462 if (bfd_is_const_section(sym_ptr
->section
))
2465 bfd_vma addend
= get_reloc_offset(ss
, reloc
, true) + sym_ptr
->value
;
2466 struct supersect
*sym_ss
=
2467 fetch_supersect(ss
->parent
, sym_ptr
->section
);
2468 struct span
*span
, *target_span
= sym_ss
->spans
.data
;
2469 for (span
= sym_ss
->spans
.data
;
2470 span
< sym_ss
->spans
.data
+ sym_ss
->spans
.size
; span
++) {
2471 if (addend
>= span
->start
&& addend
< span
->start
+ span
->size
)
2477 struct span
*reloc_address_span(struct supersect
*ss
, arelent
*reloc
)
2480 for (span
= ss
->spans
.data
; span
< ss
->spans
.data
+ ss
->spans
.size
;
2482 if (reloc
->address
>= span
->start
&&
2483 reloc
->address
< span
->start
+ span
->size
)
2489 void compute_span_shifts(struct superbfd
*sbfd
)
2493 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2494 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2497 bfd_size_type offset
= 0;
2498 for (span
= ss
->spans
.data
;
2499 span
< ss
->spans
.data
+ ss
->spans
.size
; span
++) {
2502 span
->shift
= offset
- span
->start
;
2503 offset
+= span
->size
;
2508 void remove_unkept_spans(struct superbfd
*sbfd
)
2512 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2513 struct supersect
*ss
= fetch_supersect(sbfd
, sect
);
2514 struct arelentp_vec orig_relocs
;
2515 vec_move(&orig_relocs
, &ss
->relocs
);
2516 arelent
**relocp
, *reloc
;
2517 for (relocp
= orig_relocs
.data
;
2518 relocp
< orig_relocs
.data
+ orig_relocs
.size
; relocp
++) {
2520 asymbol
*sym
= *reloc
->sym_ptr_ptr
;
2521 span
= reloc_target_span(ss
, reloc
);
2522 if ((span
!= NULL
&& span
->keep
&& span
->shift
== 0) ||
2523 bfd_is_const_section(sym
->section
)) {
2524 *vec_grow(&ss
->relocs
, 1) = reloc
;
2527 if (span
!= NULL
&& span
->keep
) {
2528 arelent
*new_reloc
= malloc(sizeof(*new_reloc
));
2529 *new_reloc
= *reloc
;
2531 get_reloc_offset(ss
, reloc
, false);
2532 new_reloc
->addend
+= span
->shift
;
2533 *vec_grow(&ss
->new_relocs
, 1) = new_reloc
;
2538 for (sect
= sbfd
->abfd
->sections
; sect
!= NULL
; sect
= sect
->next
) {
2539 struct supersect
*ss
= fetch_supersect(sbfd
, sect
), orig_ss
;
2542 supersect_move(&orig_ss
, ss
);
2543 vec_init(&ss
->spans
);
2544 for (span
= orig_ss
.spans
.data
;
2545 span
< orig_ss
.spans
.data
+ orig_ss
.spans
.size
; span
++) {
2548 struct span
*new_span
= vec_grow(&ss
->spans
, 1);
2550 new_span
->start
= span
->start
+ span
->shift
;
2551 new_span
->shift
= 0;
2552 sect_copy(ss
, sect_do_grow(ss
, 1, span
->size
, 1),
2553 &orig_ss
, orig_ss
.contents
.data
+ span
->start
,