Skip to content

Commit b997bdb

Browse files
committed
Define a new text section and use a linker script to safely calculating remote callback length
1 parent 5dd761a commit b997bdb

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

tools/swift-inspect/Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ let package = Package(
3737
name: "AndroidCLib",
3838
path: "Sources/AndroidCLib",
3939
publicHeadersPath: "include",
40-
cSettings: [.unsafeFlags(["-fPIC"])]),
40+
cSettings: [.unsafeFlags(["-fPIC"])],
41+
linkerSettings: [.unsafeFlags(["-Xlinker", "-TSources/AndroidCLib/section-text-remote.ld"])]),
4142
.systemLibrary(
4243
name: "SwiftInspectClientInterface"),
4344
.testTarget(

tools/swift-inspect/Sources/AndroidCLib/heap.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,32 +54,40 @@
5454
#define ENTRY_SIZE 2
5555

5656
// Callback for malloc_iterate. Because this function is meant to be copied to
57-
// a different process for execution, it must not make any function calls. It
58-
// could be written as asm, but simple C is more readable/maintainable and
59-
// should consistently compile to movable, position-independent code.
57+
// a different process for execution, it must not make any function calls to
58+
// ensure compiles to simple, position-independent code. It is implemented in C
59+
// for readability/maintainability. It is placed in its own code section to
60+
// simplify calculating its size.
61+
__attribute__((noinline, used, section(".text.remote")))
6062
static void heap_iterate_callback(unsigned long base, unsigned long size, void *arg) {
6163
volatile uint64_t *data = (uint64_t*)arg;
6264
while (data[NEXT_FREE_IDX] >= data[MAX_VALID_IDX]) {
6365
// SIGTRAP indicates the buffer is full and needs to be drained before more
6466
// entries can be written.
6567
__builtin_debugtrap();
68+
69+
// After the SIGTRAP, the signal handler advances the instruction pointer
70+
// (PC) to the next instruction. Inserting a nop instruction here ensures
71+
// the CPU has a clear, executable instruction to process, which avoids
72+
// potential speculative execution or pipeline issues that could arise if
73+
// the next instruction were a control transfer like a branch or jump.
6674
__asm__ __volatile__("nop");
6775
}
6876
data[data[NEXT_FREE_IDX]++] = base;
6977
data[data[NEXT_FREE_IDX]++] = size;
70-
__asm__ __volatile__(".align 8");
71-
__asm__ __volatile__(".local heap_iterate_callback_end");
72-
__asm__ __volatile__("heap_iterate_callback_end:");
7378
}
7479

80+
// Linker-populated symbol defined in section-text-remote.ld. Used to calculate
81+
// the size of the heap_iterate_callback function when copying it to a remote
82+
// process for execution.
83+
extern char _remote_code_section_end;
84+
7585
void* heap_iterate_callback_start() {
7686
return (void*)heap_iterate_callback;
7787
}
7888

7989
size_t heap_iterate_callback_len() {
80-
extern char heap_iterate_callback_end;
81-
return (uintptr_t)&heap_iterate_callback_end - (uintptr_t)heap_iterate_callback
82-
+ sizeof(uintptr_t);
90+
return (uintptr_t)&_remote_code_section_end - (uintptr_t)heap_iterate_callback;
8391
}
8492

8593
bool heap_iterate_metadata_init(void* data, size_t len) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*===------------------------------------------------------------------------===
2+
*
3+
* This source file is part of the Swift.org open source project
4+
*
5+
* Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
* Licensed under Apache License v2.0 with Runtime Library Exception
7+
*
8+
* See https://swift.org/LICENSE.txt for license information
9+
* See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
*
11+
*==------------------------------------------------------------------------==*/
12+
13+
SECTIONS
14+
{
15+
. = ALIGN(8);
16+
.text.remote : {
17+
_remote_code_section_start = .;
18+
*(.text.remote)
19+
_remote_code_section_end = .;
20+
}
21+
} INSERT AFTER .text;
22+

0 commit comments

Comments
 (0)