forked from pool/binutils
7c6063bdba
- Update to binutils 2.37: * The GNU Binutils sources now requires a C99 compiler and library to build. * Support for the arm-symbianelf format has been removed. * Support for Realm Management Extension (RME) for AArch64 has been added. * A new linker option '-z report-relative-reloc' for x86 ELF targets has been added to report dynamic relative relocations. * A new linker option '-z start-stop-gc' has been added to disable special treatment of __start_*/__stop_* references when --gc-sections. * A new linker options '-Bno-symbolic' has been added which will cancel the '-Bsymbolic' and '-Bsymbolic-functions' options. * The readelf tool has a new command line option which can be used to specify how the numeric values of symbols are reported. --sym-base=0|8|10|16 tells readelf to display the values in base 8, base 10 or base 16. A sym base of 0 represents the default action of displaying values under 10000 in base 10 and values above that in base 16. * A new format has been added to the nm program. Specifying '--format=just-symbols' (or just using -j) will tell the program to only display symbol names and nothing else. * A new command line option '--keep-section-symbols' has been added to objcopy and strip. This stops the removal of unused section symbols when the file is copied. Removing these symbols saves space, but sometimes they are needed by other tools. * The '--weaken', '--weaken-symbol' and '--weaken-symbols' options supported by objcopy now make undefined symbols weak on targets that support weak symbols. * Readelf and objdump can now display and use the contents of .debug_sup OBS-URL: https://build.opensuse.org/request/show/907786 OBS-URL: https://build.opensuse.org/package/show/devel:gcc/binutils?expand=0&rev=363
205 lines
5.9 KiB
Diff
205 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
|
|
@@ -31,6 +31,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
|
|
@@ -452,6 +452,7 @@ struct elf_x86_link_hash_table
|
|
asection *plt_second_eh_frame;
|
|
asection *plt_got;
|
|
asection *plt_got_eh_frame;
|
|
+ asection *ulp;
|
|
|
|
/* Parameters describing PLT generation, lazy or non-lazy. */
|
|
struct elf_x86_plt_layout plt;
|
|
@@ -690,6 +691,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 \
|
|
@@ -727,3 +734,7 @@ extern void _bfd_x86_elf_link_report_relative_reloc
|
|
_bfd_x86_elf_merge_gnu_properties
|
|
#define elf_backend_fixup_gnu_properties \
|
|
_bfd_x86_elf_link_fixup_gnu_properties
|
|
+#define elf_backend_is_ulp_enabled \
|
|
+ _bfd_x86_elf_is_ulp_enabled
|
|
+#define elf_backend_setup_ulp \
|
|
+ _bfd_x86_elf_setup_ulp
|