Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Generalize elf_create_symbol()

In preparation for the objtool klp diff subcommand, broaden the
elf_create_symbol() interface to give callers more control and reduce
duplication of some subtle setup logic.

While at it, make elf_create_symbol() and elf_create_section_symbol()
global so sections can be created by the upcoming klp diff code.

Acked-by: Petr Mladek <pmladek@suse.com>
Tested-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>

+69 -53
+59 -52
tools/objtool/elf.c
··· 763 763 return 0; 764 764 } 765 765 766 - static struct symbol * 767 - __elf_create_symbol(struct elf *elf, struct symbol *sym) 766 + static int elf_add_string(struct elf *elf, struct section *strtab, const char *str); 767 + 768 + struct symbol *elf_create_symbol(struct elf *elf, const char *name, 769 + struct section *sec, unsigned int bind, 770 + unsigned int type, unsigned long offset, 771 + size_t size) 768 772 { 769 773 struct section *symtab, *symtab_shndx; 770 774 Elf32_Word first_non_local, new_idx; 771 - struct symbol *old; 775 + struct symbol *old, *sym; 776 + 777 + sym = calloc(1, sizeof(*sym)); 778 + if (!sym) { 779 + ERROR_GLIBC("calloc"); 780 + return NULL; 781 + } 782 + 783 + sym->name = strdup(name); 784 + if (!sym->name) { 785 + ERROR_GLIBC("strdup"); 786 + return NULL; 787 + } 788 + 789 + if (type != STT_SECTION) { 790 + sym->sym.st_name = elf_add_string(elf, NULL, sym->name); 791 + if (sym->sym.st_name == -1) 792 + return NULL; 793 + } 794 + 795 + if (sec) { 796 + sym->sec = sec; 797 + } else { 798 + sym->sec = find_section_by_index(elf, 0); 799 + if (!sym->sec) { 800 + ERROR("no NULL section"); 801 + return NULL; 802 + } 803 + } 804 + 805 + sym->sym.st_info = GELF_ST_INFO(bind, type); 806 + sym->sym.st_value = offset; 807 + sym->sym.st_size = size; 772 808 773 809 symtab = find_section_by_name(elf, ".symtab"); 774 - if (symtab) { 775 - symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 776 - } else { 810 + if (!symtab) { 777 811 ERROR("no .symtab"); 778 812 return NULL; 779 813 } 780 814 815 + symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); 816 + 781 817 new_idx = sec_num_entries(symtab); 782 818 783 - if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL) 819 + if (bind != STB_LOCAL) 784 820 goto non_local; 785 821 786 822 /* ··· 854 818 855 819 non_local: 856 820 sym->idx = new_idx; 857 - if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) { 858 - ERROR("elf_update_symbol"); 821 + if (sym->idx && elf_update_symbol(elf, symtab, symtab_shndx, sym)) 859 822 return NULL; 860 - } 861 823 862 824 symtab->sh.sh_size += symtab->sh.sh_entsize; 863 825 mark_sec_changed(elf, symtab, true); ··· 865 831 mark_sec_changed(elf, symtab_shndx, true); 866 832 } 867 833 834 + elf_add_symbol(elf, sym); 835 + 868 836 return sym; 869 837 } 870 838 871 - static struct symbol * 872 - elf_create_section_symbol(struct elf *elf, struct section *sec) 839 + struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec) 873 840 { 874 841 struct symbol *sym = calloc(1, sizeof(*sym)); 875 842 876 - if (!sym) { 877 - ERROR_GLIBC("malloc"); 843 + sym = elf_create_symbol(elf, sec->name, sec, STB_LOCAL, STT_SECTION, 0, 0); 844 + if (!sym) 878 845 return NULL; 879 - } 880 846 881 - sym->name = sec->name; 882 - sym->sec = sec; 883 - 884 - // st_name 0 885 - sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION); 886 - // st_other 0 887 - // st_value 0 888 - // st_size 0 889 - 890 - sym = __elf_create_symbol(elf, sym); 891 - if (sym) 892 - elf_add_symbol(elf, sym); 847 + sec->sym = sym; 893 848 894 849 return sym; 895 850 } 896 - 897 - static int elf_add_string(struct elf *elf, struct section *strtab, const char *str); 898 851 899 852 struct symbol * 900 - elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size) 853 + elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, size_t size) 901 854 { 902 - struct symbol *sym = calloc(1, sizeof(*sym)); 903 855 size_t namelen = strlen(orig->name) + sizeof("__pfx_"); 904 - char *name = malloc(namelen); 905 - 906 - if (!sym || !name) { 907 - ERROR_GLIBC("malloc"); 908 - return NULL; 909 - } 856 + char name[SYM_NAME_LEN]; 857 + unsigned long offset; 910 858 911 859 snprintf(name, namelen, "__pfx_%s", orig->name); 912 860 913 - sym->name = name; 914 - sym->sec = orig->sec; 861 + offset = orig->sym.st_value - size; 915 862 916 - sym->sym.st_name = elf_add_string(elf, NULL, name); 917 - sym->sym.st_info = orig->sym.st_info; 918 - sym->sym.st_value = orig->sym.st_value - size; 919 - sym->sym.st_size = size; 920 - 921 - sym = __elf_create_symbol(elf, sym); 922 - if (sym) 923 - elf_add_symbol(elf, sym); 924 - 925 - return sym; 863 + return elf_create_symbol(elf, name, orig->sec, 864 + GELF_ST_BIND(orig->sym.st_info), 865 + GELF_ST_TYPE(orig->sym.st_info), 866 + offset, size); 926 867 } 927 868 928 869 static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, ··· 943 934 unsigned long insn_off) 944 935 { 945 936 struct symbol *sym = insn_sec->sym; 946 - int addend = insn_off; 937 + s64 addend = insn_off; 947 938 948 939 if (!is_text_sec(insn_sec)) { 949 940 ERROR("bad call to %s() for data symbol %s", __func__, sym->name); ··· 960 951 sym = elf_create_section_symbol(elf, insn_sec); 961 952 if (!sym) 962 953 return NULL; 963 - 964 - insn_sec->sym = sym; 965 954 } 966 955 967 956 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend,
+10 -1
tools/objtool/include/objtool/elf.h
··· 15 15 #include <linux/jhash.h> 16 16 #include <arch/elf.h> 17 17 18 + #define SYM_NAME_LEN 512 19 + 18 20 #ifdef LIBELF_USE_DEPRECATED 19 21 # define elf_getshdrnum elf_getshnum 20 22 # define elf_getshdrstrndx elf_getshstrndx ··· 122 120 size_t entsize, unsigned int nr, 123 121 unsigned int reloc_nr); 124 122 125 - struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size); 123 + struct symbol *elf_create_symbol(struct elf *elf, const char *name, 124 + struct section *sec, unsigned int bind, 125 + unsigned int type, unsigned long offset, 126 + size_t size); 127 + struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec); 128 + struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, 129 + size_t size); 130 + 126 131 127 132 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, 128 133 unsigned long offset,