diff --git a/tests/chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c b/tests/chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c index 0fb9b14d..ec1aecdd 100644 --- a/tests/chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c +++ b/tests/chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c @@ -1,6 +1,6 @@ /* Get the addresses of structure members to validate their offset and alignment * (including nested members accessed through chains of . and -> operations) - * and addresses one-past-the-end of structs to validate trailing padding + * and addresses of one-past-the-end of structs to validate trailing padding * */ #include "struct_sizes.h" diff --git a/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c b/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c index 7a3fc7e1..9cf3901a 100644 --- a/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c +++ b/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c @@ -70,7 +70,7 @@ int test_copy_to_array_elem(void) { return 1; // success } -// case 5: arr[i] = x +// case 5: x = arr[i] int test_copy_from_array_elem(void) { struct s arr[3] = { {"ab", {-3000, -4000}}, {"cd", {-5000, -6000}}, {"ef", {-7000, -8000}}}; diff --git a/tests/chapter_18/valid/params_and_returns/big_data_on_page_boundary_linux.s b/tests/chapter_18/valid/params_and_returns/big_data_on_page_boundary_linux.s new file mode 100644 index 00000000..81320845 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/big_data_on_page_boundary_linux.s @@ -0,0 +1,7 @@ + .bss # .bss is the last segment in the program image - the page after it will be unampped + .align 4096 # force page alignment + .zero 4078 # write a bunch of zeros so on_page_boundary is at the end of the page + .globl on_page_boundary +on_page_boundary: + .zero 18 + .section ".note.GNU-stack","",@progbits diff --git a/tests/chapter_18/valid/params_and_returns/big_data_on_page_boundary_osx.s b/tests/chapter_18/valid/params_and_returns/big_data_on_page_boundary_osx.s new file mode 100644 index 00000000..aefd1c51 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/big_data_on_page_boundary_osx.s @@ -0,0 +1,6 @@ + .bss # .bss is the last segment in the program image - the page after it will be unampped + .align 12 # force page alignment (2^12 == 4096) + .zero 4078 # write a bunch of zeros so on_page_boundary is at the end of the page + .globl _on_page_boundary +_on_page_boundary: + .zero 8 diff --git a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c index 68f0ae6a..9b24ebc1 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c @@ -32,12 +32,6 @@ struct memory return_on_stack(void) { return retval; } -int f(char c, double d) { - if (c == 'p' && d == 4.56) - return 0; - return 1; -} - int leaf_call(struct two_ints t_i, char c, double d) { // validate t_i if (t_i.c != '_' || t_i.arr[0] != 5 || t_i.arr[1] != 6 || t_i.arr[2] != 7) { diff --git a/tests/chapter_18/valid/params_and_returns/return_space_address_overlap_linux.s b/tests/chapter_18/valid/params_and_returns/return_space_address_overlap_linux.s new file mode 100644 index 00000000..7de2fdd7 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/return_space_address_overlap_linux.s @@ -0,0 +1,75 @@ + # validate that space allocated for return address does not overlap + # with storage for other objects we can access from callee (this is an ABI requirement) + # case 1: overlap w/ global variable + .data + .globl globvar + .align 8 +globvar: + .zero 24 + .text + # globvar = overlap_with_globvar() + .globl overlap_with_globvar +overlap_with_globvar: + # load address of globvar into RSI + leaq globvar(%rip), %rsi + # make sure return address (in RDI) and globvar's address (in RSI) + # are at least 24 bytes apart + subq %rdi, %rsi + # get absolute value of difference between addresses (in RSI) + # (absolute value implementation from https://stackoverflow.com/a/11927940) + movq %rsi, %rcx # copy RSI into RCX + negq %rsi # negate RSI + # if RSI is now negative, its restore original (positive) value + cmovl %rcx, %rsi + # compare diference to 24 + cmpq $24, %rsi + jl .Loverlap_detected + # no overlap, so go ahead and return value + movq $400, (%rdi) + movq $500, 8(%rdi) + movq $600, 16(%rdi) + movq %rdi, %rax + ret +.Loverlap_detected: + # space for return value overlaps w/ globvar, so exit with error code + movl $1, %edi + call exit + + # case 2: overlap w/ pointer passed as arg + # x = overlap_with_pointer(&x) + .globl overlap_with_pointer +overlap_with_pointer: + # copy pointer into RDX + leaq globvar(%rip), %rdx + # make sure return address (in RDI) and globvar's address (in RDX) + # are at least 24 bytes apart + subq %rdi, %rdx + # get absolute value of difference between addresses (in RDX) + # (absolute value implementation from https://stackoverflow.com/a/11927940) + movq %rdx, %rcx # copy RDX into RCX + negq %rdx # negate RDX + # if rdx is now negative, its restore original (positive) value + cmovl %rcx, %rdx + # compare diference to 24 + cmpq $24, %rdx + jl .Loverlap_detected.0 + # no overlap, so go ahead and return value + # set each member to twice its original value (accessed thru RSI) + # l1 + movq (%rsi), %rcx + imul $2, %rcx + movq %rcx, (%rdi) + # l2 + movq 8(%rsi), %rcx + imul $2, %rcx + movq %rcx, 8(%rdi) + # l3 + movq 16(%rsi), %rcx + imul $2, %rcx + movq %rcx, 16(%rdi) + movq %rdi, %rax + ret +.Loverlap_detected.0: + # space for return value overlaps w/ space pointed to by argument, so exit with error code + movl $3, %edi + call exit diff --git a/tests/chapter_18/valid/params_and_returns/return_space_address_overlap_osx.s b/tests/chapter_18/valid/params_and_returns/return_space_address_overlap_osx.s new file mode 100644 index 00000000..c22323da --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/return_space_address_overlap_osx.s @@ -0,0 +1,75 @@ + # validate that space allocated for return address does not overlap + # with storage for other objects we can access from callee (this is an ABI requirement) + # case 1: overlap w/ global variable + .data + .globl _globvar + .align 3 +_globvar: + .zero 24 + .text + # globvar = overlap_with_globvar() + .globl _overlap_with_globvar +_overlap_with_globvar: + # load address of globvar into RSI + leaq _globvar(%rip), %rsi + # make sure return address (in RDI) and globvar's address (in RSI) + # are at least 24 bytes apart + subq %rdi, %rsi + # get absolute value of difference between addresses (in RSI) + # (absolute value implementation from https://stackoverflow.com/a/11927940) + movq %rsi, %rcx # copy RSI into RCX + negq %rsi # negate RSI + # if RSI is now negative, its restore original (positive) value + cmovl %rcx, %rsi + # compare diference to 24 + cmpq $24, %rsi + jl Loverlap_detected + # no overlap, so go ahead and return value + movq $400, (%rdi) + movq $500, 8(%rdi) + movq $600, 16(%rdi) + movq %rdi, %rax + ret +Loverlap_detected: + # space for return value overlaps w/ globvar, so exit with error code + movl $1, %edi + call _exit + + # case 2: overlap w/ pointer passed as arg + # x = overlap_with_pointer(&x) + .globl _overlap_with_pointer +_overlap_with_pointer: + # copy pointer into RDX + movq %rsi, %rdx + # make sure return address (in RDI) and pointer's address (in RDX) + # are at least 24 bytes apart + subq %rdi, %rdx + # get absolute value of difference between addresses (in RDX) + # (absolute value implementation from https://stackoverflow.com/a/11927940) + movq %rdx, %rcx # copy RDX into RCX + negq %rdx # negate RDX + # if rdx is now negative, its restore original (positive) value + cmovl %rcx, %rdx + # compare diference to 24 + cmpq $24, %rdx + jl Loverlap_detected.0 + # no overlap, so go ahead and return value + # set each member to twice its original value (accessed thru RSI) + # l1 + movq (%rsi), %rcx + imul $2, %rcx + movq %rcx, (%rdi) + # l2 + movq 8(%rsi), %rcx + imul $2, %rcx + movq %rcx, 8(%rdi) + # l3 + movq 16(%rsi), %rcx + imul $2, %rcx + movq %rcx, 16(%rdi) + movq %rdi, %rax + ret +Loverlap_detected.0: + # space for return value overlaps w/ space pointed to by argument, so exit with error code + movl $3, %edi + call _exit