diff mbox series

livepatch-build-tools: Detect special section group sizes

Message ID c2186666-6d79-4da1-2e8a-9b7447870e43@rimuhosting.com (mailing list archive)
State New, archived
Headers show
Series livepatch-build-tools: Detect special section group sizes | expand

Commit Message

Glenn Enright April 28, 2019, 9:49 p.m. UTC
A recent xsa livepatch failed to generate due to the following message in create-diff-object.log ...

/livepatch-build-tools/create-diff-object: ERROR: grant_table.o:
kpatch_regenerate_special_section: 1162: group size mismatch for section
.altinstructions

This is similar to the issue reported and fixed in
https://github.com/dynup/kpatch/pull/528 which says ...
"Hard-coding the special section group sizes is unreliable.
 Instead, determine them dynamically by finding the related
 struct definitions in the DWARF metadata."

Signed-off-by: Glenn Enright <glenn@rimuhosting.com>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
---
CC: Ross Lagerwall <ross.lagerwall@citrix.com>
CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

This patch resulted in a loadable livepatch. The alt section size in my case was actually 14. 
---
 create-diff-object.c |   30 ++++++++++++++++++++++++++++--
 livepatch-build      |   21 +++++++++++++++++++++
 2 files changed, 49 insertions(+), 2 deletions(-)

Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
diff mbox series

Patch

diff --git a/create-diff-object.c b/create-diff-object.c
index 82f777e..f9f4abf 100644
--- a/create-diff-object.c
+++ b/create-diff-object.c
@@ -962,9 +962,35 @@  static int bug_frames_0_group_size(struct kpatch_elf *kelf, int offset) { return
 static int bug_frames_1_group_size(struct kpatch_elf *kelf, int offset) { return 8; }
 static int bug_frames_2_group_size(struct kpatch_elf *kelf, int offset) { return 8; }
 static int bug_frames_3_group_size(struct kpatch_elf *kelf, int offset) { return 16; }
-static int ex_table_group_size(struct kpatch_elf *kelf, int offset) { return 8; }
-static int altinstructions_group_size(struct kpatch_elf *kelf, int offset) { return 12; }
+int ex_table_group_size(struct kpatch_elf *kelf, int offset)
+{
+       static int size = 0;
+       char *str;
+
+       if (!size) {
+               str = getenv("EX_STRUCT_SIZE");
+               if (!str)
+                       ERROR("EX_STRUCT_SIZE not set");
+               size = atoi(str);
+       }
+
+       return size;
+}
 +int altinstructions_group_size(struct kpatch_elf *kelf, int offset)
+{
+       static int size = 0;
+       char *str;
+
+       if (!size) {
+               str = getenv("ALT_STRUCT_SIZE");
+               if (!str)
+                       ERROR("ALT_STRUCT_SIZE not set");
+               size = atoi(str);
+       }
+
+       return size;
+}
 /*
  * The rela groups in the .fixup section vary in size.  The beginning of each
  * .fixup rela group is referenced by the .ex_table section. To find the size
diff --git a/livepatch-build b/livepatch-build
index c057fa1..6c3409c 100755
--- a/livepatch-build
+++ b/livepatch-build
@@ -304,6 +304,27 @@  if [ "${SKIP}" != "build" ]; then
         XEN_DEBUG="debug=$XEN_DEBUG"
     fi
 +    echo "Reading special section data"
+    SPECIAL_VARS=$(readelf -wi "$XENSYMS" |
+        gawk --non-decimal-data '
+       BEGIN { a = e = 0 }
+       a == 0 && /DW_AT_name.* alt_instr$/ {a = 1; next}
+       e == 0 && /DW_AT_name.* exception_table_entry$/ {e = 1; next}
+       a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
+       e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
+       a == 2 && b == 2 && p == 2 && e == 2 {exit}')
+
+    [[ -n $SPECIAL_VARS ]] && eval "$SPECIAL_VARS"
+
+    if [[ -z $ALT_STRUCT_SIZE ]] || [[ -z $EX_STRUCT_SIZE ]]; then
+       die "can't find special struct size"
+    fi
+    for i in $ALT_STRUCT_SIZE $EX_STRUCT_SIZE; do +       if [[ ! $i -gt 0 ]] || [[ ! $i -le 16 ]]; then
+               die "invalid special struct size $i"
+       fi
+    done
+
     echo "Perform full initial build with ${CPUS} CPU(s)..."
     build_full
 -- 1.7.1

_______________________________________________