Skip to content

Commit b23cc71

Browse files
committed
objtool: Add 'alt_group' struct
Create a new struct associated with each group of alternatives instructions. This will help with the removal of fake jumps, and more importantly with adding support for stack layout changes in alternatives. Signed-off-by: Josh Poimboeuf <[email protected]>
1 parent ab4e074 commit b23cc71

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

tools/objtool/check.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -992,20 +992,28 @@ static int handle_group_alt(struct objtool_file *file,
992992
struct instruction *orig_insn,
993993
struct instruction **new_insn)
994994
{
995-
static unsigned int alt_group_next_index = 1;
996995
struct instruction *last_orig_insn, *last_new_insn, *insn, *fake_jump = NULL;
997-
unsigned int alt_group = alt_group_next_index++;
996+
struct alt_group *orig_alt_group, *new_alt_group;
998997
unsigned long dest_off;
999998

999+
1000+
orig_alt_group = malloc(sizeof(*orig_alt_group));
1001+
if (!orig_alt_group) {
1002+
WARN("malloc failed");
1003+
return -1;
1004+
}
10001005
last_orig_insn = NULL;
10011006
insn = orig_insn;
10021007
sec_for_each_insn_from(file, insn) {
10031008
if (insn->offset >= special_alt->orig_off + special_alt->orig_len)
10041009
break;
10051010

1006-
insn->alt_group = alt_group;
1011+
insn->alt_group = orig_alt_group;
10071012
last_orig_insn = insn;
10081013
}
1014+
orig_alt_group->orig_group = NULL;
1015+
orig_alt_group->first_insn = orig_insn;
1016+
orig_alt_group->last_insn = last_orig_insn;
10091017

10101018
if (next_insn_same_sec(file, last_orig_insn)) {
10111019
fake_jump = malloc(sizeof(*fake_jump));
@@ -1036,8 +1044,13 @@ static int handle_group_alt(struct objtool_file *file,
10361044
return 0;
10371045
}
10381046

1047+
new_alt_group = malloc(sizeof(*new_alt_group));
1048+
if (!new_alt_group) {
1049+
WARN("malloc failed");
1050+
return -1;
1051+
}
1052+
10391053
last_new_insn = NULL;
1040-
alt_group = alt_group_next_index++;
10411054
insn = *new_insn;
10421055
sec_for_each_insn_from(file, insn) {
10431056
struct reloc *alt_reloc;
@@ -1049,7 +1062,7 @@ static int handle_group_alt(struct objtool_file *file,
10491062

10501063
insn->ignore = orig_insn->ignore_alts;
10511064
insn->func = orig_insn->func;
1052-
insn->alt_group = alt_group;
1065+
insn->alt_group = new_alt_group;
10531066

10541067
/*
10551068
* Since alternative replacement code is copy/pasted by the
@@ -1098,6 +1111,10 @@ static int handle_group_alt(struct objtool_file *file,
10981111
return -1;
10991112
}
11001113

1114+
new_alt_group->orig_group = orig_alt_group;
1115+
new_alt_group->first_insn = *new_insn;
1116+
new_alt_group->last_insn = last_new_insn;
1117+
11011118
if (fake_jump)
11021119
list_add(&fake_jump->list, &last_new_insn->list);
11031120

@@ -2451,7 +2468,7 @@ static int validate_return(struct symbol *func, struct instruction *insn, struct
24512468
static void fill_alternative_cfi(struct objtool_file *file, struct instruction *insn)
24522469
{
24532470
struct instruction *first_insn = insn;
2454-
int alt_group = insn->alt_group;
2471+
struct alt_group *alt_group = insn->alt_group;
24552472

24562473
sec_for_each_insn_continue(file, insn) {
24572474
if (insn->alt_group != alt_group)

tools/objtool/include/objtool/check.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ struct insn_state {
1919
s8 instr;
2020
};
2121

22+
struct alt_group {
23+
/*
24+
* Pointer from a replacement group to the original group. NULL if it
25+
* *is* the original group.
26+
*/
27+
struct alt_group *orig_group;
28+
29+
/* First and last instructions in the group */
30+
struct instruction *first_insn, *last_insn;
31+
};
32+
2233
struct instruction {
2334
struct list_head list;
2435
struct hlist_node hash;
@@ -34,7 +45,7 @@ struct instruction {
3445
s8 instr;
3546
u8 visited;
3647
u8 ret_offset;
37-
int alt_group;
48+
struct alt_group *alt_group;
3849
struct symbol *call_dest;
3950
struct instruction *jump_dest;
4051
struct instruction *first_jump_src;

0 commit comments

Comments
 (0)