From 697a9c0e8788875dbe93ae16cf737fefe36e1508 Mon Sep 17 00:00:00 2001 From: Perry Kivolowitz Date: Wed, 28 Feb 2024 10:47:55 -0600 Subject: [PATCH] WTF was I thinking before? --- section_1/structs/defining.md | 169 ++++++++++++-------------- section_1/structs/test01_companion1.s | 21 ---- section_1/structs/test02.s | 15 +++ section_1/structs/test02_companion1.s | 49 +++++--- section_1/structs/test02_companion2.s | 45 ++++--- section_1/structs/test02_companion3.s | 51 +++++--- 6 files changed, 190 insertions(+), 160 deletions(-) delete mode 100644 section_1/structs/test01_companion1.s create mode 100644 section_1/structs/test02.s diff --git a/section_1/structs/defining.md b/section_1/structs/defining.md index 971d307..263229d 100644 --- a/section_1/structs/defining.md +++ b/section_1/structs/defining.md @@ -4,9 +4,9 @@ Given: ```c struct Foo { - short a; - char b; - int c; + short a; + char b; + int c; }; struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc }; @@ -15,62 +15,68 @@ struct Foo Bar = { 0xaaaa, 0xbb, 0xcccccccc }; Here is [one](./test02_companion1.s) way of defining and accessing the struct: ```text - .global main // 1 - .text // 2 - .align 2 // 3 - // 4 -main: // 5 - str x30, [sp, 16]! // 6 - // 7 - ldr x0, =fmt // 8 - ldr x1, =Bar // 9 - ldrh w2, [x1] // 10 - ldrb w3, [x1, 2] // 11 - ldr w4, [x1, 4] // 12 - bl printf // 13 - // 14 - ldr x30, [sp], 16 // 15 - mov w0, wzr // 16 - ret // 17 - // 18 - .data // 19 - // 20 -fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" // 21 +#include "apple-linux-convergence.S" // 1 + // 2 + GLABEL main // 3 + .text // 4 + .p2align 2 // 5 + // 6 +MAIN // 7 + PUSH_P x29, x30 // 8 + mov x29, sp // 9 + // 10 + LLD_ADDR x0, fmt // 11 + LLD_ADDR x1, bar // 12 + ldrh w2, [x1, 0] // 13 + ldrb w3, [x1, 2] // 14 + ldr w4, [x1, 4] // 15 +#if defined(__APPLE__) // 16 + PUSH_P x3, x4 // 17 + PUSH_P x1, x2 // 18 + CRT printf // 19 + add sp, sp, 32 // 20 +#else // 21 + CRT printf // 22 +#endif // 23 + POP_P x29, x30 // 24 + mov w0, wzr // 25 + ret // 26 + // 27 + .data // 28 + // 29 +fmt: .asciz "%p a: 0x%lx b: %x c: %x\n" // 30 +bar: .short 0xaaaa // 31 + .byte 0xbb // 32 + .byte 0 // padding // 33 + .word 0xcccccccc // 34 + // 35 + .end // 36 ``` -It would be understandable if you don't see where the `struct` is being -defined. That's because it isn't. Rather, the implied +0 on `line 10` and -the 2 and 4 on `lines 11` and `12` are the hard coded offsets into the -`struct`. +It would be understandable if you don't see where the structure of the +`struct` is being specified in the code. That's because it isn't. +Rather, focus on the 0, 2 and 4 on lines 30 through 32. These are the +hard coded offsets of the struct's fields `a`, `b` and `c`. -[Here](./test02_companion2.s) is a second way to define a `struct`. +A second way to define the offsets of the fields within a struct which +is preferable to the one above is excerpted here. + + +The full text of the file is located +[here](./test02_companion2.s). ```text - .global main // 1 - .text // 2 - .align 2 // 3 - // 4 - .equ foo_a, 0 # like #define // 5 - .equ foo_b, 2 # like #define // 6 - .equ foo_c, 4 # like #define // 7 - // 8 -main: // 9 - str x30, [sp, 16]! // 10 - // 11 - ldr x0, =fmt // 12 - ldr x1, =Bar // 13 - ldrh w2, [x1, foo_a] // 14 - ldrb w3, [x1, foo_b] // 15 - ldr w4, [x1, foo_c] // 16 - bl printf // 17 - // 18 - ldr x30, [sp], 16 // 19 - mov w0, wzr // 20 - ret // 21 - // 22 - .data // 23 - // 24 -fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" // 25 + .equ foo_a, 0 // like #define + .equ foo_b, 2 // like #define + .equ foo_c, 4 // like #define +``` + +and here: + +```text + ldrh w2, [x1, foo_a] + ldrb w3, [x1, foo_b] + ldr w4, [x1, foo_c] ``` This method uses `.equ` to make the offsets into symbolic constants. @@ -78,45 +84,28 @@ This is just like using `#define` in C and C++. That is, the above is equivalent to the following in C or C++: ```c -#define foo_a 0 -#define foo_b 2 -#define foo_c 4 +#define foo_a 0 +#define foo_b 2 +#define foo_c 4 ``` -Finally, [here](./test02_companion3.s) is a third way of defining `structs`. +Finally, [here](./test02_companion3.s) is a third way of defining +`structs`. However, this method works on Linux but not on Apple. We have +not yet discovered the incantation that allows something like this on +Apple. + +The salient Linux-only code is excerpted below: ```text - .global main // 1 - .text // 2 - .align 2 // 3 - // 4 -main: // 5 - str x30, [sp, 16]! // 6 - // 7 - ldr x0, =fmt // 8 - ldr x1, =Bar // 9 - ldrh w2, [x1, Foo.a] // 10 - ldrb w3, [x1, Foo.b] // 11 - ldr w4, [x1, Foo.c] // 12 - bl printf // 13 - // 14 - ldr x30, [sp], 16 // 15 - mov w0, wzr // 16 - ret // 17 - // 18 - .section Foo // 19 - .struct 0 // a starts at 0 and goes for 2 // 20 -Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2 // 21 -Foo.b: .struct Foo.b + 2 // c starts at 4 // 22 -Foo.c: // 23 - // 24 - .data // 25 - // 26 -fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" // 27 + .section Foo + .struct 0 // a starts at 0 and goes for 2 +Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2 +Foo.b: .struct Foo.b + 2 // c starts at 4 +Foo.c: ``` -This method has a *substantial* benefit over the previous methods. Imagine -you need to insert a new field between `Foo.a` and `Foo.b`. Simply do so. -If you're using this third method, which is based on relative offsets, the -assembler will do the work of adjusting the following offsets for you. - +This method has a *substantial* benefit over the previous methods. +Imagine you need to insert a new field between `Foo.a` and `Foo.b`. +Simply do so. If you're using this third method, which is based on +relative offsets, the assembler will do the work of adjusting the +following offsets for you. diff --git a/section_1/structs/test01_companion1.s b/section_1/structs/test01_companion1.s deleted file mode 100644 index a29fb6b..0000000 --- a/section_1/structs/test01_companion1.s +++ /dev/null @@ -1,21 +0,0 @@ - .global main - .text - .align 2 - -main: - str x30, [sp, 16]! - - ldr x0, =fmt - ldr x1, =Fee - ldr x2, [x1] - ldrh w3, [x1, 8] - ldr w4, [x1, 12] - bl printf - - ldr x30, [sp], 16 - mov w0, wzr - ret - - .data - -fmt: .asciz "%p a: 0x%lx b: %x c: %x\n" diff --git a/section_1/structs/test02.s b/section_1/structs/test02.s new file mode 100644 index 0000000..0de3b53 --- /dev/null +++ b/section_1/structs/test02.s @@ -0,0 +1,15 @@ + .arch armv8-a + .file "test02.c" + .text + .global Bar + .data + .align 3 + .type Bar, %object + .size Bar, 8 +Bar: + .hword -21846 + .byte -69 + .zero 1 + .word -858993460 + .ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/section_1/structs/test02_companion1.s b/section_1/structs/test02_companion1.s index d8d5759..38f9dd6 100644 --- a/section_1/structs/test02_companion1.s +++ b/section_1/structs/test02_companion1.s @@ -1,21 +1,36 @@ - .global main - .text - .align 2 +#include "apple-linux-convergence.S" -main: - str x30, [sp, 16]! + GLABEL main + .text + .p2align 2 - ldr x0, =fmt - ldr x1, =Bar - ldrh w2, [x1] - ldrb w3, [x1, 2] - ldr w4, [x1, 4] - bl printf - - ldr x30, [sp], 16 - mov w0, wzr - ret +MAIN + PUSH_P x29, x30 + mov x29, sp - .data + LLD_ADDR x0, fmt + LLD_ADDR x1, bar + ldrh w2, [x1, 0] + ldrb w3, [x1, 2] + ldr w4, [x1, 4] +#if defined(__APPLE__) + PUSH_P x3, x4 + PUSH_P x1, x2 + CRT printf + add sp, sp, 32 +#else + CRT printf +#endif + POP_P x29, x30 + mov w0, wzr + ret -fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" + .data + +fmt: .asciz "%p a: 0x%lx b: %x c: %x\n" +bar: .short 0xaaaa + .byte 0xbb + .byte 0 // padding + .word 0xcccccccc + + .end diff --git a/section_1/structs/test02_companion2.s b/section_1/structs/test02_companion2.s index 767fa0c..7279c2c 100644 --- a/section_1/structs/test02_companion2.s +++ b/section_1/structs/test02_companion2.s @@ -1,25 +1,40 @@ - .global main +#include "apple-linux-convergence.S" + + GLABEL main .text - .align 2 + .p2align 2 - .equ foo_a, 0 # like #define - .equ foo_b, 2 # like #define - .equ foo_c, 4 # like #define + .equ foo_a, 0 // like #define + .equ foo_b, 2 // like #define + .equ foo_c, 4 // like #define -main: - str x30, [sp, 16]! +MAIN + PUSH_P x29, x30 + mov x29, sp - ldr x0, =fmt - ldr x1, =Bar + LLD_ADDR x0, fmt + LLD_ADDR x1, bar ldrh w2, [x1, foo_a] - ldrb w3, [x1, foo_b] - ldr w4, [x1, foo_c] - bl printf - - ldr x30, [sp], 16 + ldrb w3, [x1, foo_b] + ldr w4, [x1, foo_c] +#if defined(__APPLE__) + PUSH_P x3, x4 + PUSH_P x1, x2 + CRT printf + add sp, sp, 32 +#else + CRT printf +#endif + POP_P x29, x30 mov w0, wzr ret .data -fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" +fmt: .asciz "%p a: 0x%lx b: %x c: %x\n" +bar: .short 0xaaaa + .byte 0xbb + .byte 0 // padding + .word 0xcccccccc + + .end diff --git a/section_1/structs/test02_companion3.s b/section_1/structs/test02_companion3.s index 88108ad..e2a8a1a 100644 --- a/section_1/structs/test02_companion3.s +++ b/section_1/structs/test02_companion3.s @@ -1,27 +1,44 @@ - .global main +#include "apple-linux-convergence.S" + +// STRUCT DEFINITION WORKS ONLY FOR LINUX + + GLABEL main .text - .align 2 + .p2align 2 -main: - str x30, [sp, 16]! +MAIN + PUSH_P x29, x30 + mov x29, sp - ldr x0, =fmt - ldr x1, =Bar + LLD_ADDR x0, fmt + LLD_ADDR x1, bar ldrh w2, [x1, Foo.a] - ldrb w3, [x1, Foo.b] - ldr w4, [x1, Foo.c] - bl printf - - ldr x30, [sp], 16 + ldrb w3, [x1, Foo.b] + ldr w4, [x1, Foo.c] +#if defined(__APPLE__) + PUSH_P x3, x4 + PUSH_P x1, x2 + CRT printf + add sp, sp, 32 +#else + CRT printf +#endif + POP_P x29, x30 mov w0, wzr ret - .section Foo - .struct 0 // a starts at 0 and goes for 2 -Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2 -Foo.b: .struct Foo.b + 2 // c starts at 4 -Foo.c: + .section Foo + .struct 0 // a starts at 0 and goes for 2 +Foo.a: .struct Foo.a + 2 // b starts at 2 and goes for 2 +Foo.b: .struct Foo.b + 2 // c starts at 4 +Foo.c: .data -fmt: .asciz "%p a: 0x%x b: 0x%x c: 0x%x\n" +fmt: .asciz "%p a: 0x%lx b: %x c: %x\n" +bar: .short 0xaaaa + .byte 0xbb + .byte 0 // padding + .word 0xcccccccc + + .end