SHA256
1
0
forked from pool/binutils
binutils/add-ulp-section.diff

163 lines
4.6 KiB
Diff
Raw Normal View History

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.
Index: bfd/elflink.c
===================================================================
--- bfd/elflink.c.orig 2019-09-09 15:19:43.000000000 +0200
+++ bfd/elflink.c 2019-11-18 18:02:54.000000000 +0100
@@ -22,6 +22,7 @@
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
+#include "ulp.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"
#include "safe-ctype.h"
@@ -7070,6 +7071,11 @@ bfd_elf_size_dynamic_sections (bfd *outp
s = bfd_get_linker_section (dynobj, ".gnu.version");
s->flags |= SEC_EXCLUDE;
}
+
+ if (bfd_is_ulp_enabled(output_bfd))
+ {
+ bfd_setup_ulp(info);
+ }
}
return TRUE;
}
Index: bfd/elfxx-x86.c
===================================================================
--- bfd/elfxx-x86.c.orig 2019-09-09 15:19:43.000000000 +0200
+++ bfd/elfxx-x86.c 2019-11-18 18:02:54.000000000 +0100
@@ -23,6 +23,7 @@
#include "objalloc.h"
#include "elf/i386.h"
#include "elf/x86-64.h"
+#include "ulp.h"
/* The name of the dynamic interpreter. This is put in the .interp
section. */
@@ -952,6 +953,64 @@ _bfd_x86_elf_link_check_relocs (bfd *abf
return _bfd_elf_link_check_relocs (abfd, info);
}
+/* Check if input bfds are ulp-enabled by containing .ulp.track section */
+
+bfd_boolean
+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 bfd_boolean
+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 */
+
+bfd_boolean
+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. */
bfd_boolean
@@ -2935,7 +2994,26 @@ error_alignment:
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 (dynobj, sec, plt_alignment))
+ goto error_alignment;
+
+ htab->ulp = sec;
+ }
+ }
if (!info->no_ld_generated_unwind_info)
{
Index: bfd/elfxx-x86.h
===================================================================
--- bfd/elfxx-x86.h.orig 2019-09-09 15:19:43.000000000 +0200
+++ bfd/elfxx-x86.h 2019-11-18 18:02:54.000000000 +0100
@@ -447,6 +447,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;
Index: bfd/ulp.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ bfd/ulp.h 2019-11-18 18:02:54.000000000 +0100
@@ -0,0 +1,12 @@
+extern bfd_boolean bfd_x86_elf_is_ulp_enabled
+ (struct bfd *);
+
+extern bfd_boolean bfd_x86_elf_setup_ulp
+ (struct bfd_link_info *);
+
+#define bfd_is_ulp_enabled bfd_x86_elf_is_ulp_enabled
+
+#define bfd_setup_ulp bfd_x86_elf_setup_ulp
+
+#define ULP_ENTRY_LEN 16
+