Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should return structs of two capabilities in ca0/ca1 #326

Open
arichardson opened this issue May 29, 2019 · 3 comments
Open

Should return structs of two capabilities in ca0/ca1 #326

arichardson opened this issue May 29, 2019 · 3 comments

Comments

@arichardson
Copy link
Member

arichardson commented May 29, 2019

EDIT: The description below applies to MIPS code generation, but the same issue also applies to RISC-V: https://cheri-compiler-explorer.cl.cam.ac.uk/z/c88q34 where we should return this pair in ca0/ca1.


The MIPS n64 ABI returns the following struct in $v0/$v1 whereas for CHERI we store to the stack instead.
This could be causing some performance differences.
However, it would be a flag day if we make this change (which is easier now that we have an ABI version that the kernel and RTLD check)

struct TwoPointers {
  void* first;
  void* second;
};

struct TwoPointers return_two_pointers() {
  struct TwoPointers result;
  result.first = (void*)(__UINTPTR_TYPE__)111;
  result.second = (void*)(__UINTPTR_TYPE__)222;
  return result;
}

IR generated for MIPS (-O2):

define inreg { i64, i64 } @return_two_pointers() local_unnamed_addr #0 {
entry:
  ret { i64, i64 } { i64 111, i64 222 }
}

IR for CHERI (-O2):

define void @return_two_pointers(%struct.TwoPointers addrspace(200)* noalias nocapture sret %agg.result) local_unnamed_addr addrspace(200) #0 {
entry:
  %0 = tail call i8 addrspace(200)* @llvm.cheri.cap.address.set.i64(i8 addrspace(200)* null, i64 111)
  %first = getelementptr inbounds %struct.TwoPointers, %struct.TwoPointers addrspace(200)* %agg.result, i64 0, i32 0
  store i8 addrspace(200)* %0, i8 addrspace(200)* addrspace(200)* %first, align 16, !tbaa !2
  %1 = tail call i8 addrspace(200)* @llvm.cheri.cap.address.set.i64(i8 addrspace(200)* null, i64 222)
  %second = getelementptr inbounds %struct.TwoPointers, %struct.TwoPointers addrspace(200)* %agg.result, i64 0, i32 1
  store i8 addrspace(200)* %1, i8 addrspace(200)* addrspace(200)* %second, align 16, !tbaa !7
  ret void
}

MIPS assembly code:

	.ent	return_two_pointers
return_two_pointers:
	.frame	$sp,0,$ra
	.mask 	0x00000000,0
	.fmask	0x00000000,0
	.set	noreorder
	.set	nomacro
	.set	noat
	daddiu	$2, $zero, 111
	jr	$ra
	daddiu	$3, $zero, 222
	.set	at
	.set	macro
	.set	reorder
	.end	return_two_pointers

CHERI code:

	.ent	return_two_pointers
return_two_pointers:
	.frame	$c11,0,$c17
	.mask 	0x00000000,0
	.fmask	0x00000000,0
	.set	noreorder
	.set	nomacro
	.set	noat
	cincoffset	$c1, $cnull, 111
	csc	$c1, $zero, 0($c3)
	cincoffset	$c1, $cnull, 222
	cjr	$c17
	csc	$c1, $zero, 16($c3)
	.set	at
	.set	macro
	.set	reorder
	.end	return_two_pointers
arichardson added a commit to arichardson/cheribsd that referenced this issue May 29, 2019
I was only testing a -O0 rtld so the inline assembly happened to work.
However, at -O2 the compiler is free to reorder instruction before/after
the inline asm (including the restore of $cgp after a function call).
This was causing the rtld $cgp to be re-installed after the inline asm so
the function calls would then crash due to a wrong $cgp.

Using "memory" clobbers should fix this issue but for the two cases the
return the target function pointer it would be much nicer if we could just
return "target+cgp" in $c3/$c4 instead of having to use an on-stack output
argument.

See CTSRD-CHERI/llvm-project#326
arichardson added a commit to arichardson/cheribsd that referenced this issue May 29, 2019
I was only testing a -O0 rtld so the inline assembly happened to work.
However, at -O2 the compiler is free to reorder instruction before/after
the inline asm (including the restore of $cgp after a function call).
This was causing the rtld $cgp to be re-installed after the inline asm so
the function calls would then crash due to a wrong $cgp.

Using "memory" clobbers should fix this issue but for the two cases the
return the target function pointer it would be much nicer if we could just
return "target+cgp" in $c3/$c4 instead of having to use an on-stack output
argument.

See CTSRD-CHERI/llvm-project#326
arichardson added a commit to arichardson/cheribsd that referenced this issue May 31, 2019
I was only testing a -O0 rtld so the inline assembly happened to work.
However, at -O2 the compiler is free to reorder instruction before/after
the inline asm (including the restore of $cgp after a function call).
This was causing the rtld $cgp to be re-installed after the inline asm so
the function calls would then crash due to a wrong $cgp.

Using "memory" clobbers should fix this issue but for the two cases the
return the target function pointer it would be much nicer if we could just
return "target+cgp" in $c3/$c4 instead of having to use an on-stack output
argument.

See CTSRD-CHERI/llvm-project#326
arichardson added a commit to arichardson/cheribsd that referenced this issue Jun 28, 2019
I was only testing a -O0 rtld so the inline assembly happened to work.
However, at -O2 the compiler is free to reorder instruction before/after
the inline asm (including the restore of $cgp after a function call).
This was causing the rtld $cgp to be re-installed after the inline asm so
the function calls would then crash due to a wrong $cgp.

Using "memory" clobbers should fix this issue but for the two cases the
return the target function pointer it would be much nicer if we could just
return "target+cgp" in $c3/$c4 instead of having to use an on-stack output
argument.

See CTSRD-CHERI/llvm-project#326
arichardson added a commit to CTSRD-CHERI/cheribsd that referenced this issue Jun 28, 2019
I was only testing a -O0 rtld so the inline assembly happened to work.
However, at -O2 the compiler is free to reorder instruction before/after
the inline asm (including the restore of $cgp after a function call).
This was causing the rtld $cgp to be re-installed after the inline asm so
the function calls would then crash due to a wrong $cgp.

Using "memory" clobbers should fix this issue but for the two cases the
return the target function pointer it would be much nicer if we could just
return "target+cgp" in $c3/$c4 instead of having to use an on-stack output
argument.

See CTSRD-CHERI/llvm-project#326
@arichardson
Copy link
Member Author

arichardson commented Feb 20, 2024

This also affects RISC-V, updating description to remove old MIPS references.

https://cheri-compiler-explorer.cl.cam.ac.uk/z/c88q34

@arichardson arichardson changed the title Should return structs of two capabilities in $c3/$c4 Should return structs of two capabilities in ca0/ca1 Feb 20, 2024
@jrtc27
Copy link
Member

jrtc27 commented Feb 20, 2024

This also affects RISC-V, updating description to remove old MIPS references.

https://cheri-compiler-explorer.cl.cam.ac.uk/

Wrong link

@arichardson
Copy link
Member Author

This also affects RISC-V, updating description to remove old MIPS references.
https://cheri-compiler-explorer.cl.cam.ac.uk/

Wrong link

Should be fixed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants