2014-07-08 20:16:37

by Behan Webster

[permalink] [raw]
Subject: [PATCH 0/6] LLVMLinux: Patches to enable the kernel to be compiled with clang/LLVM

From: Behan Webster <[email protected]>

The LLVMLinux project aims to fully build the Linux kernel using both gcc and
clang (the C front end for the LLVM compiler infrastructure project).

Clang only supports global named registers for non-allocatable registers like
the stack pointer. By centralizing the definition of current_stack_pointer, the
use of named registers for ARM remains largely unchanged while working for both
gcc and clang.

Behan Webster (6):
arm: LLVMLinux: Add global named register current_stack_pointer for
ARM
arm: LLVMLinux: Use current_stack_pointer to calculate pt_regs address
arm: LLVMLinux: Use current_stack_pointer for return_address
arm: LLVMLinux: Use current_stack_pointer in save_stack_trace_tsk
arm: LLVMLinux: Calculate current_thread_info from
current_stack_pointer
arm: LLVMLinux: Use current_stack_pointer in unwind_backtrace

arch/arm/include/asm/ptrace.h | 5 ++---
arch/arm/include/asm/thread_info.h | 9 +++++++--
arch/arm/kernel/return_address.c | 3 +--
arch/arm/kernel/stacktrace.c | 4 +---
arch/arm/kernel/unwind.c | 3 +--
5 files changed, 12 insertions(+), 12 deletions(-)

--
1.9.1


2014-07-08 20:16:42

by Behan Webster

[permalink] [raw]
Subject: [PATCH 1/6] arm: LLVMLinux: Add global named register current_stack_pointer for ARM

From: Behan Webster <[email protected]>

Define a global named register for current_stack_pointer. The use of this new
variable guarantees that both gcc and clang can access this register in C code.

Signed-off-by: Behan Webster <[email protected]>
Reviewed-by: Jan-Simon Möller <[email protected]>
Reviewed-by: Mark Charlebois <[email protected]>
---
arch/arm/include/asm/thread_info.h | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index e4e4208..9cb9c66 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -100,6 +100,11 @@ struct thread_info {
#define init_stack (init_thread_union.stack)

/*
+ * how to get the current stack pointer in C
+ */
+register unsigned long current_stack_pointer asm ("sp");
+
+/*
* how to get the thread information struct from C
*/
static inline struct thread_info *current_thread_info(void) __attribute_const__;
--
1.9.1

2014-07-08 20:16:52

by Behan Webster

[permalink] [raw]
Subject: [PATCH 3/6] arm: LLVMLinux: Use current_stack_pointer for return_address

From: Behan Webster <[email protected]>

Use the global current_stack_pointer to get the value of the stack pointer.
This change supports being able to compile the kernel with both gcc and Clang.

Signed-off-by: Behan Webster <[email protected]>
Signed-off-by: Mark Charlebois <[email protected]>
Reviewed-by: Jan-Simon M??ller <[email protected]>
---
arch/arm/kernel/return_address.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index fafedd8..5bceaef 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -39,13 +39,12 @@ void *return_address(unsigned int level)
{
struct return_address_data data;
struct stackframe frame;
- register unsigned long current_sp asm ("sp");

data.level = level + 2;
data.addr = NULL;

frame.fp = (unsigned long)__builtin_frame_address(0);
- frame.sp = current_sp;
+ frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
frame.pc = (unsigned long)return_address;

--
1.9.1

2014-07-08 20:16:59

by Behan Webster

[permalink] [raw]
Subject: [PATCH 5/6] arm: LLVMLinux: Calculate current_thread_info from current_stack_pointer

From: Behan Webster <[email protected]>

Use the global current_stack_pointer to get the value of the stack pointer.
This change supports being able to compile the kernel with both gcc and clang.

Signed-off-by: Behan Webster <[email protected]>
Signed-off-by: Mark Charlebois <[email protected]>
Reviewed-by: Jan-Simon M??ller <[email protected]>
---
arch/arm/include/asm/thread_info.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 9cb9c66..3184d94 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -111,8 +111,8 @@ static inline struct thread_info *current_thread_info(void) __attribute_const__;

static inline struct thread_info *current_thread_info(void)
{
- register unsigned long sp asm ("sp");
- return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
+ return (struct thread_info *)
+ (current_stack_pointer & ~(THREAD_SIZE - 1));
}

#define thread_saved_pc(tsk) \
--
1.9.1

2014-07-08 20:16:57

by Behan Webster

[permalink] [raw]
Subject: [PATCH 6/6] arm: LLVMLinux: Use current_stack_pointer in unwind_backtrace

From: Behan Webster <[email protected]>

Use the global current_stack_pointer to get the value of the stack pointer.
This change supports being able to compile the kernel with both gcc and clang.

Signed-off-by: Behan Webster <[email protected]>
Signed-off-by: Mark Charlebois <[email protected]>
Reviewed-by: Jan-Simon M??ller <[email protected]>
---
arch/arm/kernel/unwind.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index e67682f..e20e8dc 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -471,7 +471,6 @@ int unwind_frame(struct stackframe *frame)
void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
struct stackframe frame;
- register unsigned long current_sp asm ("sp");

pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);

@@ -487,7 +486,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
? regs->ARM_pc : regs->ARM_lr;
} else if (tsk == current) {
frame.fp = (unsigned long)__builtin_frame_address(0);
- frame.sp = current_sp;
+ frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
frame.pc = (unsigned long)unwind_backtrace;
} else {
--
1.9.1

2014-07-08 20:16:50

by Behan Webster

[permalink] [raw]
Subject: [PATCH 2/6] arm: LLVMLinux: Use current_stack_pointer to calculate pt_regs address

From: Behan Webster <[email protected]>

Use the global current_stack_pointer to calculate the end of the stack for
current_pt_regs()

Signed-off-by: Behan Webster <[email protected]>
Signed-off-by: Mark Charlebois <[email protected]>
Reviewed-by: Jan-Simon M??ller <[email protected]>
---
arch/arm/include/asm/ptrace.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index c877654..45bc592 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -148,9 +148,8 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
return regs->ARM_sp;
}

