^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef _OBJTOOL_ELF_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define _OBJTOOL_ELF_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <gelf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/hashtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #ifdef LIBELF_USE_DEPRECATED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) # define elf_getshdrnum elf_getshnum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) # define elf_getshdrstrndx elf_getshstrndx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Fallback for systems without this "read, mmaping if possible" cmd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #ifndef ELF_C_READ_MMAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ELF_C_READ_MMAP ELF_C_READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct section {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct hlist_node hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct hlist_node name_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) GElf_Shdr sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct rb_root symbol_tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct list_head symbol_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct list_head reloc_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct section *base, *reloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) Elf_Data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) bool changed, text, rodata, noinstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct symbol {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct rb_node node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct hlist_node hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct hlist_node name_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) GElf_Sym sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct section *sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned char bind, type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct symbol *pfunc, *cfunc, *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) bool uaccess_safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bool static_call_tramp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct reloc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct hlist_node hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) GElf_Rela rela;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) GElf_Rel rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct section *sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) bool jump_table_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define ELF_HASH_BITS 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct elf {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) Elf *elf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) GElf_Ehdr ehdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) bool changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct list_head sections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) DECLARE_HASHTABLE(symbol_hash, ELF_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) DECLARE_HASHTABLE(symbol_name_hash, ELF_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) DECLARE_HASHTABLE(section_hash, ELF_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) DECLARE_HASHTABLE(section_name_hash, ELF_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) DECLARE_HASHTABLE(reloc_hash, ELF_HASH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define OFFSET_STRIDE_BITS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define OFFSET_STRIDE (1UL << OFFSET_STRIDE_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define OFFSET_STRIDE_MASK (~(OFFSET_STRIDE - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define for_offset_range(_offset, _start, _end) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) for (_offset = ((_start) & OFFSET_STRIDE_MASK); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) _offset >= ((_start) & OFFSET_STRIDE_MASK) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) _offset <= ((_end) & OFFSET_STRIDE_MASK); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) _offset += OFFSET_STRIDE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static inline u32 sec_offset_hash(struct section *sec, unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u32 ol, oh, idx = sec->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) offset &= OFFSET_STRIDE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ol = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) oh = (offset >> 16) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __jhash_mix(ol, oh, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return ol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static inline u32 reloc_hash(struct reloc *reloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return sec_offset_hash(reloc->sec, reloc->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct elf *elf_open_read(const char *name, int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct section *elf_create_reloc_section(struct elf *elf, struct section *base, int reltype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) void elf_add_reloc(struct elf *elf, struct reloc *reloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int elf_write_insn(struct elf *elf, struct section *sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned long offset, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) const char *insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int elf_write_reloc(struct elf *elf, struct reloc *reloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int elf_write(struct elf *elf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) void elf_close(struct elf *elf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct section *find_section_by_name(const struct elf *elf, const char *name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned long offset, unsigned int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct symbol *find_func_containing(struct section *sec, unsigned long offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct reloc *reloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int elf_rebuild_reloc_section(struct elf *elf, struct section *sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define for_each_sec(file, sec) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) list_for_each_entry(sec, &file->elf->sections, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif /* _OBJTOOL_ELF_H */