Skip to content

Statically emit ELF notes for Swift's metadata sections. #78411

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

Closed
wants to merge 4 commits 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
56 changes: 55 additions & 1 deletion stdlib/public/runtime/SwiftRT-ELF-WASM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
#include <cstddef>
#include <new>

#if defined(__ELF__) && __has_include(<link.h>)
#define EMIT_NOTES 1
#include <link.h>
#else
#define EMIT_NOTES 0
#endif

#if defined(__ELF__)
extern "C" const char __dso_handle[];
#elif defined(__wasm__)
Expand Down Expand Up @@ -48,9 +55,56 @@ static const void *__backtraceRef __attribute__((used, retain))
BOUNDS_VISIBILITY extern const char __start_##name; \
BOUNDS_VISIBILITY extern const char __stop_##name;

#if EMIT_NOTES
/// A structure, compatible with the standard ELF note layout, that describes
/// the bounds of a section known to Swift.
///
/// Sections described by these notes can be looked up at runtime using
/// `dl_iterate_phdr()` unless an image's notes have been stripped.
struct SectionNote {
/// The standard ELF note header.
ElfW(Nhdr) header;

/// The name of the ELF note.
///
/// The size of this array must be a multiple of `sizeof(void *)` plus `4` to
/// ensure correct alignment on 64-bit archs (because `ElfW(Nhdr)` is 12 bytes
/// long and only 4-byte aligned.)
char n_name[36];

/// The "payload" of the note.
struct Bounds {
/// The start address of the section.
const void *start;

/// The end address of the section.
const void *end;
};

/// The bounds of the section.
Bounds bounds;
};

#define DECLARE_NOTE(name) \
__attribute__((section(".note.swift5.section"), used)) \
static const SectionNote note_##name = { \
{ \
sizeof(SectionNote::n_name), /* n_namesz */ \
sizeof(SectionNote::Bounds), /* n_descsz */ \
0 /* n_type (unused) */ \
}, \
#name, \
&__start_##name, \
&__stop_##name \
};
#else
#define DECLARE_NOTE(name)
#endif

#define DECLARE_SWIFT_SECTION(name) \
DECLARE_EMPTY_METADATA_SECTION(name, "aR") \
DECLARE_BOUNDS(name)
DECLARE_BOUNDS(name) \
DECLARE_NOTE(name)

// These may or may not be present, depending on compiler switches; it's
// worth calling them out as a result.
Expand Down