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 static int read_sections(struct elf
*elf
)
269 size_t shstrndx
, sections_nr
;
272 if (elf_getshdrnum(elf
->elf
, §ions_nr
)) {
273 WARN_ELF("elf_getshdrnum");
277 if (elf_getshdrstrndx(elf
->elf
, &shstrndx
)) {
278 WARN_ELF("elf_getshdrstrndx");
282 for (i
= 0; i
< sections_nr
; i
++) {
283 sec
= malloc(sizeof(*sec
));
288 memset(sec
, 0, sizeof(*sec
));
290 INIT_LIST_HEAD(&sec
->symbol_list
);
291 INIT_LIST_HEAD(&sec
->reloc_list
);
293 s
= elf_getscn(elf
->elf
, i
);
295 WARN_ELF("elf_getscn");
299 sec
->idx
= elf_ndxscn(s
);
301 if (!gelf_getshdr(s
, &sec
->sh
)) {
302 WARN_ELF("gelf_getshdr");
306 sec
->name
= elf_strptr(elf
->elf
, shstrndx
, sec
->sh
.sh_name
);
308 WARN_ELF("elf_strptr");
312 if (sec
->sh
.sh_size
!= 0) {
313 sec
->data
= elf_getdata(s
, NULL
);
315 WARN_ELF("elf_getdata");
318 if (sec
->data
->d_off
!= 0 ||
319 sec
->data
->d_size
!= sec
->sh
.sh_size
) {
320 WARN("unexpected data attributes for %s",
325 sec
->len
= sec
->sh
.sh_size
;
327 list_add_tail(&sec
->list
, &elf
->sections
);
328 elf_hash_add(elf
->section_hash
, &sec
->hash
, sec
->idx
);
329 elf_hash_add(elf
->section_name_hash
, &sec
->name_hash
, str_hash(sec
->name
));
333 printf("nr_sections: %lu\n", (unsigned long)sections_nr
);
335 /* sanity check, one more call to elf_nextscn() should return NULL */
336 if (elf_nextscn(elf
->elf
, s
)) {
337 WARN("section entry mismatch");
344 static int read_symbols(struct elf
*elf
)
346 struct section
*symtab
, *symtab_shndx
, *sec
;
347 struct symbol
*sym
, *pfunc
;
348 struct list_head
*entry
;
349 struct rb_node
*pnode
;
352 Elf_Data
*shndx_data
= NULL
;
355 symtab
= find_section_by_name(elf
, ".symtab");
357 WARN("missing symbol table");
361 symtab_shndx
= find_section_by_name(elf
, ".symtab_shndx");
363 shndx_data
= symtab_shndx
->data
;
365 symbols_nr
= symtab
->sh
.sh_size
/ symtab
->sh
.sh_entsize
;
367 for (i
= 0; i
< symbols_nr
; i
++) {
368 sym
= malloc(sizeof(*sym
));
373 memset(sym
, 0, sizeof(*sym
));
378 if (!gelf_getsymshndx(symtab
->data
, shndx_data
, i
, &sym
->sym
,
380 WARN_ELF("gelf_getsymshndx");
384 sym
->name
= elf_strptr(elf
->elf
, symtab
->sh
.sh_link
,
387 WARN_ELF("elf_strptr");
391 sym
->type
= GELF_ST_TYPE(sym
->sym
.st_info
);
392 sym
->bind
= GELF_ST_BIND(sym
->sym
.st_info
);
394 if ((sym
->sym
.st_shndx
> SHN_UNDEF
&&
395 sym
->sym
.st_shndx
< SHN_LORESERVE
) ||
396 (shndx_data
&& sym
->sym
.st_shndx
== SHN_XINDEX
)) {
397 if (sym
->sym
.st_shndx
!= SHN_XINDEX
)
398 shndx
= sym
->sym
.st_shndx
;
400 sym
->sec
= find_section_by_index(elf
, shndx
);
402 WARN("couldn't find section for symbol %s",
406 if (sym
->type
== STT_SECTION
) {
407 sym
->name
= sym
->sec
->name
;
411 sym
->sec
= find_section_by_index(elf
, 0);
413 sym
->offset
= sym
->sym
.st_value
;
414 sym
->len
= sym
->sym
.st_size
;
416 rb_add(&sym
->sec
->symbol_tree
, &sym
->node
, symbol_to_offset
);
417 pnode
= rb_prev(&sym
->node
);
419 entry
= &rb_entry(pnode
, struct symbol
, node
)->list
;
421 entry
= &sym
->sec
->symbol_list
;
422 list_add(&sym
->list
, entry
);
423 elf_hash_add(elf
->symbol_hash
, &sym
->hash
, sym
->idx
);
424 elf_hash_add(elf
->symbol_name_hash
, &sym
->name_hash
, str_hash(sym
->name
));
428 printf("nr_symbols: %lu\n", (unsigned long)symbols_nr
);
430 /* Create parent/child links for any cold subfunctions */
431 list_for_each_entry(sec
, &elf
->sections
, list
) {
432 list_for_each_entry(sym
, &sec
->symbol_list
, list
) {
433 char pname
[MAX_NAME_LEN
+ 1];
435 if (sym
->type
!= STT_FUNC
)
438 if (sym
->pfunc
== NULL
)
441 if (sym
->cfunc
== NULL
)
444 coldstr
= strstr(sym
->name
, ".cold");
448 pnamelen
= coldstr
- sym
->name
;
449 if (pnamelen
> MAX_NAME_LEN
) {
450 WARN("%s(): parent function name exceeds maximum length of %d characters",
451 sym
->name
, MAX_NAME_LEN
);
455 strncpy(pname
, sym
->name
, pnamelen
);
456 pname
[pnamelen
] = '\0';
457 pfunc
= find_symbol_by_name(elf
, pname
);
460 WARN("%s(): can't find parent function",
469 * Unfortunately, -fnoreorder-functions puts the child
470 * inside the parent. Remove the overlap so we can
471 * have sane assumptions.
473 * Note that pfunc->len now no longer matches
474 * pfunc->sym.st_size.
476 if (sym
->sec
== pfunc
->sec
&&
477 sym
->offset
>= pfunc
->offset
&&
478 sym
->offset
+ sym
->len
== pfunc
->offset
+ pfunc
->len
) {
479 pfunc
->len
-= sym
->len
;
491 void elf_add_reloc(struct elf
*elf
, struct reloc
*reloc
)
493 struct section
*sec
= reloc
->sec
;
495 list_add_tail(&reloc
->list
, &sec
->reloc_list
);
496 elf_hash_add(elf
->reloc_hash
, &reloc
->hash
, reloc_hash(reloc
));
499 static int read_rel_reloc(struct section
*sec
, int i
, struct reloc
*reloc
, unsigned int *symndx
)
501 if (!gelf_getrel(sec
->data
, i
, &reloc
->rel
)) {
502 WARN_ELF("gelf_getrel");
505 reloc
->type
= GELF_R_TYPE(reloc
->rel
.r_info
);
507 reloc
->offset
= reloc
->rel
.r_offset
;
508 *symndx
= GELF_R_SYM(reloc
->rel
.r_info
);
512 static int read_rela_reloc(struct section
*sec
, int i
, struct reloc
*reloc
, unsigned int *symndx
)
514 if (!gelf_getrela(sec
->data
, i
, &reloc
->rela
)) {
515 WARN_ELF("gelf_getrela");
518 reloc
->type
= GELF_R_TYPE(reloc
->rela
.r_info
);
519 reloc
->addend
= reloc
->rela
.r_addend
;
520 reloc
->offset
= reloc
->rela
.r_offset
;
521 *symndx
= GELF_R_SYM(reloc
->rela
.r_info
);
525 static int read_relocs(struct elf
*elf
)
531 unsigned long nr_reloc
, max_reloc
= 0, tot_reloc
= 0;
533 list_for_each_entry(sec
, &elf
->sections
, list
) {
534 if ((sec
->sh
.sh_type
!= SHT_RELA
) &&
535 (sec
->sh
.sh_type
!= SHT_REL
))
538 sec
->base
= find_section_by_index(elf
, sec
->sh
.sh_info
);
540 WARN("can't find base section for reloc section %s",
545 sec
->base
->reloc
= sec
;
548 for (i
= 0; i
< sec
->sh
.sh_size
/ sec
->sh
.sh_entsize
; i
++) {
549 reloc
= malloc(sizeof(*reloc
));
554 memset(reloc
, 0, sizeof(*reloc
));
555 switch (sec
->sh
.sh_type
) {
557 if (read_rel_reloc(sec
, i
, reloc
, &symndx
))
561 if (read_rela_reloc(sec
, i
, reloc
, &symndx
))
569 reloc
->sym
= find_symbol_by_index(elf
, symndx
);
571 WARN("can't find reloc entry symbol %d for %s",
576 elf_add_reloc(elf
, reloc
);
579 max_reloc
= max(max_reloc
, nr_reloc
);
580 tot_reloc
+= nr_reloc
;
584 printf("max_reloc: %lu\n", max_reloc
);
585 printf("tot_reloc: %lu\n", tot_reloc
);
591 struct elf
*elf_open_read(const char *name
, int flags
)
596 elf_version(EV_CURRENT
);
598 elf
= malloc(sizeof(*elf
));
603 memset(elf
, 0, offsetof(struct elf
, sections
));
605 INIT_LIST_HEAD(&elf
->sections
);
607 elf_hash_init(elf
->symbol_hash
);
608 elf_hash_init(elf
->symbol_name_hash
);
609 elf_hash_init(elf
->section_hash
);
610 elf_hash_init(elf
->section_name_hash
);
611 elf_hash_init(elf
->reloc_hash
);
613 elf
->fd
= open(name
, flags
);
615 fprintf(stderr
, "objtool: Can't open '%s': %s\n",
616 name
, strerror(errno
));
620 if ((flags
& O_ACCMODE
) == O_RDONLY
)
621 cmd
= ELF_C_READ_MMAP
;
622 else if ((flags
& O_ACCMODE
) == O_RDWR
)
627 elf
->elf
= elf_begin(elf
->fd
, cmd
, NULL
);
629 WARN_ELF("elf_begin");
633 if (!gelf_getehdr(elf
->elf
, &elf
->ehdr
)) {
634 WARN_ELF("gelf_getehdr");
638 if (read_sections(elf
))
641 if (read_symbols(elf
))
644 if (read_relocs(elf
))
654 struct section
*elf_create_section(struct elf
*elf
, const char *name
,
655 size_t entsize
, int nr
)
657 struct section
*sec
, *shstrtab
;
658 size_t size
= entsize
* nr
;
662 sec
= malloc(sizeof(*sec
));
667 memset(sec
, 0, sizeof(*sec
));
669 INIT_LIST_HEAD(&sec
->symbol_list
);
670 INIT_LIST_HEAD(&sec
->reloc_list
);
672 s
= elf_newscn(elf
->elf
);
674 WARN_ELF("elf_newscn");
678 sec
->name
= strdup(name
);
684 sec
->idx
= elf_ndxscn(s
);
688 sec
->data
= elf_newdata(s
);
690 WARN_ELF("elf_newdata");
694 sec
->data
->d_size
= size
;
695 sec
->data
->d_align
= 1;
698 sec
->data
->d_buf
= malloc(size
);
699 if (!sec
->data
->d_buf
) {
703 memset(sec
->data
->d_buf
, 0, size
);
706 if (!gelf_getshdr(s
, &sec
->sh
)) {
707 WARN_ELF("gelf_getshdr");
711 sec
->sh
.sh_size
= size
;
712 sec
->sh
.sh_entsize
= entsize
;
713 sec
->sh
.sh_type
= SHT_PROGBITS
;
714 sec
->sh
.sh_addralign
= 1;
715 sec
->sh
.sh_flags
= SHF_ALLOC
;
718 /* Add section name to .shstrtab (or .strtab for Clang) */
719 shstrtab
= find_section_by_name(elf
, ".shstrtab");
721 shstrtab
= find_section_by_name(elf
, ".strtab");
723 WARN("can't find .shstrtab or .strtab section");
727 s
= elf_getscn(elf
->elf
, shstrtab
->idx
);
729 WARN_ELF("elf_getscn");
733 data
= elf_newdata(s
);
735 WARN_ELF("elf_newdata");
739 data
->d_buf
= sec
->name
;
740 data
->d_size
= strlen(name
) + 1;
743 sec
->sh
.sh_name
= shstrtab
->len
;
745 shstrtab
->len
+= strlen(name
) + 1;
746 shstrtab
->changed
= true;
748 list_add_tail(&sec
->list
, &elf
->sections
);
749 elf_hash_add(elf
->section_hash
, &sec
->hash
, sec
->idx
);
750 elf_hash_add(elf
->section_name_hash
, &sec
->name_hash
, str_hash(sec
->name
));
757 static struct section
*elf_create_rel_reloc_section(struct elf
*elf
, struct section
*base
)
762 relocname
= malloc(strlen(base
->name
) + strlen(".rel") + 1);
767 strcpy(relocname
, ".rel");
768 strcat(relocname
, base
->name
);
770 sec
= elf_create_section(elf
, relocname
, sizeof(GElf_Rel
), 0);
778 sec
->sh
.sh_type
= SHT_REL
;
779 sec
->sh
.sh_addralign
= 8;
780 sec
->sh
.sh_link
= find_section_by_name(elf
, ".symtab")->idx
;
781 sec
->sh
.sh_info
= base
->idx
;
782 sec
->sh
.sh_flags
= SHF_INFO_LINK
;
787 static struct section
*elf_create_rela_reloc_section(struct elf
*elf
, struct section
*base
)
792 relocname
= malloc(strlen(base
->name
) + strlen(".rela") + 1);
797 strcpy(relocname
, ".rela");
798 strcat(relocname
, base
->name
);
800 sec
= elf_create_section(elf
, relocname
, sizeof(GElf_Rela
), 0);
808 sec
->sh
.sh_type
= SHT_RELA
;
809 sec
->sh
.sh_addralign
= 8;
810 sec
->sh
.sh_link
= find_section_by_name(elf
, ".symtab")->idx
;
811 sec
->sh
.sh_info
= base
->idx
;
812 sec
->sh
.sh_flags
= SHF_INFO_LINK
;
817 struct section
*elf_create_reloc_section(struct elf
*elf
,
818 struct section
*base
,
822 case SHT_REL
: return elf_create_rel_reloc_section(elf
, base
);
823 case SHT_RELA
: return elf_create_rela_reloc_section(elf
, base
);
824 default: return NULL
;
828 static int elf_rebuild_rel_reloc_section(struct section
*sec
, int nr
)
834 /* Allocate a buffer for relocations */
835 size
= nr
* sizeof(*relocs
);
836 relocs
= malloc(size
);
842 sec
->data
->d_buf
= relocs
;
843 sec
->data
->d_size
= size
;
845 sec
->sh
.sh_size
= size
;
848 list_for_each_entry(reloc
, &sec
->reloc_list
, list
) {
849 relocs
[idx
].r_offset
= reloc
->offset
;
850 relocs
[idx
].r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
857 static int elf_rebuild_rela_reloc_section(struct section
*sec
, int nr
)
863 /* Allocate a buffer for relocations with addends */
864 size
= nr
* sizeof(*relocs
);
865 relocs
= malloc(size
);
871 sec
->data
->d_buf
= relocs
;
872 sec
->data
->d_size
= size
;
874 sec
->sh
.sh_size
= size
;
877 list_for_each_entry(reloc
, &sec
->reloc_list
, list
) {
878 relocs
[idx
].r_offset
= reloc
->offset
;
879 relocs
[idx
].r_addend
= reloc
->addend
;
880 relocs
[idx
].r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
887 int elf_rebuild_reloc_section(struct elf
*elf
, struct section
*sec
)
896 list_for_each_entry(reloc
, &sec
->reloc_list
, list
)
899 switch (sec
->sh
.sh_type
) {
900 case SHT_REL
: return elf_rebuild_rel_reloc_section(sec
, nr
);
901 case SHT_RELA
: return elf_rebuild_rela_reloc_section(sec
, nr
);
906 int elf_write_insn(struct elf
*elf
, struct section
*sec
,
907 unsigned long offset
, unsigned int len
,
910 Elf_Data
*data
= sec
->data
;
912 if (data
->d_type
!= ELF_T_BYTE
|| data
->d_off
) {
913 WARN("write to unexpected data for section: %s", sec
->name
);
917 memcpy(data
->d_buf
+ offset
, insn
, len
);
918 elf_flagdata(data
, ELF_C_SET
, ELF_F_DIRTY
);
925 int elf_write_reloc(struct elf
*elf
, struct reloc
*reloc
)
927 struct section
*sec
= reloc
->sec
;
929 if (sec
->sh
.sh_type
== SHT_REL
) {
930 reloc
->rel
.r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
931 reloc
->rel
.r_offset
= reloc
->offset
;
933 if (!gelf_update_rel(sec
->data
, reloc
->idx
, &reloc
->rel
)) {
934 WARN_ELF("gelf_update_rel");
938 reloc
->rela
.r_info
= GELF_R_INFO(reloc
->sym
->idx
, reloc
->type
);
939 reloc
->rela
.r_addend
= reloc
->addend
;
940 reloc
->rela
.r_offset
= reloc
->offset
;
942 if (!gelf_update_rela(sec
->data
, reloc
->idx
, &reloc
->rela
)) {
943 WARN_ELF("gelf_update_rela");
953 int elf_write(struct elf
*elf
)
958 /* Update section headers for changed sections: */
959 list_for_each_entry(sec
, &elf
->sections
, list
) {
961 s
= elf_getscn(elf
->elf
, sec
->idx
);
963 WARN_ELF("elf_getscn");
966 if (!gelf_update_shdr(s
, &sec
->sh
)) {
967 WARN_ELF("gelf_update_shdr");
971 sec
->changed
= false;
975 /* Make sure the new section header entries get updated properly. */
976 elf_flagelf(elf
->elf
, ELF_C_SET
, ELF_F_DIRTY
);
978 /* Write all changes to the file. */
979 if (elf_update(elf
->elf
, ELF_C_WRITE
) < 0) {
980 WARN_ELF("elf_update");
984 elf
->changed
= false;
989 void elf_close(struct elf
*elf
)
991 struct section
*sec
, *tmpsec
;
992 struct symbol
*sym
, *tmpsym
;
993 struct reloc
*reloc
, *tmpreloc
;
1001 list_for_each_entry_safe(sec
, tmpsec
, &elf
->sections
, list
) {
1002 list_for_each_entry_safe(sym
, tmpsym
, &sec
->symbol_list
, list
) {
1003 list_del(&sym
->list
);
1004 hash_del(&sym
->hash
);
1007 list_for_each_entry_safe(reloc
, tmpreloc
, &sec
->reloc_list
, list
) {
1008 list_del(&reloc
->list
);
1009 hash_del(&reloc
->hash
);
1012 list_del(&sec
->list
);