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_section()

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

While at it, make elf_create_rela_section() 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>

+77 -54
+66 -52
tools/objtool/elf.c
··· 1138 1138 } 1139 1139 1140 1140 struct section *elf_create_section(struct elf *elf, const char *name, 1141 - size_t entsize, unsigned int nr) 1141 + size_t size, size_t entsize, 1142 + unsigned int type, unsigned int align, 1143 + unsigned int flags) 1142 1144 { 1143 1145 struct section *sec, *shstrtab; 1144 - size_t size = entsize * nr; 1145 1146 Elf_Scn *s; 1146 1147 1147 - sec = malloc(sizeof(*sec)); 1148 - if (!sec) { 1149 - ERROR_GLIBC("malloc"); 1148 + if (name && find_section_by_name(elf, name)) { 1149 + ERROR("section '%s' already exists", name); 1150 1150 return NULL; 1151 1151 } 1152 - memset(sec, 0, sizeof(*sec)); 1152 + 1153 + sec = calloc(1, sizeof(*sec)); 1154 + if (!sec) { 1155 + ERROR_GLIBC("calloc"); 1156 + return NULL; 1157 + } 1153 1158 1154 1159 INIT_LIST_HEAD(&sec->symbol_list); 1160 + 1161 + /* don't actually create the section, just the data structures */ 1162 + if (type == SHT_NULL) 1163 + goto add; 1155 1164 1156 1165 s = elf_newscn(elf->elf); 1157 1166 if (!s) { ··· 1168 1159 return NULL; 1169 1160 } 1170 1161 1171 - sec->name = strdup(name); 1172 - if (!sec->name) { 1173 - ERROR_GLIBC("strdup"); 1174 - return NULL; 1175 - } 1176 - 1177 1162 sec->idx = elf_ndxscn(s); 1178 1163 1179 - sec->data = elf_newdata(s); 1180 - if (!sec->data) { 1181 - ERROR_ELF("elf_newdata"); 1182 - return NULL; 1183 - } 1184 - 1185 - sec->data->d_size = size; 1186 - sec->data->d_align = 1; 1187 - 1188 1164 if (size) { 1189 - sec->data->d_buf = malloc(size); 1190 - if (!sec->data->d_buf) { 1191 - ERROR_GLIBC("malloc"); 1165 + sec->data = elf_newdata(s); 1166 + if (!sec->data) { 1167 + ERROR_ELF("elf_newdata"); 1192 1168 return NULL; 1193 1169 } 1194 - memset(sec->data->d_buf, 0, size); 1170 + 1171 + sec->data->d_size = size; 1172 + sec->data->d_align = 1; 1173 + 1174 + sec->data->d_buf = calloc(1, size); 1175 + if (!sec->data->d_buf) { 1176 + ERROR_GLIBC("calloc"); 1177 + return NULL; 1178 + } 1195 1179 } 1196 1180 1197 1181 if (!gelf_getshdr(s, &sec->sh)) { ··· 1194 1192 1195 1193 sec->sh.sh_size = size; 1196 1194 sec->sh.sh_entsize = entsize; 1197 - sec->sh.sh_type = SHT_PROGBITS; 1198 - sec->sh.sh_addralign = 1; 1199 - sec->sh.sh_flags = SHF_ALLOC; 1195 + sec->sh.sh_type = type; 1196 + sec->sh.sh_addralign = align; 1197 + sec->sh.sh_flags = flags; 1200 1198 1201 - /* Add section name to .shstrtab (or .strtab for Clang) */ 1202 - shstrtab = find_section_by_name(elf, ".shstrtab"); 1203 - if (!shstrtab) 1204 - shstrtab = find_section_by_name(elf, ".strtab"); 1205 - if (!shstrtab) { 1206 - ERROR("can't find .shstrtab or .strtab section"); 1207 - return NULL; 1199 + if (name) { 1200 + sec->name = strdup(name); 1201 + if (!sec->name) { 1202 + ERROR("strdup"); 1203 + return NULL; 1204 + } 1205 + 1206 + /* Add section name to .shstrtab (or .strtab for Clang) */ 1207 + shstrtab = find_section_by_name(elf, ".shstrtab"); 1208 + if (!shstrtab) { 1209 + shstrtab = find_section_by_name(elf, ".strtab"); 1210 + if (!shstrtab) { 1211 + ERROR("can't find .shstrtab or .strtab"); 1212 + return NULL; 1213 + } 1214 + } 1215 + sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 1216 + if (sec->sh.sh_name == -1) 1217 + return NULL; 1218 + 1219 + elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 1208 1220 } 1209 - sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); 1210 - if (sec->sh.sh_name == -1) 1211 - return NULL; 1212 1221 1222 + add: 1213 1223 list_add_tail(&sec->list, &elf->sections); 1214 1224 elf_hash_add(section, &sec->hash, sec->idx); 1215 - elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); 1216 1225 1217 1226 mark_sec_changed(elf, sec, true); 1218 1227 1219 1228 return sec; 1220 1229 } 1221 1230 1222 - static struct section *elf_create_rela_section(struct elf *elf, 1223 - struct section *sec, 1224 - unsigned int reloc_nr) 1231 + struct section *elf_create_rela_section(struct elf *elf, struct section *sec, 1232 + unsigned int reloc_nr) 1225 1233 { 1226 1234 struct section *rsec; 1227 1235 char *rsec_name; ··· 1244 1232 strcpy(rsec_name, ".rela"); 1245 1233 strcat(rsec_name, sec->name); 1246 1234 1247 - rsec = elf_create_section(elf, rsec_name, elf_rela_size(elf), reloc_nr); 1235 + rsec = elf_create_section(elf, rsec_name, reloc_nr * elf_rela_size(elf), 1236 + elf_rela_size(elf), SHT_RELA, elf_addr_size(elf), 1237 + SHF_INFO_LINK); 1248 1238 free(rsec_name); 1249 1239 if (!rsec) 1250 1240 return NULL; 1251 1241 1252 - rsec->data->d_type = ELF_T_RELA; 1253 - rsec->sh.sh_type = SHT_RELA; 1254 - rsec->sh.sh_addralign = elf_addr_size(elf); 1255 1242 rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; 1256 1243 rsec->sh.sh_info = sec->idx; 1257 - rsec->sh.sh_flags = SHF_INFO_LINK; 1258 1244 1259 - rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc)); 1260 - if (!rsec->relocs) { 1261 - ERROR_GLIBC("calloc"); 1262 - return NULL; 1245 + if (reloc_nr) { 1246 + rsec->data->d_type = ELF_T_RELA; 1247 + rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc)); 1248 + if (!rsec->relocs) { 1249 + ERROR_GLIBC("calloc"); 1250 + return NULL; 1251 + } 1263 1252 } 1264 1253 1265 1254 sec->rsec = rsec; ··· 1275 1262 { 1276 1263 struct section *sec; 1277 1264 1278 - sec = elf_create_section(elf, name, entsize, nr); 1265 + sec = elf_create_section(elf, name, nr * entsize, entsize, 1266 + SHT_PROGBITS, 1, SHF_ALLOC); 1279 1267 if (!sec) 1280 1268 return NULL; 1281 1269
+6 -1
tools/objtool/include/objtool/elf.h
··· 117 117 struct elf *elf_open_read(const char *name, int flags); 118 118 119 119 struct section *elf_create_section(struct elf *elf, const char *name, 120 - size_t entsize, unsigned int nr); 120 + size_t size, size_t entsize, 121 + unsigned int type, unsigned int align, 122 + unsigned int flags); 121 123 struct section *elf_create_section_pair(struct elf *elf, const char *name, 122 124 size_t entsize, unsigned int nr, 125 + unsigned int reloc_nr); 126 + 127 + struct section *elf_create_rela_section(struct elf *elf, struct section *sec, 123 128 unsigned int reloc_nr); 124 129 125 130 struct symbol *elf_create_symbol(struct elf *elf, const char *name,
+5 -1
tools/objtool/orc_gen.c
··· 127 127 return -1; 128 128 } 129 129 orc_sec = elf_create_section(file->elf, ".orc_unwind", 130 - sizeof(struct orc_entry), nr); 130 + nr * sizeof(struct orc_entry), 131 + sizeof(struct orc_entry), 132 + SHT_PROGBITS, 133 + 1, 134 + SHF_ALLOC); 131 135 if (!orc_sec) 132 136 return -1; 133 137