Skip to content

Commit ffb1b4a

Browse files
jpoimboeIngo Molnar
authored andcommitted
x86/unwind/orc: Add 'signal' field to ORC metadata
Add a 'signal' field which allows unwind hints to specify whether the instruction pointer should be taken literally (like for most interrupts and exceptions) rather than decremented (like for call stack return addresses) when used to find the next ORC entry. Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/d2c5ec4d83a45b513d8fd72fab59f1a8cfa46871.1676068346.git.jpoimboe@kernel.org
1 parent a20717a commit ffb1b4a

File tree

7 files changed

+29
-20
lines changed

7 files changed

+29
-20
lines changed

arch/x86/include/asm/orc_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,14 @@ struct orc_entry {
5757
unsigned sp_reg:4;
5858
unsigned bp_reg:4;
5959
unsigned type:2;
60+
unsigned signal:1;
6061
unsigned end:1;
6162
#elif defined(__BIG_ENDIAN_BITFIELD)
6263
unsigned bp_reg:4;
6364
unsigned sp_reg:4;
64-
unsigned unused:5;
65+
unsigned unused:4;
6566
unsigned end:1;
67+
unsigned signal:1;
6668
unsigned type:2;
6769
#endif
6870
} __packed;

arch/x86/include/asm/unwind_hints.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1
1616
.endm
1717

18-
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
18+
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 signal=1
1919
.if \base == %rsp
2020
.if \indirect
2121
.set sp_reg, ORC_REG_SP_INDIRECT
@@ -45,11 +45,11 @@
4545
.set type, UNWIND_HINT_TYPE_REGS
4646
.endif
4747

48-
UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type
48+
UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type signal=\signal
4949
.endm
5050

51-
.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0
52-
UNWIND_HINT_REGS base=\base offset=\offset partial=1
51+
.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 signal=1
52+
UNWIND_HINT_REGS base=\base offset=\offset partial=1 signal=\signal
5353
.endm
5454

5555
.macro UNWIND_HINT_FUNC
@@ -67,7 +67,7 @@
6767
#else
6868

6969
#define UNWIND_HINT_FUNC \
70-
UNWIND_HINT(ORC_REG_SP, 8, UNWIND_HINT_TYPE_FUNC, 0)
70+
UNWIND_HINT(ORC_REG_SP, 8, UNWIND_HINT_TYPE_FUNC, 0, 0)
7171

7272
#endif /* __ASSEMBLY__ */
7373

arch/x86/kernel/unwind_orc.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ bool unwind_next_frame(struct unwind_state *state)
484484
goto the_end;
485485
}
486486

