binutils/add-ulp-section.diff
Michael Matz 79d05b9598 Accepting request 1060669 from home:marxin:branches:devel:gcc
- Update to version 2.40:
* Objdump has a new command line option --show-all-symbols which will make it
  display all symbols that match a given address when disassembling.  (Normally
  only the first symbol that matches an address is shown).
* Add --enable-colored-disassembly configure time option to enable colored
  disassembly output by default, if the output device is a terminal.  Note,
  this configure option is disabled by default.
* DCO signed contributions are now accepted.
* objcopy --decompress-debug-sections now supports zstd compressed debug
  sections.  The new option --compress-debug-sections=zstd compresses debug
  sections with zstd.
* addr2line and objdump --dwarf now support zstd compressed debug sections.
* The dlltool program now accepts --deterministic-libraries and
  --non-deterministic-libraries as command line options to control whether or
  not it generates deterministic output libraries.  If neither of these options
  are used the default is whatever was set when the binutils were configured.
* readelf and objdump now have a newly added option --sframe which dumps the
  SFrame section.
* Add support for Intel RAO-INT instructions.
* Add support for Intel AVX-NE-CONVERT instructions.
* Add support for Intel MSRLIST instructions.
* Add support for Intel WRMSRNS instructions.
* Add support for Intel CMPccXADD instructions.
* Add support for Intel AVX-VNNI-INT8 instructions.
* Add support for Intel AVX-IFMA instructions.
* Add support for Intel PREFETCHI instructions.
* Add support for Intel AMX-FP16 instructions.
* gas now supports --compress-debug-sections=zstd to compress
  debug sections with zstd.
* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd}

OBS-URL: https://build.opensuse.org/request/show/1060669
OBS-URL: https://build.opensuse.org/package/show/devel:gcc/binutils?expand=0&rev=429
2023-01-24 15:25:48 +00:00

208 lines
5.9 KiB
Diff

