Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Runtime] Define GOT equivalents for Linux for BuiltinProtocolConformances #34457

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 68 additions & 8 deletions stdlib/public/runtime/BuiltinProtocolConformances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,39 @@ using StaticInfixWitness = SWIFT_CC(swift) bool(OpaqueValue *, OpaqueValue *,

// Elf indirect symbol references.
#if defined(__ELF__)
#define INDIRECT_RELREF_GOTPCREL(SYMBOL) SYMBOL "@GOTPCREL + 1"
#define INDIRECT_RELREF_GOTPCREL(SYMBOL) ".Lgot." SYMBOL " - . + 1"

// Helper for defining the .type on linux.
#if defined(__arm__) && !defined(__aarch64__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PPC uses the % sigil as well

#define TYPE_OBJECT "%object"
#else
#define TYPE_OBJECT "@object"
#endif

// Helper to get the pointer sized pointer to symbol and the right alignment.
#if defined(__x86_64__) || defined(__aarch64__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PPC64?

#define POINTER_FOR_GOT(SYMBOL) \
" .quad (" SYMBOL ")\n" \
" .size .Lgot." SYMBOL ", 8\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might want to have a level of indirection here. The .L not guaranteed to the assembler local prefix.


#define P2ALIGN_FOR_GOT " .p2align 3\n"
#else
#define POINTER_FOR_GOT(SYMBOL) \
" .long (" SYMBOl ")\n" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: lowercase l at the end of SYMBOl.

" .size .Lgot." SYMBOL ", 4\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here to the 8-byte case.


#define P2ALIGN_FOR_GOT " .p2align 2\n"
#endif

// Helper to significantly reduce the amount of code necessary to create got
// equivalent variables for linux.
#define GOT_EQUIVALENT(SYMBOL) \
__asm( \
" .type .Lgot." SYMBOL ", " TYPE_OBJECT "\n" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you should create another macro to generate the name rather than use the .Lgot." SYMBOL" in multiple locations.

P2ALIGN_FOR_GOT \
".Lgot." SYMBOL ":\n" \
POINTER_FOR_GOT(SYMBOL) \
);
#endif

// MachO indirect symbol references.
Expand Down Expand Up @@ -88,15 +120,22 @@ __asm(
);
#endif

// Define the got equivalents for the following on linux because some archs
// support relocations like @GOTPCREL, but others don't.
#if defined(__ELF__)
GOT_EQUIVALENT(EQUATABLE_DESCRIPTOR_SYMBOL)
GOT_EQUIVALENT(EQUATABLE_EE_METHOD_DESCRIPTOR)
#endif

// Define the conformance descriptor for tuple Equatable. We do this in
// assembly to work around relative reference issues.
__asm(
#if defined(__ELF__)
" .type __swift_tupleEquatable_private, @object\n"
" .type __swift_tupleEquatable_private, " TYPE_OBJECT "\n"
" .local __swift_tupleEquatable_private\n"
" .comm __swift_tupleEquatable_private, 128, 16\n"
" .protected " TUPLE_EQUATABLE_CONF "\n"
" .type " TUPLE_EQUATABLE_CONF ", @object\n"
" .type " TUPLE_EQUATABLE_CONF ", " TYPE_OBJECT "\n"
" .section .rodata\n"
#elif defined(__MACH__)
" .zerofill __DATA, __bss, __swift_tupleEquatable_private, 128, 4\n"
Expand Down Expand Up @@ -225,7 +264,7 @@ __asm(
__asm(
#if defined(__ELF__)
" .hidden \"" TUPLE_COMPARABLE_ASSOCIATEDCONFORMANCE "\"\n"
" .type \"" TUPLE_COMPARABLE_ASSOCIATEDCONFORMANCE "\", @object\n"
" .type \"" TUPLE_COMPARABLE_ASSOCIATEDCONFORMANCE "\", " TYPE_OBJECT "\n"
" .section swift5_typeref, \"a\"\n"
" .weak \"" TUPLE_COMPARABLE_ASSOCIATEDCONFORMANCE "\"\n"
#elif defined(__MACH__)
Expand All @@ -251,15 +290,26 @@ __asm(
#endif
);

// Define the got equivalents for the following on linux because some archs
// support relocations like @GOTPCREL, but others don't.
#if defined(__ELF__)
GOT_EQUIVALENT(COMPARABLE_DESCRIPTOR_SYMBOL)
GOT_EQUIVALENT(COMPARABLE_BASE_CONFORMANCE_DESCRIPTOR)
GOT_EQUIVALENT(COMPARABLE_LT_METHOD_DESCRIPTOR)
GOT_EQUIVALENT(COMPARBALE_LTE_METHOD_DESCRIPTOR)
GOT_EQUIVALENT(COMPARABLE_GTE_METHOD_DESCRIPTOR)
GOT_EQUIVALENT(COMPARABLE_GT_METHOD_DESCRIPTOR)
#endif

// Define the conformance descriptor for tuple Comparable. We do this in
// assembly to work around relative reference issues.
__asm(
#if defined(__ELF__)
" .type __swift_tupleComparable_private, @object\n"
" .type __swift_tupleComparable_private, " TYPE_OBJECT "\n"
" .local __swift_tupleComparable_private\n"
" .comm __swift_tupleComparable_private, 128, 16\n"
" .protected " TUPLE_COMPARABLE_CONF "\n"
" .type " TUPLE_COMPARABLE_CONF ", @object\n"
" .type " TUPLE_COMPARABLE_CONF ", " TYPE_OBJECT "\n"
" .section .rodata\n"
#elif defined(__MACH__)
" .zerofill __DATA, __bss, __swift_tupleComparable_private, 128, 4\n"
Expand Down Expand Up @@ -617,15 +667,25 @@ __asm(
);
#endif

// Define the got equivalents for the following on linux because some archs
// support relocations like @GOTPCREL, but others don't.
#if defined(__ELF__)
GOT_EQUIVALENT(HASHABLE_DESCRIPTOR_SYMBOL)
GOT_EQUIVALENT(HASHABLE_BASE_CONFORMANCE_DESCRIPTOR)
GOT_EQUIVALENT(HASHABLE_HASHVALUE_METHOD_DESCRIPTOR)
GOT_EQUIVALENT(HASHABLE_HASH_METHOD_DESCRIPTOR)
GOT_EQUIVALENT(HASHABLE_RAWHASHVALUE_METHOD_DESCRIPTOR)
#endif

// Define the conformance descriptor for tuple Hashable. We do this in
// assembly to work around relative reference issues.
__asm(
#if defined(__ELF__)
" .type __swift_tupleHashable_private, @object\n"
" .type __swift_tupleHashable_private, " TYPE_OBJECT "\n"
" .local __swift_tupleHashable_private\n"
" .comm __swift_tupleHashable_private, 128, 16\n"
" .protected " TUPLE_HASHABLE_CONF "\n"
" .type " TUPLE_HASHABLE_CONF ", @object\n"
" .type " TUPLE_HASHABLE_CONF ", " TYPE_OBJECT "\n"
" .section .rodata\n"
#elif defined(__MACH__)
" .zerofill __DATA, __bss, __swift_tupleHashable_private, 128, 4\n"
Expand Down