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: Add elf_create_data()

In preparation for the objtool klp diff subcommand, refactor
elf_add_string() by adding a new elf_add_data() helper which allows the
adding of arbitrary data to a section.

Make both interfaces global so they can be used 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>

+54 -22
+47 -19
tools/objtool/elf.c
··· 18 18 #include <errno.h> 19 19 #include <linux/interval_tree_generic.h> 20 20 #include <objtool/builtin.h> 21 - 22 21 #include <objtool/elf.h> 23 22 #include <objtool/warn.h> 23 + 24 + #define ALIGN_UP(x, align_to) (((x) + ((align_to)-1)) & ~((align_to)-1)) 24 25 25 26 static inline u32 str_hash(const char *str) 26 27 { ··· 764 763 return 0; 765 764 } 766 765 767 - static int elf_add_string(struct elf *elf, struct section *strtab, const char *str); 768 - 769 766 struct symbol *elf_create_symbol(struct elf *elf, const char *name, 770 767 struct section *sec, unsigned int bind, 771 768 unsigned int type, unsigned long offset, ··· 1099 1100 return NULL; 1100 1101 } 1101 1102 1102 - static int elf_add_string(struct elf *elf, struct section *strtab, const char *str) 1103 + unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str) 1103 1104 { 1104 - Elf_Data *data; 1105 - Elf_Scn *s; 1106 - int len; 1105 + unsigned int offset; 1107 1106 1108 1107 if (!strtab) 1109 1108 strtab = find_section_by_name(elf, ".strtab"); ··· 1110 1113 return -1; 1111 1114 } 1112 1115 1113 - s = elf_getscn(elf->elf, strtab->idx); 1116 + if (!strtab->sh.sh_addralign) { 1117 + ERROR("'%s': invalid sh_addralign", strtab->name); 1118 + return -1; 1119 + } 1120 + 1121 + offset = ALIGN_UP(strtab->sh.sh_size, strtab->sh.sh_addralign); 1122 + 1123 + if (!elf_add_data(elf, strtab, str, strlen(str) + 1)) 1124 + return -1; 1125 + 1126 + return offset; 1127 + } 1128 + 1129 + void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_t size) 1130 + { 1131 + unsigned long offset; 1132 + Elf_Scn *s; 1133 + 1134 + if (!sec->sh.sh_addralign) { 1135 + ERROR("'%s': invalid sh_addralign", sec->name); 1136 + return NULL; 1137 + } 1138 + 1139 + s = elf_getscn(elf->elf, sec->idx); 1114 1140 if (!s) { 1115 1141 ERROR_ELF("elf_getscn"); 1116 - return -1; 1142 + return NULL; 1117 1143 } 1118 1144 1119 - data = elf_newdata(s); 1120 - if (!data) { 1145 + sec->data = elf_newdata(s); 1146 + if (!sec->data) { 1121 1147 ERROR_ELF("elf_newdata"); 1122 - return -1; 1148 + return NULL; 1123 1149 } 1124 1150 1125 - data->d_buf = strdup(str); 1126 - data->d_size = strlen(str) + 1; 1127 - data->d_align = 1; 1151 + sec->data->d_buf = calloc(1, size); 1152 + if (!sec->data->d_buf) { 1153 + ERROR_GLIBC("calloc"); 1154 + return NULL; 1155 + } 1128 1156 1129 - len = strtab->sh.sh_size; 1130 - strtab->sh.sh_size += data->d_size; 1157 + if (data) 1158 + memcpy(sec->data->d_buf, data, size); 1131 1159 1132 - mark_sec_changed(elf, strtab, true); 1160 + sec->data->d_size = size; 1161 + sec->data->d_align = 1; 1133 1162 1134 - return len; 1163 + offset = ALIGN_UP(sec->sh.sh_size, sec->sh.sh_addralign); 1164 + sec->sh.sh_size = offset + size; 1165 + 1166 + mark_sec_changed(elf, sec, true); 1167 + 1168 + return sec->data->d_buf; 1135 1169 } 1136 1170 1137 1171 struct section *elf_create_section(struct elf *elf, const char *name,
+7 -3
tools/objtool/include/objtool/elf.h
··· 135 135 struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, 136 136 size_t size); 137 137 138 + void *elf_add_data(struct elf *elf, struct section *sec, const void *data, 139 + size_t size); 140 + 141 + unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str); 138 142 139 143 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, 140 144 unsigned long offset, ··· 152 148 struct symbol *sym, 153 149 s64 addend); 154 150 155 - int elf_write_insn(struct elf *elf, struct section *sec, 156 - unsigned long offset, unsigned int len, 157 - const char *insn); 151 + int elf_write_insn(struct elf *elf, struct section *sec, unsigned long offset, 152 + unsigned int len, const char *insn); 153 + 158 154 int elf_write(struct elf *elf); 159 155 void elf_close(struct elf *elf); 160 156