# define TrampolinePtrauth
#endif
+// A page of trampolines is as big as the maximum supported page size
+// everywhere except i386. i386 only exists for the watch simulator
+// now, and we know it really only has 4kB pages. Also see comments
+// below about PAGE_SIZE and PAGE_MAX_SIZE.
+#ifdef __i386__
+#define TRAMPOLINE_PAGE_SIZE PAGE_MIN_SIZE
+#else
+#define TRAMPOLINE_PAGE_SIZE PAGE_MAX_SIZE
+#endif
+
class TrampolinePointerWrapper {
struct TrampolinePointers {
class TrampolineAddress {
void check() {
#if DEBUG
- ASSERT(impl.address() == textSegment + PAGE_MAX_SIZE);
- ASSERT(impl.address() % PAGE_SIZE == 0); // not PAGE_MAX_SIZE
- assert(impl.address() + PAGE_MAX_SIZE ==
+ ASSERT(impl.address() == textSegment + TRAMPOLINE_PAGE_SIZE);
+ ASSERT(impl.address() % PAGE_SIZE == 0); // not TRAMPOLINE_PAGE_SIZE
+ ASSERT(impl.address() + TRAMPOLINE_PAGE_SIZE ==
last.address() + SLOT_SIZE);
ASSERT(last.address()+8 < textSegment + textSegmentSize);
ASSERT((last.address() - start.address()) % SLOT_SIZE == 0);
# if SUPPORT_STRET
- ASSERT(impl_stret.address() == textSegment + 2*PAGE_MAX_SIZE);
- ASSERT(impl_stret.address() % PAGE_SIZE == 0); // not PAGE_MAX_SIZE
- assert(impl_stret.address() + PAGE_MAX_SIZE ==
+ ASSERT(impl_stret.address() == textSegment + 2*TRAMPOLINE_PAGE_SIZE);
+ ASSERT(impl_stret.address() % PAGE_SIZE == 0); // not TRAMPOLINE_PAGE_SIZE
+ ASSERT(impl_stret.address() + TRAMPOLINE_PAGE_SIZE ==
last_stret.address() + SLOT_SIZE);
- assert(start.address() - impl.address() ==
+ ASSERT(start.address() - impl.address() ==
start_stret.address() - impl_stret.address());
- assert(last_stret.address() + SLOT_SIZE <
+ ASSERT(last_stret.address() + SLOT_SIZE <
textSegment + textSegmentSize);
- assert((last_stret.address() - start_stret.address())
+ ASSERT((last_stret.address() - start_stret.address())
% SLOT_SIZE == 0);
# endif
#endif
uintptr_t textSegment() { return get()->textSegment; }
uintptr_t textSegmentSize() { return get()->textSegmentSize; }
- // See comments below about PAGE_SIZE and PAGE_MAX_SIZE.
- uintptr_t dataSize() { return PAGE_MAX_SIZE; }
+ uintptr_t dataSize() { return TRAMPOLINE_PAGE_SIZE; }
uintptr_t impl() { return get()->impl.address(); }
uintptr_t start() { return get()->start.address(); }
// We must take care with our data layout on architectures that support
// multiple page sizes.
//
-// The trampoline template in __TEXT is sized and aligned with PAGE_MAX_SIZE.
-// On some platforms this requires additional linker flags.
+// The trampoline template in __TEXT is sized and aligned with PAGE_MAX_SIZE,
+// except on i386 which is a weird special case that uses PAGE_MIN_SIZE.
+// The TRAMPOLINE_PAGE_SIZE macro handles this difference. On some platforms,
+// aligning to PAGE_MAX_SIZE requires additional linker flags.
//
-// When we allocate a page group, we use PAGE_MAX_SIZE size.
-// This allows trampoline code to find its data by subtracting PAGE_MAX_SIZE.
+// When we allocate a page group, we use TRAMPOLINE_PAGE_SIZE size.
+// This allows trampoline code to find its data by subtracting TRAMPOLINE_PAGE_SIZE.
//
// When we allocate a page group, we use the process's page alignment.
// This simplifies allocation because we don't need to force greater than
// Payload data: block pointers and free list.
// Bytes parallel with trampoline header code are the fields above or unused
- // uint8_t payloads[PAGE_MAX_SIZE - sizeof(TrampolineBlockPageGroup)]
+ // uint8_t payloads[TRAMPOLINE_PAGE_SIZE - sizeof(TrampolineBlockPageGroup)]
// Code: Mach-O header, then trampoline header followed by trampolines.
// On platforms with struct return we have non-stret trampolines and
// stret trampolines. The stret and non-stret trampolines at a given
// index share the same data page.
- // uint8_t macho[PAGE_MAX_SIZE];
- // uint8_t trampolines[ArgumentModeCount][PAGE_MAX_SIZE];
+ // uint8_t macho[TRAMPOLINE_PAGE_SIZE];
+ // uint8_t trampolines[ArgumentModeCount][TRAMPOLINE_PAGE_SIZE];
// Per-trampoline block data format:
// initial value is 0 while page data is filled sequentially
// Skip over the data area, one page of Mach-O headers,
// and one text page for each mode before this one.
return (uintptr_t)this + Trampolines.dataSize() +
- PAGE_MAX_SIZE * (1 + aMode);
+ TRAMPOLINE_PAGE_SIZE * (1 + aMode);
}
IMP trampoline(int aMode, uintptr_t index) {