Skip to content

Commit 3977253

Browse files
committed
wip: rollup of aarch64 changes
1 parent 56080df commit 3977253

File tree

10 files changed

+75
-88
lines changed

10 files changed

+75
-88
lines changed
Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,16 @@
11
#pragma once
2-
#include <stddef.h>
3-
#include <stdint.h>
4-
5-
static void* memcpy (
6-
void* dst,
7-
const void* src,
8-
size_t len
9-
) {
10-
for (size_t i = 0; i < len; i++) {
11-
((uint8_t*)dst)[i] = ((const uint8_t*)src)[i];
12-
}
13-
}
14-
15-
static void* memset (
16-
void* dst,
17-
int c,
18-
size_t n
19-
) {
20-
for (size_t i = 0; i < n; i++) {
21-
((uint8_t*)dst)[i] = (uint8_t)(c);
22-
}
23-
return dst;
24-
}
252

263
static void jump_to_entrypoint (void* stack, void* entrypoint) {
4+
register long x0 asm("x0") = (long)stack;
5+
register long x1 asm("x1") = (long)entrypoint;
276
asm volatile (
287
"mov sp, x0;" // set the stack pointer.
298
"mov x29, xzr;" // clear the frame pointer.
309
"mov x0, xzr;" // clear atexit pointer
3110
"br x1;" // jump to the entrypoint
11+
:
12+
: "r"(x0), "r"(x1)
13+
: "memory", "cc"
3214
);
3315
__builtin_unreachable();
3416
}

packages/std/packages/stub/include/util.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ typedef struct {
2424
uint64_t len;
2525
} String;
2626

