From ebe7d0517a17aeb9b0932d3cd154619cde7e5ade Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Sun, 13 Nov 2022 17:25:42 +0100 Subject: [PATCH] Update 'Obtaining the Oodle library on Linux' --- Obtaining-the-Oodle-library-on-Linux.md | 104 ++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Obtaining-the-Oodle-library-on-Linux.md diff --git a/Obtaining-the-Oodle-library-on-Linux.md b/Obtaining-the-Oodle-library-on-Linux.md new file mode 100644 index 0000000..b7f087a --- /dev/null +++ b/Obtaining-the-Oodle-library-on-Linux.md @@ -0,0 +1,104 @@ +The Unreal Engine (currently v5.0.3) includes a version of the Oodle data compression library compiled for Linux (at `Engine/Source/Runtime/OodleDataCompression/Sdks/2.9.5/lib/Linux`). However, this archive was compiled for static linking, and all symbols were marked as hidden. + +To be able to create a shared library from that, follow the steps described in [StackOverflow - Keep all exported symbols when creating a shared library from a static library](https://stackoverflow.com/questions/54664759/keep-all-exported-symbols-when-creating-a-shared-library-from-a-static-library): + +**elf_unhide.py**: +```python +#!/usr/bin/python +# unhide.py - Replace hidden with default visibility on global symbols defined +# in an ELF object file + +import argparse, sys, lief +from lief.ELF import SYMBOL_BINDINGS, SYMBOL_VISIBILITY, SYMBOL_TYPES + +def warn(msg): + sys.stderr.write("WARNING: " + msg + "\n") + +def unhide(objfile_in, objfile_out = None, namedsyms=None): + if not objfile_out: + objfile_out = objfile_in + binary = lief.parse(objfile_in) + allsyms = { sym.name for sym in binary.symbols } + selectedsyms = set([]) + nasyms = { sym.name for sym in binary.symbols if \ + sym.type == SYMBOL_TYPES.NOTYPE or \ + sym.binding != SYMBOL_BINDINGS.GLOBAL or \ + sym.visibility != SYMBOL_VISIBILITY.HIDDEN } + if namedsyms: + namedsyms = set(namedsyms) + nosyms = namedsyms - allsyms + for nosym in nosyms: + warn("No symbol " + nosym + " in " + objfile_in + ": ignored") + for sym in namedsyms & nasyms: + warn("Input symbol " + sym + \ + " is not a hidden global symbol defined in " + objfile_in + \ + ": ignored") + selectedsyms = namedsyms - nosyms + else: + selectedsyms = allsyms + + selectedsyms -= nasyms + unhidden = 0; + for sym in binary.symbols: + if sym.name in selectedsyms: + sym.visibility = SYMBOL_VISIBILITY.DEFAULT + unhidden += 1 + print("Unhidden: " + sym.name) + print("{} symbols were unhidden".format(unhidden)) + binary.write(objfile_out) + +def get_args(): + parser = argparse.ArgumentParser( + description="Replace hidden with default visibility on " + \ + "global symbols defined in an ELF object file.") + parser.add_argument("ELFIN",help="ELF object file to read") + parser.add_argument("-s","--symbol",metavar="SYMBOL",action="append", + help="Unhide SYMBOL. " + \ + "If unspecified, unhide all hidden global symbols defined in ELFIN") + parser.add_argument("--symfile", + help="File of whitespace-delimited symbols to unhide") + parser.add_argument("-o","--out",metavar="ELFOUT", + help="ELF object file to write. If unspecified, rewrite ELFIN") + return parser.parse_args() + + +def main(): + args = get_args() + objfile_in = args.ELFIN + objfile_out = args.out + symlist = args.symbol + if not symlist: + symlist = [] + symfile = args.symfile + if symfile: + with open(symfile,"r") as fh: + symlist += [word for line in fh for word in line.split()] + unhide(objfile_in,objfile_out,symlist) + +main() +``` + +**elf_unhide.sh**: +```bash +#!/bin/bash + +TEMP=$(mktemp -d) + +OLD_ARCHIVE="$(realpath "$1")" +NEW_ARCHIVE="$(realpath "$2")" + +ar --output $TEMP xv $OLD_ARCHIVE + +find $TEMP -type f -exec ./elf_unhide.py --symfile symbols.txt "{}" \; + +ar rcs $NEW_ARCHIVE $TEMP/*.o + +rm -r $TEMP +echo "$(basefile $NEW_ARCHIVE) made" +``` + +**Create the shared library**: +```shell +./elf_unhide.sh liboo2corelinux64.a liboo2corelinux64_out.a +g++ -shared -o liboo2corelinux64.so -Wl,--whole-archive ./liboo2corelinux64_out.a -Wl,--no-whole-archive +``` \ No newline at end of file