]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - tools/objtool/elf.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * elf.c - ELF access library
5 * Adapted from kpatch (https://github.com/dynup/kpatch):
6 * Copyright (C) 2013-2015 Josh Poimboeuf <jpoimboe@redhat.com>
7 * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
10 #include <sys/types.h>
23 #define MAX_NAME_LEN 128
25 static inline u32
str_hash(const char *str
)
27 return jhash(str
, strlen(str
), 0);
30 static inline int elf_hash_bits(void)
32 return vmlinux
? ELF_HASH_BITS
: 16;
35 #define elf_hash_add(hashtable, node, key) \
36 hlist_add_head(node, &hashtable[hash_min(key, elf_hash_bits())])
38 static void elf_hash_init(struct hlist_head
*table
)
40 __hash_init(table
, 1U << elf_hash_bits());
43 #define elf_hash_for_each_possible(name, obj, member, key) \
44 hlist_for_each_entry(obj, &name[hash_min(key, elf_hash_bits())], member)
46 static void rb_add(struct rb_root
*tree
, struct rb_node
*node
,
47 int (*cmp
)(struct rb_node
*, const struct rb_node
*))
49 struct rb_node
**link
= &tree
->rb_node
;
50 struct rb_node
*parent
= NULL
;
54 if (cmp(node
, parent
) < 0)
55 link
= &parent
->rb_left
;
57 link
= &parent
->rb_right
;
60 rb_link_node(node
, parent
, link
);
61 rb_insert_color(node
, tree
);
64 static struct rb_node
*rb_find_first(const struct rb_root
*tree
, const void *key
,
65 int (*cmp
)(const void *key
, const struct rb_node
*))
67 struct rb_node
*node
= tree
->rb_node
;
68 struct rb_node
*match
= NULL
;
71 int c
= cmp(key
, node
);
77 node
= node
->rb_right
;
84 static struct rb_node
*rb_next_match(struct rb_node
*node
, const void *key
,
85 int (*cmp
)(const void *key
, const struct rb_node
*))
88 if (node
&& cmp(key
, node
))
93 #define rb_for_each(tree, node, key, cmp) \
94 for ((node) = rb_find_first((tree), (key), (cmp)); \
95 (node); (node) = rb_next_match((node), (key), (cmp)))
97 static int symbol_to_offset(struct rb_node
*a
, const struct rb_node
*b
)
99 struct symbol
*sa
= rb_entry(a
, struct symbol
, node
);
100 struct symbol
*sb
= rb_entry(b
, struct symbol
, node
);
102 if (sa
->offset
< sb
->offset
)
104 if (sa
->offset
> sb
->offset
)
107 if (sa
->len
< sb
->len
)
109 if (sa
->len
> sb
->len
)
117 static int symbol_by_offset(const void *key
, const struct rb_node
*node
)
119 const struct symbol
*s
= rb_entry(node
, struct symbol
, node
);
120 const unsigned long *o
= key
;
124 if (*o
>= s
->offset
+ s
->len
)
130 struct section
*find_section_by_name(const struct elf
*elf
, const char *name
)
134 elf_hash_for_each_possible(elf
->section_name_hash
, sec
, name_hash
, str_hash(name
))
135 if (!strcmp(sec
->name
, name
))
141 static struct section
*find_section_by_index(struct elf
*elf
,
146 elf_hash_for_each_possible(elf
->section_hash
, sec
, hash
, idx
)
153 static struct symbol
*find_symbol_by_index(struct elf
*elf
, unsigned int idx
)
157 elf_hash_for_each_possible(elf
->symbol_hash
, sym
, hash
, idx
)
164 struct symbol
*find_symbol_by_offset(struct section
*sec
, unsigned long offset
)
166 struct rb_node
*node
;
168 rb_for_each(&sec
->symbol_tree
, node
, &offset
, symbol_by_offset
) {
169 struct symbol
*s
= rb_entry(node
, struct symbol
, node
);
171 if (s
->offset
== offset
&& s
->type
!= STT_SECTION
)
178 struct symbol
*find_func_by_offset(struct section
*sec
, unsigned long offset
)
180 struct rb_node
*node
;
182 rb_for_each(&sec
->symbol_tree
, node
, &offset
, symbol_by_offset
) {
183 struct symbol
*s
= rb_entry(node
, struct symbol
, node
);
185 if (s
->offset
== offset
&& s
->type
== STT_FUNC
)
192 struct symbol
*find_symbol_containing(const struct section
*sec
, unsigned long offset
)
194 struct rb_node
*node
;
196 rb_for_each(&sec
->symbol_tree
, node
, &offset
, symbol_by_offset
) {
197 struct symbol
*s
= rb_entry(node
, struct symbol
, node
);
199 if (s
->type
!= STT_SECTION
)
206 struct symbol
*find_func_containing(struct section
*sec
, unsigned long offset
)
208 struct rb_node
*node
;
210 rb_for_each(&sec
->symbol_tree
, node
, &offset
, symbol_by_offset
) {
211 struct symbol
*s
= rb_entry(node
, struct symbol
, node
);
213 if (s
->type
== STT_FUNC
)
220 struct symbol
*find_symbol_by_name(const struct elf
*elf
, const char *name
)
224 elf_hash_for_each_possible(elf
->symbol_name_hash
, sym
, name_hash
, str_hash(name
))
225 if (!strcmp(sym
->name
, name
))
231 struct reloc
*find_reloc_by_dest_range(const struct elf
*elf
, struct section
*sec
,
232 unsigned long offset
, unsigned int len
)
234 struct reloc
*reloc
, *r
= NULL
;
242 for_offset_range(o
, offset
, offset
+ len
) {
243 elf_hash_for_each_possible(elf
->reloc_hash
, reloc
, hash
,
244 sec_offset_hash(sec
, o
)) {
245 if (reloc
->sec
!= sec
)
248 if (reloc
->offset
>= offset
&& reloc
->offset
< offset
+ len
) {
249 if (!r
|| reloc
->offset
< r
->offset
)
260 struct reloc
*find_reloc_by_dest(const struct elf
*elf
, struct section
*sec
, unsigned long offset
)
262 return find_reloc_by_dest_range(elf
, sec
, offset
, 1);
265 void insn_to_reloc_sym_addend(struct section
*sec
, unsigned long offset
,
269 reloc
->sym
= sec
->sym
;
270 reloc
->addend
= offset
;
275 * The Clang assembler strips section symbols, so we have to reference
276 * the function symbol instead:
278 reloc
->sym
= find_symbol_containing(sec
, offset
);
281 * Hack alert. This happens when we need to reference the NOP
282 * pad insn immediately after the function.
284 reloc
->sym
= find_symbol_containing(sec
, offset
- 1);
288 reloc
->addend
= offset
- reloc
->sym
->offset
;
291 static int read_sections(struct elf
*elf
)
295 size_t shstrndx
, sections_nr
;
298 if (elf_getshdrnum(elf
->elf
, §ions_nr
)) {
299 WARN_ELF("elf_getshdrnum");
303 if (elf_getshdrstrndx(elf
->elf
, &shstrndx
)) {
304 WARN_ELF("elf_getshdrstrndx");
308 for (i
= 0; i
< sections_nr
; i
++) {
309 sec
= malloc(sizeof(*sec
));
314 memset(sec
, 0, sizeof(*sec
));
316 INIT_LIST_HEAD(&sec
->symbol_list
);
317 INIT_LIST_HEAD(&sec
->reloc_list
);
319 s
= elf_getscn(elf
->elf
, i
);
321 WARN_ELF("elf_getscn");
325 sec
->idx
= elf_ndxscn(s
);
327 if (!gelf_getshdr(s
, &sec
->sh
)) {
328 WARN_ELF("gelf_getshdr");
332 sec
->name
= elf_strptr(elf
->elf
, shstrndx
, sec
->sh
.sh_name
);
334 WARN_ELF("elf_strptr");
338 if (sec
->sh
.sh_size
!= 0) {
339 sec
->data
= elf_getdata(s
, NULL
);
341 WARN_ELF("elf_getdata");
344 if (sec
->data
->d_off
!= 0 ||
345 sec
->data
->d_size
!= sec
->sh
.sh_size
) {
346 WARN("unexpected data attributes for %s",
351 sec
->len
= sec
->sh
.sh_size
;
353 list_add_tail(&sec
->list
, &elf
->sections
);
354 elf_hash_add(elf
->section_hash
, &sec
->hash
, sec
->idx
);
355 elf_hash_add(elf
->section_name_hash
, &sec
->name_hash
, str_hash(sec
->name
));
359 printf("nr_sections: %lu\n", (unsigned long)sections_nr
);
361 /* sanity check, one more call to elf_nextscn() should return NULL */
362 if (elf_nextscn(elf
->elf
, s
)) {
363 WARN("section entry mismatch");
370 static int read_symbols(struct elf
*elf
)
372 struct section
*symtab
, *symtab_shndx
, *sec
;
373 struct symbol
*sym
, *pfunc
;
374 struct list_head
*entry
;
375 struct rb_node
*pnode
;
378 Elf_Data
*shndx_data
= NULL
;
381 symtab
= find_section_by_name(elf
, ".symtab");
383 WARN("missing symbol table");
387 symtab_shndx
= find_section_by_name(elf
, ".symtab_shndx");
389 shndx_data
= symtab_shndx
->data
;
391 symbols_nr
= symtab
->sh
.sh_size
/ symtab
->sh
.sh_entsize
;
393 for (i
= 0; i
< symbols_nr
; i
++) {
394 sym
= malloc(sizeof(*sym
));
399 memset(sym
, 0, sizeof(*sym
));
404 if (!gelf_getsymshndx(symtab
->data
, shndx_data
, i
, &sym
->sym
,
406 WARN_ELF("gelf_getsymshndx");
410 sym
->name
= elf_strptr(elf
->elf
, symtab
->sh
.sh_link
,
413 WARN_ELF("elf_strptr");
417 sym
->type
= GELF_ST_TYPE(sym
->sym
.st_info
);
418 sym
->bind
= GELF_ST_BIND(sym
->sym
.st_info
);
420 if ((sym
->sym
.st_shndx
> SHN_UNDEF
&&
421 sym
->sym
.st_shndx
< SHN_LORESERVE
) ||
422 (shndx_data
&& sym
->sym
.st_shndx
== SHN_XINDEX
)) {
423 if (sym
->sym
.st_shndx
!= SHN_XINDEX
)
424 shndx
= sym
->sym
.st_shndx
;
426 sym
->sec
= find_section_by_index(elf
, shndx
);
428 WARN("couldn't find section for symbol %s",
432 if (sym
->type
== STT_SECTION
) {
433 sym
->name
= sym
->sec
->name
;
437 sym
->sec
= find_section_by_index(elf
, 0);
439 sym
->offset
= sym
->sym
.st_value
;
440 sym
->len
= sym
->sym
.st_size
;
442 rb_add(&sym
->sec
->symbol_tree
, &sym
->node
, symbol_to_offset
);
443 pnode
= rb_prev(&sym
->node
);
445 entry
= &rb_entry(pnode
, struct symbol
, node
)->list
;
447 entry
= &sym
->sec
->symbol_list
;
448 list_add(&sym
->list
, entry
);
449 elf_hash_add(elf
->symbol_hash
, &sym
->hash
, sym
->idx
);
450 elf_hash_add(elf
->symbol_name_hash
, &sym
->name_hash
, str_hash(sym
->name
));
453 * Don't store empty STT_NOTYPE symbols in the rbtree. They
454 * can exist within a function, confusing the sorting.
457 rb_erase(&sym
->node
, &sym
->sec
->symbol_tree
);
461 printf("nr_symbols: %lu\n", (unsigned long)symbols_nr
);
463 /* Create parent/child links for any cold subfunctions */
464 list_for_each_entry(sec
, &elf
->sections
, list
) {
465 list_for_each_entry(sym
, &sec
->symbol_list
, list
) {
466 char pname
[MAX_NAME_LEN
+ 1];
468 if (sym
->type
!= STT_FUNC
)
471 if (sym
->pfunc
== NULL
)
474 if (sym
->cfunc
== NULL
)
477 coldstr
= strstr(sym
->name
, ".cold");
481 pnamelen
= coldstr
- sym
->name
;
482 if (pnamelen
> MAX_NAME_LEN
) {
483 WARN("%s(): parent function name exceeds maximum length of %d characters",
484 sym
->name
, MAX_NAME_LEN
);
488 strncpy(pname
, sym
->name
, pnamelen
);
489 pname
[pnamelen
] = '\0';
490 pfunc
= find_symbol_by_name(elf
, pname
);
493 WARN("%s(): can't find parent function",
502 * Unfortunately, -fnoreorder-functions puts the child
503 * inside the parent. Remove the overlap so we can
504 * have sane assumptions.
506 * Note that pfunc->len now no longer matches
507 * pfunc->sym.st_size.
509 if (sym
->sec
== pfunc
->sec
&&
510 sym
->offset
>= pfunc
->offset
&&
511 sym
->offset
+ sym
->len
== pfunc
->offset
+ pfunc
->len
) {
512 pfunc
->len
-= sym
->len
;
524 void elf_add_reloc(struct elf
*elf
, struct reloc
*reloc
)
526 struct section
*sec
= reloc
->sec
;
528 list_add_tail(&reloc
->list
, &sec
->reloc_list
);
529 elf_hash_add(elf
->reloc_hash
, &reloc
->hash
, reloc_hash(reloc
));
532 static int read_rel_reloc(struct section
*sec
, int i
, struct reloc
*reloc
, unsigned int *symndx
)
534 if (!gelf_getrel(sec
->data
, i
, &reloc
->rel
)) {
535 WARN_ELF("gelf_getrel");
538 reloc
->type
= GELF_R_TYPE(reloc
->rel
.r_info
);
540 reloc
->offset
= reloc
->rel
.r_offset
;
541 *symndx
= GELF_R_SYM(reloc
->rel
.r_info
);
545 static int read_rela_reloc(struct section
*sec
, int i
, struct reloc
*reloc
, unsigned int *symndx
)
547 if (!gelf_getrela(sec
->data
, i
, &reloc
->rela
)) {
548 WARN_ELF("gelf_getrela");
551 reloc
->type
= GELF_R_TYPE(reloc
->rela
.r_info
);
552 reloc
->addend
= reloc
->rela
.r_addend
;
553 reloc
->offset
= reloc
->rela
.r_offset
;
554 *symndx
= GELF_R_SYM(reloc
->rela
.r_info
);
558 static int read_relocs(struct elf
*elf
)
564 unsigned long nr_reloc
, max_reloc
= 0, tot_reloc
= 0;
566 list_for_each_entry(sec
, &elf
->sections
, list
) {
567 if ((sec
->sh
.sh_type
!= SHT_RELA
) &&
568 (sec
->sh
.sh_type
!= SHT_REL
))
571 sec
->base
= find_section_by_index(elf
, sec
->sh
.sh_info
);
573 WARN("can't find base section for reloc section %s",
578 sec
->base
->reloc
= sec
;
581 for (i
= 0; i
< sec
->sh
.sh_size
/ sec
->sh
.sh_entsize
; i
++) {
582 reloc
= malloc(sizeof(*reloc
));
587 memset(reloc
, 0, sizeof(*reloc
));
588 switch (sec
->sh
.sh_type
) {
590 if (read_rel_reloc(sec
, i
, reloc
, &symndx
))
594 if (read_rela_reloc(sec
, i
, reloc
, &symndx
))
602 reloc
->sym
= find_symbol_by_index(elf
, symndx
);
604 WARN("can't find reloc entry symbol %d for %s",
609 elf_add_reloc(elf
, reloc
);
612 max_reloc
= max(max_reloc
, nr_reloc
);
613 tot_reloc
+= nr_reloc
;
617 printf("max_reloc: %lu\n", max_reloc
);
618 printf("tot_reloc: %lu\n", tot_reloc
);
624 struct elf
*elf_open_read(const char *name
, int flags
)
629 elf_version(EV_CURRENT
);
631 elf
= malloc(sizeof(*elf
));
636 memset(elf
, 0, offsetof(struct elf
, sections
));
638 INIT_LIST_HEAD(&elf
->sections
);
640 elf_hash_init(elf
->symbol_hash
);
641 elf_hash_init(elf
->symbol_name_hash
);
642 elf_hash_init(elf
->section_hash
);
643 elf_hash_init(elf
->section_name_hash
);
644 elf_hash_init(elf
->reloc_hash
);
646 elf
->fd
= open(name
, flags
);
648 fprintf(stderr
, "objtool: Can't open '%s': %s\n",
649 name
, strerror(errno
));
653 if ((flags
& O_ACCMODE
) == O_RDONLY
)
654 cmd
= ELF_C_READ_MMAP
;
655 else if ((flags
& O_ACCMODE
) == O_RDWR
)
660 elf
->elf
= elf_begin(elf
->fd
, cmd
, NULL
);
662 WARN_ELF("elf_begin");
666 if (!gelf_getehdr(elf
->elf
, &elf
->ehdr
)) {
667 WARN_ELF("gelf_getehdr");
671 if (read_sections(elf
))
674 if (read_symbols(elf
))
677 if (read_relocs(elf
))
687 struct section
*elf_create_section(struct elf
*elf
, const char *name
,
688 unsigned int sh_flags
, size_t entsize
, int nr
)
690 struct section
*sec
, *shstrtab
;
691 size_t size
= entsize
* nr
;
695 sec
= malloc(sizeof(*sec
));
700 memset(sec
, 0, sizeof(*sec
));
702 INIT_LIST_HEAD(&sec
->symbol_list
);
703 INIT_LIST_HEAD(&sec
->reloc_list
);
705 s
= elf_newscn(elf
->elf
);
707 WARN_ELF("elf_newscn");
711 sec
->name
= strdup(name
);
717 sec
->idx
= elf_ndxscn(s
);
721 sec
->data
= elf_newdata(s
);
723 WARN_ELF("elf_newdata");
727 sec
->data
->d_size
= size
;
728 sec
->data
->d_align
= 1;
731 sec
->data
->d_buf
= malloc(size
);
732 if (!sec
->data
->d_buf
) {
736 memset(sec
->data
->d_buf
, 0, size
);
739 if (!gelf_getshdr(s
, &sec
->sh
)) {
740 WARN_ELF("gelf_getshdr");
744 sec
->sh
.sh_size
= size
;
745 sec
->sh
.sh_entsize
= entsize
;
746 sec
->sh
.sh_type
= SHT_PROGBITS
;
747 sec
->sh
.sh_addralign
= 1;
748 sec
->sh
.sh_flags
= SHF_ALLOC
| sh_flags
;
751 /* Add section name to .shstrtab (or .strtab for Clang) */
752 shstrtab
= find_section_by_name(elf
, ".shstrtab");
754 shstrtab
= find_section_by_name(elf
, ".strtab");
756 WARN("can't find .shstrtab or .strtab section");
760 s
= elf_getscn(elf
->elf
, shstrtab
->idx
);
762 WARN_ELF("elf_getscn");
766 data
= elf_newdata(s
);
768 WARN_ELF("elf_newdata");
772 data
->d_buf
= sec
->name
;
773 data
->d_size
= strlen(name
) + 1;
776 sec
->sh
.sh_name
= shstrtab
->len
;
778 shstrtab
->len
+= strlen(name
) + 1;
779 shstrtab
->changed
= true;
781 list_add_tail(&sec
->list
, &elf
->sections
);
782 elf_hash_add(elf
->section_hash
, &sec
->hash
, sec
->idx
);
783 elf_hash_add(elf
->section_name_hash
, &sec
->name_hash
, str_hash(sec
->name
));
790 static struct section
*elf_create_rel_reloc_section(struct elf
*elf
, struct section
*base
)
795 relocname
= malloc(strlen(base
->name
) + strlen(".rel") + 1);
800 strcpy(relocname
, ".rel");
801 strcat(relocname
, base
->name
);
803 sec
= elf_create_section(elf
, relocname
, 0, sizeof(GElf_Rel
), 0);
811 sec
->sh
.sh_type
= SHT_REL
;
812 sec
->sh
.sh_addralign
= 8;
813 sec
->sh
.sh_link
= find_section_by_name(elf
, ".symtab")->idx
;
814 sec
->sh
.sh_info
= base
->idx
;
815 sec
->sh
.sh_flags
= SHF_INFO_LINK
;
820 static struct section
*elf_create_rela_reloc_section(struct elf
*elf
, struct section
*base
)
825 relocname
= malloc(strlen(base
->name
) + strlen(".rela") + 1);
830 strcpy(relocname
, ".rela");
831 strcat(relocname
, base
->name
);
833 sec
= elf_create_section(elf
, relocname
, 0, sizeof(GElf_Rela
), 0);
841 sec
->sh
.sh_type
= SHT_RELA
;
842 sec
->sh
.sh_addralign
= 8;
843 sec
->sh
.sh_link
= find_section_by_name(elf
, ".symtab")->idx
;
844 sec
->sh
.sh_info
= base
->idx
;
845 sec
->sh
.sh_flags
= SHF_INFO_LINK
;
850 struct section
*elf_create_reloc_section(struct elf
*elf
,
851 struct section
*base
,
855 case SHT_REL
: return elf_create_rel_reloc_section(elf
, base
);
856 case SHT_RELA
: return elf_create_rela_reloc_section(elf
, base
);
857 default: return NULL
;
861 static int elf_rebuild_rel_reloc_section(struct section
*sec
, int nr
)
867 /* Allocate a buffer for relocations */
868 size
= nr
* sizeof(*relocs
);
869 relocs
= malloc(size
);
875 sec
->data
->d_buf
= relocs
;
876 sec
->data
->d_size
= size
;
878 sec
->sh
.sh_size
= size
;
881 list_for_each_entry(reloc
, &sec
->reloc_list
, list
) {
882 relocs
[idx
].r_offset
= reloc
->offset
;
883 relocs
[idx
].r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
890 static int elf_rebuild_rela_reloc_section(struct section
*sec
, int nr
)
896 /* Allocate a buffer for relocations with addends */
897 size
= nr
* sizeof(*relocs
);
898 relocs
= malloc(size
);
904 sec
->data
->d_buf
= relocs
;
905 sec
->data
->d_size
= size
;
907 sec
->sh
.sh_size
= size
;
910 list_for_each_entry(reloc
, &sec
->reloc_list
, list
) {
911 relocs
[idx
].r_offset
= reloc
->offset
;
912 relocs
[idx
].r_addend
= reloc
->addend
;
913 relocs
[idx
].r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
920 int elf_rebuild_reloc_section(struct elf
*elf
, struct section
*sec
)
929 list_for_each_entry(reloc
, &sec
->reloc_list
, list
)
932 switch (sec
->sh
.sh_type
) {
933 case SHT_REL
: return elf_rebuild_rel_reloc_section(sec
, nr
);
934 case SHT_RELA
: return elf_rebuild_rela_reloc_section(sec
, nr
);
939 int elf_write_insn(struct elf
*elf
, struct section
*sec
,
940 unsigned long offset
, unsigned int len
,
943 Elf_Data
*data
= sec
->data
;
945 if (data
->d_type
!= ELF_T_BYTE
|| data
->d_off
) {
946 WARN("write to unexpected data for section: %s", sec
->name
);
950 memcpy(data
->d_buf
+ offset
, insn
, len
);
951 elf_flagdata(data
, ELF_C_SET
, ELF_F_DIRTY
);
958 int elf_write_reloc(struct elf
*elf
, struct reloc
*reloc
)
960 struct section
*sec
= reloc
->sec
;
962 if (sec
->sh
.sh_type
== SHT_REL
) {
963 reloc
->rel
.r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
964 reloc
->rel
.r_offset
= reloc
->offset
;
966 if (!gelf_update_rel(sec
->data
, reloc
->idx
, &reloc
->rel
)) {
967 WARN_ELF("gelf_update_rel");
971 reloc
->rela
.r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
972 reloc
->rela
.r_addend
= reloc
->addend
;
973 reloc
->rela
.r_offset
= reloc
->offset
;
975 if (!gelf_update_rela(sec
->data
, reloc
->idx
, &reloc
->rela
)) {
976 WARN_ELF("gelf_update_rela");
986 int elf_write(struct elf
*elf
)
991 /* Update section headers for changed sections: */
992 list_for_each_entry(sec
, &elf
->sections
, list
) {
994 s
= elf_getscn(elf
->elf
, sec
->idx
);
996 WARN_ELF("elf_getscn");
999 if (!gelf_update_shdr(s
, &sec
->sh
)) {
1000 WARN_ELF("gelf_update_shdr");
1004 sec
->changed
= false;
1008 /* Make sure the new section header entries get updated properly. */
1009 elf_flagelf(elf
->elf
, ELF_C_SET
, ELF_F_DIRTY
);
1011 /* Write all changes to the file. */
1012 if (elf_update(elf
->elf
, ELF_C_WRITE
) < 0) {
1013 WARN_ELF("elf_update");
1017 elf
->changed
= false;
1022 void elf_close(struct elf
*elf
)
1024 struct section
*sec
, *tmpsec
;
1025 struct symbol
*sym
, *tmpsym
;
1026 struct reloc
*reloc
, *tmpreloc
;
1034 list_for_each_entry_safe(sec
, tmpsec
, &elf
->sections
, list
) {
1035 list_for_each_entry_safe(sym
, tmpsym
, &sec
->symbol_list
, list
) {
1036 list_del(&sym
->list
);
1037 hash_del(&sym
->hash
);
1040 list_for_each_entry_safe(reloc
, tmpreloc
, &sec
->reloc_list
, list
) {
1041 list_del(&reloc
->list
);
1042 hash_del(&reloc
->hash
);
1045 list_del(&sec
->list
);