27+
void* memcpy (void* dst, const void* src, size_t len);
28+
void* memset (void* dst, int c, size_t n);
29+
2730
// Get the length of a string including the null byte.
2831
static size_t strlen_including_nul (const char* str) {
2932
size_t len = 0;

packages/std/packages/stub/include/x86_64/util.h

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,6 @@
11
#pragma once
22
#include <stddef.h>
33

4-
// Memcpy implementation.
5-
__attribute__((naked))
6-
static void* memcpy (
7-
void* dst,
8-
const void* src,
9-
size_t len
10-
) {
11-
asm volatile (
12-
"rep rex.w movsb;"
13-
"ret;"
14-
: "+D"(dst), "+S"(src), "+c"(len)
15-
:
16-
: "memory", "cc"
17-
);
18-
}
19-
20-
// Memset implementation.
21-
__attribute__((naked))
22-
static void* memset (
23-
void* dst,
24-
int c,
25-
size_t n
26-
) {
27-
asm volatile (
28-
"rep rex.w stosb;"
29-
"ret;"
30-
: "+D"(dst), "+c"(n)
31-
: "a"(c)
32-
: "memory", "cc"
33-
);
34-
}
35-
364
__attribute__((naked))
375
static void jump_to_entrypoint (void* stack, void* entrypoint) {
386
asm volatile (

packages/std/packages/stub/src/aarch64/start.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
_start:
55
mov x29, xzr
66
mov x0, sp
7-
bl _stub_start
7+
bl main

packages/std/packages/stub/src/aarch64/start2.s

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/std/packages/stub/src/stub.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44
#error "unknown architecture"
55
#endif
66

7-
// Common includes.
87
#include <stddef.h>
98
#include <stdint.h>
109
#include <elf.h>
1110
#include <stdbool.h>
1211

13-
// Internals.
1412
#include "arena.h"
1513
#include "debug.h"
1614
#include "footer.h"
@@ -807,7 +805,7 @@ static void exec (Arena* arena, Manifest* manifest, char* argv0, Options* option
807805
}
808806

809807
// Main entrypoint.
810-
void _stub_start (void *sp) {
808+
void main (void *sp) {
811809
// State.
812810
Arena arena = {0};
813811
Footer footer = {0};

packages/std/packages/stub/src/stub2.c

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/std/packages/stub/src/wrap.c

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
#include <unistd.h>
1111

1212
#ifdef __aarch64__
13-
#define PAGE_SIZE 0x10000
1413
#define MACHINE EM_AARCH64
1514
#endif
1615
#ifdef __x86_64__
17-
#define PAGE_SIZE 0x1000
1816
#define MACHINE EM_X86_64
1917
#endif
2018

@@ -51,6 +49,7 @@ typedef struct Analysis Analysis;
5149
struct Analysis {
5250
Elf64_Phdr* pt_interp;
5351
Elf64_Addr max_vaddr;
52+
Elf64_Addr max_align;
5453
};
5554

5655
typedef struct ProgramHeaders ProgramHeaders;
@@ -127,12 +126,15 @@ Analysis elf_analyze (Elf elf) {
127126
Elf64_Phdr* end = itr + elf.ehdr->e_phnum;
128127
int i = 0;
129128
for(; itr != end; itr++) {
130-
if (itr->p_type != PT_LOAD) {
129+
if (itr->p_type == PT_LOAD) {
131130
Elf64_Addr end_of_segment = itr->p_vaddr + itr->p_memsz;
132131
TRACE("phdr[%d] vaddr:%lx memsz:%lx, end:%lx", i++, itr->p_vaddr, itr->p_memsz, end_of_segment);
133132
if (end_of_segment > analysis.max_vaddr) {
134133
analysis.max_vaddr = end_of_segment;
135134
}
135+
if (itr->p_align > analysis.max_align) {
136+
analysis.max_align = itr->p_align;
137+
}
136138
}
137139
if (itr->p_type == PT_INTERP) {
138140
ABORT_IF(analysis.pt_interp, "multiple interpreters found");
@@ -143,6 +145,35 @@ Analysis elf_analyze (Elf elf) {
143145
return analysis;
144146
}
145147

148+
149+
// Bubble sort loadable segments
150+
void elf_sort_segments (Elf64_Phdr* phdr, size_t num) {
151+
TRACE("num segments = %d", num);
152+
Elf64_Addr start_addr, end_addr;
153+
for(;;) {
154+
bool swapped = false;
155+
for (int n = 0; n < (num - 1); n++) {
156+
end_addr = phdr[n].p_vaddr + phdr[n].p_memsz;
157+
start_addr = phdr[n + 1].p_vaddr;
158+
TRACE("phdr[%d].start = %lx, phdr[%d].end = %lx, phdr[%d].start = %lx", n, phdr[n].p_vaddr, n, end_addr, n + 1, start_addr);
159+
ABORT_IF(start_addr >= phdr[n].p_vaddr && start_addr < end_addr, "invalid program headers");
160+
if (end_addr > start_addr) {
161+
TRACE("swap phdr[%d], phdr[%d]", n, n+1);
162+
Elf64_Phdr tmp = phdr[n];
163+
phdr[n] = phdr[n+1];
164+
phdr[n + 1] = tmp;
165+
swapped = true;
166+
TRACE("swapped %d and %d", n, n + 1);
167+
} else {
168+
TRACE("skipping %d", n);
169+
}
170+
}
171+
if (!swapped) {
172+
break;
173+
}
174+
}
175+
}
176+
146177
int main (int argc, const char** argv) {
147178
TRACING_ENABLED = getenv("TANGRAM_TRACING") != NULL;
148179

@@ -207,20 +238,22 @@ int main (int argc, const char** argv) {
207238

208239
// Compute the offset/size of the stub binary.
209240
size_t stub_offs = headers.phdr
210-
? ALIGN(headers.offs + headers.sz, PAGE_SIZE)
211-
: ALIGN(output.sz, PAGE_SIZE);
212-
size_t stub_sz = ALIGN(stub_bin.sz, PAGE_SIZE);
241+
? ALIGN(headers.offs + headers.sz, analysis.max_align)
242+
: ALIGN(output.sz, analysis.max_align);
243+
size_t stub_sz = ALIGN(stub_bin.sz, analysis.max_align);
213244

214245
// Create segment for the stub.
215246
stub_segment->p_type = PT_LOAD;
216247
stub_segment->p_flags = PF_R | PF_X;
217-
stub_segment->p_align = 0x1000;
248+
stub_segment->p_align = analysis.max_align;
218249
stub_segment->p_offset = stub_offs;
219-
stub_segment->p_paddr = analysis.max_vaddr;
220-
stub_segment->p_vaddr = analysis.max_vaddr;
250+
stub_segment->p_paddr = ALIGN(analysis.max_vaddr, analysis.max_align);
251+
stub_segment->p_vaddr = ALIGN(analysis.max_vaddr, analysis.max_align);
221252
stub_segment->p_filesz = stub_sz;
222253
stub_segment->p_memsz = stub_sz;
223254

255+
TRACE("new segment vaddr: %lx, memsz: %lx", stub_segment->p_vaddr, stub_segment->p_memsz);
256+
224257
// Create the footer.
225258
Footer footer = {
226259
.size = manifest.sz,
@@ -230,12 +263,26 @@ int main (int argc, const char** argv) {
230263

231264
// Update the entrypoint.
232265
TRACE("%s entrypoint:%lx", stub_elf.path, stub_exe.ehdr->e_entry);
233-
output_exe.ehdr->e_entry = analysis.max_vaddr + stub_exe.ehdr->e_entry;
266+
output_exe.ehdr->e_entry = stub_segment->p_vaddr + stub_exe.ehdr->e_entry;
234267

235268
// Patch the program header table if necessary.
236269
if (headers.phdr) {
237270
output_exe.ehdr->e_phoff = headers.offs;
238271
output_exe.ehdr->e_phnum = headers.num;
272+
} else {
273+
// Sort program headers.
274+
Elf64_Phdr* start = NULL;
275+
size_t num = 0;
276+
for(int i = 0; i < output_exe.ehdr->e_phnum; i++) {
277+
if (output_exe.phdr[i].p_type != PT_LOAD) {
278+
continue;
279+
}
280+
if (!start) {
281+
start = &output_exe.phdr[i];
282+
}
283+
num++;
284+
}
285+
elf_sort_segments(start, num);
239286
}
240287

241288
// Close elf objects.
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
# This defines the entrypoint of the stub itself.
21
.section .text.start,"ax",@progbits
32
.global _start
43
.type _start, @function
54
_start:
6-
# Clear the base pointer.
75
xor %rbp, %rbp
8-
9-
# _stub_start(%rsp)
106
mov %rsp, %rdi
11-
call _stub_start
12-
7+
call main

packages/std/wrap/stub.tg.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,18 @@ export const build = async (unresolved: tg.Unresolved<BuildArg>) => {
145145
146146
# Compile our sources
147147
$CC_${tripleToEnvVar(target)} \
148-
${source}/stub/src/${arch}/start2.s \
149-
${source}/stub/src/stub2.c \
148+
${source}/stub/src/${arch}/start.s \
149+
${source}/stub/src/stub.c \
150+
${source}/stub/src/manifest.c \
151+
${source}/stub/src/manifest/json.c \
152+
${source}/stub/src/util.c \
150153
-I${source}/stub/include \
151154
-nostdlib \
155+
-nolibc \
152156
-ffreestanding \
153157
-fno-stack-protector \
154158
-static \
159+
-static-libgcc \
155160
-fno-asynchronous-unwind-tables \
156161
-fPIC \
157162
-Werror \

0 commit comments

Comments
 (0)