forked from Minki/linux
- A bunch of objtool fixes to improve unwinding, sibling call detection,
fallthrough detection and relocation handling of weak symbols when the toolchain strips section symbols -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmJuckgACgkQEsHwGGHe VUrnTw//TQ1gcAYX4vNibZvOYLRS090uvrnfrosCLBTlOLuPTnB71hTTCxaV6wPV lXbW5n795G9XmQAkKyqRjNA2PHGKP+D187ooFwJjHW661+dQgdo4EhbRtR4s/IMW Vd3ZRL0bmCImPKz4MrSVPEL0UotMHI2XYwr6Wf/kOmJ6nlTgmnVE3dI4sOkXQCtJ ZMCtSm6XN4LTnYLgkP99AuPQe4tC2Fw/zXkFZWkm3Ku6xvEtyfSLLByli8Tqf4p9 mcVoLfBnvYc6ift/tBg9tGFTdw8BzQdmhvnwgMnouiA7bjuhEZ+ef7+LwEpg/5J6 tMNIeO9m8DzR1jZm2vuu+VHB+GwYonXhElJY8JbpGfvI/zjYhxHNdyx3Nn9Cpd7B whxu7dRodUmI78/Ab3ywA+rDbMQw9ljT4254JhA/VeHxWuKodWU5PKRcS9nYSR+p NNSSxWmzy4+3h4d9Twd35CWa7ALroepr4JjyEs54Xar7kmoZhiFg8/P0cD2u5ZtL aBuDDOw8sQOzFHY8sQpYr4k4sI7VdA8fOBXJ0bllu962Gg1aujfuHlCP/ToRpJGc 2YXXUI0tWmOsn5pGI5ludAQ5B+M0j1JxrowEb+gPfuqk7hoN53c4fery4JjtrsJ5 0DPsSKq9SVY+SSLNTuTchQUBZcWAY3GXZYBHr8KuV+iY1zL/rCg= =7nEx -----END PGP SIGNATURE----- Merge tag 'objtool_urgent_for_v5.18_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull objtool fixes from Borislav Petkov: "A bunch of objtool fixes to improve unwinding, sibling call detection, fallthrough detection and relocation handling of weak symbols when the toolchain strips section symbols" * tag 'objtool_urgent_for_v5.18_rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: objtool: Fix code relocs vs weak symbols objtool: Fix type of reloc::addend objtool: Fix function fallthrough detection for vmlinux objtool: Fix sibling call detection in alternatives objtool: Don't set 'jump_dest' for sibling calls x86/uaccess: Don't jump between functions
This commit is contained in:
commit
b70ed23c23
@ -53,12 +53,12 @@
|
||||
SYM_FUNC_START(copy_user_generic_unrolled)
|
||||
ASM_STAC
|
||||
cmpl $8,%edx
|
||||
jb 20f /* less then 8 bytes, go to byte copy loop */
|
||||
jb .Lcopy_user_short_string_bytes
|
||||
ALIGN_DESTINATION
|
||||
movl %edx,%ecx
|
||||
andl $63,%edx
|
||||
shrl $6,%ecx
|
||||
jz .L_copy_short_string
|
||||
jz copy_user_short_string
|
||||
1: movq (%rsi),%r8
|
||||
2: movq 1*8(%rsi),%r9
|
||||
3: movq 2*8(%rsi),%r10
|
||||
@ -79,37 +79,11 @@ SYM_FUNC_START(copy_user_generic_unrolled)
|
||||
leaq 64(%rdi),%rdi
|
||||
decl %ecx
|
||||
jnz 1b
|
||||
.L_copy_short_string:
|
||||
movl %edx,%ecx
|
||||
andl $7,%edx
|
||||
shrl $3,%ecx
|
||||
jz 20f
|
||||
18: movq (%rsi),%r8
|
||||
19: movq %r8,(%rdi)
|
||||
leaq 8(%rsi),%rsi
|
||||
leaq 8(%rdi),%rdi
|
||||
decl %ecx
|
||||
jnz 18b
|
||||
20: andl %edx,%edx
|
||||
jz 23f
|
||||
movl %edx,%ecx
|
||||
21: movb (%rsi),%al
|
||||
22: movb %al,(%rdi)
|
||||
incq %rsi
|
||||
incq %rdi
|
||||
decl %ecx
|
||||
jnz 21b
|
||||
23: xor %eax,%eax
|
||||
ASM_CLAC
|
||||
RET
|
||||
jmp copy_user_short_string
|
||||
|
||||
30: shll $6,%ecx
|
||||
addl %ecx,%edx
|
||||
jmp 60f
|
||||
40: leal (%rdx,%rcx,8),%edx
|
||||
jmp 60f
|
||||
50: movl %ecx,%edx
|
||||
60: jmp .Lcopy_user_handle_tail /* ecx is zerorest also */
|
||||
jmp .Lcopy_user_handle_tail
|
||||
|
||||
_ASM_EXTABLE_CPY(1b, 30b)
|
||||
_ASM_EXTABLE_CPY(2b, 30b)
|
||||
@ -127,10 +101,6 @@ SYM_FUNC_START(copy_user_generic_unrolled)
|
||||
_ASM_EXTABLE_CPY(14b, 30b)
|
||||
_ASM_EXTABLE_CPY(15b, 30b)
|
||||
_ASM_EXTABLE_CPY(16b, 30b)
|
||||
_ASM_EXTABLE_CPY(18b, 40b)
|
||||
_ASM_EXTABLE_CPY(19b, 40b)
|
||||
_ASM_EXTABLE_CPY(21b, 50b)
|
||||
_ASM_EXTABLE_CPY(22b, 50b)
|
||||
SYM_FUNC_END(copy_user_generic_unrolled)
|
||||
EXPORT_SYMBOL(copy_user_generic_unrolled)
|
||||
|
||||
@ -191,7 +161,7 @@ EXPORT_SYMBOL(copy_user_generic_string)
|
||||
SYM_FUNC_START(copy_user_enhanced_fast_string)
|
||||
ASM_STAC
|
||||
/* CPUs without FSRM should avoid rep movsb for short copies */
|
||||
ALTERNATIVE "cmpl $64, %edx; jb .L_copy_short_string", "", X86_FEATURE_FSRM
|
||||
ALTERNATIVE "cmpl $64, %edx; jb copy_user_short_string", "", X86_FEATURE_FSRM
|
||||
movl %edx,%ecx
|
||||
1: rep movsb
|
||||
xorl %eax,%eax
|
||||
@ -243,6 +213,53 @@ SYM_CODE_START_LOCAL(.Lcopy_user_handle_tail)
|
||||
|
||||
SYM_CODE_END(.Lcopy_user_handle_tail)
|
||||
|
||||
/*
|
||||
* Finish memcpy of less than 64 bytes. #AC should already be set.
|
||||
*
|
||||
* Input:
|
||||
* rdi destination
|
||||
* rsi source
|
||||
* rdx count (< 64)
|
||||
*
|
||||
* Output:
|
||||
* eax uncopied bytes or 0 if successful.
|
||||
*/
|
||||
SYM_CODE_START_LOCAL(copy_user_short_string)
|
||||
movl %edx,%ecx
|
||||
andl $7,%edx
|
||||
shrl $3,%ecx
|
||||
jz .Lcopy_user_short_string_bytes
|
||||
18: movq (%rsi),%r8
|
||||
19: movq %r8,(%rdi)
|
||||
leaq 8(%rsi),%rsi
|
||||
leaq 8(%rdi),%rdi
|
||||
decl %ecx
|
||||
jnz 18b
|
||||
.Lcopy_user_short_string_bytes:
|
||||
andl %edx,%edx
|
||||
jz 23f
|
||||
movl %edx,%ecx
|
||||
21: movb (%rsi),%al
|
||||
22: movb %al,(%rdi)
|
||||
incq %rsi
|
||||
incq %rdi
|
||||
decl %ecx
|
||||
jnz 21b
|
||||
23: xor %eax,%eax
|
||||
ASM_CLAC
|
||||
RET
|
||||
|
||||
40: leal (%rdx,%rcx,8),%edx
|
||||
jmp 60f
|
||||
50: movl %ecx,%edx /* ecx is zerorest also */
|
||||
60: jmp .Lcopy_user_handle_tail
|
||||
|
||||
_ASM_EXTABLE_CPY(18b, 40b)
|
||||
_ASM_EXTABLE_CPY(19b, 40b)
|
||||
_ASM_EXTABLE_CPY(21b, 50b)
|
||||
_ASM_EXTABLE_CPY(22b, 50b)
|
||||
SYM_CODE_END(copy_user_short_string)
|
||||
|
||||
/*
|
||||
* copy_user_nocache - Uncached memory copy with exception handling
|
||||
* This will force destination out of cache for more performance.
|
||||
|
@ -559,12 +559,12 @@ static int add_dead_ends(struct objtool_file *file)
|
||||
else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
|
||||
insn = find_last_insn(file, reloc->sym->sec);
|
||||
if (!insn) {
|
||||
WARN("can't find unreachable insn at %s+0x%x",
|
||||
WARN("can't find unreachable insn at %s+0x%lx",
|
||||
reloc->sym->sec->name, reloc->addend);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
WARN("can't find unreachable insn at %s+0x%x",
|
||||
WARN("can't find unreachable insn at %s+0x%lx",
|
||||
reloc->sym->sec->name, reloc->addend);
|
||||
return -1;
|
||||
}
|
||||
@ -594,12 +594,12 @@ reachable:
|
||||
else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
|
||||
insn = find_last_insn(file, reloc->sym->sec);
|
||||
if (!insn) {
|
||||
WARN("can't find reachable insn at %s+0x%x",
|
||||
WARN("can't find reachable insn at %s+0x%lx",
|
||||
reloc->sym->sec->name, reloc->addend);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
WARN("can't find reachable insn at %s+0x%x",
|
||||
WARN("can't find reachable insn at %s+0x%lx",
|
||||
reloc->sym->sec->name, reloc->addend);
|
||||
return -1;
|
||||
}
|
||||
@ -1271,12 +1271,19 @@ static bool is_first_func_insn(struct objtool_file *file, struct instruction *in
|
||||
*/
|
||||
static int add_jump_destinations(struct objtool_file *file)
|
||||
{
|
||||
struct instruction *insn;
|
||||
struct instruction *insn, *jump_dest;
|
||||
struct reloc *reloc;
|
||||
struct section *dest_sec;
|
||||
unsigned long dest_off;
|
||||
|
||||
for_each_insn(file, insn) {
|
||||
if (insn->jump_dest) {
|
||||
/*
|
||||
* handle_group_alt() may have previously set
|
||||
* 'jump_dest' for some alternatives.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (!is_static_jump(insn))
|
||||
continue;
|
||||
|
||||
@ -1291,7 +1298,10 @@ static int add_jump_destinations(struct objtool_file *file)
|
||||
add_retpoline_call(file, insn);
|
||||
continue;
|
||||
} else if (insn->func) {
|
||||
/* internal or external sibling call (with reloc) */
|
||||
/*
|
||||
* External sibling call or internal sibling call with
|
||||
* STT_FUNC reloc.
|
||||
*/
|
||||
add_call_dest(file, insn, reloc->sym, true);
|
||||
continue;
|
||||
} else if (reloc->sym->sec->idx) {
|
||||
@ -1303,17 +1313,8 @@ static int add_jump_destinations(struct objtool_file *file)
|
||||
continue;
|
||||
}
|
||||
|
||||
insn->jump_dest = find_insn(file, dest_sec, dest_off);
|
||||
if (!insn->jump_dest) {
|
||||
|
||||
/*
|
||||
* This is a special case where an alt instruction
|
||||
* jumps past the end of the section. These are
|
||||
* handled later in handle_group_alt().
|
||||
*/
|
||||
if (!strcmp(insn->sec->name, ".altinstr_replacement"))
|
||||
continue;
|
||||
|
||||
jump_dest = find_insn(file, dest_sec, dest_off);
|
||||
if (!jump_dest) {
|
||||
WARN_FUNC("can't find jump dest instruction at %s+0x%lx",
|
||||
insn->sec, insn->offset, dest_sec->name,
|
||||
dest_off);
|
||||
@ -1323,8 +1324,8 @@ static int add_jump_destinations(struct objtool_file *file)
|
||||
/*
|
||||
* Cross-function jump.
|
||||
*/
|
||||
if (insn->func && insn->jump_dest->func &&
|
||||
insn->func != insn->jump_dest->func) {
|
||||
if (insn->func && jump_dest->func &&
|
||||
insn->func != jump_dest->func) {
|
||||
|
||||
/*
|
||||
* For GCC 8+, create parent/child links for any cold
|
||||
@ -1342,16 +1343,22 @@ static int add_jump_destinations(struct objtool_file *file)
|
||||
* subfunction is through a jump table.
|
||||
*/
|
||||
if (!strstr(insn->func->name, ".cold") &&
|
||||
strstr(insn->jump_dest->func->name, ".cold")) {
|
||||
insn->func->cfunc = insn->jump_dest->func;
|
||||
insn->jump_dest->func->pfunc = insn->func;
|
||||
strstr(jump_dest->func->name, ".cold")) {
|
||||
insn->func->cfunc = jump_dest->func;
|
||||
jump_dest->func->pfunc = insn->func;
|
||||
|
||||
} else if (!same_function(insn, insn->jump_dest) &&
|
||||
is_first_func_insn(file, insn->jump_dest)) {
|
||||
/* internal sibling call (without reloc) */
|
||||
add_call_dest(file, insn, insn->jump_dest->func, true);
|
||||
} else if (!same_function(insn, jump_dest) &&
|
||||
is_first_func_insn(file, jump_dest)) {
|
||||
/*
|
||||
* Internal sibling call without reloc or with
|
||||
* STT_SECTION reloc.
|
||||
*/
|
||||
add_call_dest(file, insn, jump_dest->func, true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
insn->jump_dest = jump_dest;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1540,13 +1547,13 @@ static int handle_group_alt(struct objtool_file *file,
|
||||
continue;
|
||||
|
||||
dest_off = arch_jump_destination(insn);
|
||||
if (dest_off == special_alt->new_off + special_alt->new_len)
|
||||
if (dest_off == special_alt->new_off + special_alt->new_len) {
|
||||
insn->jump_dest = next_insn_same_sec(file, last_orig_insn);
|
||||
|
||||
if (!insn->jump_dest) {
|
||||
WARN_FUNC("can't find alternative jump destination",
|
||||
insn->sec, insn->offset);
|
||||
return -1;
|
||||
if (!insn->jump_dest) {
|
||||
WARN_FUNC("can't find alternative jump destination",
|
||||
insn->sec, insn->offset);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2245,14 +2252,14 @@ static int decode_sections(struct objtool_file *file)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Must be before add_special_section_alts() as that depends on
|
||||
* jump_dest being set.
|
||||
* Must be before add_jump_destinations(), which depends on 'func'
|
||||
* being set for alternatives, to enable proper sibling call detection.
|
||||
*/
|
||||
ret = add_jump_destinations(file);
|
||||
ret = add_special_section_alts(file);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = add_special_section_alts(file);
|
||||
ret = add_jump_destinations(file);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -3303,7 +3310,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
|
||||
while (1) {
|
||||
next_insn = next_insn_to_validate(file, insn);
|
||||
|
||||
if (file->c_file && func && insn->func && func != insn->func->pfunc) {
|
||||
if (func && insn->func && func != insn->func->pfunc) {
|
||||
WARN("%s() falls through to next function %s()",
|
||||
func->name, insn->func->name);
|
||||
return 1;
|
||||
|
@ -546,7 +546,7 @@ static struct section *elf_create_reloc_section(struct elf *elf,
|
||||
int reltype);
|
||||
|
||||
int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
|
||||
unsigned int type, struct symbol *sym, int addend)
|
||||
unsigned int type, struct symbol *sym, long addend)
|
||||
{
|
||||
struct reloc *reloc;
|
||||
|
||||
@ -575,37 +575,180 @@ int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that any reloc section containing references to @sym is marked
|
||||
* changed such that it will get re-generated in elf_rebuild_reloc_sections()
|
||||
* with the new symbol index.
|
||||
*/
|
||||
static void elf_dirty_reloc_sym(struct elf *elf, struct symbol *sym)
|
||||
{
|
||||
struct section *sec;
|
||||
|
||||
list_for_each_entry(sec, &elf->sections, list) {
|
||||
struct reloc *reloc;
|
||||
|
||||
if (sec->changed)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(reloc, &sec->reloc_list, list) {
|
||||
if (reloc->sym == sym) {
|
||||
sec->changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the first global symbol, as per sh_info, into a new, higher symbol
|
||||
* index. This fees up the shndx for a new local symbol.
|
||||
*/
|
||||
static int elf_move_global_symbol(struct elf *elf, struct section *symtab,
|
||||
struct section *symtab_shndx)
|
||||
{
|
||||
Elf_Data *data, *shndx_data = NULL;
|
||||
Elf32_Word first_non_local;
|
||||
struct symbol *sym;
|
||||
Elf_Scn *s;
|
||||
|
||||
first_non_local = symtab->sh.sh_info;
|
||||
|
||||
sym = find_symbol_by_index(elf, first_non_local);
|
||||
if (!sym) {
|
||||
WARN("no non-local symbols !?");
|
||||
return first_non_local;
|
||||
}
|
||||
|
||||
s = elf_getscn(elf->elf, symtab->idx);
|
||||
if (!s) {
|
||||
WARN_ELF("elf_getscn");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data = elf_newdata(s);
|
||||
if (!data) {
|
||||
WARN_ELF("elf_newdata");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->d_buf = &sym->sym;
|
||||
data->d_size = sizeof(sym->sym);
|
||||
data->d_align = 1;
|
||||
data->d_type = ELF_T_SYM;
|
||||
|
||||
sym->idx = symtab->sh.sh_size / sizeof(sym->sym);
|
||||
elf_dirty_reloc_sym(elf, sym);
|
||||
|
||||
symtab->sh.sh_info += 1;
|
||||
symtab->sh.sh_size += data->d_size;
|
||||
symtab->changed = true;
|
||||
|
||||
if (symtab_shndx) {
|
||||
s = elf_getscn(elf->elf, symtab_shndx->idx);
|
||||
if (!s) {
|
||||
WARN_ELF("elf_getscn");
|
||||
return -1;
|
||||
}
|
||||
|
||||
shndx_data = elf_newdata(s);
|
||||
if (!shndx_data) {
|
||||
WARN_ELF("elf_newshndx_data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
shndx_data->d_buf = &sym->sec->idx;
|
||||
shndx_data->d_size = sizeof(Elf32_Word);
|
||||
shndx_data->d_align = 4;
|
||||
shndx_data->d_type = ELF_T_WORD;
|
||||
|
||||
symtab_shndx->sh.sh_size += 4;
|
||||
symtab_shndx->changed = true;
|
||||
}
|
||||
|
||||
return first_non_local;
|
||||
}
|
||||
|
||||
static struct symbol *
|
||||
elf_create_section_symbol(struct elf *elf, struct section *sec)
|
||||
{
|
||||
struct section *symtab, *symtab_shndx;
|
||||
Elf_Data *shndx_data = NULL;
|
||||
struct symbol *sym;
|
||||
Elf32_Word shndx;
|
||||
|
||||
symtab = find_section_by_name(elf, ".symtab");
|
||||
if (symtab) {
|
||||
symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
|
||||
if (symtab_shndx)
|
||||
shndx_data = symtab_shndx->data;
|
||||
} else {
|
||||
WARN("no .symtab");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sym = malloc(sizeof(*sym));
|
||||
if (!sym) {
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
}
|
||||
memset(sym, 0, sizeof(*sym));
|
||||
|
||||
sym->idx = elf_move_global_symbol(elf, symtab, symtab_shndx);
|
||||
if (sym->idx < 0) {
|
||||
WARN("elf_move_global_symbol");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sym->name = sec->name;
|
||||
sym->sec = sec;
|
||||
|
||||
// st_name 0
|
||||
sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION);
|
||||
// st_other 0
|
||||
// st_value 0
|
||||
// st_size 0
|
||||
shndx = sec->idx;
|
||||
if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) {
|
||||
sym->sym.st_shndx = shndx;
|
||||
if (!shndx_data)
|
||||
shndx = 0;
|
||||
} else {
|
||||
sym->sym.st_shndx = SHN_XINDEX;
|
||||
if (!shndx_data) {
|
||||
WARN("no .symtab_shndx");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gelf_update_symshndx(symtab->data, shndx_data, sym->idx, &sym->sym, shndx)) {
|
||||
WARN_ELF("gelf_update_symshndx");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
elf_add_symbol(elf, sym);
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
|
||||
unsigned long offset, unsigned int type,
|
||||
struct section *insn_sec, unsigned long insn_off)
|
||||
{
|
||||
struct symbol *sym;
|
||||
int addend;
|
||||
struct symbol *sym = insn_sec->sym;
|
||||
int addend = insn_off;
|
||||
|
||||
if (insn_sec->sym) {
|
||||
sym = insn_sec->sym;
|
||||
addend = insn_off;
|
||||
|
||||
} else {
|
||||
if (!sym) {
|
||||
/*
|
||||
* The Clang assembler strips section symbols, so we have to
|
||||
* reference the function symbol instead:
|
||||
* Due to how weak functions work, we must use section based
|
||||
* relocations. Symbol based relocations would result in the
|
||||
* weak and non-weak function annotations being overlaid on the
|
||||
* non-weak function after linking.
|
||||
*/
|
||||
sym = find_symbol_containing(insn_sec, insn_off);
|
||||
if (!sym) {
|
||||
/*
|
||||
* Hack alert. This happens when we need to reference
|
||||
* the NOP pad insn immediately after the function.
|
||||
*/
|
||||
sym = find_symbol_containing(insn_sec, insn_off - 1);
|
||||
}
|
||||
|
||||
if (!sym) {
|
||||
WARN("can't find symbol containing %s+0x%lx", insn_sec->name, insn_off);
|
||||
sym = elf_create_section_symbol(elf, insn_sec);
|
||||
if (!sym)
|
||||
return -1;
|
||||
}
|
||||
|
||||
addend = insn_off - sym->offset;
|
||||
insn_sec->sym = sym;
|
||||
}
|
||||
|
||||
return elf_add_reloc(elf, sec, offset, type, sym, addend);
|
||||
|
@ -73,7 +73,7 @@ struct reloc {
|
||||
struct symbol *sym;
|
||||
unsigned long offset;
|
||||
unsigned int type;
|
||||
int addend;
|
||||
long addend;
|
||||
int idx;
|
||||
bool jump_table_start;
|
||||
};
|
||||
@ -135,7 +135,7 @@ struct elf *elf_open_read(const char *name, int flags);
|
||||
struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
|
||||
|
||||
int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
|
||||
unsigned int type, struct symbol *sym, int addend);
|
||||
unsigned int type, struct symbol *sym, long addend);
|
||||
int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
|
||||
unsigned long offset, unsigned int type,
|
||||
struct section *insn_sec, unsigned long insn_off);
|
||||
|
@ -27,7 +27,7 @@ struct objtool_file {
|
||||
struct list_head static_call_list;
|
||||
struct list_head mcount_loc_list;
|
||||
struct list_head endbr_list;
|
||||
bool ignore_unreachables, c_file, hints, rodata;
|
||||
bool ignore_unreachables, hints, rodata;
|
||||
|
||||
unsigned int nr_endbr;
|
||||
unsigned int nr_endbr_int;
|
||||
|
@ -129,7 +129,6 @@ struct objtool_file *objtool_open_read(const char *_objname)
|
||||
INIT_LIST_HEAD(&file.static_call_list);
|
||||
INIT_LIST_HEAD(&file.mcount_loc_list);
|
||||
INIT_LIST_HEAD(&file.endbr_list);
|
||||
file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
|
||||
file.ignore_unreachables = no_unreachable;
|
||||
file.hints = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user