public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
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


  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).