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 section/symbol type helpers

Add some helper macros to improve readability.

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

+108 -42
+1 -1
tools/objtool/arch/x86/special.c
··· 89 89 /* look for a relocation which references .rodata */ 90 90 text_reloc = find_reloc_by_dest_range(file->elf, insn->sec, 91 91 insn->offset, insn->len); 92 - if (!text_reloc || text_reloc->sym->type != STT_SECTION || 92 + if (!text_reloc || !is_sec_sym(text_reloc->sym) || 93 93 !text_reloc->sym->sec->rodata) 94 94 return NULL; 95 95
+29 -29
tools/objtool/check.c
··· 261 261 if (!func) 262 262 return false; 263 263 264 - if (func->bind == STB_GLOBAL || func->bind == STB_WEAK) { 264 + if (!is_local_sym(func)) { 265 265 if (is_rust_noreturn(func)) 266 266 return true; 267 267 ··· 270 270 return true; 271 271 } 272 272 273 - if (func->bind == STB_WEAK) 273 + if (is_weak_sym(func)) 274 274 return false; 275 275 276 276 if (!func->len) ··· 436 436 u8 prev_len = 0; 437 437 u8 idx = 0; 438 438 439 - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) 439 + if (!is_text_sec(sec)) 440 440 continue; 441 441 442 442 if (strcmp(sec->name, ".altinstr_replacement") && ··· 459 459 if (!strcmp(sec->name, ".init.text") && !opts.module) 460 460 sec->init = true; 461 461 462 - for (offset = 0; offset < sec->sh.sh_size; offset += insn->len) { 462 + for (offset = 0; offset < sec_size(sec); offset += insn->len) { 463 463 if (!insns || idx == INSN_CHUNK_MAX) { 464 464 insns = calloc(INSN_CHUNK_SIZE, sizeof(*insn)); 465 465 if (!insns) { ··· 478 478 insn->offset = offset; 479 479 insn->prev_len = prev_len; 480 480 481 - if (arch_decode_instruction(file, sec, offset, sec->sh.sh_size - offset, insn)) 481 + if (arch_decode_instruction(file, sec, offset, sec_size(sec) - offset, insn)) 482 482 return -1; 483 483 484 484 prev_len = insn->len; ··· 496 496 } 497 497 498 498 sec_for_each_sym(sec, func) { 499 - if (func->type != STT_NOTYPE && func->type != STT_FUNC) 499 + if (!is_notype_sym(func) && !is_func_sym(func)) 500 500 continue; 501 501 502 - if (func->offset == sec->sh.sh_size) { 502 + if (func->offset == sec_size(sec)) { 503 503 /* Heuristic: likely an "end" symbol */ 504 - if (func->type == STT_NOTYPE) 504 + if (is_notype_sym(func)) 505 505 continue; 506 506 ERROR("%s(): STT_FUNC at end of section", func->name); 507 507 return -1; ··· 517 517 518 518 sym_for_each_insn(file, func, insn) { 519 519 insn->sym = func; 520 - if (func->type == STT_FUNC && 520 + if (is_func_sym(func) && 521 521 insn->type == INSN_ENDBR && 522 522 list_empty(&insn->call_node)) { 523 523 if (insn->offset == func->offset) { ··· 561 561 idx = (reloc_offset(reloc) - sym->offset) / sizeof(unsigned long); 562 562 563 563 func = reloc->sym; 564 - if (func->type == STT_SECTION) 564 + if (is_sec_sym(func)) 565 565 func = find_symbol_by_offset(reloc->sym->sec, 566 566 reloc_addend(reloc)); 567 567 if (!func) { ··· 823 823 struct symbol *sym = insn->sym; 824 824 *site = 0; 825 825 826 - if (opts.module && sym && sym->type == STT_FUNC && 826 + if (opts.module && sym && is_func_sym(sym) && 827 827 insn->offset == sym->offset && 828 828 (!strcmp(sym->name, "init_module") || 829 829 !strcmp(sym->name, "cleanup_module"))) { ··· 858 858 859 859 idx = 0; 860 860 for_each_sym(file->elf, sym) { 861 - if (sym->type != STT_FUNC) 861 + if (!is_func_sym(sym)) 862 862 continue; 863 863 864 864 if (strncmp(sym->name, "__cfi_", 6)) ··· 874 874 875 875 idx = 0; 876 876 for_each_sym(file->elf, sym) { 877 - if (sym->type != STT_FUNC) 877 + if (!is_func_sym(sym)) 878 878 continue; 879 879 880 880 if (strncmp(sym->name, "__cfi_", 6)) ··· 1463 1463 return false; 1464 1464 1465 1465 /* Disallow sibling calls into STT_NOTYPE */ 1466 - if (ts->type == STT_NOTYPE) 1466 + if (is_notype_sym(ts)) 1467 1467 return false; 1468 1468 1469 1469 /* Must not be self to be a sibling */ ··· 1497 1497 if (!reloc) { 1498 1498 dest_sec = insn->sec; 1499 1499 dest_off = arch_jump_destination(insn); 1500 - } else if (reloc->sym->type == STT_SECTION) { 1500 + } else if (is_sec_sym(reloc->sym)) { 1501 1501 dest_sec = reloc->sym->sec; 1502 1502 dest_off = arch_insn_adjusted_addend(insn, reloc); 1503 1503 } else if (reloc->sym->retpoline_thunk) { ··· 1657 1657 return -1; 1658 1658 } 1659 1659 1660 - if (func && insn_call_dest(insn)->type != STT_FUNC) { 1660 + if (func && !is_func_sym(insn_call_dest(insn))) { 1661 1661 ERROR_INSN(insn, "unsupported call to non-function"); 1662 1662 return -1; 1663 1663 } 1664 1664 1665 - } else if (reloc->sym->type == STT_SECTION) { 1665 + } else if (is_sec_sym(reloc->sym)) { 1666 1666 dest_off = arch_insn_adjusted_addend(insn, reloc); 1667 1667 dest = find_call_destination(reloc->sym->sec, dest_off); 1668 1668 if (!dest) { ··· 2146 2146 return 0; 2147 2147 2148 2148 for_each_sym(file->elf, func) { 2149 - if (func->type != STT_FUNC) 2149 + if (!is_func_sym(func)) 2150 2150 continue; 2151 2151 2152 2152 mark_func_jump_tables(file, func); ··· 2185 2185 return -1; 2186 2186 } 2187 2187 2188 - if (sec->sh.sh_size % sizeof(struct unwind_hint)) { 2188 + if (sec_size(sec) % sizeof(struct unwind_hint)) { 2189 2189 ERROR("struct unwind_hint size mismatch"); 2190 2190 return -1; 2191 2191 } 2192 2192 2193 2193 file->hints = true; 2194 2194 2195 - for (i = 0; i < sec->sh.sh_size / sizeof(struct unwind_hint); i++) { 2195 + for (i = 0; i < sec_size(sec) / sizeof(struct unwind_hint); i++) { 2196 2196 hint = (struct unwind_hint *)sec->data->d_buf + i; 2197 2197 2198 2198 reloc = find_reloc_by_dest(file->elf, sec, i * sizeof(*hint)); ··· 2201 2201 return -1; 2202 2202 } 2203 2203 2204 - if (reloc->sym->type == STT_SECTION) { 2204 + if (is_sec_sym(reloc->sym)) { 2205 2205 offset = reloc_addend(reloc); 2206 2206 } else if (reloc->sym->local_label) { 2207 2207 offset = reloc->sym->offset; ··· 2237 2237 if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { 2238 2238 struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset); 2239 2239 2240 - if (sym && sym->bind == STB_GLOBAL) { 2240 + if (sym && is_global_sym(sym)) { 2241 2241 if (opts.ibt && insn->type != INSN_ENDBR && !insn->noendbr) { 2242 2242 ERROR_INSN(insn, "UNWIND_HINT_IRET_REGS without ENDBR"); 2243 2243 return -1; ··· 2452 2452 struct symbol *func; 2453 2453 2454 2454 for_each_sym(file->elf, func) { 2455 - if (func->type == STT_NOTYPE && strstarts(func->name, ".L")) 2455 + if (is_notype_sym(func) && strstarts(func->name, ".L")) 2456 2456 func->local_label = true; 2457 2457 2458 - if (func->bind != STB_GLOBAL) 2458 + if (!is_global_sym(func)) 2459 2459 continue; 2460 2460 2461 2461 if (!strncmp(func->name, STATIC_CALL_TRAMP_PREFIX_STR, ··· 4179 4179 struct symbol *func; 4180 4180 4181 4181 for_each_sec(file->elf, sec) { 4182 - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) 4182 + if (!is_text_sec(sec)) 4183 4183 continue; 4184 4184 4185 4185 sec_for_each_sym(sec, func) { 4186 - if (func->type != STT_FUNC) 4186 + if (!is_func_sym(func)) 4187 4187 continue; 4188 4188 4189 4189 add_prefix_symbol(file, func); ··· 4227 4227 int warnings = 0; 4228 4228 4229 4229 sec_for_each_sym(sec, func) { 4230 - if (func->type != STT_FUNC) 4230 + if (!is_func_sym(func)) 4231 4231 continue; 4232 4232 4233 4233 init_insn_state(file, &state, sec); ··· 4271 4271 int warnings = 0; 4272 4272 4273 4273 for_each_sec(file->elf, sec) { 4274 - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) 4274 + if (!is_text_sec(sec)) 4275 4275 continue; 4276 4276 4277 4277 warnings += validate_section(file, sec); ··· 4452 4452 for_each_sec(file->elf, sec) { 4453 4453 4454 4454 /* Already done by validate_ibt_insn() */ 4455 - if (sec->sh.sh_flags & SHF_EXECINSTR) 4455 + if (is_text_sec(sec)) 4456 4456 continue; 4457 4457 4458 4458 if (!sec->rsec)
+10 -10
tools/objtool/elf.c
··· 170 170 struct symbol *iter; 171 171 172 172 __sym_for_each(iter, tree, offset, offset) { 173 - if (iter->offset == offset && iter->type != STT_SECTION) 173 + if (iter->offset == offset && !is_sec_sym(iter)) 174 174 return iter; 175 175 } 176 176 ··· 183 183 struct symbol *iter; 184 184 185 185 __sym_for_each(iter, tree, offset, offset) { 186 - if (iter->offset == offset && iter->type == STT_FUNC) 186 + if (iter->offset == offset && is_func_sym(iter)) 187 187 return iter; 188 188 } 189 189 ··· 264 264 struct symbol *iter; 265 265 266 266 __sym_for_each(iter, tree, offset, offset) { 267 - if (iter->type == STT_FUNC) 267 + if (is_func_sym(iter)) 268 268 return iter; 269 269 } 270 270 ··· 373 373 return -1; 374 374 } 375 375 376 - if (sec->sh.sh_size != 0 && !is_dwarf_section(sec)) { 376 + if (sec_size(sec) != 0 && !is_dwarf_section(sec)) { 377 377 sec->data = elf_getdata(s, NULL); 378 378 if (!sec->data) { 379 379 ERROR_ELF("elf_getdata"); 380 380 return -1; 381 381 } 382 382 if (sec->data->d_off != 0 || 383 - sec->data->d_size != sec->sh.sh_size) { 383 + sec->data->d_size != sec_size(sec)) { 384 384 ERROR("unexpected data attributes for %s", sec->name); 385 385 return -1; 386 386 } ··· 420 420 sym->type = GELF_ST_TYPE(sym->sym.st_info); 421 421 sym->bind = GELF_ST_BIND(sym->sym.st_info); 422 422 423 - if (sym->type == STT_FILE) 423 + if (is_file_sym(sym)) 424 424 elf->num_files++; 425 425 426 426 sym->offset = sym->sym.st_value; ··· 527 527 sec_for_each_sym(sec, sym) { 528 528 char *pname; 529 529 size_t pnamelen; 530 - if (sym->type != STT_FUNC) 530 + if (!is_func_sym(sym)) 531 531 continue; 532 532 533 533 if (sym->pfunc == NULL) ··· 929 929 struct symbol *sym = insn_sec->sym; 930 930 int addend = insn_off; 931 931 932 - if (!(insn_sec->sh.sh_flags & SHF_EXECINSTR)) { 932 + if (!is_text_sec(insn_sec)) { 933 933 ERROR("bad call to %s() for data symbol %s", __func__, sym->name); 934 934 return NULL; 935 935 } ··· 958 958 struct symbol *sym, 959 959 s64 addend) 960 960 { 961 - if (sym->sec && (sec->sh.sh_flags & SHF_EXECINSTR)) { 961 + if (is_text_sec(sec)) { 962 962 ERROR("bad call to %s() for text symbol %s", __func__, sym->name); 963 963 return NULL; 964 964 } ··· 1287 1287 */ 1288 1288 static int elf_truncate_section(struct elf *elf, struct section *sec) 1289 1289 { 1290 - u64 size = sec->sh.sh_size; 1290 + u64 size = sec_size(sec); 1291 1291 bool truncated = false; 1292 1292 Elf_Data *data = NULL; 1293 1293 Elf_Scn *s;
+66
tools/objtool/include/objtool/elf.h
··· 8 8 9 9 #include <stdio.h> 10 10 #include <gelf.h> 11 + #include <linux/string.h> 11 12 #include <linux/list.h> 12 13 #include <linux/hashtable.h> 13 14 #include <linux/rbtree.h> ··· 179 178 return elf_addr_size(elf) == 4 ? R_TEXT32 : R_TEXT64; 180 179 } 181 180 181 + static inline bool sym_has_sec(struct symbol *sym) 182 + { 183 + return sym->sec->idx; 184 + } 185 + 186 + static inline bool is_null_sym(struct symbol *sym) 187 + { 188 + return !sym->idx; 189 + } 190 + 191 + static inline bool is_sec_sym(struct symbol *sym) 192 + { 193 + return sym->type == STT_SECTION; 194 + } 195 + 196 + static inline bool is_object_sym(struct symbol *sym) 197 + { 198 + return sym->type == STT_OBJECT; 199 + } 200 + 201 + static inline bool is_func_sym(struct symbol *sym) 202 + { 203 + return sym->type == STT_FUNC; 204 + } 205 + 206 + static inline bool is_file_sym(struct symbol *sym) 207 + { 208 + return sym->type == STT_FILE; 209 + } 210 + 211 + static inline bool is_notype_sym(struct symbol *sym) 212 + { 213 + return sym->type == STT_NOTYPE; 214 + } 215 + 216 + static inline bool is_global_sym(struct symbol *sym) 217 + { 218 + return sym->bind == STB_GLOBAL; 219 + } 220 + 221 + static inline bool is_weak_sym(struct symbol *sym) 222 + { 223 + return sym->bind == STB_WEAK; 224 + } 225 + 226 + static inline bool is_local_sym(struct symbol *sym) 227 + { 228 + return sym->bind == STB_LOCAL; 229 + } 230 + 182 231 static inline bool is_reloc_sec(struct section *sec) 183 232 { 184 233 return sec->sh.sh_type == SHT_RELA || sec->sh.sh_type == SHT_REL; 234 + } 235 + 236 + static inline bool is_string_sec(struct section *sec) 237 + { 238 + return sec->sh.sh_flags & SHF_STRINGS; 239 + } 240 + 241 + static inline bool is_text_sec(struct section *sec) 242 + { 243 + return sec->sh.sh_flags & SHF_EXECINSTR; 185 244 } 186 245 187 246 static inline bool sec_changed(struct section *sec) ··· 282 221 * Elf64_Rela: 24 bytes 283 222 */ 284 223 return reloc->sec->sh.sh_entsize < 16; 224 + } 225 + 226 + static inline unsigned long sec_size(struct section *sec) 227 + { 228 + return sec->sh.sh_size; 285 229 } 286 230 287 231 #define __get_reloc_field(reloc, field) \
+2 -2
tools/objtool/special.c
··· 142 142 if (!sec) 143 143 continue; 144 144 145 - if (sec->sh.sh_size % entry->size != 0) { 145 + if (sec_size(sec) % entry->size != 0) { 146 146 ERROR("%s size not a multiple of %d", sec->name, entry->size); 147 147 return -1; 148 148 } 149 149 150 - nr_entries = sec->sh.sh_size / entry->size; 150 + nr_entries = sec_size(sec) / entry->size; 151 151 152 152 for (idx = 0; idx < nr_entries; idx++) { 153 153 alt = malloc(sizeof(*alt));