From: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
To: binutils@sourceware.org
Cc: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Subject: [PATCH 2/4] gas: Add support for LLVM addrsig and addrsig_sym directives on ELF.
Date: Wed, 25 May 2022 15:42:50 +0900 [thread overview]
Message-ID: <20220525064252.58603-3-ishitatsuyuki@gmail.com> (raw)
In-Reply-To: <20220525064252.58603-1-ishitatsuyuki@gmail.com>
These are LLVM extensions for specifying address significance, i.e.
if the symbols have their address taken, which is in turn used for
the Identical Code Folding link-time optimization.
For now, it's only implemented for the ELF platform; LLVM also supports
COFF, but the format is not well documented and usage is not widespread.
The addrsig directive signifies the assembler to emit the .llvm_addrsig
section, which signals the linker that it's possible to do (safe) ICF on
this object file.
The addrsig_sym directive marks a symbol as address significant. In this
patch, it's recorded with a boolean flag on the symbol. Later when the
symtab is ready, we loop over the symbols and construct the addrsig
section with indices of those symbols.
---
gas/config/obj-elf.c | 62 ++++++++++++++++++++++++++++++++++++++++++++
gas/symbols.c | 23 +++++++++++++++-
gas/symbols.h | 2 ++
3 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index c02d26ba453..a1c9ee6922c 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -75,6 +75,8 @@ static void obj_elf_symver (int);
static void obj_elf_subsection (int);
static void obj_elf_popsection (int);
static void obj_elf_gnu_attribute (int);
+static void obj_elf_llvm_addrsig (int);
+static void obj_elf_llvm_addrsig_sym (int);
static void obj_elf_tls_common (int);
static void obj_elf_lcomm (int);
static void obj_elf_struct (int);
@@ -121,6 +123,9 @@ static const pseudo_typeS elf_pseudo_table[] =
/* A GNU extension for object attributes. */
{"gnu_attribute", obj_elf_gnu_attribute, 0},
+ {"addrsig", obj_elf_llvm_addrsig, 0},
+ {"addrsig_sym", obj_elf_llvm_addrsig_sym, 0},
+
/* These are used for dwarf2. */
{ "file", dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
@@ -191,6 +196,7 @@ static const pseudo_typeS ecoff_debug_pseudo_table[] =
/* This is called when the assembler starts. */
asection *elf_com_section_ptr;
+static bool addrsig_enabled;
void
elf_begin (void)
@@ -205,6 +211,8 @@ elf_begin (void)
s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
symbol_table_insert (section_symbol (s));
elf_com_section_ptr = bfd_com_section_ptr;
+
+ addrsig_enabled = false;
}
void
@@ -2104,6 +2112,58 @@ obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
obj_elf_vendor_attribute (OBJ_ATTR_GNU);
}
+static void obj_elf_llvm_addrsig (int ignored ATTRIBUTE_UNUSED)
+{
+ demand_empty_rest_of_line ();
+ addrsig_enabled = true;
+}
+
+static void obj_elf_llvm_addrsig_sym (int ignored ATTRIBUTE_UNUSED)
+{
+ char *name;
+ symbolS *sym;
+
+ get_symbol_name (&name);
+ demand_empty_rest_of_line ();
+
+ sym = symbol_find_or_make (name);
+ S_SET_ADDRSIG (sym);
+ symbol_mark_used_in_reloc (sym);
+}
+
+/* Emit an unsigned "little-endian base 128" number. */
+
+static unsigned int
+out_uleb128 (valueT value)
+{
+ return output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
+}
+
+static void
+obj_elf_out_llvm_addrsig (void)
+{
+ segT addrsig_seg;
+ symbolS *symp;
+ int symtab_index;
+ unsigned int len = 0;
+
+ if (!addrsig_enabled)
+ return;
+
+ addrsig_seg = subseg_new (".llvm_addrsig", 0);
+ elf_section_type (addrsig_seg) = SHT_LLVM_ADDRSIG;
+ bfd_set_section_flags (addrsig_seg, SEC_HAS_CONTENTS | SEC_EXCLUDE);
+ for (symtab_index = 0, symp = symbol_rootP; symp; symp = symbol_next (symp))
+ {
+ if (S_GET_ADDRSIG (symp))
+ len += out_uleb128 (symtab_index);
+ if (symbol_written_p (symp))
+ symtab_index++;
+ }
+ frag_now->fr_fix = frag_now_fix_octets ();
+ bfd_set_section_size(addrsig_seg, len);
+}
+
void
elf_obj_read_begin_hook (void)
{
@@ -2899,6 +2959,8 @@ elf_frob_file (void)
{
bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
+ obj_elf_out_llvm_addrsig();
+
#ifdef elf_tc_final_processing
elf_tc_final_processing ();
#endif
diff --git a/gas/symbols.c b/gas/symbols.c
index fb480be6f21..dda37143a54 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -88,6 +88,10 @@ struct symbol_flags
/* Set when a warning about the symbol containing multibyte characters
is generated. */
unsigned int multibyte_warned : 1;
+
+ /* Set when a symbol is marked as address significant, i.e. its address
+ is taken. */
+ unsigned int addr_sig : 1;
};
/* A pointer in the symbol may point to either a complete symbol
@@ -204,7 +208,7 @@ static void *
symbol_entry_find (htab_t table, const char *name)
{
hashval_t hash = htab_hash_string (name);
- symbol_entry_t needle = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ symbol_entry_t needle = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
hash, name, 0, 0, 0 } };
return htab_find_with_hash (table, &needle, hash);
}
@@ -2578,6 +2582,23 @@ S_SET_FORWARD_REF (symbolS *s)
s->flags.forward_ref = 1;
}
+bool
+S_GET_ADDRSIG (symbolS *s)
+{
+ if (s->flags.local_symbol)
+ abort();
+ return s->flags.addr_sig;
+}
+
+
+void
+S_SET_ADDRSIG (symbolS *s)
+{
+ if (s->flags.local_symbol)
+ s = local_symbol_convert (s);
+ s->flags.addr_sig = 1;
+}
+
/* Return the previous symbol in a chain. */
symbolS *
diff --git a/gas/symbols.h b/gas/symbols.h
index 19eb658ca68..e7802ba8734 100644
--- a/gas/symbols.h
+++ b/gas/symbols.h
@@ -115,6 +115,8 @@ extern void S_SET_THREAD_LOCAL (symbolS *);
extern void S_SET_VOLATILE (symbolS *);
extern void S_CLEAR_VOLATILE (symbolS *);
extern void S_SET_FORWARD_REF (symbolS *);
+extern bool S_GET_ADDRSIG (symbolS *s);
+extern void S_SET_ADDRSIG (symbolS *);
#ifndef WORKING_DOT_WORD
struct broken_word
--
2.36.1
next prev parent reply other threads:[~2022-05-25 6:43 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-25 6:42 [PATCH 0/4] gas: Add support for LLVM addrsig and addrsig_sym Tatsuyuki Ishi
2022-05-25 6:42 ` [PATCH 1/4] elf: Add definition for SHT_LLVM_ADDRSIG Tatsuyuki Ishi
2022-05-26 10:03 ` Jan Beulich
2022-05-26 10:13 ` Tatsuyuki Ishi
2022-05-26 10:19 ` Jan Beulich
2022-05-26 10:36 ` Tatsuyuki Ishi
2022-05-27 17:28 ` Peter Collingbourne
2022-05-25 6:42 ` Tatsuyuki Ishi [this message]
2022-05-25 7:23 ` [PATCH 2/4] gas: Add support for LLVM addrsig and addrsig_sym directives on ELF Alan Modra
2022-05-25 7:49 ` Jan Beulich
2022-05-25 7:58 ` Tatsuyuki Ishi
2022-05-25 8:07 ` Fangrui Song
2022-05-25 8:34 ` Jan Beulich
2022-05-25 8:41 ` Tatsuyuki Ishi
2022-05-25 6:42 ` [PATCH 3/4] bfd: Output SH_LINK to .symtab for SHT_LLVM_ADDRSIG Tatsuyuki Ishi
2022-05-25 7:46 ` Jan Beulich
2022-05-25 6:42 ` [PATCH 4/4] gas: Add basic test for addrsig Tatsuyuki Ishi
2022-05-25 7:30 ` Alan Modra
2022-05-25 7:19 ` [PATCH 0/4] gas: Add support for LLVM addrsig and addrsig_sym Fangrui Song
2022-05-25 7:34 ` Alan Modra
2022-05-25 7:59 ` Fangrui Song
2022-05-25 8:01 ` Tatsuyuki Ishi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220525064252.58603-3-ishitatsuyuki@gmail.com \
--to=ishitatsuyuki@gmail.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).