aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/aarch64elf.em
diff options
context:
space:
mode:
Diffstat (limited to 'ld/emultempl/aarch64elf.em')
-rw-r--r--ld/emultempl/aarch64elf.em48
1 files changed, 47 insertions, 1 deletions
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index afa91af..91d58d8 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -42,6 +42,11 @@ static aarch64_protection_opts sw_protections = {
.gcs_report_dynamic = MARKING_UNSET,
};
+static aarch64_memtag_opts memtag_opts = {
+ .memtag_mode = AARCH64_MEMTAG_MODE_NONE,
+ .memtag_stack = 0,
+};
+
#define COMPILE_TIME_STRLEN(s) \
(sizeof(s) - 1)
@@ -335,7 +340,8 @@ aarch64_elf_create_output_section_statements (void)
pic_veneer,
fix_erratum_835769, fix_erratum_843419,
no_apply_dynamic_relocs,
- &sw_protections);
+ &sw_protections,
+ &memtag_opts);
stub_file = lang_add_input_file ("linker stubs",
lang_input_file_is_fake_enum,
@@ -440,6 +446,31 @@ aarch64_parse_gcs_option (const char *_optarg)
#undef GCS
#undef GCS_LEN
}
+
+static bool
+aarch64_parse_memtag_mode_option (const char *_optarg)
+{
+ #define MEMTAG_MODE "memtag-mode"
+ #define MEMTAG_MODE_LEN COMPILE_TIME_STRLEN (MEMTAG_MODE)
+
+ if (strncmp (_optarg, MEMTAG_MODE, MEMTAG_MODE_LEN) != 0)
+ return false;
+
+ if (strcmp (_optarg + MEMTAG_MODE_LEN, "=none") == 0)
+ memtag_opts.memtag_mode = AARCH64_MEMTAG_MODE_NONE;
+ else if (strcmp (_optarg + MEMTAG_MODE_LEN, "=sync") == 0)
+ memtag_opts.memtag_mode = AARCH64_MEMTAG_MODE_SYNC;
+ else if (strcmp (_optarg + MEMTAG_MODE_LEN, "=async") == 0)
+ memtag_opts.memtag_mode = AARCH64_MEMTAG_MODE_ASYNC;
+ else
+ einfo (_("%X%P: error: unrecognized value '-z %s'\n"), _optarg);
+
+ return true;
+
+ #undef MEMTAG_MODE
+ #undef MEMTAG_MODE_LEN
+}
+
EOF
# Define some shell vars to insert bits of code into the standard elf
@@ -518,6 +549,17 @@ PARSE_AND_LIST_OPTIONS='
and output have GCS marking.\n\
error: Emit error when the input objects are missing GCS markings\n\
and output have GCS marking.\n"));
+ fprintf (file, _("\
+ -z memtag-mode[=none|sync|async] Select Memory Tagging Extension mode of operation to use.\n\
+ Emits a DT_AARCH64_MEMTAG_MODE dynamic tag for the binary.\n\
+ This entry is only valid on the main executable. It is\n\
+ ignored in the dynamically loaded objects by the loader.\n\
+ none (default): Disable MTE checking of memory reads and writes.\n\
+ sync: Enable precise exceptions when mismatched address and\n\
+ allocation tags detected on load/store operations.\n\
+ async: Enable imprecise exceptions.\n"));
+ fprintf (file, _("\
+ -z memtag-stack Mark program stack with MTE protection.\n"));
'
PARSE_AND_LIST_ARGS_CASE_Z_AARCH64='
@@ -533,6 +575,10 @@ PARSE_AND_LIST_ARGS_CASE_Z_AARCH64='
{}
else if (aarch64_parse_gcs_option (optarg))
{}
+ else if (aarch64_parse_memtag_mode_option (optarg))
+ {}
+ else if (strcmp (optarg, "memtag-stack") == 0)
+ memtag_opts.memtag_stack = 1;
'
PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_AARCH64"