487+
state->signal = orc->signal;
488+
487489
/* Find the previous frame's stack: */
488490
switch (orc->sp_reg) {
489491
case ORC_REG_SP:
@@ -563,7 +565,6 @@ bool unwind_next_frame(struct unwind_state *state)
563565
state->sp = sp;
564566
state->regs = NULL;
565567
state->prev_regs = NULL;
566-
state->signal = false;
567568
break;
568569

569570
case UNWIND_HINT_TYPE_REGS:
@@ -587,7 +588,6 @@ bool unwind_next_frame(struct unwind_state *state)
587588
state->regs = (struct pt_regs *)sp;
588589
state->prev_regs = NULL;
589590
state->full_regs = true;
590-
state->signal = true;
591591
break;
592592

593593
case UNWIND_HINT_TYPE_REGS_PARTIAL:
@@ -604,7 +604,6 @@ bool unwind_next_frame(struct unwind_state *state)
604604
state->prev_regs = state->regs;
605605
state->regs = (void *)sp - IRET_FRAME_OFFSET;
606606
state->full_regs = false;
607-
state->signal = true;
608607
break;
609608

610609
default:

include/linux/objtool.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct unwind_hint {
1515
s16 sp_offset;
1616
u8 sp_reg;
1717
u8 type;
18+
u8 signal;
1819
u8 end;
1920
};
2021
#endif
@@ -49,14 +50,15 @@ struct unwind_hint {
4950

5051
#ifndef __ASSEMBLY__
5152

52-
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
53+
#define UNWIND_HINT(sp_reg, sp_offset, type, signal, end) \
5354
"987: \n\t" \
5455
".pushsection .discard.unwind_hints\n\t" \
5556
/* struct unwind_hint */ \
5657
".long 987b - .\n\t" \
5758
".short " __stringify(sp_offset) "\n\t" \
5859
".byte " __stringify(sp_reg) "\n\t" \
5960
".byte " __stringify(type) "\n\t" \
61+
".byte " __stringify(signal) "\n\t" \
6062
".byte " __stringify(end) "\n\t" \
6163
".balign 4 \n\t" \
6264
".popsection\n\t"
@@ -129,14 +131,15 @@ struct unwind_hint {
129131
* the debuginfo as necessary. It will also warn if it sees any
130132
* inconsistencies.
131133
*/
132-
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
134+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 end=0
133135
.Lunwind_hint_ip_\@:
134136
.pushsection .discard.unwind_hints
135137
/* struct unwind_hint */
136138
.long .Lunwind_hint_ip_\@ - .
137139
.short \sp_offset
138140
.byte \sp_reg
139141
.byte \type
142+
.byte \signal
140143
.byte \end
141144
.balign 4
142145
.popsection
@@ -174,15 +177,15 @@ struct unwind_hint {
174177

175178
#ifndef __ASSEMBLY__
176179

177-
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
180+
#define UNWIND_HINT(sp_reg, sp_offset, type, signal, end) \
178181
"\n\t"
179182
#define STACK_FRAME_NON_STANDARD(func)
180183
#define STACK_FRAME_NON_STANDARD_FP(func)
181184
#define ANNOTATE_NOENDBR
182185
#define ASM_REACHABLE
183186
#else
184187
#define ANNOTATE_INTRA_FUNCTION_CALL
185-
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
188+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 end=0
186189
.endm
187190
.macro STACK_FRAME_NON_STANDARD func:req
188191
.endm

tools/arch/x86/include/asm/orc_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,14 @@ struct orc_entry {
5757
unsigned sp_reg:4;
5858
unsigned bp_reg:4;
5959
unsigned type:2;
60+
unsigned signal:1;
6061
unsigned end:1;
6162
#elif defined(__BIG_ENDIAN_BITFIELD)
6263
unsigned bp_reg:4;
6364
unsigned sp_reg:4;
64-
unsigned unused:5;
65+
unsigned unused:4;
6566
unsigned end:1;
67+
unsigned signal:1;
6668
unsigned type:2;
6769
#endif
6870
} __packed;

tools/include/linux/objtool.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct unwind_hint {
1515
s16 sp_offset;
1616
u8 sp_reg;
1717
u8 type;
18+
u8 signal;
1819
u8 end;
1920
};
2021
#endif
@@ -49,14 +50,15 @@ struct unwind_hint {
4950

5051
#ifndef __ASSEMBLY__
5152

52-
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
53+
#define UNWIND_HINT(sp_reg, sp_offset, type, signal, end) \
5354
"987: \n\t" \
5455
".pushsection .discard.unwind_hints\n\t" \
5556
/* struct unwind_hint */ \
5657
".long 987b - .\n\t" \
5758
".short " __stringify(sp_offset) "\n\t" \
5859
".byte " __stringify(sp_reg) "\n\t" \
5960
".byte " __stringify(type) "\n\t" \
61+
".byte " __stringify(signal) "\n\t" \
6062
".byte " __stringify(end) "\n\t" \
6163
".balign 4 \n\t" \
6264
".popsection\n\t"
@@ -129,14 +131,15 @@ struct unwind_hint {
129131
* the debuginfo as necessary. It will also warn if it sees any
130132
* inconsistencies.
131133
*/
132-
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
134+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 end=0
133135
.Lunwind_hint_ip_\@:
134136
.pushsection .discard.unwind_hints
135137
/* struct unwind_hint */
136138
.long .Lunwind_hint_ip_\@ - .
137139
.short \sp_offset
138140
.byte \sp_reg
139141
.byte \type
142+
.byte \signal
140143
.byte \end
141144
.balign 4
142145
.popsection
@@ -174,15 +177,15 @@ struct unwind_hint {
174177

175178
#ifndef __ASSEMBLY__
176179

177-
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
180+
#define UNWIND_HINT(sp_reg, sp_offset, type, signal, end) \
178181
"\n\t"
179182
#define STACK_FRAME_NON_STANDARD(func)
180183
#define STACK_FRAME_NON_STANDARD_FP(func)
181184
#define ANNOTATE_NOENDBR
182185
#define ASM_REACHABLE
183186
#else
184187
#define ANNOTATE_INTRA_FUNCTION_CALL
185-
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
188+
.macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0 end=0
186189
.endm
187190
.macro STACK_FRAME_NON_STANDARD func:req
188191
.endm

tools/objtool/orc_dump.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,8 @@ int orc_dump(const char *_objname)
211211

212212
print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset));
213213

214-
printf(" type:%s end:%d\n",
215-
orc_type_name(orc[i].type), orc[i].end);
214+
printf(" type:%s signal:%d end:%d\n",
215+
orc_type_name(orc[i].type), orc[i].signal, orc[i].end);
216216
}
217217

218218
elf_end(elf);

0 commit comments

Comments
 (0)