]>
git.proxmox.com Git - mirror_ubuntu-hirsute-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");
384 * A missing symbol table is actually possible if it's an empty
385 * .o file. This can happen for thunk_64.o.
390 symtab_shndx
= find_section_by_name(elf
, ".symtab_shndx");
392 shndx_data
= symtab_shndx
->data
;
394 symbols_nr
= symtab
->sh
.sh_size
/ symtab
->sh
.sh_entsize
;
396 for (i
= 0; i
< symbols_nr
; i
++) {
397 sym
= malloc(sizeof(*sym
));
402 memset(sym
, 0, sizeof(*sym
));
407 if (!gelf_getsymshndx(symtab
->data
, shndx_data
, i
, &sym
->sym
,
409 WARN_ELF("gelf_getsymshndx");
413 sym
->name
= elf_strptr(elf
->elf
, symtab
->sh
.sh_link
,
416 WARN_ELF("elf_strptr");
420 sym
->type
= GELF_ST_TYPE(sym
->sym
.st_info
);
421 sym
->bind
= GELF_ST_BIND(sym
->sym
.st_info
);
423 if ((sym
->sym
.st_shndx
> SHN_UNDEF
&&
424 sym
->sym
.st_shndx
< SHN_LORESERVE
) ||
425 (shndx_data
&& sym
->sym
.st_shndx
== SHN_XINDEX
)) {
426 if (sym
->sym
.st_shndx
!= SHN_XINDEX
)
427 shndx
= sym
->sym
.st_shndx
;
429 sym
->sec
= find_section_by_index(elf
, shndx
);
431 WARN("couldn't find section for symbol %s",
435 if (sym
->type
== STT_SECTION
) {
436 sym
->name
= sym
->sec
->name
;
440 sym
->sec
= find_section_by_index(elf
, 0);
442 sym
->offset
= sym
->sym
.st_value
;
443 sym
->len
= sym
->sym
.st_size
;
445 rb_add(&sym
->sec
->symbol_tree
, &sym
->node
, symbol_to_offset
);
446 pnode
= rb_prev(&sym
->node
);
448 entry
= &rb_entry(pnode
, struct symbol
, node
)->list
;
450 entry
= &sym
->sec
->symbol_list
;
451 list_add(&sym
->list
, entry
);
452 elf_hash_add(elf
->symbol_hash
, &sym
->hash
, sym
->idx
);
453 elf_hash_add(elf
->symbol_name_hash
, &sym
->name_hash
, str_hash(sym
->name
));
456 * Don't store empty STT_NOTYPE symbols in the rbtree. They
457 * can exist within a function, confusing the sorting.
460 rb_erase(&sym
->node
, &sym
->sec
->symbol_tree
);
464 printf("nr_symbols: %lu\n", (unsigned long)symbols_nr
);
466 /* Create parent/child links for any cold subfunctions */
467 list_for_each_entry(sec
, &elf
->sections
, list
) {
468 list_for_each_entry(sym
, &sec
->symbol_list
, list
) {
469 char pname
[MAX_NAME_LEN
+ 1];
471 if (sym
->type
!= STT_FUNC
)
474 if (sym
->pfunc
== NULL
)
477 if (sym
->cfunc
== NULL
)
480 coldstr
= strstr(sym
->name
, ".cold");
484 pnamelen
= coldstr
- sym
->name
;
485 if (pnamelen
> MAX_NAME_LEN
) {
486 WARN("%s(): parent function name exceeds maximum length of %d characters",
487 sym
->name
, MAX_NAME_LEN
);
491 strncpy(pname
, sym
->name
, pnamelen
);
492 pname
[pnamelen
] = '\0';
493 pfunc
= find_symbol_by_name(elf
, pname
);
496 WARN("%s(): can't find parent function",
505 * Unfortunately, -fnoreorder-functions puts the child
506 * inside the parent. Remove the overlap so we can
507 * have sane assumptions.
509 * Note that pfunc->len now no longer matches
510 * pfunc->sym.st_size.
512 if (sym
->sec
== pfunc
->sec
&&
513 sym
->offset
>= pfunc
->offset
&&
514 sym
->offset
+ sym
->len
== pfunc
->offset
+ pfunc
->len
) {
515 pfunc
->len
-= sym
->len
;
527 void elf_add_reloc(struct elf
*elf
, struct reloc
*reloc
)
529 struct section
*sec
= reloc
->sec
;
531 list_add_tail(&reloc
->list
, &sec
->reloc_list
);
532 elf_hash_add(elf
->reloc_hash
, &reloc
->hash
, reloc_hash(reloc
));
535 static int read_rel_reloc(struct section
*sec
, int i
, struct reloc
*reloc
, unsigned int *symndx
)
537 if (!gelf_getrel(sec
->data
, i
, &reloc
->rel
)) {
538 WARN_ELF("gelf_getrel");
541 reloc
->type
= GELF_R_TYPE(reloc
->rel
.r_info
);
543 reloc
->offset
= reloc
->rel
.r_offset
;
544 *symndx
= GELF_R_SYM(reloc
->rel
.r_info
);
548 static int read_rela_reloc(struct section
*sec
, int i
, struct reloc
*reloc
, unsigned int *symndx
)
550 if (!gelf_getrela(sec
->data
, i
, &reloc
->rela
)) {
551 WARN_ELF("gelf_getrela");
554 reloc
->type
= GELF_R_TYPE(reloc
->rela
.r_info
);
555 reloc
->addend
= reloc
->rela
.r_addend
;
556 reloc
->offset
= reloc
->rela
.r_offset
;
557 *symndx
= GELF_R_SYM(reloc
->rela
.r_info
);
561 static int read_relocs(struct elf
*elf
)
567 unsigned long nr_reloc
, max_reloc
= 0, tot_reloc
= 0;
569 list_for_each_entry(sec
, &elf
->sections
, list
) {
570 if ((sec
->sh
.sh_type
!= SHT_RELA
) &&
571 (sec
->sh
.sh_type
!= SHT_REL
))
574 sec
->base
= find_section_by_index(elf
, sec
->sh
.sh_info
);
576 WARN("can't find base section for reloc section %s",
581 sec
->base
->reloc
= sec
;
584 for (i
= 0; i
< sec
->sh
.sh_size
/ sec
->sh
.sh_entsize
; i
++) {
585 reloc
= malloc(sizeof(*reloc
));
590 memset(reloc
, 0, sizeof(*reloc
));
591 switch (sec
->sh
.sh_type
) {
593 if (read_rel_reloc(sec
, i
, reloc
, &symndx
))
597 if (read_rela_reloc(sec
, i
, reloc
, &symndx
))
605 reloc
->sym
= find_symbol_by_index(elf
, symndx
);
607 WARN("can't find reloc entry symbol %d for %s",
612 elf_add_reloc(elf
, reloc
);
615 max_reloc
= max(max_reloc
, nr_reloc
);
616 tot_reloc
+= nr_reloc
;
620 printf("max_reloc: %lu\n", max_reloc
);
621 printf("tot_reloc: %lu\n", tot_reloc
);
627 struct elf
*elf_open_read(const char *name
, int flags
)
632 elf_version(EV_CURRENT
);
634 elf
= malloc(sizeof(*elf
));
639 memset(elf
, 0, offsetof(struct elf
, sections
));
641 INIT_LIST_HEAD(&elf
->sections
);
643 elf_hash_init(elf
->symbol_hash
);
644 elf_hash_init(elf
->symbol_name_hash
);
645 elf_hash_init(elf
->section_hash
);
646 elf_hash_init(elf
->section_name_hash
);
647 elf_hash_init(elf
->reloc_hash
);
649 elf
->fd
= open(name
, flags
);
651 fprintf(stderr
, "objtool: Can't open '%s': %s\n",
652 name
, strerror(errno
));
656 if ((flags
& O_ACCMODE
) == O_RDONLY
)
657 cmd
= ELF_C_READ_MMAP
;
658 else if ((flags
& O_ACCMODE
) == O_RDWR
)
663 elf
->elf
= elf_begin(elf
->fd
, cmd
, NULL
);
665 WARN_ELF("elf_begin");
669 if (!gelf_getehdr(elf
->elf
, &elf
->ehdr
)) {
670 WARN_ELF("gelf_getehdr");
674 if (read_sections(elf
))
677 if (read_symbols(elf
))
680 if (read_relocs(elf
))
690 struct section
*elf_create_section(struct elf
*elf
, const char *name
,
691 unsigned int sh_flags
, size_t entsize
, int nr
)
693 struct section
*sec
, *shstrtab
;
694 size_t size
= entsize
* nr
;
698 sec
= malloc(sizeof(*sec
));
703 memset(sec
, 0, sizeof(*sec
));
705 INIT_LIST_HEAD(&sec
->symbol_list
);
706 INIT_LIST_HEAD(&sec
->reloc_list
);
708 s
= elf_newscn(elf
->elf
);
710 WARN_ELF("elf_newscn");
714 sec
->name
= strdup(name
);
720 sec
->idx
= elf_ndxscn(s
);
724 sec
->data
= elf_newdata(s
);
726 WARN_ELF("elf_newdata");
730 sec
->data
->d_size
= size
;
731 sec
->data
->d_align
= 1;
734 sec
->data
->d_buf
= malloc(size
);
735 if (!sec
->data
->d_buf
) {
739 memset(sec
->data
->d_buf
, 0, size
);
742 if (!gelf_getshdr(s
, &sec
->sh
)) {
743 WARN_ELF("gelf_getshdr");
747 sec
->sh
.sh_size
= size
;
748 sec
->sh
.sh_entsize
= entsize
;
749 sec
->sh
.sh_type
= SHT_PROGBITS
;
750 sec
->sh
.sh_addralign
= 1;
751 sec
->sh
.sh_flags
= SHF_ALLOC
| sh_flags
;
754 /* Add section name to .shstrtab (or .strtab for Clang) */
755 shstrtab
= find_section_by_name(elf
, ".shstrtab");
757 shstrtab
= find_section_by_name(elf
, ".strtab");
759 WARN("can't find .shstrtab or .strtab section");
763 s
= elf_getscn(elf
->elf
, shstrtab
->idx
);
765 WARN_ELF("elf_getscn");
769 data
= elf_newdata(s
);
771 WARN_ELF("elf_newdata");
775 data
->d_buf
= sec
->name
;
776 data
->d_size
= strlen(name
) + 1;
779 sec
->sh
.sh_name
= shstrtab
->len
;
781 shstrtab
->len
+= strlen(name
) + 1;
782 shstrtab
->changed
= true;
784 list_add_tail(&sec
->list
, &elf
->sections
);
785 elf_hash_add(elf
->section_hash
, &sec
->hash
, sec
->idx
);
786 elf_hash_add(elf
->section_name_hash
, &sec
->name_hash
, str_hash(sec
->name
));
793 static struct section
*elf_create_rel_reloc_section(struct elf
*elf
, struct section
*base
)
798 relocname
= malloc(strlen(base
->name
) + strlen(".rel") + 1);
803 strcpy(relocname
, ".rel");
804 strcat(relocname
, base
->name
);
806 sec
= elf_create_section(elf
, relocname
, 0, sizeof(GElf_Rel
), 0);
814 sec
->sh
.sh_type
= SHT_REL
;
815 sec
->sh
.sh_addralign
= 8;
816 sec
->sh
.sh_link
= find_section_by_name(elf
, ".symtab")->idx
;
817 sec
->sh
.sh_info
= base
->idx
;
818 sec
->sh
.sh_flags
= SHF_INFO_LINK
;
823 static struct section
*elf_create_rela_reloc_section(struct elf
*elf
, struct section
*base
)
828 relocname
= malloc(strlen(base
->name
) + strlen(".rela") + 1);
833 strcpy(relocname
, ".rela");
834 strcat(relocname
, base
->name
);
836 sec
= elf_create_section(elf
, relocname
, 0, sizeof(GElf_Rela
), 0);
844 sec
->sh
.sh_type
= SHT_RELA
;
845 sec
->sh
.sh_addralign
= 8;
846 sec
->sh
.sh_link
= find_section_by_name(elf
, ".symtab")->idx
;
847 sec
->sh
.sh_info
= base
->idx
;
848 sec
->sh
.sh_flags
= SHF_INFO_LINK
;
853 struct section
*elf_create_reloc_section(struct elf
*elf
,
854 struct section
*base
,
858 case SHT_REL
: return elf_create_rel_reloc_section(elf
, base
);
859 case SHT_RELA
: return elf_create_rela_reloc_section(elf
, base
);
860 default: return NULL
;
864 static int elf_rebuild_rel_reloc_section(struct section
*sec
, int nr
)
870 /* Allocate a buffer for relocations */
871 size
= nr
* sizeof(*relocs
);
872 relocs
= malloc(size
);
878 sec
->data
->d_buf
= relocs
;
879 sec
->data
->d_size
= size
;
881 sec
->sh
.sh_size
= size
;
884 list_for_each_entry(reloc
, &sec
->reloc_list
, list
) {
885 relocs
[idx
].r_offset
= reloc
->offset
;
886 relocs
[idx
].r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
893 static int elf_rebuild_rela_reloc_section(struct section
*sec
, int nr
)
899 /* Allocate a buffer for relocations with addends */
900 size
= nr
* sizeof(*relocs
);
901 relocs
= malloc(size
);
907 sec
->data
->d_buf
= relocs
;
908 sec
->data
->d_size
= size
;
910 sec
->sh
.sh_size
= size
;
913 list_for_each_entry(reloc
, &sec
->reloc_list
, list
) {
914 relocs
[idx
].r_offset
= reloc
->offset
;
915 relocs
[idx
].r_addend
= reloc
->addend
;
916 relocs
[idx
].r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
923 int elf_rebuild_reloc_section(struct elf
*elf
, struct section
*sec
)
932 list_for_each_entry(reloc
, &sec
->reloc_list
, list
)
935 switch (sec
->sh
.sh_type
) {
936 case SHT_REL
: return elf_rebuild_rel_reloc_section(sec
, nr
);
937 case SHT_RELA
: return elf_rebuild_rela_reloc_section(sec
, nr
);
942 int elf_write_insn(struct elf
*elf
, struct section
*sec
,
943 unsigned long offset
, unsigned int len
,
946 Elf_Data
*data
= sec
->data
;
948 if (data
->d_type
!= ELF_T_BYTE
|| data
->d_off
) {
949 WARN("write to unexpected data for section: %s", sec
->name
);
953 memcpy(data
->d_buf
+ offset
, insn
, len
);
954 elf_flagdata(data
, ELF_C_SET
, ELF_F_DIRTY
);
961 int elf_write_reloc(struct elf
*elf
, struct reloc
*reloc
)
963 struct section
*sec
= reloc
->sec
;
965 if (sec
->sh
.sh_type
== SHT_REL
) {
966 reloc
->rel
.r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
967 reloc
->rel
.r_offset
= reloc
->offset
;
969 if (!gelf_update_rel(sec
->data
, reloc
->idx
, &reloc
->rel
)) {
970 WARN_ELF("gelf_update_rel");
974 reloc
->rela
.r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
975 reloc
->rela
.r_addend
= reloc
->addend
;
976 reloc
->rela
.r_offset
= reloc
->offset
;
978 if (!gelf_update_rela(sec
->data
, reloc
->idx
, &reloc
->rela
)) {
979 WARN_ELF("gelf_update_rela");
989 int elf_write(struct elf
*elf
)
994 /* Update section headers for changed sections: */
995 list_for_each_entry(sec
, &elf
->sections
, list
) {
997 s
= elf_getscn(elf
->elf
, sec
->idx
);
999 WARN_ELF("elf_getscn");
1002 if (!gelf_update_shdr(s
, &sec
->sh
)) {
1003 WARN_ELF("gelf_update_shdr");
1007 sec
->changed
= false;
1011 /* Make sure the new section header entries get updated properly. */
1012 elf_flagelf(elf
->elf
, ELF_C_SET
, ELF_F_DIRTY
);
1014 /* Write all changes to the file. */
1015 if (elf_update(elf
->elf
, ELF_C_WRITE
) < 0) {
1016 WARN_ELF("elf_update");
1020 elf
->changed
= false;
1025 void elf_close(struct elf
*elf
)
1027 struct section
*sec
, *tmpsec
;
1028 struct symbol
*sym
, *tmpsym
;
1029 struct reloc
*reloc
, *tmpreloc
;
1037 list_for_each_entry_safe(sec
, tmpsec
, &elf
->sections
, list
) {
1038 list_for_each_entry_safe(sym
, tmpsym
, &sec
->symbol_list
, list
) {
1039 list_del(&sym
->list
);
1040 hash_del(&sym
->hash
);
1043 list_for_each_entry_safe(reloc
, tmpreloc
, &sec
->reloc_list
, list
) {
1044 list_del(&reloc
->list
);
1045 hash_del(&reloc
->hash
);
1048 list_del(&sec
->list
);