diff mbox series

[v3,7/7] livepatch-build: Strip all metadata symbols from hotpatch modules

Message ID 20191126122511.7409-8-wipawel@amazon.de (mailing list archive)
State New, archived
Headers show
Series livepatch-build-tools: new features and fixes | expand

Commit Message

Wieczorkiewicz, Pawel Nov. 26, 2019, 12:25 p.m. UTC
Strip all unneeded metadata symbols from generated hotpatch modules.
The metadata symbols are the symbols from metadata-like sections (e.g.
'.livepatch.funcs') or livepatch hooks symbols (defined by a set of
prefixes. E.g. 'livepatch_load_data_').

By default the create-diff-object does not create symbols in metadata
sections. However, such symbols may be implicitly added by speciying
extra entries in the sections manually (in a given patch).
The symbols are not needed for the hotpatch modules and should be
stripped to avoid symbol names collisions and to save hotpatch files
space.

Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
---
 livepatch-build | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/livepatch-build b/livepatch-build
index 9e5bad3..e1715ea 100755
--- a/livepatch-build
+++ b/livepatch-build
@@ -112,10 +112,39 @@  function build_special()
     unset LIVEPATCH_CAPTURE_DIR
 }
 
-strip_extra_symbols ()
+elf_section_exists ()
+{
+    local ELF="$1"
+    local SEC="$2"
+
+    objdump -h -j "$SEC" "$ELF" &> /dev/null
+}
+
+# Extract a set of unique symbols for a specified section.
+elf_extract_section_symbols ()
+{
+    local -r ELF="$1"
+    local -r SEC="$2"
+
+    if elf_section_exists "$ELF" "$SEC"
+    then
+        # Example objdump command output to be parsed:
+        #
+        # SYMBOL TABLE:
+        # 0000000000000000 l    d  .livepatch.funcs    0000000000000000 .livepatch.funcs
+        objdump -w -j "$SEC" -t "$ELF" | awk '/^SYMBOL TABLE:/ {seen = 1; next} seen && $NF {print $NF}' | sort -u
+    fi
+}
+
+# Strip all metadata symbols belonging to a metadata section
+# or whose name starts with a livepatch hook prefix.
+# The function constructs the 'strip' utility command line
+# and then invokes strip with that command line.
+strip_metadata_symbols ()
 {
     local -r FILE="$1"
     local -a STRIP_CMD_OPTS=()
+    local -a SYM_SECTIONS=(".livepatch.funcs")
     local -a SYM_PREFIX=("livepatch_load_data_"
                          "livepatch_unload_data_"
                          "livepatch_preapply_data_"
@@ -124,13 +153,35 @@  strip_extra_symbols ()
                          "livepatch_prerevert_data_"
                          "livepatch_revert_data_"
                          "livepatch_postrevert_data_")
+    local -a SYMS=()
 
+    # Enable wildcard
     STRIP_CMD_OPTS+=("-w")
+
+    # Strip all livepatch hooks metadata symbols
     for sym in "${SYM_PREFIX[@]}"; do
         STRIP_CMD_OPTS+=("-N")
         STRIP_CMD_OPTS+=("\"${sym}*\"")
     done
 
+    # Find all symbols from metadata sections
+    # Note: There may be name conflicts between global
+    # and local symbols belonging to the same section.
+    # For the '.livepatch.funcs' section it is not a
+    # problem. Think about it before adding more sections.
+    for sec in "${SYM_SECTIONS[@]}"; do
+        SYMS+=($(elf_extract_section_symbols "$FILE" "$sec"))
+    done
+
+    # Strip metadata sections' symbols
+    if [ ${#SYMS[@]} -gt 0 ]
+    then
+        for sym in "${SYMS[@]}"; do
+            STRIP_CMD_OPTS+=("-N")
+            STRIP_CMD_OPTS+=("${sym}")
+        done
+    fi
+
     strip "${STRIP_CMD_OPTS[@]}" "$FILE"
 }
 
@@ -200,7 +251,7 @@  function create_patch()
         "${TOOLSDIR}"/prelink $debugopt output.o "${PATCHNAME}.livepatch" "$XENSYMS" &>> "${OUTPUT}/prelink.log" || die
     fi
 
-    strip_extra_symbols "${PATCHNAME}.livepatch"
+    strip_metadata_symbols "${PATCHNAME}.livepatch"
 
     objcopy --add-section .livepatch.depends=depends.bin "${PATCHNAME}.livepatch"
     objcopy --set-section-flags .livepatch.depends=alloc,readonly "${PATCHNAME}.livepatch"