-#define current_pt_regs(void) ({ \
- register unsigned long sp asm ("sp"); \
- (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1; \
+#define current_pt_regs(void) ({ \
+ (struct pt_regs *)((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
})

#endif /* __ASSEMBLY__ */
--
1.9.1

2014-07-08 20:18:00

by Behan Webster

[permalink] [raw]
Subject: [PATCH 4/6] arm: LLVMLinux: Use current_stack_pointer in save_stack_trace_tsk

From: Behan Webster <[email protected]>

Use the global current_stack_pointer to get the value of the stack pointer.
This change supports being able to compile the kernel with both gcc and clang.

Signed-off-by: Behan Webster <[email protected]>
Signed-off-by: Mark Charlebois <[email protected]>
Reviewed-by: Jan-Simon M??ller <[email protected]>
---
arch/arm/kernel/stacktrace.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index f065eb0..92b7237 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -134,12 +134,10 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
frame.pc = thread_saved_pc(tsk);
#endif
} else {
- register unsigned long current_sp asm ("sp");
-
/* We don't want this function nor the caller */
data.skip += 2;
frame.fp = (unsigned long)__builtin_frame_address(0);
- frame.sp = current_sp;
+ frame.sp = current_stack_pointer;
frame.lr = (unsigned long)__builtin_return_address(0);
frame.pc = (unsigned long)__save_stack_trace;
}
--
1.9.1

2014-07-09 09:57:12

by Will Deacon

[permalink] [raw]
Subject: Re: [PATCH 0/6] LLVMLinux: Patches to enable the kernel to be compiled with clang/LLVM

On Tue, Jul 08, 2014 at 09:16:10PM +0100, [email protected] wrote:
> From: Behan Webster <[email protected]>
>
> The LLVMLinux project aims to fully build the Linux kernel using both gcc and
> clang (the C front end for the LLVM compiler infrastructure project).
>
> Clang only supports global named registers for non-allocatable registers like
> the stack pointer. By centralizing the definition of current_stack_pointer, the
> use of named registers for ARM remains largely unchanged while working for both
> gcc and clang.

All looks sane to me. For the series:

Acked-by: Will Deacon <[email protected]>

BTW, have you tried building an arm64 kernel with clang?

Will

2014-07-09 11:24:24

by Jan-Simon Möller

[permalink] [raw]
Subject: Re: [PATCH 0/6] LLVMLinux: Patches to enable the kernel to be compiled with clang/LLVM

Hi Will,


> BTW, have you tried building an arm64 kernel with clang?

ragarding arm64: yes, there is a test target already - see
http://git.linuxfoundation.org/?p=llvmlinux.git;a=tree;f=targets/vexpress64

Reproduce with:
git clone http://git.linuxfoundation.org/llvmlinux.git
cd llvmlinux/targets/vexpress64
make


Best,
Jan-Simon

2014-07-13 09:11:12

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH 0/6] LLVMLinux: Patches to enable the kernel to be compiled with clang/LLVM

On Tue, 8 Jul 2014, [email protected] wrote:

> From: Behan Webster <[email protected]>
>
> The LLVMLinux project aims to fully build the Linux kernel using both gcc and
> clang (the C front end for the LLVM compiler infrastructure project).
>
> Clang only supports global named registers for non-allocatable registers like
> the stack pointer. By centralizing the definition of current_stack_pointer, the
> use of named registers for ARM remains largely unchanged while working for both
> gcc and clang.

You verified that the compiled code is identical on gcc? If so:

Acked-by: Nicolas Pitre <[email protected]>

>
> Behan Webster (6):
> arm: LLVMLinux: Add global named register current_stack_pointer for
> ARM
> arm: LLVMLinux: Use current_stack_pointer to calculate pt_regs address
> arm: LLVMLinux: Use current_stack_pointer for return_address
> arm: LLVMLinux: Use current_stack_pointer in save_stack_trace_tsk
> arm: LLVMLinux: Calculate current_thread_info from
> current_stack_pointer
> arm: LLVMLinux: Use current_stack_pointer in unwind_backtrace
>
> arch/arm/include/asm/ptrace.h | 5 ++---
> arch/arm/include/asm/thread_info.h | 9 +++++++--
> arch/arm/kernel/return_address.c | 3 +--
> arch/arm/kernel/stacktrace.c | 4 +---
> arch/arm/kernel/unwind.c | 3 +--
> 5 files changed, 12 insertions(+), 12 deletions(-)
>
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>

2014-07-17 04:17:49

by Behan Webster

[permalink] [raw]
Subject: Re: [PATCH 0/6] LLVMLinux: Patches to enable the kernel to be compiled with clang/LLVM

On 07/13/14 02:10, Nicolas Pitre wrote:
> On Tue, 8 Jul 2014, [email protected] wrote:
>
>> From: Behan Webster <[email protected]>
>>
>> The LLVMLinux project aims to fully build the Linux kernel using both gcc and
>> clang (the C front end for the LLVM compiler infrastructure project).
>>
>> Clang only supports global named registers for non-allocatable registers like
>> the stack pointer. By centralizing the definition of current_stack_pointer, the
>> use of named registers for ARM remains largely unchanged while working for both
>> gcc and clang.
> You verified that the compiled code is identical on gcc?
Yes. Identical.

> If so:
>
> Acked-by: Nicolas Pitre <[email protected]>
Thanks,

Behan

--
Behan Webster
[email protected]