This is for userspace live patching, adding some space into
shared libs or executable (in the .ulp section) when one of the
input files contains a section named .ulp.track.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 101c2fdf50d..f5d9e201fdb 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1487,6 +1487,10 @@ struct elf_backend_data
(const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection,
Elf_Internal_Shdr *osection);
+ bool (*elf_backend_is_ulp_enabled) (bfd *abfd);
+
+ bool (*elf_backend_setup_ulp) (struct bfd_link_info *);
+
/* Used to handle bad SHF_LINK_ORDER input. */
void (*link_order_error_handler) (const char *, ...);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ce1407fa2dc..5c70bcf6c07 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -7260,6 +7260,13 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
s = bfd_get_linker_section (dynobj, ".gnu.version");
s->flags |= SEC_EXCLUDE;
}
+
+ if (bed->elf_backend_is_ulp_enabled != NULL
+ && bed->elf_backend_setup_ulp != NULL
+ && (*bed->elf_backend_is_ulp_enabled) (info->input_bfds))
+ {
+ (*bed->elf_backend_setup_ulp)(info);
+ }
}
return true;
}
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 4c6b1f20340..1f54509cd08 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -771,6 +771,14 @@
#define elf_backend_copy_special_section_fields _bfd_elf_copy_special_section_fields
#endif
+#ifndef elf_backend_is_ulp_enabled
+#define elf_backend_is_ulp_enabled NULL
+#endif
+
+#ifndef elf_backend_setup_ulp
+#define elf_backend_setup_ulp NULL
+#endif
+
#ifndef elf_backend_compact_eh_encoding
#define elf_backend_compact_eh_encoding NULL
#endif
@@ -904,6 +912,8 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_maybe_function_sym,
elf_backend_get_reloc_section,
elf_backend_copy_special_section_fields,
+ elf_backend_is_ulp_enabled,
+ elf_backend_setup_ulp,
elf_backend_link_order_error_handler,
elf_backend_relplt_name,
ELF_MACHINE_ALT1,
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 62d516aab8d..c0fb718d85c 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -29,6 +29,8 @@
#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
#define ELFX32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
+#define ULP_ENTRY_LEN 16
+
bool
_bfd_x86_elf_mkobject (bfd *abfd)
{
@@ -984,6 +986,64 @@ _bfd_elf_x86_valid_reloc_p (asection *input_section,
return valid_p;
}
+/* Check if input bfds are ulp-enabled by containing .ulp.track section */
+
+bool
+_bfd_x86_elf_is_ulp_enabled (struct bfd *input_bfd)
+{
+ while (input_bfd != NULL)
+ for (; input_bfd != NULL; input_bfd = input_bfd->link.next)
+ {
+ if (input_bfd->section_count == 0) continue;
+ if (bfd_get_section_by_name (input_bfd, ".ulp.track")) return true;
+ }
+ return false;
+}
+
+/* To be used by elf_link_hash_traverse when computing the ulp length */
+
+static bool
+bfd_x86_elf_link_compute_ulp (struct elf_link_hash_entry *h, void *data)
+{
+ unsigned long *ulp_length = (unsigned long *) data;
+
+ if (h->dynindx != -1 && h->type == STT_FUNC && !h->def_dynamic)
+ {
+ ++(*ulp_length);
+ }
+ return true;
+}
+
+/* Fill the user-space live patching section */
+
+bool
+_bfd_x86_elf_setup_ulp (struct bfd_link_info *info)
+{
+ struct elf_x86_link_hash_table *htab;
+ asection *ulp;
+ unsigned int ulp_length = 0;
+
+ htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ bfd_x86_elf_link_compute_ulp,
+ &ulp_length);
+
+ ulp = htab->ulp;
+
+ ulp->size = ulp_length * ULP_ENTRY_LEN;
+
+ ulp->contents = (bfd_byte *) bfd_malloc (ulp->size);
+ if (ulp->contents == NULL)
+ return false;
+
+ if (!ulp->contents)
+ return false;
+
+ memset(ulp->contents, 0x00, ulp->size);
+ return true;
+}
+
/* Set the sizes of the dynamic sections. */
bool
@@ -3030,7 +3090,26 @@ _bfd_x86_elf_link_setup_gnu_properties
htab->plt_second = sec;
}
- }
+
+ /* create sections to support user-space live patching */
+ if (_bfd_x86_elf_is_ulp_enabled(info->input_bfds))
+ {
+ flagword flags = (bed->dynamic_sec_flags
+ | SEC_ALLOC
+ | SEC_CODE
+ | SEC_LOAD
+ | SEC_READONLY);
+
+ sec = bfd_make_section_anyway_with_flags (dynobj, ".ulp", flags);
+ if (sec == NULL)
+ info->callbacks->einfo (_("%F%P: failed to create ULP section\n"));
+
+ if (!bfd_set_section_alignment (sec, plt_alignment))
+ goto error_alignment;
+
+ htab->ulp = sec;
+ }
+ }
if (!info->no_ld_generated_unwind_info)
{
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index db11327e96f..89f51382216 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -607,6 +607,7 @@ struct elf_x86_link_hash_table
asection *plt_second_eh_frame;
asection *plt_got;
asection *plt_got_eh_frame;
+ asection *ulp;
sframe_encoder_ctx *plt_cfe_ctx;
asection *plt_sframe;
@@ -694,6 +695,12 @@ extern void _bfd_x86_elf_link_report_relative_reloc
(struct bfd_link_info *, asection *, struct elf_link_hash_entry *,
Elf_Internal_Sym *, const char *, const void *);
+extern bool _bfd_x86_elf_is_ulp_enabled
+ (struct bfd *);
+
+extern bool _bfd_x86_elf_setup_ulp
+ (struct bfd_link_info *);
+
#define bfd_elf64_mkobject \
_bfd_x86_elf_mkobject
#define bfd_elf32_mkobject \
@@ -907,6 +914,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc
_bfd_elf_x86_size_relative_relocs
#define elf_backend_finish_relative_relocs \
_bfd_elf_x86_finish_relative_relocs
+#define elf_backend_is_ulp_enabled \
+ _bfd_x86_elf_is_ulp_enabled
+#define elf_backend_setup_ulp \
+ _bfd_x86_elf_setup_ulp
#define ELF_P_ALIGN ELF_MINPAGESIZE