aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.depend5
-rw-r--r--.github/workflows/build-test-ci.yml80
-rw-r--r--.github/workflows/ci-alpine-linux.yml34
-rw-r--r--.github/workflows/codespell.yml13
-rw-r--r--.github/workflows/coverity.yml19
-rw-r--r--.github/workflows/python.yml28
-rw-r--r--.gitignore31
-rw-r--r--.pylintrc34
-rw-r--r--.travis.yml33
-rw-r--r--BUGS2
-rw-r--r--Makefile190
-rw-r--r--Makefile.am111
-rw-r--r--README.md40
-rw-r--r--TODO2
-rwxr-xr-xautogen.sh74
-rw-r--r--configure.ac71
-rw-r--r--dumpelf.c101
-rw-r--r--elf.h1162
-rwxr-xr-xlddtree.py1627
-rwxr-xr-xlddtree.sh26
-rw-r--r--macho.h16
-rwxr-xr-xmake-seccomp-filters.sh13
-rwxr-xr-xmake-tarball.sh86
-rw-r--r--man/Makefile13
-rw-r--r--man/custom.xsl3
-rw-r--r--man/fragment/date0
-rw-r--r--man/fragment/reftail4
-rw-r--r--man/fragment/version1
-rw-r--r--man/meson.build44
-rw-r--r--man/pax-utils.docbook.in (renamed from man/pax-utils.docbook)15
-rw-r--r--man/scanelf.docbook7
-rwxr-xr-xmeson-build-dist-man.sh12
-rw-r--r--meson.build174
-rw-r--r--meson_options.txt17
-rw-r--r--paxelf.c13
-rw-r--r--paxelf.h4
-rw-r--r--paxinc.c118
-rw-r--r--paxinc.h25
-rw-r--r--paxldso.c261
-rw-r--r--paxldso.h7
-rw-r--r--paxmacho.c9
-rw-r--r--paxmacho.h4
-rw-r--r--porting.h55
-rw-r--r--pspax.c155
-rwxr-xr-xpylint55
-rw-r--r--pyproject.toml121
-rw-r--r--requirements-dev.txt12
-rw-r--r--requirements.txt9
-rw-r--r--scanelf.c71
-rw-r--r--scanmacho.c84
-rw-r--r--seccomp-bpf.c277
-rw-r--r--seccomp-bpf.h229
-rw-r--r--security.c206
-rw-r--r--security.h6
-rw-r--r--tests/Makefile10
-rw-r--r--tests/lddtree/Makefile13
-rw-r--r--tests/lddtree/meson.build10
-rw-r--r--tests/lib.sh17
-rw-r--r--tests/scanelf/Makefile8
-rwxr-xr-xtests/scanelf/dotest6
-rw-r--r--tests/scanelf/meson.build8
-rw-r--r--tests/source/Makefile8
-rwxr-xr-xtests/source/dotest29
-rw-r--r--tests/source/meson.build8
-rw-r--r--travis/autotools.tar.xzbin9208 -> 0 bytes
-rw-r--r--travis/lib.sh38
-rwxr-xr-xtravis/main.sh75
-rw-r--r--version.h.in1
-rw-r--r--xfuncs.c4
-rw-r--r--xfuncs.h4
70 files changed, 3824 insertions, 2224 deletions
diff --git a/.depend b/.depend
deleted file mode 100644
index 5371c1c..0000000
--- a/.depend
+++ /dev/null
@@ -1,5 +0,0 @@
-scanelf.o: scanelf.c paxinc.h porting.h elf.h paxelf.h
-pspax.o: pspax.c paxinc.h porting.h elf.h paxelf.h
-dumpelf.o: dumpelf.c paxinc.h porting.h elf.h paxelf.h
-paxelf.o: paxelf.c paxinc.h porting.h elf.h paxelf.h
-paxinc.o: paxinc.c paxinc.h porting.h elf.h paxelf.h
diff --git a/.github/workflows/build-test-ci.yml b/.github/workflows/build-test-ci.yml
new file mode 100644
index 0000000..e4e5857
--- /dev/null
+++ b/.github/workflows/build-test-ci.yml
@@ -0,0 +1,80 @@
+# GitHub actions workflow.
+# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
+
+name: Build+Test CI
+
+on: [pull_request, push]
+
+jobs:
+ make:
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ cc: [gcc, clang]
+ bb: [meson, muon]
+ sanitizer: [none, address, undefined]
+ fail-fast: false
+ runs-on: ${{ matrix.os }}
+ env:
+ CC: ${{ matrix.cc }}
+ BB: ${{ matrix.bb }}
+ SANITIZER: ${{ matrix.sanitizer }}
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y python3-pyelftools python3-pip \
+ libcap-dev libseccomp-dev ninja-build \
+ pkg-config
+ case "$BB" in
+ meson)
+ sudo pip3 install meson
+ ;;
+ muon)
+ wget https://muon.build/releases/edge/muon-edge-amd64-linux-static -O muon
+ chmod +x muon
+ sudo install -Dm755 muon /usr/local/bin/muon
+ ;;
+ esac
+ - uses: actions/checkout@v4
+ - run: |
+ export PKG_CONFIG_PATH="/usr/lib/$(uname -m)-linux-gnu/pkgconfig/"
+ case "$BB" in
+ muon)
+ alias ninja="muon samu"
+ ;;
+ esac
+
+ "$BB" setup -Duse_libcap=enabled \
+ -Duse_seccomp=true \
+ -Dbuild_manpages=disabled \
+ -Dtests=true \
+ -Duse_fuzzing=true \
+ -Db_sanitize="${SANITIZER}" \
+ build
+ ninja -C build
+ ( cd build && "$BB" test -v ; )
+
+ build-macos:
+ strategy:
+ matrix:
+ os: [macos-latest]
+ cc: [clang]
+ runs-on: ${{ matrix.os }}
+ env:
+ CC: ${{ matrix.cc }}
+ steps:
+ - name: Install dependencies
+ run: brew install meson ninja
+ - uses: actions/checkout@v4
+ - run: |
+ meson -Duse_libcap=disabled \
+ -Duse_seccomp=false \
+ -Dbuild_manpages=disabled \
+ -Dtests=true \
+ -Duse_fuzzing=false \
+ build
+ ninja -C build
+ # The unittests generally assume a Linux ELF host, so don't bother making
+ # sure they pass on macOS. Run them out of morbid curiosity I guess.
+ ninja -kC build test ||:
diff --git a/.github/workflows/ci-alpine-linux.yml b/.github/workflows/ci-alpine-linux.yml
new file mode 100644
index 0000000..575e959
--- /dev/null
+++ b/.github/workflows/ci-alpine-linux.yml
@@ -0,0 +1,34 @@
+name: ci_alpine_linux
+
+on: [push, pull_request]
+
+jobs:
+
+ alpine:
+ name: Alpine Linux
+ runs-on: ubuntu-latest
+ container: alpine:latest
+ strategy:
+ fail-fast: false
+ matrix:
+ compiler:
+ - gcc
+ - clang
+ env:
+ CC: ${{ matrix.compiler }}
+ steps:
+ - run: >-
+ apk --no-cache add \
+ build-base \
+ clang \
+ meson \
+ pkgconf \
+ py3-elftools \
+ libcap \
+ libcap-dev \
+ libseccomp \
+ libseccomp-dev
+ - uses: actions/checkout@v4
+ - run: meson setup -Dtests=false -Duse_fuzzing=false builddir/
+ - run: meson compile -C builddir
+ - run: meson test --verbose -C builddir
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
new file mode 100644
index 0000000..605d2bb
--- /dev/null
+++ b/.github/workflows/codespell.yml
@@ -0,0 +1,13 @@
+# GitHub actions workflow.
+# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
+
+name: Codespell
+
+on: [push, pull_request]
+
+jobs:
+ codespell:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: codespell-project/actions-codespell@v2
diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml
new file mode 100644
index 0000000..1cd6c55
--- /dev/null
+++ b/.github/workflows/coverity.yml
@@ -0,0 +1,19 @@
+# GitHub actions workflow.
+# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
+
+# https://scan.coverity.com/projects/gentoo-pax-utils
+name: Coverity Scan
+
+on:
+ push:
+ branches: [master]
+
+jobs:
+ coverity:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: vapier/coverity-scan-action@v1
+ with:
+ email: vapier@gentoo.org
+ token: ${{ secrets.COVERITY_SCAN_TOKEN }}
diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
new file mode 100644
index 0000000..7b7dcaf
--- /dev/null
+++ b/.github/workflows/python.yml
@@ -0,0 +1,28 @@
+# GitHub actions workflow.
+# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
+
+name: Python
+
+on: [push, pull_request]
+
+jobs:
+ python:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ # NB: v1.4.0 covers Python 3.8.
+ - uses: ricardochaves/python-lint@v1.4.0
+ with:
+ python-root-list: lddtree.py pylint
+ use-pylint: true
+ use-pycodestyle: false
+ use-flake8: false
+ use-black: true
+ use-mypy: true
+ use-isort: true
+ extra-pylint-options: ""
+ extra-pycodestyle-options: ""
+ extra-flake8-options: ""
+ extra-black-options: ""
+ extra-mypy-options: ""
+ extra-isort-options: ""
diff --git a/.gitignore b/.gitignore
index 6e0a530..a6bf3ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,25 +20,30 @@ core
.gdb_history
.gdbinit
-aclocal.m4
-autom4te.cache
-build
-config.cache
-config.h
-config.h.in
-config.log
-config.status
-configure
-autotools
-libtool
-Makefile.in
-stamp-h1
+/aclocal.m4
+/autom4te.cache
+/autotools
+/build
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/INSTALL
+/libtool
+/Makefile.in
+/stamp-h1
/dumpelf
/lddtree
+/paxelf
+/paxldso
+/paxmacho
/pspax
/scanelf
/scanmacho
+/seccomp-bpf
/symtree
/man/*.1
diff --git a/.pylintrc b/.pylintrc
deleted file mode 100644
index b58abfa..0000000
--- a/.pylintrc
+++ /dev/null
@@ -1,34 +0,0 @@
-[MESSAGES CONTROL]
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifier separated by comma (,) or put this option
-# multiple times (only on the command line, not in the configuration file where
-# it should appear only once).
-disable=
- too-many-lines,
- too-many-branches,
- too-many-statements,
- too-few-public-methods,
- too-many-instance-attributes,
- too-many-public-methods,
- too-many-locals,
- too-many-arguments,
- locally-enabled,
- locally-disabled,
- fixme,
- invalid-name,
-
-[REPORTS]
-reports=no
-
-[FORMAT]
-max-line-length=80
-indent-string=' '
-
-[SIMILARITIES]
-min-similarity-lines=20
-
-[VARIABLES]
-dummy-variables-rgx=_
-
-[DESIGN]
-max-parents=10
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index f8b90cf..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-# Travis build integration.
-# https://docs.travis-ci.com/
-
-language: c
-# Order here matters for implicit matrix generation and coverity scan.
-# See travis/main.sh for details.
-compiler:
- - gcc
- - clang
-
-sudo: false
-
-# Order here matters; see compiler comment above.
-os:
- - linux
- - osx
-
-# Travis currently uses Ubuntu 12.04 (Precise) which is too old: it does
-# not include pyelftools. Disable until they update.
-env:
- global:
- - USE_PYTHON=no
- - secure: "ePjz/xsdTlf0lhdZtANITiAk2lBAA9wwzB5PK/9aR5i1eBfjgXQgIJLY1y7Lqa4WU8TnSF2mwzd0pYgb320lQMC5rP7aEMAqxVZeG9WmFjet2G5vQ48tDhEJzzDhOpfvQyPehiWqLL6RUhNjE8+kpdK74P7oUFJVIuoQkUn2EuW9eUD9hV6z6tS60C0F4COdE/6DPnBySmqvjm9r9Sdfz1flCI2FXoV7MrrqrwLIx3OMtHmqmM9vGF1d2rGXRADVEGL+ldx9KvdfTLddXhWkCuHZil9YMvQLu0+gTK/g3V02Gh1/xrKmTa6v2RDqimCYDGKdHn0An+tQShYqk2JqJfzvPeysGS8lWfQePaEnHnf6niQN6h4078Ru5jH3D6AFjInrdPEOS3UZsbrJ//7hhUdiHONeQZcVcCVk7bvaJoanjjI9hJaPQXc72u81uyjlXaTOEj/znOAV92WyTaR62cT5r0GR+R7Jp214YR1IyAIB63zQVw2QCNi6W2HpyUEo3d2fOdJdaPwPQL52GxD/i3h4uGh1orYdRL4s/tdqwvYHklE2AGrEAboq2pIkmVirWH9+3+vRTnZ+fyoXD6dqDa0QvkN0pxEwmFy0IvbvTUA+0k6iplDVY21hqoid2OUpus+LjdXT2QALsY9OfMvMPdUaoFSTzWFm1jwZBPqlZN0="
-
-# Note: OS X deps are maintained in .travis.sh until Travis supports it here.
-addons:
- apt:
- packages:
- - autoconf-archive
- - gnulib
- - xmlto
-
-script: ./travis/main.sh
diff --git a/BUGS b/BUGS
index 2df43a4..4ae0846 100644
--- a/BUGS
+++ b/BUGS
@@ -14,5 +14,5 @@ REPORTING BUGS
--------------
e-mail us:
-solar@gentoo.org
vapier@gentoo.org
+toolchain@gentoo.org
diff --git a/Makefile b/Makefile
deleted file mode 100644
index c906311..0000000
--- a/Makefile
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright 2003-2006 Ned Ludd <solar@linbsd.net>
-# Distributed under the terms of the GNU General Public License v2
-####################################################################
-
-check_compiler = \
- $(shell if $(CC) $(WUNKNOWN) $(1) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \
- then echo "$(1)"; else echo "$(2)"; fi)
-check_compiler_many = $(foreach flag,$(1),$(call check_compiler,$(flag)))
-
-####################################################################
-# Avoid CC overhead when installing
-ifneq ($(MAKECMDGOALS),install)
-WUNKNOWN := $(call check_compiler,-Werror=unknown-warning-option)
-_WFLAGS := \
- -Wdeclaration-after-statement \
- -Wextra \
- -Wsequence-point \
- -Wstrict-overflow \
- -Wmisleading-indentation
-WFLAGS := -Wall -Wunused -Wimplicit -Wshadow -Wformat=2 \
- -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings \
- -Wbad-function-cast -Wnested-externs -Wcomment -Winline \
- -Wchar-subscripts -Wcast-align -Wno-format-nonliteral \
- $(call check_compiler_many,$(_WFLAGS))
-endif
-
-CFLAGS ?= -O2 -pipe
-override CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
-LDFLAGS +=
-LIBS :=
-DESTDIR =
-PREFIX = $(DESTDIR)/usr
-DATADIR = $(PREFIX)/share
-MANDIR = $(DATADIR)/man
-DOCDIR = $(DATADIR)/doc
-PKGDOCDIR = $(DOCDIR)/pax-utils
-STRIP := strip
-MKDIR := mkdir -p
-INS_EXE := install -m755
-INS_DATA := install -m644
-
-PKG_CONFIG ?= pkg-config
-
-ifeq ($(USE_CAP),yes)
-LIBCAPS_CFLAGS := $(shell $(PKG_CONFIG) --cflags libcap)
-LIBCAPS_LIBS := $(shell $(PKG_CONFIG) --libs libcap)
-CPPFLAGS-pspax.c += $(LIBCAPS_CFLAGS) -DWANT_SYSCAP
-LIBS-pspax += $(LIBCAPS_LIBS)
-endif
-
-ifeq ($(USE_DEBUG),yes)
-override CPPFLAGS += -DEBUG
-endif
-
-ifeq ($(USE_SECCOMP),yes)
-LIBSECCOMP_CFLAGS := $(shell $(PKG_CONFIG) --cflags libseccomp)
-LIBSECCOMP_LIBS := $(shell $(PKG_CONFIG) --libs libseccomp)
-override CPPFLAGS += $(LIBSECCOMP_CFLAGS) -DWANT_SECCOMP
-LIBS += $(LIBSECCOMP_LIBS)
-endif
-
-ifdef PV
-override CPPFLAGS += -DVERSION=\"$(PV)\"
-else
-VCSID := $(shell git describe --tags HEAD)
-endif
-override CPPFLAGS += -DVCSID='"$(VCSID)"'
-
-####################################################################
-ELF_TARGETS = scanelf dumpelf $(shell echo | $(CC) -dM -E - | grep -q __svr4__ || echo pspax)
-ELF_OBJS = paxelf.o paxldso.o
-MACH_TARGETS = scanmacho
-MACH_OBJS = paxmacho.o
-COMMON_OBJS = paxinc.o security.o xfuncs.o
-TARGETS = $(ELF_TARGETS) $(MACH_TARGETS)
-SCRIPTS_SH = lddtree symtree
-SCRIPTS_PY = lddtree
-OBJS = $(ELF_OBJS) $(MACH_OBJS) $(COMMON_OBJS) $(TARGETS:%=%.o)
-MPAGES = $(TARGETS:%=man/%.1)
-SOURCES = $(OBJS:%.o=%.c)
-
-all: $(OBJS) $(TARGETS)
- @:
-
-DEBUG_FLAGS = \
- -nopie \
- -fsanitize=address \
- -fsanitize=leak \
- -fsanitize=undefined
-debug: clean
- $(MAKE) CFLAGS="$(CFLAGS) -g3 -ggdb $(call check_compiler_many,$(DEBUG_FLAGS))" all
- @-chpax -permsx $(ELF_TARGETS)
- @-paxctl -permsx $(ELF_TARGETS)
-
-analyze: clean
- scan-build $(MAKE) all
-
-fuzz: clean
- $(MAKE) AFL_HARDEN=1 CC=afl-gcc all
- @rm -rf findings
- @printf '\nNow run:\n%s\n' \
- "afl-fuzz -t 100 -i tests/fuzz/small/ -o findings/ ./scanelf -s '*' -axetrnibSDIYZB @@"
-
-compile.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(CPPFLAGS-$<) -o $@ -c $<
-
-ifeq ($(V),)
-Q := @
-else
-Q :=
-endif
-%.o: %.c
-ifeq ($(V),)
- @echo $(compile.c)
-endif
- $(Q)$(compile.c) $(WFLAGS)
-
-$(ELF_TARGETS): %: $(ELF_OBJS) $(COMMON_OBJS) %.o
- $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS) $(LIBS-$@)
-
-$(MACH_TARGETS): %: $(MACH_OBJS) $(COMMON_OBJS) %.o
- $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS) $(LIBS-$@)
-
-%.so: %.c
- $(CC) -shared -fPIC -o $@ $<
-
-depend:
- $(CC) $(CFLAGS) -MM $(SOURCES) > .depend
-
-clean:
- -rm -f $(OBJS) $(TARGETS)
-
-distclean: clean
- -rm -f *~ core *.o
- -cd man && $(MAKE) clean
-strip: all
- $(STRIP) $(TARGETS)
-strip-more:
- $(STRIP) --strip-unneeded $(TARGETS)
-
-install: all
- $(MKDIR) $(PREFIX)/bin/ $(MANDIR)/man1/ $(PKGDOCDIR)/
- for sh in $(SCRIPTS_SH) ; do $(INS_EXE) $$sh.sh $(PREFIX)/bin/$$sh || exit $$? ; done
-ifneq ($(USE_PYTHON),no)
- for py in $(SCRIPTS_PY) ; do $(INS_EXE) $$py.py $(PREFIX)/bin/$$py || exit $$? ; done
-endif
- $(INS_EXE) $(TARGETS) $(PREFIX)/bin/
- $(INS_DATA) README.md BUGS TODO $(PKGDOCDIR)/
- $(INS_DATA) $(MPAGES) $(MANDIR)/man1/
-
-PN = pax-utils
-P = $(PN)-$(PV)
-dist:
- ./make-tarball.sh $(DISTCHECK) $(PV)
-distcheck:
- $(MAKE) dist DISTCHECK=--check
-
--include .depend
-
-check test:
- $(MAKE) -C tests
-
-.PHONY: all check clean dist install test
-
-#
-# All logic related to autotools is below here
-#
-GEN_MARK_START = \# @@@ GEN START @@@ \#
-GEN_MARK_END = \# @@@ GEN END @@@ \#
-EXTRA_DIST = $(shell git ls-files | grep -v ^travis/)
-autotools-update:
- $(MAKE) -C man -j
- sed -i.tmp '/^$(GEN_MARK_START)$$/,/^$(GEN_MARK_END)$$/d' Makefile.am
- @rm -f Makefile.am.tmp
- ( \
- echo "$(GEN_MARK_START)"; \
- printf 'dist_man_MANS +='; \
- printf ' \\\n\t%s' `printf '%s\n' man/*.1 | LC_ALL=C sort`; \
- echo; \
- printf 'EXTRA_DIST +='; \
- printf ' \\\n\t%s' $(EXTRA_DIST); \
- echo; \
- echo "$(GEN_MARK_END)"; \
- ) >> Makefile.am
-autotools:
-ifeq ($(SKIP_AUTOTOOLS_UPDATE),)
- $(MAKE) autotools-update
-endif
- ./autogen.sh --from=make
-
-.PHONY: autotools autotools-update _autotools-update
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 79e5ed1..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,111 +0,0 @@
-ACLOCAL_AMFLAGS = -I autotools/m4
-
-SUBDIRS = autotools/gnulib
-
-AM_CPPFLAGS = \
- -I$(top_builddir)/autotools/gnulib \
- -I$(top_srcdir)/autotools/gnulib
-
-noinst_LTLIBRARIES = libpaxutils.la
-libpaxutils_la_LDFLAGS = -no-undefined
-libpaxutils_la_SOURCES = \
- paxelf.c \
- paxinc.c \
- paxldso.c \
- paxmacho.c \
- security.c \
- xfuncs.c
-LDADD = libpaxutils.la $(top_builddir)/autotools/gnulib/libgnu.a $(LIB_EACCESS)
-
-bin_SCRIPTS = lddtree symtree
-bin_PROGRAMS = scanelf dumpelf pspax scanmacho
-CLEANFILES = $(bin_SCRIPTS)
-
-if USE_PYTHON
-lddtree: lddtree.py
-else
-lddtree: lddtree.sh
-endif
- cp $< $@
-
-symtree: symtree.sh
- cp $< $@
-
-TMAKE = \
- $(MAKE) -C $(abs_top_srcdir)/tests \
- AUTOTOOLS=true \
- abs_top_builddir="$(abs_top_builddir)" \
- abs_top_srcdir="$(abs_top_srcdir)"
-check-hook:
- $(TMAKE) check
-check: check-hook
-
-# Start off with base values which we append below
-dist_man_MANS =
-EXTRA_DIST = autotools/m4/gnulib-cache.m4
-
-# @@@ GEN START @@@ #
-dist_man_MANS += \
- man/dumpelf.1 \
- man/pspax.1 \
- man/scanelf.1 \
- man/scanmacho.1
-EXTRA_DIST += \
- .depend \
- .gitignore \
- .travis.yml \
- BUGS \
- COPYING \
- Makefile \
- Makefile.am \
- README.md \
- TODO \
- autogen.sh \
- configure.ac \
- dumpelf.c \
- elf.h \
- lddtree.py \
- lddtree.sh \
- macho.h \
- make-tarball.sh \
- man/Makefile \
- man/custom.xsl \
- man/dumpelf.docbook \
- man/fragment/date \
- man/fragment/reftail \
- man/fragment/version \
- man/pax-utils.docbook \
- man/pspax.docbook \
- man/scanelf.docbook \
- man/scanmacho.docbook \
- paxelf.c \
- paxelf.h \
- paxinc.c \
- paxinc.h \
- paxldso.c \
- paxldso.h \
- paxmacho.c \
- paxmacho.h \
- porting.h \
- pspax.c \
- scanelf.c \
- scanmacho.c \
- security.c \
- security.h \
- symtree.sh \
- tests/Makefile \
- tests/lddtree/Makefile \
- tests/lddtree/dotest.cmp \
- tests/lddtree/dotest.py \
- tests/lddtree/dotest.sfx \
- tests/lddtree/dotest.sh \
- tests/lib.sh \
- tests/scanelf/Makefile \
- tests/scanelf/dotest \
- tests/scanelf/scanelf.simple.good \
- tests/source/Makefile \
- tests/source/dotest \
- tests/source/space \
- xfuncs.c \
- xfuncs.h
-# @@@ GEN END @@@ #
diff --git a/README.md b/README.md
index fa0f0f8..845c8de 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,11 @@
| HOMEPAGE | https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities |
| GIT | git clone git://anongit.gentoo.org/proj/pax-utils.git |
| VIEWVCS | https://gitweb.gentoo.org/proj/pax-utils.git/ |
-| STATUS | [![Build Status](https://travis-ci.org/gentoo/pax-utils.svg?branch=master)](https://travis-ci.org/gentoo/pax-utils) [![Coverity Status](https://scan.coverity.com/projects/9213/badge.svg)](https://scan.coverity.com/projects/gentoo-pax-utils) |
+| STATUS | [![Build Status](https://github.com/gentoo/pax-utils/actions/workflows/build-test-ci.yml/badge.svg)](https://github.com/gentoo/pax-utils/actions/workflows/build-test-ci.yml) [![Coverity Status](https://scan.coverity.com/projects/9213/badge.svg)](https://scan.coverity.com/projects/gentoo-pax-utils) |
-pax-utils is a small set of utilities for peforming Q/A (mostly security)
+pax-utils is a small set of utilities for performing Q/A (mostly security)
checks on systems (most notably, `scanelf`). It is focused on the ELF
-format, but does include a Mach-O helper too for OS X systems.
+format, but does include a Mach-O helper too for macOS systems.
While heavily integrated into Gentoo's build system, it can be used on any
distro as it is a generic toolset.
@@ -18,22 +18,15 @@ Originally focused only on [PaX](https://pax.grsecurity.net/), it has been
expanded to be generally security focused. It still has a good number of
PaX helpers for people interested in that.
-## Building
+## Building and installing
+pax-utils uses a bog-standard meson-based build system. See `meson_options.txt`
+for configuration options.
-Just run `make`. This should work on any recent POSIX compliant system.
-
-Note: To rebuild the man-pages, you will need xmlto and the docbook-xml-dtd
- packages installed on your system.
-
-## Installation
-
-`make install`
-
-You don't need PaX to use the pax-utils. Infact the only thing they
+You don't need PaX to use the pax-utils. In fact the only thing they
really have in common is that pax-utils was initially written to aid in
deploying PaX systems so it includes support for PT_PAX_FLAGS and the
deprecated but still in use EI_PAX flags. For more information about PaX
-see the homepage at http://pax.grsecurity.net/
+see the homepage at https://pax.grsecurity.net/
## Links
@@ -42,32 +35,33 @@ If you include pax-utils in your distro, feel free to send an update for this.
##### Gentoo
* https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities
* https://gitweb.gentoo.org/proj/pax-utils.git/
- * Maintainer: Mike Frysinger <vapier@gentoo.org>, Ned Ludd <solar@gentoo.org>
+ * Maintainer: Mike Frysinger <vapier@gentoo.org>, Toolchain Project <toolchain@gentoo.org>
+ * Original author: Ned Ludd <solar@gentoo.org>
##### openSUSE
* https://build.opensuse.org/package/show?package=pax-utils&project=openSUSE%3AFactory
* Maintainer: ludwig.nussel@suse.de
##### Ubuntu
- * http://packages.ubuntu.com/edgy/devel/pax-utils
+ * https://packages.ubuntu.com/hirsute/pax-utils
* Maintainer: john.r.moser@gmail.com
##### Debian
- * http://packages.debian.org/unstable/misc/pax-utils
- * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=388200
+ * https://packages.debian.org/unstable/misc/pax-utils
+ * https://bugs.debian.org/388200
* Maintainer: rdenis@simphalempin.com
##### FreeBSD
- * http://portsmon.freebsd.org/portoverview.py?category=sysutils&portname=pax-utils
- * http://www.freshports.org/sysutils/pax-utils/
+ * https://portsmon.freebsd.org/portoverview.py?category=sysutils&portname=pax-utils
+ * https://www.freshports.org/sysutils/pax-utils/
* http://archive.netbsd.se/?ml=freebsd-cvs-all&a=2006-08&m=2311441
* Maintainer: sbz@FreeBSD.org
##### OpenEmedded
- * http://www.openembedded.org/filebrowser/org.openembedded.dev/packages/pax-utils
+ * https://www.openembedded.org/filebrowser/org.openembedded.dev/packages/pax-utils
##### Crux
- * http://magog.se/crux/pax-utils/Pkgfile
+ * https://magog.se/crux/pax-utils/Pkgfile
* Maintainer: mattias@hedenskog.se
##### Fedora
diff --git a/TODO b/TODO
index 3c9968c..613bfb6 100644
--- a/TODO
+++ b/TODO
@@ -22,7 +22,7 @@ no hits as all of our symbol comparisons ignore the versioning info.
allow digging into ARM_ATTRIBUTES (.ARM.attributes) sections
- need info on the section layout
- figure out how to integrate cleanly (target-independent driller)
- http://sourceware.org/binutils/docs/as/GNU-Object-Attributes.html
+ https://sourceware.org/binutils/docs/as/GNU-Object-Attributes.html
scanelf should look at the dynamic table for rpath/needed/soname entries instead
of requiring section headers and looking up by section names. need to implement
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index 42e8a8c..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash -e
-
-. "${0%/*}"/travis/lib.sh
-
-m4dir="autotools/m4"
-
-v rm -rf autotools
-if [[ $1 != "--from=make" ]] ; then
- v ${MAKE:-make} autotools-update
-fi
-
-# reload the gnulib code if possible
-PATH=/usr/local/src/gnu/gnulib:${PATH}
-mods="
- alloca
- euidaccess
- faccessat
- fdopendir
- fstatat
- futimens
- getline
- getopt-posix
- mkdirat
- openat
- progname
- readlinkat
- renameat
- stat-time
- stpcpy
- strcasestr-simple
- strncat
- symlinkat
- sys_stat
- unlinkat
- utimensat
- vasprintf-posix
-"
-v --fold="gnulib-tool" gnulib-tool \
- --source-base=autotools/gnulib --m4-base=autotools/m4 \
- --import \
- ${mods}
-
-# not everyone has sys-devel/autoconf-archive installed
-v tar xf travis/autotools.tar.xz
-has() { [[ " ${*:2} " == *" $1 "* ]] ; }
-import_ax() {
- local macro content m4 lm4s=()
- content=$(sed -e '/^[[:space:]]*#/d' -e 's:\<dnl\>.*::' "$@")
- for macro in $(echo "${content}" | grep -o '\<AX[A-Z_]*\>' | sort -u) ; do
- for m4 in $(grep -rl "\[${macro}\]" /usr/share/aclocal/) ; do
- has ${m4} "${m4s[@]}" || lm4s+=( ${m4} )
- done
- done
- if [[ ${#lm4s[@]} -gt 0 ]] ; then
- cp -v `printf '%s\n' ${lm4s[@]} | sort -u` autotools/m4/
- m4s+=( "${lm4s[@]}" )
- fi
-}
-m4s=()
-import_ax configure.ac
-curr=1
-new=0
-while [[ ${curr} -ne ${new} ]] ; do
- curr=${#m4s[@]}
- import_ax autotools/m4/ax_*.m4
- new=${#m4s[@]}
-done
-
-export AUTOMAKE="automake --foreign"
-v autoreconf -i -f
-
-if [[ -x ./test.sh ]] ; then
- exec ./test.sh "$@"
-fi
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index a22e11a..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,71 +0,0 @@
-AC_PREREQ([2.65])
-AC_INIT([pax-utils], [git])
-AC_CONFIG_AUX_DIR([autotools])
-AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip silent-rules -Wall])
-AM_SILENT_RULES([yes]) # AM_INIT_AUTOMAKE([silent-rules]) is broken atm
-AC_CONFIG_HEADER([config.h])
-AC_CONFIG_MACRO_DIR([autotools/m4])
-
-AC_PROG_CC_C99
-AM_PROG_CC_C_O
-AM_PROG_AR
-AC_USE_SYSTEM_EXTENSIONS
-LT_INIT
-PKG_PROG_PKG_CONFIG
-
-gl_EARLY
-gl_INIT
-
-AC_ARG_WITH([caps], [AS_HELP_STRING([--with-caps], [build with capabilities])])
-AS_IF([test "x$with_caps" = "xyes"], [
- PKG_CHECK_MODULES(LIBCAP, libcap)
- CPPFLAGS="$CPPFLAGS $LIBCAP_CFLAGS -DWANT_SYSCAP"
- LIBS="$LIBS $LIBCAP_LIBS"
-])
-
-AC_ARG_WITH([debug], [AS_HELP_STRING([--with-debug], [enable debug code])])
-AS_IF([test "x$with_debug" = "xyes"], [
- CPPFLAGS="$CPPFLAGS -DEBUG"
-])
-
-AC_ARG_WITH([python], [AS_HELP_STRING([--with-python], [use lddtree.py])])
-AM_CONDITIONAL([USE_PYTHON], [test "x$with_python" = "xyes"])
-
-AC_ARG_WITH([seccomp], [AS_HELP_STRING([--with-seccomp], [build with seccomp])])
-AS_IF([test "x$with_seccomp" = "xyes"], [
- PKG_CHECK_MODULES(LIBSECCOMP, libseccomp)
- CPPFLAGS="$CPPFLAGS $LIBSECCOMP_CFLAGS -DWANT_SECCOMP"
- LIBS="$LIBS $LIBSECCOMP_LIBS"
-])
-
-AX_CFLAGS_WARN_ALL
-AC_DEFUN([PT_CHECK_CFLAG],[AX_CHECK_COMPILER_FLAGS([$1],[CFLAGS="$CFLAGS $1"])])
-m4_foreach_w([flag], [
- -Wunused
- -Wimplicit
- -Wshadow
- -Wformat=2
- -Wmissing-declarations
- -Wno-missing-prototypes
- -Wwrite-strings
- -Wbad-function-cast
- -Wnested-externs
- -Wcomment
- -Winline
- -Wchar-subscripts
- -Wcast-align
- -Wno-format-nonliteral
- -Wsequence-point
- -Wold-style-definition
- -Wextra
-], [
- AX_CHECK_COMPILE_FLAG(flag, AS_VAR_APPEND([CFLAGS], " flag"))
-])
-
-AC_CHECK_HEADERS([linux/securebits.h])
-
-AC_CONFIG_FILES([
- Makefile
- autotools/gnulib/Makefile
-])
-AC_OUTPUT
diff --git a/dumpelf.c b/dumpelf.c
index 405beba..0afb6c7 100644
--- a/dumpelf.c
+++ b/dumpelf.c
@@ -1,9 +1,9 @@
/*
- * Copyright 2005-2012 Gentoo Foundation
+ * Copyright 2005-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
*/
const char argv0[] = "dumpelf";
@@ -11,18 +11,15 @@ const char argv0[] = "dumpelf";
#include "paxinc.h"
/* prototypes */
-static void dumpelf(const char *filename, size_t file_cnt);
-static void dump_ehdr(elfobj *elf, const void *ehdr);
-static void dump_phdr(elfobj *elf, const void *phdr, size_t phdr_cnt);
-static void dump_shdr(elfobj *elf, const void *shdr, size_t shdr_cnt, const char *section_name);
-static void dump_dyn(elfobj *elf, const void *dyn, size_t dyn_cnt);
+static void dump_ehdr(const elfobj *elf, const void *ehdr);
+static void dump_phdr(const elfobj *elf, const void *phdr, size_t phdr_cnt);
+static void dump_shdr(const elfobj *elf, const void *shdr, size_t shdr_cnt, const char *section_name);
+static void dump_dyn(const elfobj *elf, const void *dyn, size_t dyn_cnt);
#if 0
-static void dump_sym(elfobj *elf, const void *sym);
-static void dump_rel(elfobj *elf, const void *rel);
-static void dump_rela(elfobj *elf, const void *rela);
+static void dump_sym(const elfobj *elf, const void *sym);
+static void dump_rel(const elfobj *elf, const void *rel);
+static void dump_rela(const elfobj *elf, const void *rela);
#endif
-static void usage(int status);
-static void parseargs(int argc, char *argv[]);
/* variables to control behavior */
static char be_verbose = 0;
@@ -31,15 +28,10 @@ static char be_verbose = 0;
static const void *phdr_dynamic_void;
/* dump all internal elf info */
-static void dumpelf(const char *filename, size_t file_cnt)
+static void dumpelf(const elfobj *elf, size_t file_cnt)
{
- elfobj *elf;
size_t i, b;
- /* verify this is real ELF */
- if ((elf = readelf(filename)) == NULL)
- return;
-
phdr_dynamic_void = NULL;
printf("#include <elf.h>\n");
@@ -48,9 +40,9 @@ static void dumpelf(const char *filename, size_t file_cnt)
"\n"
"/*\n"
" * ELF dump of '%s'\n"
- " * %ji (0x%jX) bytes\n"
+ " * %" PRIi64 " (0x%" PRIX64 ") bytes\n"
" */\n\n",
- filename, elf->len, elf->len);
+ elf->filename, (int64_t)elf->len, (uint64_t)elf->len);
/* setup the struct to namespace this elf */
#define MAKE_STRUCT(B) \
@@ -122,7 +114,7 @@ static void dumpelf(const char *filename, size_t file_cnt)
break_out_shdr:
printf("},\n");
- /* finish the namespace struct and start the abitrary ones */
+ /* finish the namespace struct and start the arbitrary ones */
printf("\n.dyns = dumpedelf_dyn_%zu,\n", file_cnt);
printf("};\n");
@@ -148,12 +140,23 @@ static void dumpelf(const char *filename, size_t file_cnt)
printf(" /* no dynamic tags ! */ ");
}
printf("};\n");
+}
+
+static void dumpelf_file(const char *filename, size_t file_cnt)
+{
+ elfobj *elf = readelf(filename);
+
+ /* verify this is real ELF */
+ if (elf == NULL)
+ return;
+
+ dumpelf(elf, file_cnt);
/* get out of here */
unreadelf(elf);
}
-static void dump_ehdr(elfobj *elf, const void *ehdr_void)
+static void dump_ehdr(const elfobj *elf, const void *ehdr_void)
{
#define DUMP_EHDR(B) \
if (elf->elf_class == ELFCLASS ## B) { \
@@ -203,7 +206,7 @@ static void dump_ehdr(elfobj *elf, const void *ehdr_void)
DUMP_EHDR(64)
}
-static void dump_notes(elfobj *elf, size_t B, const void *memory, const void *memory_end)
+static void dump_notes(const elfobj *elf, size_t B, const void *memory, const void *memory_end)
{
/* While normally we'd worry about Elf32_Nhdr vs Elf64_Nhdr, in the ELF
* world, the two structs are exactly the same. So avoid ugly CPP.
@@ -294,7 +297,7 @@ static const char *dump_p_flags(uint32_t type, uint32_t flags)
return buf + 3;
}
-static void dump_phdr(elfobj *elf, const void *phdr_void, size_t phdr_cnt)
+static void dump_phdr(const elfobj *elf, const void *phdr_void, size_t phdr_cnt)
{
#define DUMP_PHDR(B) \
if (elf->elf_class == ELFCLASS ## B) { \
@@ -351,7 +354,7 @@ static const char *timestamp(uint64_t stamp)
return buf;
}
-static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const char *section_name)
+static void dump_shdr(const elfobj *elf, const void *shdr_void, size_t shdr_cnt, const char *section_name)
{
size_t i;
@@ -460,6 +463,7 @@ static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const
++lib; \
} \
printf("\t */\n"); \
+ break; \
} \
default: { \
if (be_verbose <= 1) \
@@ -482,7 +486,7 @@ static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const
DUMP_SHDR(64)
}
-static void dump_dyn(elfobj *elf, const void *dyn_void, size_t dyn_cnt)
+static void dump_dyn(const elfobj *elf, const void *dyn_void, size_t dyn_cnt)
{
#define DUMP_DYN(B) \
if (elf->elf_class == ELFCLASS ## B) { \
@@ -503,7 +507,6 @@ static void dump_dyn(elfobj *elf, const void *dyn_void, size_t dyn_cnt)
/* usage / invocation handling functions */
#define PARSE_FLAGS "vhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
@@ -520,21 +523,16 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- size_t i;
- printf("* Dump internal ELF structure\n\n"
- "Usage: %s <file1> [file2 fileN ...]\n\n", argv0);
- printf("Options:\n");
- for (i = 0; long_opts[i].name; ++i)
- if (long_opts[i].has_arg == no_argument)
- printf(" -%c, --%-13s* %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
- else
- printf(" -%c, --%-6s <arg> * %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
- exit(status);
+ pax_usage(
+ "Dump internal ELF structure",
+ "<file1> [file2 fileN ...]",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
-/* parse command line arguments and preform needed actions */
+/* parse command line arguments and perform needed actions */
static void parseargs(int argc, char *argv[])
{
int flag;
@@ -569,10 +567,30 @@ static void parseargs(int argc, char *argv[])
size_t file_cnt = 0;
while (optind < argc)
- dumpelf(argv[optind++], file_cnt++);
+ dumpelf_file(argv[optind++], file_cnt++);
}
}
+#if PAX_UTILS_LIBFUZZ
+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+ (void)argc;
+ (void)argv;
+ (void)parseargs;
+ security_init(false);
+ return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ elfobj *elf = readelf_buffer("libFuzzer", data, size);
+ if (elf == NULL)
+ return 0;
+ dumpelf(elf, 0);
+ unreadelf(elf);
+ return 0;
+}
+#else
int main(int argc, char *argv[])
{
security_init(false);
@@ -581,3 +599,4 @@ int main(int argc, char *argv[])
parseargs(argc, argv);
return EXIT_SUCCESS;
}
+#endif
diff --git a/elf.h b/elf.h
index fda7585..5c1c197 100644
--- a/elf.h
+++ b/elf.h
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995-2015 Free Software Foundation, Inc.
+ Copyright (C) 1995-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -14,7 +14,7 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
+ <https://www.gnu.org/licenses/>. */
#ifndef _ELF_H
#define _ELF_H 1
@@ -168,106 +168,203 @@ typedef struct
/* Legal values for e_machine (architecture). */
-#define EM_NONE 0 /* No machine */
-#define EM_M32 1 /* AT&T WE 32100 */
-#define EM_SPARC 2 /* SUN SPARC */
-#define EM_386 3 /* Intel 80386 */
-#define EM_68K 4 /* Motorola m68k family */
-#define EM_88K 5 /* Motorola m88k family */
-#define EM_860 7 /* Intel 80860 */
-#define EM_MIPS 8 /* MIPS R3000 big-endian */
-#define EM_S370 9 /* IBM System/370 */
-#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
-
-#define EM_PARISC 15 /* HPPA */
-#define EM_VPP500 17 /* Fujitsu VPP500 */
-#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-#define EM_960 19 /* Intel 80960 */
-#define EM_PPC 20 /* PowerPC */
-#define EM_PPC64 21 /* PowerPC 64-bit */
-#define EM_S390 22 /* IBM S390 */
-
-#define EM_V800 36 /* NEC V800 series */
-#define EM_FR20 37 /* Fujitsu FR20 */
-#define EM_RH32 38 /* TRW RH-32 */
-#define EM_RCE 39 /* Motorola RCE */
-#define EM_ARM 40 /* ARM */
-#define EM_FAKE_ALPHA 41 /* Digital Alpha */
-#define EM_SH 42 /* Hitachi SH */
-#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-#define EM_TRICORE 44 /* Siemens Tricore */
-#define EM_ARC 45 /* Argonaut RISC Core */
-#define EM_H8_300 46 /* Hitachi H8/300 */
-#define EM_H8_300H 47 /* Hitachi H8/300H */
-#define EM_H8S 48 /* Hitachi H8S */
-#define EM_H8_500 49 /* Hitachi H8/500 */
-#define EM_IA_64 50 /* Intel Merced */
-#define EM_MIPS_X 51 /* Stanford MIPS-X */
-#define EM_COLDFIRE 52 /* Motorola Coldfire */
-#define EM_68HC12 53 /* Motorola M68HC12 */
-#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
-#define EM_PCP 55 /* Siemens PCP */
-#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
-#define EM_NDR1 57 /* Denso NDR1 microprocessor */
-#define EM_STARCORE 58 /* Motorola Start*Core processor */
-#define EM_ME16 59 /* Toyota ME16 processor */
-#define EM_ST100 60 /* STMicroelectronic ST100 processor */
-#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
-#define EM_X86_64 62 /* AMD x86-64 architecture */
-#define EM_PDSP 63 /* Sony DSP Processor */
-
-#define EM_FX66 66 /* Siemens FX66 microcontroller */
-#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
-#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
-#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
-#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
-#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
-#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
-#define EM_SVX 73 /* Silicon Graphics SVx */
-#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
-#define EM_VAX 75 /* Digital VAX */
-#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
-#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
-#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
-#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
-#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
-#define EM_HUANY 81 /* Harvard University machine-independent object files */
-#define EM_PRISM 82 /* SiTera Prism */
-#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
-#define EM_FR30 84 /* Fujitsu FR30 */
-#define EM_D10V 85 /* Mitsubishi D10V */
-#define EM_D30V 86 /* Mitsubishi D30V */
-#define EM_V850 87 /* NEC v850 */
-#define EM_M32R 88 /* Mitsubishi M32R */
-#define EM_MN10300 89 /* Matsushita MN10300 */
-#define EM_MN10200 90 /* Matsushita MN10200 */
-#define EM_PJ 91 /* picoJava */
-#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
-#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
-#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
-#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */
-#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */
-#define EM_NS32K 97 /* National Semiconductor 32000 series */
-#define EM_TPC 98 /* Tenor Network TPC processor */
-#define EM_SNP1K 99 /* Trebia SNP 1000 processor */
-#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller */
-#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family */
-#define EM_MAX 102 /* MAX Processor */
-#define EM_CR 103 /* NatSemi CompactRISC microprocessor */
-#define EM_F2MC16 104 /* Fujitsu F2MC16 */
-#define EM_MSP430 105 /* TI embedded microcontroller msp430 */
-#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor */
-#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors */
-#define EM_SEP 108 /* Sharp embedded microprocessor */
-#define EM_ARCA 109 /* Arca RISC Microprocessor */
-#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. */
- /* and MPRC of Peking University */
-#define EM_ALTERA_NIOS2 113 /* Altera Nios II */
-#define EM_AARCH64 183 /* ARM AARCH64 */
-#define EM_TILEPRO 188 /* Tilera TILEPro */
-#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
-#define EM_TILEGX 191 /* Tilera TILE-Gx */
-#define EM_NUM 192
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SUN SPARC */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola m68k family */
+#define EM_88K 5 /* Motorola m88k family */
+#define EM_IAMCU 6 /* Intel MCU */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_S370 9 /* IBM System/370 */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
+ /* reserved 11-14 */
+#define EM_PARISC 15 /* HPPA */
+ /* reserved 16 */
+#define EM_VPP500 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* PowerPC 64-bit */
+#define EM_S390 22 /* IBM S390 */
+#define EM_SPU 23 /* IBM SPU/SPC */
+ /* reserved 24-35 */
+#define EM_V800 36 /* NEC V800 series */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH-32 */
+#define EM_RCE 39 /* Motorola RCE */
+#define EM_ARM 40 /* ARM */
+#define EM_FAKE_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Hitachi SH */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_TRICORE 44 /* Siemens Tricore */
+#define EM_ARC 45 /* Argonaut RISC Core */
+#define EM_H8_300 46 /* Hitachi H8/300 */
+#define EM_H8_300H 47 /* Hitachi H8/300H */
+#define EM_H8S 48 /* Hitachi H8S */
+#define EM_H8_500 49 /* Hitachi H8/500 */
+#define EM_IA_64 50 /* Intel Merced */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_68HC12 53 /* Motorola M68HC12 */
+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */
+#define EM_PCP 55 /* Siemens PCP */
+#define EM_NCPU 56 /* Sony nCPU embedded RISC */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
+#define EM_STARCORE 58 /* Motorola Start*Core processor */
+#define EM_ME16 59 /* Toyota ME16 processor */
+#define EM_ST100 60 /* STMicroelectronic ST100 processor */
+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam */
+#define EM_X86_64 62 /* AMD x86-64 architecture */
+#define EM_PDSP 63 /* Sony DSP Processor */
+#define EM_PDP10 64 /* Digital PDP-10 */
+#define EM_PDP11 65 /* Digital PDP-11 */
+#define EM_FX66 66 /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
+#define EM_SVX 73 /* Silicon Graphics SVx */
+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX 75 /* Digital VAX */
+#define EM_CRIS 76 /* Axis Communications 32-bit emb.proc */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit emb.proc */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc */
+#define EM_HUANY 81 /* Harvard University machine-independent object files */
+#define EM_PRISM 82 /* SiTera Prism */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 84 /* Fujitsu FR30 */
+#define EM_D10V 85 /* Mitsubishi D10V */
+#define EM_D30V 86 /* Mitsubishi D30V */
+#define EM_V850 87 /* NEC v850 */
+#define EM_M32R 88 /* Mitsubishi M32R */
+#define EM_MN10300 89 /* Matsushita MN10300 */
+#define EM_MN10200 90 /* Matsushita MN10200 */
+#define EM_PJ 91 /* picoJava */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_COMPACT 93 /* ARC International ARCompact */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */
+#define EM_NS32K 97 /* National Semi. 32000 */
+#define EM_TPC 98 /* Tenor Network TPC */
+#define EM_SNP1K 99 /* Trebia SNP 1000 */
+#define EM_ST200 100 /* STMicroelectronics ST200 */
+#define EM_IP2K 101 /* Ubicom IP2xxx */
+#define EM_MAX 102 /* MAX processor */
+#define EM_CR 103 /* National Semi. CompactRISC */
+#define EM_F2MC16 104 /* Fujitsu F2MC16 */
+#define EM_MSP430 105 /* Texas Instruments msp430 */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin DSP */
+#define EM_SE_C33 107 /* Seiko Epson S1C33 family */
+#define EM_SEP 108 /* Sharp embedded microprocessor */
+#define EM_ARCA 109 /* Arca RISC */
+#define EM_UNICORE 110 /* PKU-Unity & MPRC Peking Uni. mc series */
+#define EM_EXCESS 111 /* eXcess configurable cpu */
+#define EM_DXP 112 /* Icera Semi. Deep Execution Processor */
+#define EM_ALTERA_NIOS2 113 /* Altera Nios II */
+#define EM_CRX 114 /* National Semi. CompactRISC CRX */
+#define EM_XGATE 115 /* Motorola XGATE */
+#define EM_C166 116 /* Infineon C16x/XC16x */
+#define EM_M16C 117 /* Renesas M16C */
+#define EM_DSPIC30F 118 /* Microchip Technology dsPIC30F */
+#define EM_CE 119 /* Freescale Communication Engine RISC */
+#define EM_M32C 120 /* Renesas M32C */
+ /* reserved 121-130 */
+#define EM_TSK3000 131 /* Altium TSK3000 */
+#define EM_RS08 132 /* Freescale RS08 */
+#define EM_SHARC 133 /* Analog Devices SHARC family */
+#define EM_ECOG2 134 /* Cyan Technology eCOG2 */
+#define EM_SCORE7 135 /* Sunplus S+core7 RISC */
+#define EM_DSP24 136 /* New Japan Radio (NJR) 24-bit DSP */
+#define EM_VIDEOCORE3 137 /* Broadcom VideoCore III */
+#define EM_LATTICEMICO32 138 /* RISC for Lattice FPGA */
+#define EM_SE_C17 139 /* Seiko Epson C17 */
+#define EM_TI_C6000 140 /* Texas Instruments TMS320C6000 DSP */
+#define EM_TI_C2000 141 /* Texas Instruments TMS320C2000 DSP */
+#define EM_TI_C5500 142 /* Texas Instruments TMS320C55x DSP */
+#define EM_TI_ARP32 143 /* Texas Instruments App. Specific RISC */
+#define EM_TI_PRU 144 /* Texas Instruments Prog. Realtime Unit */
+ /* reserved 145-159 */
+#define EM_MMDSP_PLUS 160 /* STMicroelectronics 64bit VLIW DSP */
+#define EM_CYPRESS_M8C 161 /* Cypress M8C */
+#define EM_R32C 162 /* Renesas R32C */
+#define EM_TRIMEDIA 163 /* NXP Semi. TriMedia */
+#define EM_QDSP6 164 /* QUALCOMM DSP6 */
+#define EM_8051 165 /* Intel 8051 and variants */
+#define EM_STXP7X 166 /* STMicroelectronics STxP7x */
+#define EM_NDS32 167 /* Andes Tech. compact code emb. RISC */
+#define EM_ECOG1X 168 /* Cyan Technology eCOG1X */
+#define EM_MAXQ30 169 /* Dallas Semi. MAXQ30 mc */
+#define EM_XIMO16 170 /* New Japan Radio (NJR) 16-bit DSP */
+#define EM_MANIK 171 /* M2000 Reconfigurable RISC */
+#define EM_CRAYNV2 172 /* Cray NV2 vector architecture */
+#define EM_RX 173 /* Renesas RX */
+#define EM_METAG 174 /* Imagination Tech. META */
+#define EM_MCST_ELBRUS 175 /* MCST Elbrus */
+#define EM_ECOG16 176 /* Cyan Technology eCOG16 */
+#define EM_CR16 177 /* National Semi. CompactRISC CR16 */
+#define EM_ETPU 178 /* Freescale Extended Time Processing Unit */
+#define EM_SLE9X 179 /* Infineon Tech. SLE9X */
+#define EM_L10M 180 /* Intel L10M */
+#define EM_K10M 181 /* Intel K10M */
+ /* reserved 182 */
+#define EM_AARCH64 183 /* ARM AARCH64 */
+ /* reserved 184 */
+#define EM_AVR32 185 /* Amtel 32-bit microprocessor */
+#define EM_STM8 186 /* STMicroelectronics STM8 */
+#define EM_TILE64 187 /* Tilera TILE64 */
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
+#define EM_CUDA 190 /* NVIDIA CUDA */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_CLOUDSHIELD 192 /* CloudShield */
+#define EM_COREA_1ST 193 /* KIPO-KAIST Core-A 1st gen. */
+#define EM_COREA_2ND 194 /* KIPO-KAIST Core-A 2nd gen. */
+#define EM_ARCV2 195 /* Synopsys ARCv2 ISA. */
+#define EM_OPEN8 196 /* Open8 RISC */
+#define EM_RL78 197 /* Renesas RL78 */
+#define EM_VIDEOCORE5 198 /* Broadcom VideoCore V */
+#define EM_78KOR 199 /* Renesas 78KOR */
+#define EM_56800EX 200 /* Freescale 56800EX DSC */
+#define EM_BA1 201 /* Beyond BA1 */
+#define EM_BA2 202 /* Beyond BA2 */
+#define EM_XCORE 203 /* XMOS xCORE */
+#define EM_MCHP_PIC 204 /* Microchip 8-bit PIC(r) */
+#define EM_INTELGT 205 /* Intel Graphics Technology */
+ /* reserved 206-209 */
+#define EM_KM32 210 /* KM211 KM32 */
+#define EM_KMX32 211 /* KM211 KMX32 */
+#define EM_EMX16 212 /* KM211 KMX16 */
+#define EM_EMX8 213 /* KM211 KMX8 */
+#define EM_KVARC 214 /* KM211 KVARC */
+#define EM_CDP 215 /* Paneve CDP */
+#define EM_COGE 216 /* Cognitive Smart Memory Processor */
+#define EM_COOL 217 /* Bluechip CoolEngine */
+#define EM_NORC 218 /* Nanoradio Optimized RISC */
+#define EM_CSR_KALIMBA 219 /* CSR Kalimba */
+#define EM_Z80 220 /* Zilog Z80 */
+#define EM_VISIUM 221 /* Controls and Data Services VISIUMcore */
+#define EM_FT32 222 /* FTDI Chip FT32 */
+#define EM_MOXIE 223 /* Moxie processor */
+#define EM_AMDGPU 224 /* AMD GPU */
+ /* reserved 225-242 */
+#define EM_RISCV 243 /* RISC-V */
+
+#define EM_BPF 247 /* Linux BPF -- in-kernel virtual machine */
+#define EM_CSKY 252 /* C-SKY */
+#define EM_LOONGARCH 258 /* LoongArch */
+
+#define EM_NUM 259
+
+/* Old spellings/synonyms. */
+
+#define EM_ARC_A5 EM_ARC_COMPACT
/* If it is necessary to assign new unofficial EM_* values, please
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
@@ -346,8 +443,9 @@ typedef struct
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
-#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
-#define SHT_NUM 19 /* Number of defined types. */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
+#define SHT_RELR 19 /* RELR relative relocations */
+#define SHT_NUM 20 /* Number of defined types. */
#define SHT_LOOS 0x60000000 /* Start OS-specific. */
#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
@@ -380,13 +478,40 @@ typedef struct
required */
#define SHF_GROUP (1 << 9) /* Section is member of a group. */
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
+#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
+#define SHF_GNU_RETAIN (1 << 21) /* Not to be GCed by linker. */
#define SHF_ORDERED (1 << 30) /* Special ordering requirement
(Solaris). */
-#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
+#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless
referenced or allocated (Solaris).*/
+/* Section compression header. Used when SHF_COMPRESSED is set. */
+
+typedef struct
+{
+ Elf32_Word ch_type; /* Compression format. */
+ Elf32_Word ch_size; /* Uncompressed data size. */
+ Elf32_Word ch_addralign; /* Uncompressed data alignment. */
+} Elf32_Chdr;
+
+typedef struct
+{
+ Elf64_Word ch_type; /* Compression format. */
+ Elf64_Word ch_reserved;
+ Elf64_Xword ch_size; /* Uncompressed data size. */
+ Elf64_Xword ch_addralign; /* Uncompressed data alignment. */
+} Elf64_Chdr;
+
+/* Legal values for ch_type (compression algorithm). */
+#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */
+#define ELFCOMPRESS_ZSTD 2 /* Zstandard algorithm. */
+#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */
+#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */
+#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */
+#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */
+
/* Section group handling. */
#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
@@ -434,7 +559,7 @@ typedef struct
/* Possible bitmasks for si_flags. */
#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
-#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-through symbol for translator */
#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
loaded */
@@ -540,6 +665,11 @@ typedef struct
Elf64_Sxword r_addend; /* Addend */
} Elf64_Rela;
+/* RELR relocation table entry */
+
+typedef Elf32_Word Elf32_Relr;
+typedef Elf64_Xword Elf64_Relr;
+
/* How to extract and insert information held in the r_info field. */
#define ELF32_R_SYM(val) ((val) >> 8)
@@ -597,6 +727,8 @@ typedef struct
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
+#define PT_GNU_PROPERTY 0x6474e553 /* GNU property */
+#define PT_GNU_SFRAME 0x6474e554 /* SFrame segment. */
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
@@ -616,6 +748,8 @@ typedef struct
/* Legal values for note segment descriptor types for core files. */
#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
+#define NT_PRFPREG 2 /* Contains copy of fpregset
+ struct. */
#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
#define NT_PRXREG 4 /* Contains copy of prxregset struct */
@@ -639,9 +773,30 @@ typedef struct
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_PPC_TAR 0x103 /* Target Address Register */
+#define NT_PPC_PPR 0x104 /* Program Priority Register */
+#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */
+#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */
+#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */
+#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
+#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
+#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
+#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
+#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
+#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address
+ Register */
+#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority
+ Register */
+#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control
+ Register */
+#define NT_PPC_PKEY 0x110 /* Memory Protection Keys
+ registers. */
+#define NT_PPC_DEXCR 0x111 /* PowerPC DEXCR registers. */
+#define NT_PPC_HASHKEYR 0x112 /* PowerPC HASHKEYR register. */
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
+#define NT_X86_SHSTK 0x204 /* x86 SHSTK state */
#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
#define NT_S390_TIMER 0x301 /* s390 timer register */
#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
@@ -651,10 +806,48 @@ typedef struct
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
+#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15
+ upper half. */
+#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */
+#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */
+#define NT_S390_GS_BC 0x30c /* s390 guarded storage
+ broadcast control block. */
+#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */
+#define NT_S390_PV_CPU_DATA 0x30e /* s390 protvirt cpu dump data. */
#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
#define NT_ARM_TLS 0x401 /* ARM TLS register */
#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
+#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
+#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension
+ registers */
+#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication
+ code masks. */
+#define NT_ARM_PACA_KEYS 0x407 /* ARM pointer authentication
+ address keys. */
+#define NT_ARM_PACG_KEYS 0x408 /* ARM pointer authentication
+ generic key. */
+#define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* AArch64 tagged address
+ control. */
+#define NT_ARM_PAC_ENABLED_KEYS 0x40a /* AArch64 pointer authentication
+ enabled keys. */
+#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */
+#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */
+#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */
+#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */
+#define NT_RISCV_CSR 0x900 /* RISC-V Control and Status Registers */
+#define NT_RISCV_VECTOR 0x901 /* RISC-V vector registers */
+#define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers. */
+#define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and
+ status registers. */
+#define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD
+ Extension registers. */
+#define NT_LOONGARCH_LASX 0xa03 /* LoongArch Loongson Advanced
+ SIMD Extension registers. */
+#define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary
+ Translation registers. */
+#define NT_LOONGARCH_HW_BREAK 0xa05 /* LoongArch hardware breakpoint registers */
+#define NT_LOONGARCH_HW_WATCH 0xa06 /* LoongArch hardware watchpoint registers */
/* Legal values for the note segment descriptor types for object files. */
@@ -719,7 +912,11 @@ typedef struct
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
-#define DT_NUM 34 /* Number used */
+#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */
+#define DT_RELRSZ 35 /* Total size of RELR relative relocations */
+#define DT_RELR 36 /* Address of RELR relative relocations */
+#define DT_RELRENT 37 /* Size of one RELR relative relocaction */
+#define DT_NUM 38 /* Number used */
#define DT_LOOS 0x6000000d /* Start of OS-specific */
#define DT_HIOS 0x6ffff000 /* End of OS-specific */
#define DT_LOPROC 0x70000000 /* Start of processor-specific */
@@ -827,6 +1024,11 @@ typedef struct
#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
+#define DF_1_STUB 0x04000000
+#define DF_1_PIE 0x08000000
+#define DF_1_KMOD 0x10000000
+#define DF_1_WEAKFILTER 0x20000000
+#define DF_1_NOCOMMON 0x40000000
/* Flags for the feature selection in DT_FEATURE_1. */
#define DTF_1_PARINIT 0x00000001
@@ -871,7 +1073,8 @@ typedef struct
/* Legal values for vd_flags (version information flags). */
#define VER_FLG_BASE 0x1 /* Version definition of file itself */
-#define VER_FLG_WEAK 0x2 /* Weak version identifier */
+#define VER_FLG_WEAK 0x2 /* Weak version identifier. Also
+ used by vna_flags below. */
/* Versym symbol index values. */
#define VER_NDX_LOCAL 0 /* Symbol is local. */
@@ -879,7 +1082,7 @@ typedef struct
#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */
#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */
-/* Auxialiary version information. */
+/* Auxiliary version information. */
typedef struct
{
@@ -949,10 +1152,6 @@ typedef struct
} Elf64_Vernaux;
-/* Legal values for vna_flags. */
-#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-
-
/* Auxiliary vector. */
/* This vector is normally only used by the program interpreter. The
@@ -1032,6 +1231,9 @@ typedef struct
#define AT_HWCAP2 26 /* More machine-dependent hints about
processor capabilities. */
+#define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */
+#define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */
+
#define AT_EXECFN 31 /* Filename of executable. */
/* Pointer to the global system page used for system calls and other
@@ -1046,6 +1248,20 @@ typedef struct
#define AT_L2_CACHESHAPE 36
#define AT_L3_CACHESHAPE 37
+/* Shapes of the caches, with more room to describe them.
+ *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits
+ and the cache associativity in the next 16 bits. */
+#define AT_L1I_CACHESIZE 40
+#define AT_L1I_CACHEGEOMETRY 41
+#define AT_L1D_CACHESIZE 42
+#define AT_L1D_CACHEGEOMETRY 43
+#define AT_L2_CACHESIZE 44
+#define AT_L2_CACHEGEOMETRY 45
+#define AT_L3_CACHESIZE 46
+#define AT_L3_CACHEGEOMETRY 47
+
+#define AT_MINSIGSTKSZ 51 /* Stack needed for signal delivery */
+
/* Note section contents. Each entry in the note section begins with
a header of a fixed form. */
@@ -1071,6 +1287,8 @@ typedef struct
/* Note entries for GNU systems have this name. */
#define ELF_NOTE_GNU "GNU"
+/* Note entries for freedesktop.org have this name. */
+#define ELF_NOTE_FDO "FDO"
/* Defined types of notes for Solaris. */
@@ -1111,6 +1329,84 @@ typedef struct
/* Version note generated by GNU gold containing a version string. */
#define NT_GNU_GOLD_VERSION 4
+/* Program property. */
+#define NT_GNU_PROPERTY_TYPE_0 5
+
+/* Packaging metadata as defined on
+ https://systemd.io/COREDUMP_PACKAGE_METADATA/ */
+#define NT_FDO_PACKAGING_METADATA 0xcafe1a7e
+
+/* Note section name of program property. */
+#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property"
+
+/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */
+
+/* Stack size. */
+#define GNU_PROPERTY_STACK_SIZE 1
+/* No copy relocation on protected data symbol. */
+#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2
+
+/* A 4-byte unsigned integer property: A bit is set if it is set in all
+ relocatable inputs. */
+#define GNU_PROPERTY_UINT32_AND_LO 0xb0000000
+#define GNU_PROPERTY_UINT32_AND_HI 0xb0007fff
+
+/* A 4-byte unsigned integer property: A bit is set if it is set in any
+ relocatable inputs. */
+#define GNU_PROPERTY_UINT32_OR_LO 0xb0008000
+#define GNU_PROPERTY_UINT32_OR_HI 0xb000ffff
+
+/* The needed properties by the object file. */
+#define GNU_PROPERTY_1_NEEDED GNU_PROPERTY_UINT32_OR_LO
+
+/* Set if the object file requires canonical function pointers and
+ cannot be used with copy relocation. */
+#define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS (1U << 0)
+
+/* Processor-specific semantics, lo */
+#define GNU_PROPERTY_LOPROC 0xc0000000
+/* Processor-specific semantics, hi */
+#define GNU_PROPERTY_HIPROC 0xdfffffff
+/* Application-specific semantics, lo */
+#define GNU_PROPERTY_LOUSER 0xe0000000
+/* Application-specific semantics, hi */
+#define GNU_PROPERTY_HIUSER 0xffffffff
+
+/* AArch64 specific GNU properties. */
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
+
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1)
+
+/* The x86 instruction sets indicated by the corresponding bits are
+ used in program. Their support in the hardware is optional. */
+#define GNU_PROPERTY_X86_ISA_1_USED 0xc0010002
+/* The x86 instruction sets indicated by the corresponding bits are
+ used in program and they must be supported by the hardware. */
+#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0008002
+/* X86 processor-specific features used in program. */
+#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002
+
+/* GNU_PROPERTY_X86_ISA_1_BASELINE: CMOV, CX8 (cmpxchg8b), FPU (fld),
+ MMX, OSFXSR (fxsave), SCE (syscall), SSE and SSE2. */
+#define GNU_PROPERTY_X86_ISA_1_BASELINE (1U << 0)
+/* GNU_PROPERTY_X86_ISA_1_V2: GNU_PROPERTY_X86_ISA_1_BASELINE,
+ CMPXCHG16B (cmpxchg16b), LAHF-SAHF (lahf), POPCNT (popcnt), SSE3,
+ SSSE3, SSE4.1 and SSE4.2. */
+#define GNU_PROPERTY_X86_ISA_1_V2 (1U << 1)
+/* GNU_PROPERTY_X86_ISA_1_V3: GNU_PROPERTY_X86_ISA_1_V2, AVX, AVX2, BMI1,
+ BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE. */
+#define GNU_PROPERTY_X86_ISA_1_V3 (1U << 2)
+/* GNU_PROPERTY_X86_ISA_1_V4: GNU_PROPERTY_X86_ISA_1_V3, AVX512F,
+ AVX512BW, AVX512CD, AVX512DQ and AVX512VL. */
+#define GNU_PROPERTY_X86_ISA_1_V4 (1U << 3)
+
+/* This indicates that all executable sections are compatible with
+ IBT. */
+#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0)
+/* This indicates that all executable sections are compatible with
+ SHSTK. */
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1)
/* Move records. */
typedef struct
@@ -1257,8 +1553,10 @@ typedef struct
argument, returning the TLS
offset for the symbol. */
#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
+#define R_386_GOT32X 43 /* Load from 32 bit GOT entry,
+ relaxable. */
/* Keep this the last entry. */
-#define R_386_NUM 43
+#define R_386_NUM 44
/* SUN SPARC specific definitions. */
@@ -1394,11 +1692,25 @@ typedef struct
#define EF_MIPS_PIC 2 /* Contains PIC code. */
#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */
#define EF_MIPS_XGOT 8
-#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_UCODE 16
#define EF_MIPS_ABI2 32
#define EF_MIPS_ABI_ON32 64
+#define EF_MIPS_OPTIONS_FIRST 0x00000080 /* Process the .MIPS.options
+ section first by ld. */
+#define EF_MIPS_32BITMODE 0x00000100 /* Indicates code compiled for
+ a 64-bit machine in 32-bit
+ mode (regs are 32-bits
+ wide). */
#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */
#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */
+#define EF_MIPS_ARCH_ASE 0x0f000000 /* Architectural Extensions
+ used by this file. */
+#define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* Use MDMX multimedia
+ extensions. */
+#define EF_MIPS_ARCH_ASE_M16 0x04000000 /* Use MIPS-16 ISA
+ extensions. */
+#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000 /* Use MICROMIPS ISA
+ extensions. */
#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */
/* Legal values for MIPS architecture level. */
@@ -1412,6 +1724,38 @@ typedef struct
#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */
#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */
+#define EF_MIPS_ARCH_32R6 0x90000000 /* MIPS32r6 code. */
+#define EF_MIPS_ARCH_64R6 0xa0000000 /* MIPS64r6 code. */
+#define EF_MIPS_ABI 0x0000F000 /* The ABI of the file. Also
+ see EF_MIPS_ABI2 above. */
+#define EF_MIPS_ABI_O32 0x00001000 /* The original o32 abi. */
+#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended to work on
+ 64 bit architectures. */
+#define EF_MIPS_ABI_EABI32 0x00003000 /* EABI in 32 bit mode. */
+#define EF_MIPS_ABI_EABI64 0x00004000 /* EABI in 64 bit mode. */
+#define EF_MIPS_MACH 0x00FF0000
+#define EF_MIPS_MACH_3900 0x00810000
+#define EF_MIPS_MACH_4010 0x00820000
+#define EF_MIPS_MACH_4100 0x00830000
+#define EF_MIPS_MACH_ALLEGREX 0x00840000
+#define EF_MIPS_MACH_4650 0x00850000
+#define EF_MIPS_MACH_4120 0x00870000
+#define EF_MIPS_MACH_4111 0x00880000
+#define EF_MIPS_MACH_SB1 0x008a0000
+#define EF_MIPS_MACH_OCTEON 0x008b0000
+#define EF_MIPS_MACH_XLR 0x008c0000
+#define EF_MIPS_MACH_OCTEON2 0x008d0000
+#define EF_MIPS_MACH_OCTEON3 0x008e0000
+#define EF_MIPS_MACH_5400 0x00910000
+#define EF_MIPS_MACH_5900 0x00920000
+#define EF_MIPS_MACH_IAMR2 0x00930000
+#define EF_MIPS_MACH_5500 0x00980000
+#define EF_MIPS_MACH_9000 0x00990000
+#define EF_MIPS_MACH_LS2E 0x00A00000
+#define EF_MIPS_MACH_LS2F 0x00A10000
+#define EF_MIPS_MACH_GS464 0x00A20000
+#define EF_MIPS_MACH_GS464E 0x00A30000
+#define EF_MIPS_MACH_GS264E 0x00A40000
/* The following are unofficial names and should not be used. */
@@ -1472,6 +1816,8 @@ typedef struct
#define SHT_MIPS_EH_REGION 0x70000027
#define SHT_MIPS_XLATE_OLD 0x70000028
#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+#define SHT_MIPS_ABIFLAGS 0x7000002a
+#define SHT_MIPS_XHASH 0x7000002b
/* Legal values for sh_flags field of Elf32_Shdr. */
@@ -1639,10 +1985,68 @@ typedef struct
#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
#define R_MIPS_GLOB_DAT 51
+#define R_MIPS_PC21_S2 60
+#define R_MIPS_PC26_S2 61
+#define R_MIPS_PC18_S3 62
+#define R_MIPS_PC19_S2 63
+#define R_MIPS_PCHI16 64
+#define R_MIPS_PCLO16 65
+#define R_MIPS16_26 100
+#define R_MIPS16_GPREL 101
+#define R_MIPS16_GOT16 102
+#define R_MIPS16_CALL16 103
+#define R_MIPS16_HI16 104
+#define R_MIPS16_LO16 105
+#define R_MIPS16_TLS_GD 106
+#define R_MIPS16_TLS_LDM 107
+#define R_MIPS16_TLS_DTPREL_HI16 108
+#define R_MIPS16_TLS_DTPREL_LO16 109
+#define R_MIPS16_TLS_GOTTPREL 110
+#define R_MIPS16_TLS_TPREL_HI16 111
+#define R_MIPS16_TLS_TPREL_LO16 112
+#define R_MIPS16_PC16_S1 113
#define R_MIPS_COPY 126
#define R_MIPS_JUMP_SLOT 127
+#define R_MIPS_RELATIVE 128
+#define R_MICROMIPS_26_S1 133
+#define R_MICROMIPS_HI16 134
+#define R_MICROMIPS_LO16 135
+#define R_MICROMIPS_GPREL16 136
+#define R_MICROMIPS_LITERAL 137
+#define R_MICROMIPS_GOT16 138
+#define R_MICROMIPS_PC7_S1 139
+#define R_MICROMIPS_PC10_S1 140
+#define R_MICROMIPS_PC16_S1 141
+#define R_MICROMIPS_CALL16 142
+#define R_MICROMIPS_GOT_DISP 145
+#define R_MICROMIPS_GOT_PAGE 146
+#define R_MICROMIPS_GOT_OFST 147
+#define R_MICROMIPS_GOT_HI16 148
+#define R_MICROMIPS_GOT_LO16 149
+#define R_MICROMIPS_SUB 150
+#define R_MICROMIPS_HIGHER 151
+#define R_MICROMIPS_HIGHEST 152
+#define R_MICROMIPS_CALL_HI16 153
+#define R_MICROMIPS_CALL_LO16 154
+#define R_MICROMIPS_SCN_DISP 155
+#define R_MICROMIPS_JALR 156
+#define R_MICROMIPS_HI0_LO16 157
+#define R_MICROMIPS_TLS_GD 162
+#define R_MICROMIPS_TLS_LDM 163
+#define R_MICROMIPS_TLS_DTPREL_HI16 164
+#define R_MICROMIPS_TLS_DTPREL_LO16 165
+#define R_MICROMIPS_TLS_GOTTPREL 166
+#define R_MICROMIPS_TLS_TPREL_HI16 169
+#define R_MICROMIPS_TLS_TPREL_LO16 170
+#define R_MICROMIPS_GPREL7_S2 172
+#define R_MICROMIPS_PC23_S2 173
+#define R_MIPS_PC32 248
+#define R_MIPS_EH 249
+#define R_MIPS_GNU_REL16_S2 250
+#define R_MIPS_GNU_VTINHERIT 253
+#define R_MIPS_GNU_VTENTRY 254
/* Keep this the last entry. */
-#define R_MIPS_NUM 128
+#define R_MIPS_NUM 255
/* Legal values for p_type field of Elf32_Phdr. */
@@ -1715,7 +2119,13 @@ typedef struct
PLT is writable. For a non-writable PLT, this is omitted or has a zero
value. */
#define DT_MIPS_RWPLT 0x70000034
-#define DT_MIPS_NUM 0x35
+/* An alternative description of the classic MIPS RLD_MAP that is usable
+ in a PIE as it stores a relative offset from the address of the tag
+ rather than an absolute address. */
+#define DT_MIPS_RLD_MAP_REL 0x70000035
+/* GNU-style hash table with xlat. */
+#define DT_MIPS_XHASH 0x70000036
+#define DT_MIPS_NUM 0x37
/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
@@ -1886,9 +2296,9 @@ enum
#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-/* Additional section indeces. */
+/* Additional section indices. */
-#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tentatively declared
symbols in ANSI C. */
#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
@@ -2207,6 +2617,8 @@ enum
#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
+#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */
+#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
@@ -2250,7 +2662,11 @@ enum
/* PowerPC specific values for the Dyn d_tag field. */
#define DT_PPC_GOT (DT_LOPROC + 0)
-#define DT_PPC_NUM 1
+#define DT_PPC_OPT (DT_LOPROC + 1)
+#define DT_PPC_NUM 2
+
+/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */
+#define PPC_OPT_TLS 1
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
@@ -2396,9 +2812,10 @@ enum
#define DT_PPC64_OPT (DT_LOPROC + 3)
#define DT_PPC64_NUM 4
-/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */
+/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry. */
#define PPC64_OPT_TLS 1
#define PPC64_OPT_MULTI_TOC 2
+#define PPC64_OPT_LOCALENTRY 4
/* PowerPC64 specific values for the Elf64_Sym st_other field. */
#define STO_PPC64_LOCAL_BIT 5
@@ -2610,6 +3027,18 @@ enum
#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
+/* MTE memory tag segment type. */
+#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 2)
+
+/* AArch64 specific values for the Dyn d_tag field. */
+#define DT_AARCH64_BTI_PLT (DT_LOPROC + 1)
+#define DT_AARCH64_PAC_PLT (DT_LOPROC + 3)
+#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5)
+#define DT_AARCH64_NUM 6
+
+/* AArch64 specific values for the st_other field. */
+#define STO_AARCH64_VARIANT_PCS 0x80
+
/* ARM relocs. */
#define R_ARM_NONE 0 /* No reloc */
@@ -2778,6 +3207,81 @@ enum
/* Keep this the last entry. */
#define R_ARM_NUM 256
+/* C-SKY */
+#define R_CKCORE_NONE 0 /* no reloc */
+#define R_CKCORE_ADDR32 1 /* direct 32 bit (S + A) */
+#define R_CKCORE_PCRELIMM8BY4 2 /* disp ((S + A - P) >> 2) & 0xff */
+#define R_CKCORE_PCRELIMM11BY2 3 /* disp ((S + A - P) >> 1) & 0x7ff */
+#define R_CKCORE_PCREL32 5 /* 32-bit rel (S + A - P) */
+#define R_CKCORE_PCRELJSR_IMM11BY2 6 /* disp ((S + A - P) >>1) & 0x7ff */
+#define R_CKCORE_RELATIVE 9 /* 32 bit adjust program base(B + A)*/
+#define R_CKCORE_COPY 10 /* 32 bit adjust by program base */
+#define R_CKCORE_GLOB_DAT 11 /* off between got and sym (S) */
+#define R_CKCORE_JUMP_SLOT 12 /* PLT entry (S) */
+#define R_CKCORE_GOTOFF 13 /* offset to GOT (S + A - GOT) */
+#define R_CKCORE_GOTPC 14 /* PC offset to GOT (GOT + A - P) */
+#define R_CKCORE_GOT32 15 /* 32 bit GOT entry (G) */
+#define R_CKCORE_PLT32 16 /* 32 bit PLT entry (G) */
+#define R_CKCORE_ADDRGOT 17 /* GOT entry in GLOB_DAT (GOT + G) */
+#define R_CKCORE_ADDRPLT 18 /* PLT entry in GLOB_DAT (GOT + G) */
+#define R_CKCORE_PCREL_IMM26BY2 19 /* ((S + A - P) >> 1) & 0x3ffffff */
+#define R_CKCORE_PCREL_IMM16BY2 20 /* disp ((S + A - P) >> 1) & 0xffff */
+#define R_CKCORE_PCREL_IMM16BY4 21 /* disp ((S + A - P) >> 2) & 0xffff */
+#define R_CKCORE_PCREL_IMM10BY2 22 /* disp ((S + A - P) >> 1) & 0x3ff */
+#define R_CKCORE_PCREL_IMM10BY4 23 /* disp ((S + A - P) >> 2) & 0x3ff */
+#define R_CKCORE_ADDR_HI16 24 /* high & low 16 bit ADDR */
+ /* ((S + A) >> 16) & 0xffff */
+#define R_CKCORE_ADDR_LO16 25 /* (S + A) & 0xffff */
+#define R_CKCORE_GOTPC_HI16 26 /* high & low 16 bit GOTPC */
+ /* ((GOT + A - P) >> 16) & 0xffff */
+#define R_CKCORE_GOTPC_LO16 27 /* (GOT + A - P) & 0xffff */
+#define R_CKCORE_GOTOFF_HI16 28 /* high & low 16 bit GOTOFF */
+ /* ((S + A - GOT) >> 16) & 0xffff */
+#define R_CKCORE_GOTOFF_LO16 29 /* (S + A - GOT) & 0xffff */
+#define R_CKCORE_GOT12 30 /* 12 bit disp GOT entry (G) */
+#define R_CKCORE_GOT_HI16 31 /* high & low 16 bit GOT */
+ /* (G >> 16) & 0xffff */
+#define R_CKCORE_GOT_LO16 32 /* (G & 0xffff) */
+#define R_CKCORE_PLT12 33 /* 12 bit disp PLT entry (G) */
+#define R_CKCORE_PLT_HI16 34 /* high & low 16 bit PLT */
+ /* (G >> 16) & 0xffff */
+#define R_CKCORE_PLT_LO16 35 /* G & 0xffff */
+#define R_CKCORE_ADDRGOT_HI16 36 /* high & low 16 bit ADDRGOT */
+ /* (GOT + G * 4) & 0xffff */
+#define R_CKCORE_ADDRGOT_LO16 37 /* (GOT + G * 4) & 0xffff */
+#define R_CKCORE_ADDRPLT_HI16 38 /* high & low 16 bit ADDRPLT */
+ /* ((GOT + G * 4) >> 16) & 0xFFFF */
+#define R_CKCORE_ADDRPLT_LO16 39 /* (GOT+G*4) & 0xffff */
+#define R_CKCORE_PCREL_JSR_IMM26BY2 40 /* disp ((S+A-P) >>1) & x3ffffff */
+#define R_CKCORE_TOFFSET_LO16 41 /* (S+A-BTEXT) & 0xffff */
+#define R_CKCORE_DOFFSET_LO16 42 /* (S+A-BTEXT) & 0xffff */
+#define R_CKCORE_PCREL_IMM18BY2 43 /* disp ((S+A-P) >>1) & 0x3ffff */
+#define R_CKCORE_DOFFSET_IMM18 44 /* disp (S+A-BDATA) & 0x3ffff */
+#define R_CKCORE_DOFFSET_IMM18BY2 45 /* disp ((S+A-BDATA)>>1) & 0x3ffff */
+#define R_CKCORE_DOFFSET_IMM18BY4 46 /* disp ((S+A-BDATA)>>2) & 0x3ffff */
+#define R_CKCORE_GOT_IMM18BY4 48 /* disp (G >> 2) */
+#define R_CKCORE_PLT_IMM18BY4 49 /* disp (G >> 2) */
+#define R_CKCORE_PCREL_IMM7BY4 50 /* disp ((S+A-P) >>2) & 0x7f */
+#define R_CKCORE_TLS_LE32 51 /* 32 bit offset to TLS block */
+#define R_CKCORE_TLS_IE32 52
+#define R_CKCORE_TLS_GD32 53
+#define R_CKCORE_TLS_LDM32 54
+#define R_CKCORE_TLS_LDO32 55
+#define R_CKCORE_TLS_DTPMOD32 56
+#define R_CKCORE_TLS_DTPOFF32 57
+#define R_CKCORE_TLS_TPOFF32 58
+
+/* C-SKY elf header definition. */
+#define EF_CSKY_ABIMASK 0XF0000000
+#define EF_CSKY_OTHER 0X0FFF0000
+#define EF_CSKY_PROCESSOR 0X0000FFFF
+
+#define EF_CSKY_ABIV1 0X10000000
+#define EF_CSKY_ABIV2 0X20000000
+
+/* C-SKY attributes section. */
+#define SHT_CSKY_ATTRIBUTES (SHT_LOPROC + 1)
+
/* IA-64 specific declarations. */
/* Processor specific flags for the Ehdr e_flags field. */
@@ -3122,8 +3626,18 @@ enum
#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
+ /* 39 Reserved was R_X86_64_PC32_BND */
+ /* 40 Reserved was R_X86_64_PLT32_BND */
+#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative
+ offset to GOT entry without REX
+ prefix, relaxable. */
+#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative
+ offset to GOT entry with REX prefix,
+ relaxable. */
+#define R_X86_64_NUM 43
-#define R_X86_64_NUM 39
+/* x86-64 sh_type values. */
+#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */
/* AM33 relocations. */
@@ -3534,4 +4048,408 @@ enum
#define R_TILEGX_NUM 130
+/* RISC-V ELF Flags */
+#define EF_RISCV_RVC 0x0001
+#define EF_RISCV_FLOAT_ABI 0x0006
+#define EF_RISCV_FLOAT_ABI_SOFT 0x0000
+#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002
+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004
+#define EF_RISCV_FLOAT_ABI_QUAD 0x0006
+#define EF_RISCV_RVE 0x0008
+#define EF_RISCV_TSO 0x0010
+
+/* RISC-V relocations. */
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+#define R_RISCV_RVC_LUI 46
+#define R_RISCV_GPREL_I 47
+#define R_RISCV_GPREL_S 48
+#define R_RISCV_TPREL_I 49
+#define R_RISCV_TPREL_S 50
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6 52
+#define R_RISCV_SET6 53
+#define R_RISCV_SET8 54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
+#define R_RISCV_32_PCREL 57
+#define R_RISCV_IRELATIVE 58
+#define R_RISCV_PLT32 59
+#define R_RISCV_SET_ULEB128 60
+#define R_RISCV_SUB_ULEB128 61
+
+#define R_RISCV_NUM 62
+
+/* RISC-V specific values for the st_other field. */
+#define STO_RISCV_VARIANT_CC 0x80 /* Function uses variant calling
+ convention */
+
+/* RISC-V specific values for the sh_type field. */
+#define SHT_RISCV_ATTRIBUTES (SHT_LOPROC + 3)
+
+/* RISC-V specific values for the p_type field. */
+#define PT_RISCV_ATTRIBUTES (PT_LOPROC + 3)
+
+/* RISC-V specific values for the d_tag field. */
+#define DT_RISCV_VARIANT_CC (DT_LOPROC + 1)
+
+/* BPF specific declarations. */
+
+#define R_BPF_NONE 0 /* No reloc */
+#define R_BPF_64_64 1
+#define R_BPF_64_32 10
+
+/* Imagination Meta specific relocations. */
+
+#define R_METAG_HIADDR16 0
+#define R_METAG_LOADDR16 1
+#define R_METAG_ADDR32 2 /* 32bit absolute address */
+#define R_METAG_NONE 3 /* No reloc */
+#define R_METAG_RELBRANCH 4
+#define R_METAG_GETSETOFF 5
+
+/* Backward compatibility */
+#define R_METAG_REG32OP1 6
+#define R_METAG_REG32OP2 7
+#define R_METAG_REG32OP3 8
+#define R_METAG_REG16OP1 9
+#define R_METAG_REG16OP2 10
+#define R_METAG_REG16OP3 11
+#define R_METAG_REG32OP4 12
+
+#define R_METAG_HIOG 13
+#define R_METAG_LOOG 14
+
+#define R_METAG_REL8 15
+#define R_METAG_REL16 16
+
+/* GNU */
+#define R_METAG_GNU_VTINHERIT 30
+#define R_METAG_GNU_VTENTRY 31
+
+/* PIC relocations */
+#define R_METAG_HI16_GOTOFF 32
+#define R_METAG_LO16_GOTOFF 33
+#define R_METAG_GETSET_GOTOFF 34
+#define R_METAG_GETSET_GOT 35
+#define R_METAG_HI16_GOTPC 36
+#define R_METAG_LO16_GOTPC 37
+#define R_METAG_HI16_PLT 38
+#define R_METAG_LO16_PLT 39
+#define R_METAG_RELBRANCH_PLT 40
+#define R_METAG_GOTOFF 41
+#define R_METAG_PLT 42
+#define R_METAG_COPY 43
+#define R_METAG_JMP_SLOT 44
+#define R_METAG_RELATIVE 45
+#define R_METAG_GLOB_DAT 46
+
+/* TLS relocations */
+#define R_METAG_TLS_GD 47
+#define R_METAG_TLS_LDM 48
+#define R_METAG_TLS_LDO_HI16 49
+#define R_METAG_TLS_LDO_LO16 50
+#define R_METAG_TLS_LDO 51
+#define R_METAG_TLS_IE 52
+#define R_METAG_TLS_IENONPIC 53
+#define R_METAG_TLS_IENONPIC_HI16 54
+#define R_METAG_TLS_IENONPIC_LO16 55
+#define R_METAG_TLS_TPOFF 56
+#define R_METAG_TLS_DTPMOD 57
+#define R_METAG_TLS_DTPOFF 58
+#define R_METAG_TLS_LE 59
+#define R_METAG_TLS_LE_HI16 60
+#define R_METAG_TLS_LE_LO16 61
+
+/* NDS32 relocations. */
+#define R_NDS32_NONE 0
+#define R_NDS32_32_RELA 20
+#define R_NDS32_COPY 39
+#define R_NDS32_GLOB_DAT 40
+#define R_NDS32_JMP_SLOT 41
+#define R_NDS32_RELATIVE 42
+#define R_NDS32_TLS_TPOFF 102
+#define R_NDS32_TLS_DESC 119
+
+/* LoongArch ELF Flags */
+#define EF_LARCH_ABI_MODIFIER_MASK 0x07
+#define EF_LARCH_ABI_SOFT_FLOAT 0x01
+#define EF_LARCH_ABI_SINGLE_FLOAT 0x02
+#define EF_LARCH_ABI_DOUBLE_FLOAT 0x03
+#define EF_LARCH_OBJABI_V1 0x40
+
+/* LoongArch specific dynamic relocations */
+#define R_LARCH_NONE 0
+#define R_LARCH_32 1
+#define R_LARCH_64 2
+#define R_LARCH_RELATIVE 3
+#define R_LARCH_COPY 4
+#define R_LARCH_JUMP_SLOT 5
+#define R_LARCH_TLS_DTPMOD32 6
+#define R_LARCH_TLS_DTPMOD64 7
+#define R_LARCH_TLS_DTPREL32 8
+#define R_LARCH_TLS_DTPREL64 9
+#define R_LARCH_TLS_TPREL32 10
+#define R_LARCH_TLS_TPREL64 11
+#define R_LARCH_IRELATIVE 12
+
+/* Reserved for future relocs that the dynamic linker must understand. */
+
+/* used by the static linker for relocating .text. */
+#define R_LARCH_MARK_LA 20
+#define R_LARCH_MARK_PCREL 21
+#define R_LARCH_SOP_PUSH_PCREL 22
+#define R_LARCH_SOP_PUSH_ABSOLUTE 23
+#define R_LARCH_SOP_PUSH_DUP 24
+#define R_LARCH_SOP_PUSH_GPREL 25
+#define R_LARCH_SOP_PUSH_TLS_TPREL 26
+#define R_LARCH_SOP_PUSH_TLS_GOT 27
+#define R_LARCH_SOP_PUSH_TLS_GD 28
+#define R_LARCH_SOP_PUSH_PLT_PCREL 29
+#define R_LARCH_SOP_ASSERT 30
+#define R_LARCH_SOP_NOT 31
+#define R_LARCH_SOP_SUB 32
+#define R_LARCH_SOP_SL 33
+#define R_LARCH_SOP_SR 34
+#define R_LARCH_SOP_ADD 35
+#define R_LARCH_SOP_AND 36
+#define R_LARCH_SOP_IF_ELSE 37
+#define R_LARCH_SOP_POP_32_S_10_5 38
+#define R_LARCH_SOP_POP_32_U_10_12 39
+#define R_LARCH_SOP_POP_32_S_10_12 40
+#define R_LARCH_SOP_POP_32_S_10_16 41
+#define R_LARCH_SOP_POP_32_S_10_16_S2 42
+#define R_LARCH_SOP_POP_32_S_5_20 43
+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44
+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45
+#define R_LARCH_SOP_POP_32_U 46
+
+/* used by the static linker for relocating non .text. */
+#define R_LARCH_ADD8 47
+#define R_LARCH_ADD16 48
+#define R_LARCH_ADD24 49
+#define R_LARCH_ADD32 50
+#define R_LARCH_ADD64 51
+#define R_LARCH_SUB8 52
+#define R_LARCH_SUB16 53
+#define R_LARCH_SUB24 54
+#define R_LARCH_SUB32 55
+#define R_LARCH_SUB64 56
+#define R_LARCH_GNU_VTINHERIT 57
+#define R_LARCH_GNU_VTENTRY 58
+
+/* reserved 59-63 */
+
+#define R_LARCH_B16 64
+#define R_LARCH_B21 65
+#define R_LARCH_B26 66
+#define R_LARCH_ABS_HI20 67
+#define R_LARCH_ABS_LO12 68
+#define R_LARCH_ABS64_LO20 69
+#define R_LARCH_ABS64_HI12 70
+#define R_LARCH_PCALA_HI20 71
+#define R_LARCH_PCALA_LO12 72
+#define R_LARCH_PCALA64_LO20 73
+#define R_LARCH_PCALA64_HI12 74
+#define R_LARCH_GOT_PC_HI20 75
+#define R_LARCH_GOT_PC_LO12 76
+#define R_LARCH_GOT64_PC_LO20 77
+#define R_LARCH_GOT64_PC_HI12 78
+#define R_LARCH_GOT_HI20 79
+#define R_LARCH_GOT_LO12 80
+#define R_LARCH_GOT64_LO20 81
+#define R_LARCH_GOT64_HI12 82
+#define R_LARCH_TLS_LE_HI20 83
+#define R_LARCH_TLS_LE_LO12 84
+#define R_LARCH_TLS_LE64_LO20 85
+#define R_LARCH_TLS_LE64_HI12 86
+#define R_LARCH_TLS_IE_PC_HI20 87
+#define R_LARCH_TLS_IE_PC_LO12 88
+#define R_LARCH_TLS_IE64_PC_LO20 89
+#define R_LARCH_TLS_IE64_PC_HI12 90
+#define R_LARCH_TLS_IE_HI20 91
+#define R_LARCH_TLS_IE_LO12 92
+#define R_LARCH_TLS_IE64_LO20 93
+#define R_LARCH_TLS_IE64_HI12 94
+#define R_LARCH_TLS_LD_PC_HI20 95
+#define R_LARCH_TLS_LD_HI20 96
+#define R_LARCH_TLS_GD_PC_HI20 97
+#define R_LARCH_TLS_GD_HI20 98
+#define R_LARCH_32_PCREL 99
+#define R_LARCH_RELAX 100
+#define R_LARCH_DELETE 101
+#define R_LARCH_ALIGN 102
+#define R_LARCH_PCREL20_S2 103
+#define R_LARCH_CFA 104
+#define R_LARCH_ADD6 105
+#define R_LARCH_SUB6 106
+#define R_LARCH_ADD_ULEB128 107
+#define R_LARCH_SUB_ULEB128 108
+#define R_LARCH_64_PCREL 109
+
+/* ARC specific declarations. */
+
+/* Processor specific flags for the Ehdr e_flags field. */
+#define EF_ARC_MACH_MSK 0x000000ff
+#define EF_ARC_OSABI_MSK 0x00000f00
+#define EF_ARC_ALL_MSK (EF_ARC_MACH_MSK | EF_ARC_OSABI_MSK)
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_ARC_ATTRIBUTES (SHT_LOPROC + 1) /* ARC attributes section. */
+
+/* ARCompact/ARCv2 specific relocs. */
+#define R_ARC_NONE 0x0
+#define R_ARC_8 0x1
+#define R_ARC_16 0x2
+#define R_ARC_24 0x3
+#define R_ARC_32 0x4
+
+#define R_ARC_B22_PCREL 0x6
+#define R_ARC_H30 0x7
+#define R_ARC_N8 0x8
+#define R_ARC_N16 0x9
+#define R_ARC_N24 0xA
+#define R_ARC_N32 0xB
+#define R_ARC_SDA 0xC
+#define R_ARC_SECTOFF 0xD
+#define R_ARC_S21H_PCREL 0xE
+#define R_ARC_S21W_PCREL 0xF
+#define R_ARC_S25H_PCREL 0x10
+#define R_ARC_S25W_PCREL 0x11
+#define R_ARC_SDA32 0x12
+#define R_ARC_SDA_LDST 0x13
+#define R_ARC_SDA_LDST1 0x14
+#define R_ARC_SDA_LDST2 0x15
+#define R_ARC_SDA16_LD 0x16
+#define R_ARC_SDA16_LD1 0x17
+#define R_ARC_SDA16_LD2 0x18
+#define R_ARC_S13_PCREL 0x19
+#define R_ARC_W 0x1A
+#define R_ARC_32_ME 0x1B
+#define R_ARC_N32_ME 0x1C
+#define R_ARC_SECTOFF_ME 0x1D
+#define R_ARC_SDA32_ME 0x1E
+#define R_ARC_W_ME 0x1F
+#define R_ARC_H30_ME 0x20
+#define R_ARC_SECTOFF_U8 0x21
+#define R_ARC_SECTOFF_S9 0x22
+#define R_AC_SECTOFF_U8 0x23
+#define R_AC_SECTOFF_U8_1 0x24
+#define R_AC_SECTOFF_U8_2 0x25
+#define R_AC_SECTOFF_S9 0x26
+#define R_AC_SECTOFF_S9_1 0x27
+#define R_AC_SECTOFF_S9_2 0x28
+#define R_ARC_SECTOFF_ME_1 0x29
+#define R_ARC_SECTOFF_ME_2 0x2A
+#define R_ARC_SECTOFF_1 0x2B
+#define R_ARC_SECTOFF_2 0x2C
+#define R_ARC_SDA_12 0x2D
+#define R_ARC_SDA16_ST2 0x30
+#define R_ARC_32_PCREL 0x31
+#define R_ARC_PC32 0x32
+#define R_ARC_GOTPC32 0x33
+#define R_ARC_PLT32 0x34
+#define R_ARC_COPY 0x35
+#define R_ARC_GLOB_DAT 0x36
+#define R_ARC_JMP_SLOT 0x37
+#define R_ARC_RELATIVE 0x38
+#define R_ARC_GOTOFF 0x39
+#define R_ARC_GOTPC 0x3A
+#define R_ARC_GOT32 0x3B
+#define R_ARC_S21W_PCREL_PLT 0x3C
+#define R_ARC_S25H_PCREL_PLT 0x3D
+
+#define R_ARC_JLI_SECTOFF 0x3F
+
+#define R_ARC_TLS_DTPMOD 0x42
+#define R_ARC_TLS_DTPOFF 0x43
+#define R_ARC_TLS_TPOFF 0x44
+#define R_ARC_TLS_GD_GOT 0x45
+#define R_ARC_TLS_GD_LD 0x46
+#define R_ARC_TLS_GD_CALL 0x47
+#define R_ARC_TLS_IE_GOT 0x48
+#define R_ARC_TLS_DTPOFF_S9 0x49
+#define R_ARC_TLS_LE_S9 0x4A
+#define R_ARC_TLS_LE_32 0x4B
+#define R_ARC_S25W_PCREL_PLT 0x4C
+#define R_ARC_S21H_PCREL_PLT 0x4D
+#define R_ARC_NPS_CMEM16 0x4E
+
+/* OpenRISC 1000 specific relocs. */
+#define R_OR1K_NONE 0
+#define R_OR1K_32 1
+#define R_OR1K_16 2
+#define R_OR1K_8 3
+#define R_OR1K_LO_16_IN_INSN 4
+#define R_OR1K_HI_16_IN_INSN 5
+#define R_OR1K_INSN_REL_26 6
+#define R_OR1K_GNU_VTENTRY 7
+#define R_OR1K_GNU_VTINHERIT 8
+#define R_OR1K_32_PCREL 9
+#define R_OR1K_16_PCREL 10
+#define R_OR1K_8_PCREL 11
+#define R_OR1K_GOTPC_HI16 12
+#define R_OR1K_GOTPC_LO16 13
+#define R_OR1K_GOT16 14
+#define R_OR1K_PLT26 15
+#define R_OR1K_GOTOFF_HI16 16
+#define R_OR1K_GOTOFF_LO16 17
+#define R_OR1K_COPY 18
+#define R_OR1K_GLOB_DAT 19
+#define R_OR1K_JMP_SLOT 20
+#define R_OR1K_RELATIVE 21
+#define R_OR1K_TLS_GD_HI16 22
+#define R_OR1K_TLS_GD_LO16 23
+#define R_OR1K_TLS_LDM_HI16 24
+#define R_OR1K_TLS_LDM_LO16 25
+#define R_OR1K_TLS_LDO_HI16 26
+#define R_OR1K_TLS_LDO_LO16 27
+#define R_OR1K_TLS_IE_HI16 28
+#define R_OR1K_TLS_IE_LO16 29
+#define R_OR1K_TLS_LE_HI16 30
+#define R_OR1K_TLS_LE_LO16 31
+#define R_OR1K_TLS_TPOFF 32
+#define R_OR1K_TLS_DTPOFF 33
+#define R_OR1K_TLS_DTPMOD 34
+
#endif /* elf.h */
diff --git a/lddtree.py b/lddtree.py
index 66f5e01..3a41886 100755
--- a/lddtree.py
+++ b/lddtree.py
@@ -1,15 +1,14 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright 2012-2014 Gentoo Foundation
-# Copyright 2012-2014 Mike Frysinger <vapier@gentoo.org>
-# Copyright 2012-2014 The Chromium OS Authors
+#!/usr/bin/env python
+# PYTHON_ARGCOMPLETE_OK
+# Copyright 2012-2024 Gentoo Foundation
+# Copyright 2012-2024 Mike Frysinger <vapier@gentoo.org>
+# Copyright 2012-2024 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license (BSD-3)
-# pylint: disable=C0301
"""Read the ELF dependency tree and show it
This does not work like `ldd` in that we do not execute/load code (only read
-files on disk), and we should the ELFs as a tree rather than a flat list.
+files on disk), and we show the ELFs as a tree rather than a flat list.
Paths may be globs that lddtree will take care of expanding.
Useful when you want to glob a path under the ROOT path.
@@ -41,764 +40,996 @@ This will place bash, lspci, and lsof into /foo/bin/. All the libraries
they need will be placed into /foo/lib/ only.
"""
-from __future__ import print_function
-
import argparse
-import glob
import errno
+import functools
+import glob
+import mmap
import os
+import re
import shutil
import sys
+from typing import Any, cast, Dict, Iterable, List, Optional, Tuple, Union
+
+
+assert sys.version_info >= (3, 8), f"Python 3.8+ required, but found {sys.version}"
+
+# Disable import errors for all 3rd party modules.
+# pylint: disable=import-error
+try:
+ import argcomplete # type: ignore
+except ImportError:
+ argcomplete = cast(Any, None)
+
+from elftools.common import exceptions # type: ignore
+from elftools.elf.elffile import ELFFile # type: ignore
+
-from elftools.elf.elffile import ELFFile
-from elftools.common import exceptions
+# pylint: enable=import-error
-def warn(msg, prefix='warning'):
- """Write |msg| to stderr with a |prefix| before it"""
- print('%s: %s: %s' % (os.path.basename(sys.argv[0]), prefix, msg), file=sys.stderr)
+def warn(msg: Any, prefix: Optional[str] = "warning") -> None:
+ """Write |msg| to stderr with a |prefix| before it"""
+ print(f"{os.path.basename(sys.argv[0])}: {prefix}: {msg}", file=sys.stderr)
-def err(msg, status=1):
- """Write |msg| to stderr and exit with |status|"""
- warn(msg, prefix='error')
- sys.exit(status)
+def err(msg: Any, status: Optional[int] = 1) -> None:
+ """Write |msg| to stderr and exit with |status|"""
+ warn(msg, prefix="error")
+ sys.exit(status)
-def dbg(debug, *args, **kwargs):
- """Pass |args| and |kwargs| to print() when |debug| is True"""
- if debug:
- print(*args, **kwargs)
+def dbg(debug: bool, *args, **kwargs) -> None:
+ """Pass |args| and |kwargs| to print() when |debug| is True"""
+ if debug:
+ print(*args, **kwargs)
-def bstr(buf):
- """Decode the byte string into a string"""
- if isinstance(buf, str):
- return buf
- return buf.decode('utf-8')
+def bstr(buf: Union[bytes, str]) -> str:
+ """Decode the byte string into a string"""
+ if isinstance(buf, str):
+ return buf
+ return buf.decode("utf-8")
-def normpath(path):
- """Normalize a path
+def normpath(path: str) -> str:
+ """Normalize a path
- Python's os.path.normpath() doesn't handle some cases:
- // -> //
- //..// -> //
- //..//..// -> ///
- """
- return os.path.normpath(path).replace('//', '/')
+ Python's os.path.normpath() doesn't handle some cases:
+ // -> //
+ //..// -> //
+ //..//..// -> ///
+ """
+ return os.path.normpath(path).replace("//", "/")
-def readlink(path, root, prefixed=False):
- """Like os.readlink(), but relative to a |root|
+@functools.lru_cache(maxsize=None)
+def readlink(path: str, root: str, prefixed: Optional[bool] = False) -> str:
+ """Like os.readlink(), but relative to a |root|
- This does not currently handle the pathological case:
- /lib/foo.so -> ../../../../../../../foo.so
- This relies on the .. entries in / to point to itself.
+ This does not currently handle the pathological case:
+ /lib/foo.so -> ../../../../../../../foo.so
+ This relies on the .. entries in / to point to itself.
- Args:
- path: The symlink to read
- root: The path to use for resolving absolute symlinks
- prefixed: When False, the |path| must not have |root| prefixed to it, nor
- will the return value have |root| prefixed. When True, |path|
- must have |root| prefixed, and the return value will have |root|
- added.
+ Args:
+ path: The symlink to read
+ root: The path to use for resolving absolute symlinks
+ prefixed: When False, the |path| must not have |root| prefixed to it, nor
+ will the return value have |root| prefixed. When True, |path|
+ must have |root| prefixed, and the return value will have |root|
+ added.
- Returns:
- A fully resolved symlink path
- """
- root = root.rstrip('/')
- if prefixed:
- path = path[len(root):]
+ Returns:
+ A fully resolved symlink path
+ """
+ root = root.rstrip("/")
+ if prefixed:
+ path = path[len(root) :]
- while os.path.islink(root + path):
- path = os.path.join(os.path.dirname(path), os.readlink(root + path))
+ while os.path.islink(root + path):
+ path = os.path.join(os.path.dirname(path), os.readlink(root + path))
- return normpath((root + path) if prefixed else path)
+ return normpath((root + path) if prefixed else path)
-def makedirs(path):
- """Like os.makedirs(), but ignore EEXIST errors"""
- try:
- os.makedirs(path)
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
+def dedupe(items: List[str]) -> List[str]:
+ """Remove all duplicates from |items| (keeping order)"""
+ seen: Dict[str, str] = {}
+ return [seen.setdefault(x, x) for x in items if x not in seen]
-def dedupe(items):
- """Remove all duplicates from |items| (keeping order)"""
- seen = {}
- return [seen.setdefault(x, x) for x in items if x not in seen]
+@functools.lru_cache(maxsize=None)
+def interp_supports_argv0(interp: str) -> bool:
+ """See whether |interp| supports the --argv0 option.
+ Starting with glibc-2.33, the ldso supports --argv0 to override argv[0].
+ """
+ with open(interp, "rb") as fp:
+ with mmap.mmap(fp.fileno(), 0, prot=mmap.PROT_READ) as mm:
+ return mm.find(b"--argv0") >= 0
-def GenerateLdsoWrapper(root, path, interp, libpaths=()):
- """Generate a shell script wrapper which uses local ldso to run the ELF
- Since we cannot rely on the host glibc (or other libraries), we need to
- execute the local packaged ldso directly and tell it where to find our
- copies of libraries.
+def GenerateLdsoWrapper(
+ root: str,
+ path: str,
+ interp: str,
+ libpaths: Iterable[str] = (),
+ preload: Optional[str] = None,
+) -> None:
+ """Generate a shell script wrapper which uses local ldso to run the ELF
+
+ Since we cannot rely on the host glibc (or other libraries), we need to
+ execute the local packaged ldso directly and tell it where to find our
+ copies of libraries.
+
+ Args:
+ root: The root tree to generate scripts inside of
+ path: The full path (inside |root|) to the program to wrap
+ interp: The ldso interpreter that we need to execute
+ libpaths: Extra lib paths to search for libraries
+ """
+ basedir = os.path.dirname(path)
+ interp_dir, interp_name = os.path.split(interp)
+ # Add ldso interpreter dir to end of libpaths as a fallback library path.
+ libpaths = dedupe(list(libpaths) + [interp_dir])
+ if preload:
+ # If preload is an absolute path, calculate it from basedir.
+ preload_prefix = f'${{basedir}}/{os.path.relpath("/", basedir)}'
+ preload = ":".join(
+ f"{preload_prefix}{x}" if os.path.isabs(x) else x
+ for x in re.split(r"[ :]", preload)
+ )
+
+ replacements = {
+ "interp": os.path.join(os.path.relpath(interp_dir, basedir), interp_name),
+ "interp_rel": os.path.relpath(path, interp_dir),
+ "libpaths": ":".join(
+ "${basedir}/" + os.path.relpath(p, basedir) for p in libpaths
+ ),
+ "argv0_arg": '--argv0 "$0"' if interp_supports_argv0(root + interp) else "",
+ "preload_arg": f'--preload "{preload}"' if preload else "",
+ }
- Args:
- root: The root tree to generate scripts inside of
- path: The full path (inside |root|) to the program to wrap
- interp: The ldso interpreter that we need to execute
- libpaths: Extra lib paths to search for libraries
- """
- basedir = os.path.dirname(path)
- interp_dir, interp_name = os.path.split(interp)
- libpaths = dedupe([interp_dir] + list(libpaths))
- replacements = {
- 'interp': os.path.join(os.path.relpath(interp_dir, basedir),
- interp_name),
- 'libpaths': ':'.join(['${basedir}/' + os.path.relpath(p, basedir)
- for p in libpaths]),
- }
- wrapper = """#!/bin/sh
-if ! base=$(realpath "$0" 2>/dev/null); then
+ # Keep path relativeness of argv0 (in ${base}.elf). This allows tools to
+ # remove absolute paths from build outputs and enables directory independent
+ # cache sharing in distributed build systems.
+ #
+ # NB: LD_ARGV0_REL below is unrelated & non-standard. It's to let tools see
+ # the original path if they need it and when they know they'll be wrapped up
+ # by this script.
+ wrapper = """#!/bin/sh
+if base=$(readlink "$0" 2>/dev/null); then
+ # If $0 is an abspath symlink, fully resolve the target.
+ case ${base} in
+ /*) base=$(readlink -f "$0" 2>/dev/null);;
+ *) base=$(dirname "$0")/${base};;
+ esac
+else
case $0 in
/*) base=$0;;
*) base=${PWD:-`pwd`}/$0;;
esac
fi
basedir=${base%%/*}
-exec \
- "${basedir}/%(interp)s" \
- --library-path "%(libpaths)s" \
- --inhibit-cache \
- --inhibit-rpath '' \
- "${base}.elf" \
+LD_ARGV0_REL="%(interp_rel)s" \\
+exec \\
+ "${basedir}/%(interp)s" \\
+ %(argv0_arg)s \\
+ %(preload_arg)s \\
+ --library-path "%(libpaths)s" \\
+ --inhibit-cache \\
+ --inhibit-rpath '' \\
+ "${base}.elf" \\
"$@"
"""
- wrappath = root + path
- os.rename(wrappath, wrappath + '.elf')
- with open(wrappath, 'w') as f:
- f.write(wrapper % replacements)
- os.chmod(wrappath, 0o0755)
-
-
-def ParseLdPaths(str_ldpaths, root='', path=None):
- """Parse the colon-delimited list of paths and apply ldso rules to each
-
- Note the special handling as dictated by the ldso:
- - Empty paths are equivalent to $PWD
- - $ORIGIN is expanded to the path of the given file
- - (TODO) $LIB and friends
-
- Args:
- str_ldpaths: A colon-delimited string of paths
- root: The path to prepend to all paths found
- path: The object actively being parsed (used for $ORIGIN)
-
- Returns:
- list of processed paths
- """
- ldpaths = []
- for ldpath in str_ldpaths.split(':'):
- if ldpath == '':
- # The ldso treats "" paths as $PWD.
- ldpath = os.getcwd()
- elif '$ORIGIN' in ldpath:
- ldpath = ldpath.replace('$ORIGIN', os.path.dirname(path))
- else:
- ldpath = root + ldpath
- ldpaths.append(normpath(ldpath))
- return dedupe(ldpaths)
-
-
-def ParseLdSoConf(ldso_conf, root='/', debug=False, _first=True):
- """Load all the paths from a given ldso config file
-
- This should handle comments, whitespace, and "include" statements.
-
- Args:
- ldso_conf: The file to scan
- root: The path to prepend to all paths found
- debug: Enable debug output
- _first: Recursive use only; is this the first ELF ?
-
- Returns:
- list of paths found
- """
- paths = []
-
- dbg_pfx = '' if _first else ' '
- try:
- dbg(debug, '%sParseLdSoConf(%s)' % (dbg_pfx, ldso_conf))
- with open(ldso_conf) as f:
- for line in f.readlines():
- line = line.split('#', 1)[0].strip()
- if not line:
- continue
- if line.startswith('include '):
- line = line[8:]
- if line[0] == '/':
- line = root + line.lstrip('/')
- else:
- line = os.path.dirname(ldso_conf) + '/' + line
- dbg(debug, '%s glob: %s' % (dbg_pfx, line))
- # ldconfig in glibc uses glob() which returns entries sorted according
- # to LC_COLLATE. Further, ldconfig does not reset that but respects
- # the active env settings (which might be a mistake). Python does not
- # sort its results by default though, so do it ourselves.
- for path in sorted(glob.glob(line)):
- paths += ParseLdSoConf(path, root=root, debug=debug, _first=False)
+ wrappath = root + path
+ os.rename(wrappath, wrappath + ".elf")
+ with open(wrappath, "w", encoding="utf-8") as f:
+ f.write(wrapper % replacements)
+ os.chmod(wrappath, 0o0755)
+
+
+@functools.lru_cache(maxsize=None)
+def ParseLdPaths(
+ str_ldpaths: str,
+ root: str = "",
+ cwd: Optional[str] = None,
+ path: str = "",
+) -> List[str]:
+ """Parse the colon-delimited list of paths and apply ldso rules to each
+
+ Note the special handling as dictated by the ldso:
+ - Empty paths are equivalent to $PWD
+ - $ORIGIN is expanded to the path of the given file
+ - (TODO) $LIB and friends
+
+ Args:
+ str_ldpaths: A colon-delimited string of paths
+ root: The path to prepend to all paths found
+ cwd: The path to resolve relative paths against (defaults to getcwd()).
+ path: The object actively being parsed (used for $ORIGIN)
+
+ Returns:
+ list of processed paths
+ """
+ if cwd is None:
+ cwd = os.getcwd()
+
+ ldpaths = []
+ for ldpath in str_ldpaths.split(":"):
+ # Expand placeholders first.
+ if "$ORIGIN" in ldpath:
+ ldpath = ldpath.replace("$ORIGIN", os.path.dirname(path))
+ elif "${ORIGIN}" in ldpath:
+ ldpath = ldpath.replace("${ORIGIN}", os.path.dirname(path))
+
+ # Expand relative paths if needed. These don't make sense in general,
+ # but that doesn't stop people from using them. As such, root prefix
+ # doesn't make sense with it either.
+ if not ldpath.startswith("/"):
+ # NB: The ldso treats "" paths as cwd too.
+ ldpath = os.path.join(cwd, ldpath)
else:
- paths += [normpath(root + line)]
- except IOError as e:
- if e.errno != errno.ENOENT:
- warn(e)
-
- if _first:
- # XXX: Load paths from ldso itself.
- # Remove duplicate entries to speed things up.
- paths = dedupe(paths)
-
- return paths
-
-
-def LoadLdpaths(root='/', prefix='', debug=False):
- """Load linker paths from common locations
-
- This parses the ld.so.conf and LD_LIBRARY_PATH env var.
-
- Args:
- root: The root tree to prepend to paths
- prefix: The path under |root| to search
- debug: Enable debug output
-
- Returns:
- dict containing library paths to search
- """
- ldpaths = {
- 'conf': [],
- 'env': [],
- 'interp': [],
- }
-
- # Load up $LD_LIBRARY_PATH.
- ldpaths['env'] = []
- env_ldpath = os.environ.get('LD_LIBRARY_PATH')
- if not env_ldpath is None:
- if root != '/':
- warn('ignoring LD_LIBRARY_PATH due to ROOT usage')
- else:
- # XXX: If this contains $ORIGIN, we probably have to parse this
- # on a per-ELF basis so it can get turned into the right thing.
- ldpaths['env'] = ParseLdPaths(env_ldpath, path='')
-
- # Load up /etc/ld.so.conf.
- ldpaths['conf'] = ParseLdSoConf(root + prefix + '/etc/ld.so.conf', root=root,
- debug=debug)
-
- return ldpaths
-
-
-def CompatibleELFs(elf1, elf2):
- """See if two ELFs are compatible
-
- This compares the aspects of the ELF to see if they're compatible:
- bit size, endianness, machine type, and operating system.
-
- Args:
- elf1: an ELFFile object
- elf2: an ELFFile object
-
- Returns:
- True if compatible, False otherwise
- """
- osabis = frozenset([e.header['e_ident']['EI_OSABI'] for e in (elf1, elf2)])
- compat_sets = (
- frozenset('ELFOSABI_%s' % x for x in ('NONE', 'SYSV', 'GNU', 'LINUX',)),
- )
- return ((len(osabis) == 1 or any(osabis.issubset(x) for x in compat_sets)) and
- elf1.elfclass == elf2.elfclass and
- elf1.little_endian == elf2.little_endian and
- elf1.header['e_machine'] == elf2.header['e_machine'])
-
-
-def FindLib(elf, lib, ldpaths, root='/', debug=False):
- """Try to locate a |lib| that is compatible to |elf| in the given |ldpaths|
-
- Args:
- elf: The elf which the library should be compatible with (ELF wise)
- lib: The library (basename) to search for
- ldpaths: A list of paths to search
- root: The root path to resolve symlinks
- debug: Enable debug output
-
- Returns:
- Tuple of the full path to the desired library and the real path to it
- """
- dbg(debug, ' FindLib(%s)' % lib)
-
- for ldpath in ldpaths:
- path = os.path.join(ldpath, lib)
- target = readlink(path, root, prefixed=True)
- if path != target:
- dbg(debug, ' checking: %s -> %s' % (path, target))
- else:
- dbg(debug, ' checking:', path)
+ ldpath = root + ldpath
+
+ ldpaths.append(normpath(ldpath))
+
+ return dedupe(ldpaths)
- if os.path.exists(target):
- with open(target, 'rb') as f:
- try:
- libelf = ELFFile(f)
- if CompatibleELFs(elf, libelf):
- return (target, path)
- except exceptions.ELFError as e:
- warn('%s: %s' % (target, e))
- return (None, None)
+def ParseLdSoConf(
+ ldso_conf: str,
+ root: str = "/",
+ debug: bool = False,
+ _first: bool = True,
+) -> List[str]:
+ """Load all the paths from a given ldso config file
+
+ This should handle comments, whitespace, and "include" statements.
+
+ Args:
+ ldso_conf: The file to scan
+ root: The path to prepend to all paths found
+ debug: Enable debug output
+ _first: Recursive use only; is this the first ELF ?
+
+ Returns:
+ list of paths found
+ """
+ paths = []
+
+ dbg_pfx = "" if _first else " "
+ try:
+ dbg(debug, f"{dbg_pfx}ParseLdSoConf({ldso_conf})")
+ with open(ldso_conf, encoding="utf-8") as f:
+ for line in f.readlines():
+ line = line.split("#", 1)[0].strip()
+ if not line:
+ continue
+ if line.startswith("include "):
+ line = line[8:]
+ if line[0] == "/":
+ line = root + line.lstrip("/")
+ else:
+ line = os.path.dirname(ldso_conf) + "/" + line
+ dbg(debug, dbg_pfx, "glob:", line)
+ # ldconfig in glibc uses glob() which returns entries sorted according
+ # to LC_COLLATE. Further, ldconfig does not reset that but respects
+ # the active env settings (which might be a mistake). Python does not
+ # sort its results by default though, so do it ourselves.
+ for path in sorted(glob.glob(line)):
+ paths += ParseLdSoConf(
+ path, root=root, debug=debug, _first=False
+ )
+ else:
+ paths += [normpath(root + line)]
+ except IOError as e:
+ if e.errno != errno.ENOENT:
+ warn(e)
+
+ if _first:
+ # XXX: Load paths from ldso itself.
+ # Remove duplicate entries to speed things up.
+ paths = dedupe(paths)
+
+ return paths
+
+
+def LoadLdpaths(
+ root: str = "/",
+ cwd: Optional[str] = None,
+ prefix: str = "",
+ debug: bool = False,
+) -> Dict[str, List[str]]:
+ """Load linker paths from common locations
+
+ This parses the ld.so.conf and LD_LIBRARY_PATH env var.
+
+ Args:
+ root: The root tree to prepend to paths
+ cwd: The path to resolve relative paths against
+ prefix: The path under |root| to search
+ debug: Enable debug output
+
+ Returns:
+ dict containing library paths to search
+ """
+ ldpaths: Dict[str, List[str]] = {
+ "conf": [],
+ "env": [],
+ "interp": [],
+ }
+
+ # Load up $LD_LIBRARY_PATH.
+ ldpaths["env"] = []
+ env_ldpath = os.environ.get("LD_LIBRARY_PATH")
+ if not env_ldpath is None:
+ if root != "/":
+ warn("ignoring LD_LIBRARY_PATH due to ROOT usage")
+ else:
+ # XXX: If this contains $ORIGIN, we probably have to parse this
+ # on a per-ELF basis so it can get turned into the right thing.
+ ldpaths["env"] = ParseLdPaths(env_ldpath, cwd=cwd, path="")
+
+ # Load up /etc/ld.so.conf.
+ ldpaths["conf"] = ParseLdSoConf(
+ root + prefix + "/etc/ld.so.conf", root=root, debug=debug
+ )
+
+ return ldpaths
+
+
+def CompatibleELFs(elf1: ELFFile, elf2: ELFFile) -> bool:
+ """See if two ELFs are compatible
+
+ This compares the aspects of the ELF to see if they're compatible:
+ bit size, endianness, machine type, and operating system.
+
+ Args:
+ elf1: an ELFFile object
+ elf2: an ELFFile object
+
+ Returns:
+ True if compatible, False otherwise
+ """
+ osabis = frozenset([e.header["e_ident"]["EI_OSABI"] for e in (elf1, elf2)])
+ compat_sets = (
+ frozenset(f"ELFOSABI_{x}" for x in ("NONE", "SYSV", "GNU", "LINUX")),
+ )
+ return (
+ (len(osabis) == 1 or any(osabis.issubset(x) for x in compat_sets))
+ and elf1.elfclass == elf2.elfclass
+ and elf1.little_endian == elf2.little_endian
+ and elf1.header["e_machine"] == elf2.header["e_machine"]
+ )
+
+
+def FindLib(
+ elf: ELFFile,
+ lib: str,
+ ldpaths: List[str],
+ root: str = "/",
+ debug: bool = False,
+) -> Tuple[Optional[str], Optional[str]]:
+ """Try to locate a |lib| that is compatible to |elf| in the given |ldpaths|
+
+ Args:
+ elf: The elf which the library should be compatible with (ELF wise)
+ lib: The library (basename) to search for
+ ldpaths: A list of paths to search
+ root: The root path to resolve symlinks
+ debug: Enable debug output
+
+ Returns:
+ Tuple of the full path to the desired library and the real path to it
+ """
+ dbg(debug, f" FindLib({lib})")
+
+ for ldpath in ldpaths:
+ path = os.path.join(ldpath, lib)
+ target = readlink(path, root, prefixed=True)
+ if path != target:
+ dbg(debug, " checking:", path, "->", target)
+ else:
+ dbg(debug, " checking:", path)
+
+ if os.path.exists(target):
+ with open(target, "rb") as f:
+ try:
+ libelf = ELFFile(f)
+ if CompatibleELFs(elf, libelf):
+ return (target, path)
+ except exceptions.ELFError as e:
+ warn(f"{target}: {e}")
+
+ return (None, None)
# We abuse the _all_libs state. We probably shouldn't, but we do currently.
# pylint: disable=dangerous-default-value
-def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[]},
- display=None, debug=False, _first=True, _all_libs={}):
- """Parse the ELF dependency tree of the specified file
-
- Args:
- path: The ELF to scan
- root: The root tree to prepend to paths; this applies to interp and rpaths
+def ParseELF(
+ path: str,
+ root: str = "/",
+ cwd: Optional[str] = None,
+ prefix: str = "",
+ ldpaths={"conf": [], "env": [], "interp": []},
+ display: Optional[str] = None,
+ debug: bool = False,
+ _first: bool = True,
+ _all_libs={},
+) -> Dict[str, Any]:
+ """Parse the ELF dependency tree of the specified file
+
+ Args:
+ path: The ELF to scan
+ root: The root tree to prepend to paths; this applies to interp and rpaths
only as |path| and |ldpaths| are expected to be prefixed already
- prefix: The path under |root| to search
- ldpaths: dict containing library paths to search; should have the keys:
- conf, env, interp
- display: The path to show rather than |path|
- debug: Enable debug output
- _first: Recursive use only; is this the first ELF ?
- _all_libs: Recursive use only; dict of all libs we've seen
-
- Returns:
- a dict containing information about all the ELFs; e.g.
- {
- 'interp': '/lib64/ld-linux.so.2',
- 'needed': ['libc.so.6', 'libcurl.so.4',],
- 'libs': {
- 'libc.so.6': {
- 'path': '/lib64/libc.so.6',
- 'needed': [],
- },
- 'libcurl.so.4': {
- 'path': '/usr/lib64/libcurl.so.4',
- 'needed': ['libc.so.6', 'librt.so.1',],
+ cwd: The path to resolve relative paths against.
+ prefix: The path under |root| to search
+ ldpaths: dict containing library paths to search; should have the keys:
+ conf, env, interp
+ display: The path to show rather than |path|
+ debug: Enable debug output
+ _first: Recursive use only; is this the first ELF ?
+ _all_libs: Recursive use only; dict of all libs we've seen
+
+ Returns:
+ a dict containing information about all the ELFs; e.g.
+ {
+ 'interp': '/lib64/ld-linux.so.2',
+ 'needed': ['libc.so.6', 'libcurl.so.4',],
+ 'libs': {
+ 'libc.so.6': {
+ 'path': '/lib64/libc.so.6',
+ 'needed': [],
+ },
+ 'libcurl.so.4': {
+ 'path': '/usr/lib64/libcurl.so.4',
+ 'needed': ['libc.so.6', 'librt.so.1',],
+ },
},
- },
- }
- """
- if _first:
- _all_libs = {}
- ldpaths = ldpaths.copy()
- ret = {
- 'interp': None,
- 'path': path if display is None else display,
- 'realpath': path,
- 'needed': [],
- 'rpath': [],
- 'runpath': [],
- 'libs': _all_libs,
- }
-
- dbg(debug, 'ParseELF(%s)' % path)
-
- with open(path, 'rb') as f:
- elf = ELFFile(f)
-
- # If this is the first ELF, extract the interpreter.
+ }
+ """
if _first:
- for segment in elf.iter_segments():
- if segment.header.p_type != 'PT_INTERP':
- continue
-
- interp = bstr(segment.get_interp_name())
- dbg(debug, ' interp =', interp)
- ret['interp'] = normpath(root + interp)
- real_interp = readlink(ret['interp'], root, prefixed=True)
- ret['libs'][os.path.basename(interp)] = {
- 'path': ret['interp'],
- 'realpath': real_interp,
- 'needed': [],
- }
- # XXX: Could read it and scan for /lib paths.
- # If the interp is a symlink, lets follow it on the assumption that it
- # is in this path purely for ABI reasons, and the distro is using a
- # different (probably more correct) path. This can come up in some
- # multilib situations like s390x where /lib64/ contains all the native
- # libraries, but /lib/ld64.so.1 is the interp hardcoded in gcc, so the
- # ld64.so.1 is really a symlink to ../lib64/ld64.so.1. In the multiarch
- # setup, it'll be /lib/ld64.so.1 -> /lib/s390x-linux-gnu/ld64.so.1.
- # That is why we use |real_interp| here instead of |interp|.
- ldpaths['interp'] = [
- os.path.dirname(real_interp),
- normpath(root + prefix + '/usr/' + os.path.dirname(
- real_interp)[len(root) + len(prefix):]),
- ]
- dbg(debug, ' ldpaths[interp] =', ldpaths['interp'])
- break
-
- # Parse the ELF's dynamic tags.
- libs = []
- rpaths = []
- runpaths = []
- for segment in elf.iter_segments():
- if segment.header.p_type != 'PT_DYNAMIC':
- continue
-
- for t in segment.iter_tags():
- if t.entry.d_tag == 'DT_RPATH':
- rpaths = ParseLdPaths(bstr(t.rpath), root=root, path=path)
- elif t.entry.d_tag == 'DT_RUNPATH':
- runpaths = ParseLdPaths(bstr(t.runpath), root=root, path=path)
- elif t.entry.d_tag == 'DT_NEEDED':
- libs.append(bstr(t.needed))
- if runpaths:
- # If both RPATH and RUNPATH are set, only the latter is used.
- rpaths = []
+ _all_libs = {}
+ ldpaths = ldpaths.copy()
+ ret: Dict[str, Any] = {
+ "interp": None,
+ "path": path if display is None else display,
+ "realpath": path,
+ "needed": [],
+ "rpath": [],
+ "runpath": [],
+ "libs": _all_libs,
+ }
- # XXX: We assume there is only one PT_DYNAMIC. This is
- # probably fine since the runtime ldso does the same.
- break
- if _first:
- # Propagate the rpaths used by the main ELF since those will be
- # used at runtime to locate things.
- ldpaths['rpath'] = rpaths
- ldpaths['runpath'] = runpaths
- dbg(debug, ' ldpaths[rpath] =', rpaths)
- dbg(debug, ' ldpaths[runpath] =', runpaths)
- ret['rpath'] = rpaths
- ret['runpath'] = runpaths
- ret['needed'] = libs
-
- # Search for the libs this ELF uses.
- all_ldpaths = None
- for lib in libs:
- if lib in _all_libs:
- continue
- if all_ldpaths is None:
- all_ldpaths = rpaths + ldpaths['rpath'] + ldpaths['env'] + runpaths + ldpaths['runpath'] + ldpaths['conf'] + ldpaths['interp']
- realpath, fullpath = FindLib(elf, lib, all_ldpaths, root, debug=debug)
- _all_libs[lib] = {
- 'realpath': realpath,
- 'path': fullpath,
- 'needed': [],
- }
- if fullpath:
+ dbg(debug, f"ParseELF({path})")
+
+ with open(path, "rb") as f:
try:
- lret = ParseELF(realpath, root, prefix, ldpaths, display=fullpath,
- debug=debug, _first=False, _all_libs=_all_libs)
- except exceptions.ELFError as e:
- warn('%s: %s' % (realpath, e))
- _all_libs[lib]['needed'] = lret['needed']
+ elf = ELFFile(f)
+ except exceptions.ELFParseError:
+ warn("ELFParser failed to parse", path)
+ raise
+
+ # If this is the first ELF, extract the interpreter.
+ if _first:
+ for segment in elf.iter_segments():
+ if segment.header.p_type != "PT_INTERP":
+ continue
+
+ interp = bstr(segment.get_interp_name())
+ dbg(debug, " interp =", interp)
+ ret["interp"] = normpath(root + interp)
+ real_interp = readlink(ret["interp"], root, prefixed=True)
+ ret["libs"][os.path.basename(interp)] = {
+ "path": ret["interp"],
+ "realpath": real_interp,
+ "needed": [],
+ }
+ # XXX: Could read it and scan for /lib paths.
+ # If the interp is a symlink, lets follow it on the assumption that it
+ # is in this path purely for ABI reasons, and the distro is using a
+ # different (probably more correct) path. This can come up in some
+ # multilib situations like s390x where /lib64/ contains all the native
+ # libraries, but /lib/ld64.so.1 is the interp hardcoded in gcc, so the
+ # ld64.so.1 is really a symlink to ../lib64/ld64.so.1. In the multiarch
+ # setup, it'll be /lib/ld64.so.1 -> /lib/s390x-linux-gnu/ld64.so.1.
+ # That is why we use |real_interp| here instead of |interp|.
+ ldpaths["interp"] = [
+ os.path.dirname(real_interp),
+ normpath(
+ root
+ + prefix
+ + "/usr/"
+ + os.path.dirname(real_interp)[len(root) + len(prefix) :]
+ ),
+ ]
+ dbg(debug, " ldpaths[interp] =", ldpaths["interp"])
+ break
+
+ # Parse the ELF's dynamic tags.
+ libs = []
+ rpaths = []
+ runpaths = []
+ for segment in elf.iter_segments():
+ if segment.header.p_type != "PT_DYNAMIC":
+ continue
+
+ for t in segment.iter_tags():
+ if t.entry.d_tag == "DT_RPATH":
+ rpaths = ParseLdPaths(bstr(t.rpath), root=root, cwd=cwd, path=path)
+ elif t.entry.d_tag == "DT_RUNPATH":
+ runpaths = ParseLdPaths(
+ bstr(t.runpath), root=root, cwd=cwd, path=path
+ )
+ elif t.entry.d_tag == "DT_NEEDED":
+ libs.append(bstr(t.needed))
+ if runpaths:
+ # If both RPATH and RUNPATH are set, only the latter is used.
+ rpaths = []
+
+ # XXX: We assume there is only one PT_DYNAMIC. This is
+ # probably fine since the runtime ldso does the same.
+ break
+ if _first:
+ # Propagate the rpaths used by the main ELF since those will be
+ # used at runtime to locate things.
+ ldpaths["rpath"] = rpaths
+ ldpaths["runpath"] = runpaths
+ dbg(debug, " ldpaths[rpath] =", rpaths)
+ dbg(debug, " ldpaths[runpath] =", runpaths)
+ ret["rpath"] = rpaths
+ ret["runpath"] = runpaths
+ ret["needed"] = libs
+
+ # Search for the libs this ELF uses.
+ all_ldpaths = None
+ for lib in libs:
+ if lib in _all_libs:
+ continue
+ if all_ldpaths is None:
+ all_ldpaths = (
+ rpaths
+ + ldpaths["rpath"]
+ + ldpaths["env"]
+ + runpaths
+ + ldpaths["runpath"]
+ + ldpaths["conf"]
+ + ldpaths["interp"]
+ )
+ realpath, fullpath = FindLib(elf, lib, all_ldpaths, root, debug=debug)
+ _all_libs[lib] = {
+ "realpath": realpath,
+ "path": fullpath,
+ "needed": [],
+ }
+ if realpath is not None:
+ try:
+ lret = ParseELF(
+ realpath,
+ root,
+ cwd,
+ prefix,
+ ldpaths,
+ display=fullpath,
+ debug=debug,
+ _first=False,
+ _all_libs=_all_libs,
+ )
+ except exceptions.ELFError as e:
+ warn(f"{realpath}: {e}")
+ _all_libs[lib]["needed"] = lret["needed"]
+
+ del elf
+
+ return ret
- del elf
- return ret
# pylint: enable=dangerous-default-value
class _NormalizePathAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, normpath(values))
+ """Argparse action to normalize paths."""
+
+ def __call__(self, parser, namespace, values, option_string=None):
+ setattr(namespace, self.dest, normpath(values))
+
+def _ActionShow(options: argparse.Namespace, elf: dict):
+ """Show the dependency tree for this ELF"""
-def _ActionShow(options, elf):
- """Show the dependency tree for this ELF"""
- def _show(lib, depth):
- chain_libs.append(lib)
- fullpath = elf['libs'][lib]['path']
+ def _show(lib, depth):
+ chain_libs.append(lib)
+ fullpath = elf["libs"][lib]["path"]
+ if options.list:
+ print(fullpath or lib)
+ else:
+ indent = " " * depth
+ print(f"{indent}{lib}", "=>", fullpath)
+
+ new_libs = []
+ for nlib in elf["libs"][lib]["needed"]:
+ if nlib in chain_libs:
+ if not options.list:
+ print(f"{indent}{nlib} => !!! circular loop !!!")
+ continue
+ if options.all or not nlib in shown_libs:
+ shown_libs.add(nlib)
+ new_libs.append(nlib)
+
+ for nlib in new_libs:
+ _show(nlib, depth + 1)
+ chain_libs.pop()
+
+ shown_libs = set(elf["needed"])
+ new_libs = elf["needed"][:]
+ chain_libs: List[str] = []
+ interp = elf["interp"]
+ if interp:
+ lib = os.path.basename(interp)
+ shown_libs.add(lib)
+ # If we are in non-list mode, then we want to show the "duplicate" interp
+ # lines -- first the header (interp=>xxx), and then the DT_NEEDED line to
+ # show that the ELF is directly linked against the interp.
+ # If we're in list mode though, we only want to show the interp once.
+ # Unless of course we have the --all flag active, then we show everything.
+ if not options.all and options.list and lib in new_libs:
+ new_libs.remove(lib)
if options.list:
- print(fullpath or lib)
+ print(elf["path"])
+ if not interp is None:
+ print(interp)
else:
- print('%s%s => %s' % (' ' * depth, lib, fullpath))
-
- new_libs = []
- for lib in elf['libs'][lib]['needed']:
- if lib in chain_libs:
- if not options.list:
- print('%s%s => !!! circular loop !!!' % (' ' * depth, lib))
- continue
- if options.all or not lib in shown_libs:
- shown_libs.add(lib)
- new_libs.append(lib)
-
+ print(elf["path"], f"(interpreter => {interp})")
for lib in new_libs:
- _show(lib, depth + 1)
- chain_libs.pop()
-
- shown_libs = set(elf['needed'])
- new_libs = elf['needed'][:]
- chain_libs = []
- interp = elf['interp']
- if interp:
- lib = os.path.basename(interp)
- shown_libs.add(lib)
- # If we are in non-list mode, then we want to show the "duplicate" interp
- # lines -- first the header (interp=>xxx), and then the DT_NEEDED line to
- # show that the ELF is directly linked against the interp.
- # If we're in list mode though, we only want to show the interp once.
- # Unless of course we have the --all flag active, then we show everything.
- if not options.all and options.list and lib in new_libs:
- new_libs.remove(lib)
- if options.list:
- print(elf['path'])
- if not interp is None:
- print(interp)
- else:
- print('%s (interpreter => %s)' % (elf['path'], interp))
- for lib in new_libs:
- _show(lib, 1)
-
-
-def _ActionCopy(options, elf):
- """Copy the ELF and its dependencies to a destination tree"""
- def _StripRoot(path):
- return path[len(options.root) - 1:]
-
- def _copy(realsrc, src, striproot=True, wrapit=False, libpaths=(),
- outdir=None):
- if realsrc is None:
- return
-
- if wrapit:
- # Static ELFs don't need to be wrapped.
- if not elf['interp']:
- wrapit = False
-
- striproot = _StripRoot if striproot else lambda x: x
-
- if outdir:
- subdst = os.path.join(outdir, os.path.basename(src))
- else:
- subdst = striproot(src)
- dst = options.dest + subdst
+ _show(lib, 1)
- try:
- # See if they're the same file.
- nstat = os.stat(dst + ('.elf' if wrapit else ''))
- ostat = os.stat(realsrc)
- for field in ('mode', 'mtime', 'size'):
- if getattr(ostat, 'st_' + field) != \
- getattr(nstat, 'st_' + field):
- break
- else:
- return
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
-
- if options.verbose:
- print('%s -> %s' % (src, dst))
-
- makedirs(os.path.dirname(dst))
- try:
- shutil.copy2(realsrc, dst)
- except IOError:
- os.unlink(dst)
- shutil.copy2(realsrc, dst)
-
- if wrapit:
- if options.verbose:
- print('generate wrapper %s' % (dst,))
-
- if options.libdir:
- interp = os.path.join(options.libdir, os.path.basename(elf['interp']))
- else:
- interp = _StripRoot(elf['interp'])
- GenerateLdsoWrapper(options.dest, subdst, interp, libpaths)
-
- # XXX: We should automatically import libgcc_s.so whenever libpthread.so
- # is copied over (since we know it can be dlopen-ed by NPTL at runtime).
- # Similarly, we should provide an option for automatically copying over
- # the libnsl.so and libnss_*.so libraries, as well as an open ended list
- # for known libs that get loaded (e.g. curl will dlopen(libresolv)).
- uniq_libpaths = set()
- for lib in elf['libs']:
- libdata = elf['libs'][lib]
- path = libdata['realpath']
- if path is None:
- warn('could not locate library: %s' % lib)
- continue
- if not options.libdir:
- uniq_libpaths.add(_StripRoot(os.path.dirname(path)))
- _copy(path, libdata['path'], outdir=options.libdir)
- if not options.libdir:
- libpaths = list(uniq_libpaths)
- if elf['runpath']:
- libpaths = elf['runpath'] + libpaths
- else:
- libpaths = elf['rpath'] + libpaths
- else:
- uniq_libpaths.add(options.libdir)
- libpaths = list(uniq_libpaths)
-
- # We don't bother to copy this as ParseElf adds the interp to the 'libs',
- # so it was already copied in the libs loop above.
- #_copy(elf['interp'], outdir=options.libdir)
- _copy(elf['realpath'], elf['path'], striproot=options.auto_root,
- wrapit=options.generate_wrappers, libpaths=libpaths,
- outdir=options.bindir)
-
-
-def GetParser():
- """Get a CLI parser."""
- parser = argparse.ArgumentParser(
- description=__doc__,
- formatter_class=argparse.RawDescriptionHelpFormatter)
- parser.add_argument('-a', '--all',
- action='store_true', default=False,
- help='Show all duplicated dependencies')
- parser.add_argument('-R', '--root',
- default=os.environ.get('ROOT', ''), type=str,
- action=_NormalizePathAction,
- help='Search for all files/dependencies in ROOT')
- parser.add_argument('-P', '--prefix',
- default=os.environ.get(
- 'EPREFIX', '@GENTOO_PORTAGE_EPREFIX@'), type=str,
- action=_NormalizePathAction,
- help='Specify EPREFIX for binaries (for Gentoo Prefix)')
- parser.add_argument('--no-auto-root',
- dest='auto_root', action='store_false', default=True,
- help='Do not automatically prefix input ELFs with ROOT')
- parser.add_argument('-l', '--list',
- action='store_true', default=False,
- help='Display output in a simple list (easy for copying)')
- parser.add_argument('-x', '--debug',
- action='store_true', default=False,
- help='Run with debugging')
- parser.add_argument('-v', '--verbose',
- action='store_true', default=False,
- help='Be verbose')
- parser.add_argument('--skip-non-elfs',
- action='store_true', default=False,
- help='Skip plain (non-ELF) files instead of warning')
- parser.add_argument('-V', '--version',
- action='version',
- version='lddtree by Mike Frysinger <vapier@gentoo.org>',
- help='Show version information')
- parser.add_argument('path', nargs='+')
-
- group = parser.add_argument_group('Copying options')
- group.add_argument('--copy-to-tree',
- dest='dest', default=None, type=str,
- action=_NormalizePathAction,
- help='Copy all files to the specified tree')
- group.add_argument('--bindir',
- default=None, type=str,
- action=_NormalizePathAction,
- help='Dir to store all ELFs specified on the command line')
- group.add_argument('--libdir',
- default=None, type=str,
- action=_NormalizePathAction,
- help='Dir to store all ELF libs')
- group.add_argument('--generate-wrappers',
- action='store_true', default=False,
- help='Wrap executable ELFs with scripts for local ldso')
- group.add_argument('--copy-non-elfs',
- action='store_true', default=False,
- help='Copy over plain (non-ELF) files instead of warn+ignore')
-
- return parser
-
-
-def main(argv):
- """The main entry point!"""
- parser = GetParser()
- options = parser.parse_args(argv)
- paths = options.path
-
- if options.root != '/':
- options.root += '/'
- if options.prefix == '@''GENTOO_PORTAGE_EPREFIX''@':
- options.prefix = ''
-
- if options.bindir and options.bindir[0] != '/':
- parser.error('--bindir accepts absolute paths only')
- if options.libdir and options.libdir[0] != '/':
- parser.error('--libdir accepts absolute paths only')
-
- if options.skip_non_elfs and options.copy_non_elfs:
- parser.error('pick one handler for non-ELFs: skip or copy')
-
- dbg(options.debug, 'root =', options.root)
- if options.dest:
- dbg(options.debug, 'dest =', options.dest)
- if not paths:
- err('missing ELF files to scan')
-
- ldpaths = LoadLdpaths(options.root, options.prefix, debug=options.debug)
- dbg(options.debug, 'ldpaths[conf] =', ldpaths['conf'])
- dbg(options.debug, 'ldpaths[env] =', ldpaths['env'])
-
- # Process all the files specified.
- ret = 0
- for path in paths:
- dbg(options.debug, 'argv[x] =', path)
- # Only auto-prefix the path if the ELF is absolute.
- # If it's a relative path, the user most likely wants
- # the local path.
- if options.auto_root and path.startswith('/'):
- path = options.root + path.lstrip('/')
- dbg(options.debug, ' +auto-root =', path)
-
- matched = False
- for p in glob.iglob(path):
- # Once we've processed the globs, resolve the symlink. This way you can
- # operate on a path that is an absolute symlink itself. e.g.:
- # $ ln -sf /bin/bash $PWD/root/bin/sh
- # $ lddtree --root $PWD/root /bin/sh
- # First we'd turn /bin/sh into $PWD/root/bin/sh, then we want to resolve
- # the symlink to $PWD/root/bin/bash rather than a plain /bin/bash.
- dbg(options.debug, ' globbed =', p)
- if not path.startswith('/'):
- realpath = os.path.realpath(path)
- elif options.auto_root:
- realpath = readlink(p, options.root, prefixed=True)
- else:
- realpath = path
- if path != realpath:
- dbg(options.debug, ' resolved =', realpath)
-
- matched = True
- try:
- elf = ParseELF(realpath, options.root, options.prefix, ldpaths,
- display=p, debug=options.debug)
- except exceptions.ELFError as e:
- if options.skip_non_elfs:
- continue
- # XXX: Ugly. Should unify with _Action* somehow.
- if options.dest is not None and options.copy_non_elfs:
- if os.path.exists(p):
- elf = {
- 'interp': None,
- 'libs': [],
- 'runpath': [],
- 'rpath': [],
- 'path': p,
- 'realpath': realpath,
- }
- _ActionCopy(options, elf)
- continue
- ret = 1
- warn('%s: %s' % (p, e))
- continue
- except IOError as e:
- ret = 1
- warn('%s: %s' % (p, e))
- continue
+def _ActionCopy(options: argparse.Namespace, elf: dict):
+ """Copy the ELF and its dependencies to a destination tree"""
+
+ def _StripRoot(path: str) -> str:
+ return path[len(options.root) - 1 :]
- if options.dest is None:
- _ActionShow(options, elf)
- else:
- _ActionCopy(options, elf)
+ def _copy(
+ realsrc,
+ src,
+ striproot=True,
+ wrapit=False,
+ libpaths=(),
+ outdir=None,
+ preload=None,
+ ):
+ if realsrc is None:
+ return
- if not matched:
- ret = 1
- warn('%s: did not match any paths' % (path,))
+ if wrapit:
+ # Static ELFs don't need to be wrapped.
+ if not elf["interp"]:
+ wrapit = False
- return ret
+ striproot = _StripRoot if striproot else lambda x: x
+ if outdir:
+ subdst = os.path.join(outdir, os.path.basename(src))
+ else:
+ subdst = striproot(src)
+ dst = options.dest + subdst
+
+ try:
+ # See if they're the same file.
+ nstat = os.stat(dst + (".elf" if wrapit else ""))
+ ostat = os.stat(realsrc)
+ for field in ("mode", "mtime", "size"):
+ if getattr(ostat, "st_" + field) != getattr(nstat, "st_" + field):
+ break
+ else:
+ return
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
+
+ if options.verbose:
+ print(src, "->", dst)
+
+ os.makedirs(os.path.dirname(dst), exist_ok=True)
+ try:
+ shutil.copy2(realsrc, dst)
+ except FileNotFoundError as e:
+ warn(f'{elf["path"]}: {e}')
+ return
+ except IOError:
+ try:
+ os.unlink(dst)
+ except FileNotFoundError:
+ pass
+ shutil.copy2(realsrc, dst)
+
+ if wrapit:
+ if options.verbose:
+ print("generate wrapper", dst)
+
+ if options.libdir:
+ interp = os.path.join(options.libdir, os.path.basename(elf["interp"]))
+ else:
+ interp = _StripRoot(elf["interp"])
+ GenerateLdsoWrapper(options.dest, subdst, interp, libpaths, preload)
+
+ # XXX: We should automatically import libgcc_s.so whenever libpthread.so
+ # is copied over (since we know it can be dlopen-ed by NPTL at runtime).
+ # Similarly, we should provide an option for automatically copying over
+ # the libnsl.so and libnss_*.so libraries, as well as an open ended list
+ # for known libs that get loaded (e.g. curl will dlopen(libresolv)).
+ uniq_libpaths = set()
+ for lib in elf["libs"]:
+ libdata = elf["libs"][lib]
+ path = libdata["realpath"]
+ if path is None:
+ warn("could not locate library:", lib)
+ continue
+ if not options.libdir:
+ uniq_libpaths.add(_StripRoot(os.path.dirname(path)))
+ _copy(path, libdata["path"], outdir=options.libdir)
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
+ if not options.libdir:
+ libpaths = list(uniq_libpaths)
+ if elf["runpath"]:
+ libpaths = elf["runpath"] + libpaths
+ else:
+ libpaths = elf["rpath"] + libpaths
+ else:
+ uniq_libpaths.add(options.libdir)
+ libpaths = list(uniq_libpaths)
+
+ # We don't bother to copy this as ParseElf adds the interp to the 'libs',
+ # so it was already copied in the libs loop above.
+ # _copy(elf['interp'], outdir=options.libdir)
+ _copy(
+ elf["realpath"],
+ elf["path"],
+ striproot=options.auto_root,
+ wrapit=options.generate_wrappers,
+ libpaths=libpaths,
+ outdir=options.bindir,
+ preload=options.wrapper_preload,
+ )
+
+
+def GetParser() -> argparse.ArgumentParser:
+ """Get a CLI parser."""
+ parser = argparse.ArgumentParser(
+ description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
+ )
+ parser.add_argument(
+ "-a",
+ "--all",
+ action="store_true",
+ default=False,
+ help="Show all duplicated dependencies",
+ )
+ parser.add_argument(
+ "-l",
+ "--list",
+ action="store_true",
+ default=False,
+ help="Display output in a simple list (easy for copying)",
+ )
+ parser.add_argument(
+ "-x", "--debug", action="store_true", default=False, help="Run with debugging"
+ )
+ parser.add_argument(
+ "-v", "--verbose", action="store_true", default=False, help="Be verbose"
+ )
+ parser.add_argument(
+ "--skip-non-elfs",
+ action="store_true",
+ default=False,
+ help="Skip plain (non-ELF) files instead of warning",
+ )
+ parser.add_argument(
+ "--skip-missing",
+ action="store_true",
+ default=False,
+ help="Skip missing files instead of failing",
+ )
+ parser.add_argument(
+ "-V",
+ "--version",
+ action="version",
+ version="lddtree by Mike Frysinger <vapier@gentoo.org>",
+ help="Show version information",
+ )
+ parser.add_argument("path", nargs="+")
+
+ group = parser.add_argument_group("Path options")
+ group.add_argument(
+ "-R",
+ "--root",
+ default=os.environ.get("ROOT", ""),
+ type=str,
+ action=_NormalizePathAction,
+ help="Search for all files/dependencies in ROOT",
+ )
+ group.add_argument(
+ "--no-auto-root",
+ dest="auto_root",
+ action="store_false",
+ default=True,
+ help="Do not automatically prefix input ELFs with ROOT",
+ )
+ group.add_argument(
+ "-C",
+ "--cwd",
+ default=os.getcwd(),
+ type=str,
+ action=_NormalizePathAction,
+ help="Path to resolve relative paths against",
+ )
+ group.add_argument(
+ "-P",
+ "--prefix",
+ default=os.environ.get("EPREFIX", "@GENTOO_PORTAGE_EPREFIX@"),
+ type=str,
+ action=_NormalizePathAction,
+ help="Specify EPREFIX for binaries (for Gentoo Prefix)",
+ )
+
+ group = parser.add_argument_group("Copying options")
+ group.add_argument(
+ "--copy-to-tree",
+ dest="dest",
+ default=None,
+ type=str,
+ action=_NormalizePathAction,
+ help="Copy all files to the specified tree",
+ )
+ group.add_argument(
+ "--bindir",
+ default=None,
+ type=str,
+ action=_NormalizePathAction,
+ help="Dir to store all ELFs specified on the command line",
+ )
+ group.add_argument(
+ "--libdir",
+ default=None,
+ type=str,
+ action=_NormalizePathAction,
+ help="Dir to store all ELF libs",
+ )
+ group.add_argument(
+ "--generate-wrappers",
+ action="store_true",
+ default=False,
+ help="Wrap executable ELFs with scripts for local ldso",
+ )
+ group.add_argument(
+ "--copy-non-elfs",
+ action="store_true",
+ default=False,
+ help="Copy over plain (non-ELF) files instead of warn+ignore",
+ )
+ group.add_argument(
+ "--wrapper-preload",
+ default=None,
+ type=str,
+ help="Have wrapper add --preload to the ldso invocation",
+ )
+
+ if argcomplete is not None:
+ argcomplete.autocomplete(parser)
+ return parser
+
+
+def main(argv: List[str]) -> Optional[int]:
+ """The main entry point!"""
+ parser = GetParser()
+ options = parser.parse_args(argv)
+ paths = options.path
+
+ if options.root != "/":
+ options.root += "/"
+ if options.prefix == "@" "GENTOO_PORTAGE_EPREFIX" "@":
+ options.prefix = ""
+
+ if options.bindir and options.bindir[0] != "/":
+ parser.error("--bindir accepts absolute paths only")
+ if options.libdir and options.libdir[0] != "/":
+ parser.error("--libdir accepts absolute paths only")
+
+ if options.skip_non_elfs and options.copy_non_elfs:
+ parser.error("pick one handler for non-ELFs: skip or copy")
+
+ dbg(options.debug, "root =", options.root)
+ dbg(options.debug, "cwd =", options.cwd)
+ if options.dest:
+ dbg(options.debug, "dest =", options.dest)
+ if not paths:
+ err("missing ELF files to scan")
+
+ ldpaths = LoadLdpaths(
+ options.root, cwd=options.cwd, prefix=options.prefix, debug=options.debug
+ )
+ dbg(options.debug, "ldpaths[conf] =", ldpaths["conf"])
+ dbg(options.debug, "ldpaths[env] =", ldpaths["env"])
+
+ # Process all the files specified.
+ ret = 0
+ for path in paths:
+ dbg(options.debug, "argv[x] =", path)
+ # Only auto-prefix the path if the ELF is absolute.
+ # If it's a relative path, the user most likely wants
+ # the local path.
+ if options.auto_root and path.startswith("/"):
+ path = options.root + path.lstrip("/")
+ dbg(options.debug, " +auto-root =", path)
+
+ matched = False
+ for p in glob.iglob(path):
+ # Once we've processed the globs, resolve the symlink. This way you can
+ # operate on a path that is an absolute symlink itself. e.g.:
+ # $ ln -sf /bin/bash $PWD/root/bin/sh
+ # $ lddtree --root $PWD/root /bin/sh
+ # First we'd turn /bin/sh into $PWD/root/bin/sh, then we want to resolve
+ # the symlink to $PWD/root/bin/bash rather than a plain /bin/bash.
+ dbg(options.debug, " globbed =", p)
+ if not path.startswith("/"):
+ realpath = os.path.realpath(path)
+ elif options.auto_root:
+ realpath = readlink(p, options.root, prefixed=True)
+ else:
+ realpath = path
+ if path != realpath:
+ dbg(options.debug, " resolved =", realpath)
+
+ matched = True
+ try:
+ elf = ParseELF(
+ realpath,
+ options.root,
+ options.cwd,
+ options.prefix,
+ ldpaths,
+ display=p,
+ debug=options.debug,
+ )
+ except exceptions.ELFError as e:
+ if options.skip_non_elfs:
+ continue
+ # XXX: Ugly. Should unify with _Action* somehow.
+ if options.dest is not None and options.copy_non_elfs:
+ if os.path.exists(p):
+ elf = {
+ "interp": None,
+ "libs": [],
+ "runpath": [],
+ "rpath": [],
+ "path": p,
+ "realpath": realpath,
+ }
+ _ActionCopy(options, elf)
+ continue
+ ret = 1
+ warn(f"{p}: {e}")
+ continue
+ except IOError as e:
+ ret = 1
+ warn(f"{p}: {e}")
+ continue
+
+ if options.dest is None:
+ _ActionShow(options, elf)
+ else:
+ _ActionCopy(options, elf)
+
+ if not matched:
+ if not options.skip_missing:
+ ret = 1
+ warn(f"{path}: did not match any paths")
+
+ return ret
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/lddtree.sh b/lddtree.sh
index 96163e3..e0185f4 100755
--- a/lddtree.sh
+++ b/lddtree.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2007-2013 Gentoo Foundation
-# Copyright 2007-2013 Mike Frysinger <vapier@gentoo.org>
+# Copyright 2007-2024 Gentoo Foundation
+# Copyright 2007-2024 Mike Frysinger <vapier@gentoo.org>
# Distributed under the terms of the GNU General Public License v2
argv0=${0##*/}
@@ -45,7 +45,7 @@ elf_specs() {
sed -E 's: (LINUX|GNU)$: NONE:'
}
-lib_paths_fallback="${ROOT}lib* ${ROOT}usr/lib* ${ROOT}usr/local/lib*"
+lib_paths_fallback="${ROOT}lib* ${ROOT}usr/lib* ${ROOT}usr/local/lib* ${ROOT}usr/X11R6/lib*"
c_ldso_paths_loaded='false'
find_elf() {
_find_elf=''
@@ -73,7 +73,7 @@ find_elf() {
if [[ ${c_last_needed_by} != ${needed_by} ]] ; then
c_last_needed_by=${needed_by}
c_last_needed_by_rpaths=$(scanelf -qF '#F%r' "${needed_by}" | \
- sed -e 's|:| |g' -e "s:[$]ORIGIN:${needed_by%/*}:")
+ sed -E -e 's|:| |g' -e "s:[$](ORIGIN|\{ORIGIN\}):${needed_by%/*}:")
fi
check_paths "${elf}" ${c_last_needed_by_rpaths} && return 0
@@ -96,8 +96,8 @@ find_elf() {
read_ldso_conf() {
local line p
for p ; do
- # if the glob didnt match anything #360041,
- # or the files arent readable, skip it
+ # If the glob didn't match anything #360041,
+ # or the files aren't readable, skip it.
[[ -r ${p} ]] || continue
while read line ; do
case ${line} in
@@ -118,7 +118,7 @@ find_elf() {
check_paths "${elf}" "${c_ldso_paths[@]}" && return 0
fi
- check_paths "${elf}" ${lib_paths_ldso:-${lib_paths_fallback}} && return 0
+ check_paths "${elf}" ${lib_paths_fallback} && return 0
fi
return 1
}
@@ -154,13 +154,6 @@ show_elf() {
else
printf " (interpreter => ${interp:-none})"
fi
- if [[ -r ${interp} ]] ; then
- # Extract the default lib paths out of the ldso.
- lib_paths_ldso=$(
- strings "${interp}" | \
- sed -nr -e "/^\/.*lib/{s|^/?|${ROOT}|;s|/$||;s|/?:/?|\n${ROOT}|g;p}"
- )
- fi
full_interp=${interp}
interp=${interp##*/}
# If we are in non-list mode, then we want to show the "duplicate" interp
@@ -186,12 +179,12 @@ show_elf() {
# No need for leading comma w/my_allhits as we guarantee it always
# starts with one due to the way we append the value above.
[[ ${my_allhits}, == *,${lib},* ]] && continue
- # If the interp is being linked against directly, re-use the existing
+ # If the interp is being linked against directly, reuse the existing
# full path rather than perform a search for it. When systems symlink
# the interp to a diff location, we might locate a different path, and
# displaying both doesn't make sense as it doesn't match the runtime --
# the ldso won't load another copy of ldso into memory from the search
- # path, it'll re-use the existing copy that was loaded from the full
+ # path, it'll reuse the existing copy that was loaded from the full
# hardcoded path.
if [[ ${lib} == "${interp}" ]] ; then
rlib=${full_interp}
@@ -235,7 +228,6 @@ ${SET_X} && set -x
ret=0
for elf ; do
- unset lib_paths_ldso
unset c_last_needed_by
if ${AUTO_ROOT} && [[ ${elf} == /* ]] ; then
elf="${ROOT}${elf#/}"
diff --git a/macho.h b/macho.h
index 09caba1..4a99e8f 100644
--- a/macho.h
+++ b/macho.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2012 Gentoo Foundation
+ * Copyright 2008-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*/
@@ -9,7 +9,8 @@
#include <stdint.h>
/*
- * http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
+ * https://nicolascormier.com/documentation/macosx-programming/MachORuntime.pdf
+ * https://web.archive.org/web/20090404123504/http://developer.apple.com/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
*/
#define CPU_ARCH_ABI64 0x01000000 /* 64 bit */
@@ -72,7 +73,7 @@ struct mach_header
incremental link against a base file and
cannot be link edited again */
#define MH_DYLDLINK 0x4 /* the object file is input for the dynamic
- linker and cannot be staticly link edited
+ linker and cannot be statically link edited
again */
#define MH_TWOLEVEL 0x80 /* the image is using two-level namespace
bindings */
@@ -106,7 +107,7 @@ struct mach_header
they are not used by other
code */
#define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees there are no
- multiple defintions of symbols in its
+ multiple definitions of symbols in its
subimages, as a result the two-level
namespace hints can always be used */
@@ -128,6 +129,7 @@ struct mach_header_64
/* cputype */
#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64)
+#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
struct load_command
{
@@ -257,6 +259,12 @@ struct rpath_command {
union lc_str path;
};
+struct uuid_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint8_t uuid[16];
+};
+
struct fat_header
{
uint32_t magic;
diff --git a/make-seccomp-filters.sh b/make-seccomp-filters.sh
new file mode 100755
index 0000000..124646a
--- /dev/null
+++ b/make-seccomp-filters.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -ufe
+>&2 echo THIS IS A DEVELOPER SCRIPT
+>&2 echo YOU DO NOT NEED TO RUN IT UNLESS YOU EDITED seccomp-bpf.c
+
+: "${CC:=gcc}"
+: "${CCFLAGS:=$(pkg-config --cflags --libs libseccomp)}"
+
+generator="$(mktemp)"
+trap 'rm "${generator}"' EXIT
+
+"${CC}" -o "${generator}" -D_GNU_SOURCE ${CCFLAGS} seccomp-bpf.c && \
+ "${generator}" > seccomp-bpf.h
diff --git a/make-tarball.sh b/make-tarball.sh
deleted file mode 100755
index 04f778d..0000000
--- a/make-tarball.sh
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/bin/bash
-
-set -e
-
-if ! . /etc/init.d/functions.sh 2>/dev/null ; then
- einfo() { printf ' * %b\n' "$*"; }
- eerror() { einfo "$@" 1>&2; }
-fi
-die() { eerror "$@"; exit 1; }
-
-v() { printf '\t%s\n' "$*"; "$@"; }
-
-: ${MAKE:=make}
-
-CHECK=false
-if [[ $1 == "--check" ]] ; then
- CHECK=true
- shift
-fi
-
-if [[ $# -ne 1 ]] ; then
- die "Usage: $0 <ver>"
-fi
-
-case $1 in
-snap) ver=$(date -u +%Y%m%d) ;;
-git) ver="HEAD" ;;
-*)
- ver="v${1#v}"
- if ! git describe --tags "${ver}" >&/dev/null ; then
- die "Please create the tag first: git tag ${ver}"
- fi
- ;;
-esac
-p="pax-utils-${ver#v}"
-
-rm -rf "${p}"
-mkdir "${p}"
-
-einfo "Checking out clean git sources ..."
-git archive "${ver}" | tar xf - -C "${p}"
-
-pushd "${p}" >/dev/null
-
-einfo "Building docs ..."
-echo "<releaseinfo>${ver#v}</releaseinfo>" > man/fragment/version
-make -C man
-
-einfo "Building autotools ..."
-sed -i "/^AC_INIT/s:git:${ver}:" configure.ac
-sed -i "1iPV := ${ver}" Makefile
-SKIP_AUTOTOOLS_UPDATE=true LC_ALL=C ${MAKE} -s autotools >/dev/null
-rm -rf autom4te.cache
-
-popd >/dev/null
-
-einfo "Generating tarball ..."
-tar cf - "${p}" | xz > "${p}".tar.xz
-rm -r "${p}"
-
-if ${CHECK} ; then
-
-einfo "Checking tarball (simple) ..."
-tar xf "${p}".tar.*
-pushd "${p}" >/dev/null
-v ${MAKE} -s
-v ${MAKE} -s check
-popd >/dev/null
-rm -rf "${p}"
-
-einfo "Checking tarball (autotools) ..."
-tar xf "${p}".tar.*
-pushd "${p}" >/dev/null
-v ./configure -q
-v ${MAKE} -s
-v ${MAKE} -s check
-popd >/dev/null
-rm -rf "${p}"
-
-fi
-
-echo
-einfo "All ready for distribution!"
-du -b "${p}".tar.*
-
-exit 0
diff --git a/man/Makefile b/man/Makefile
deleted file mode 100644
index 6f1f185..0000000
--- a/man/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: man
-
-XMLTO_FLAGS_man = -x custom.xsl --skip-validation
-man pdf txt xhtml xhtml-nochunks:
- @xmlto $@ $(XMLTO_FLAGS_$@) pax-utils.docbook || echo "If this failed, you probably need to emerge ~app-text/docbook-xml-dtd-4.4 app-text/xmlto dev-tex/xmltex"
- @# scanelf.1 has funky indented lists ... hack it back
- @sed -i.tmp 's:^[.]TP 4:.TP 2:' scanelf.1
- @rm scanelf.1.tmp
-clean distclean:
- rm -f *.1 *.html
-
-.PHONY: all clean distclean \
- man pdf txt xhtml xhtml-nochunks
diff --git a/man/custom.xsl b/man/custom.xsl
index bf01b14..c1ab12d 100644
--- a/man/custom.xsl
+++ b/man/custom.xsl
@@ -12,8 +12,7 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:text>.sp -1&#10;</xsl:text>
<xsl:text>.TP</xsl:text>
<xsl:if test="not($list-indent = '')">
- <xsl:text> </xsl:text>
- <xsl:value-of select="$list-indent"/>
+ <xsl:text> 2</xsl:text>
</xsl:if>
<xsl:text>&#10;</xsl:text>
</xsl:if>
diff --git a/man/fragment/date b/man/fragment/date
deleted file mode 100644
index e69de29..0000000
--- a/man/fragment/date
+++ /dev/null
diff --git a/man/fragment/reftail b/man/fragment/reftail
index 3acd009..c722421 100644
--- a/man/fragment/reftail
+++ b/man/fragment/reftail
@@ -1,6 +1,6 @@
<refsect1 id='homepage'>
<title>HOMEPAGE</title>
- <para><ulink>http://hardened.gentoo.org/pax-utils.xml</ulink></para>
+ <para><ulink>https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities</ulink></para>
</refsect1>
<refsect1 id='report_bugs'>
@@ -9,7 +9,7 @@
Please include as much information as possible (using any available
debugging options) and send bug reports to the maintainers (see the
<link><emphasis remap='B'>AUTHORS</emphasis></link> section). Please
- use the Gentoo bugzilla at <ulink>http://bugs.gentoo.org/</ulink> if
+ use the Gentoo bugzilla at <ulink>https://bugs.gentoo.org/</ulink> if
possible.
</para>
</refsect1>
diff --git a/man/fragment/version b/man/fragment/version
deleted file mode 100644
index 69ba922..0000000
--- a/man/fragment/version
+++ /dev/null
@@ -1 +0,0 @@
-<releaseinfo>git</releaseinfo>
diff --git a/man/meson.build b/man/meson.build
new file mode 100644
index 0000000..09ac0d5
--- /dev/null
+++ b/man/meson.build
@@ -0,0 +1,44 @@
+xmlto = find_program('xmlto', required : get_option('build_manpages'), disabler: true)
+
+docbook_conf = configuration_data()
+docbook_conf.set('version', meson.project_version())
+docbook_conf.set('man_dir', meson.current_source_dir())
+
+book = configure_file(
+ input : 'pax-utils.docbook.in',
+ output : 'pax-utils.docbook',
+ configuration : docbook_conf
+)
+
+pages = [
+ 'dumpelf.docbook', 'pspax.docbook', 'scanelf.docbook', 'scanmacho.docbook'
+]
+
+fs = import('fs')
+
+out_pages = []
+generated_man_pages_exist = true
+foreach page : pages
+ man_page_name = page.replace('.docbook', '.1')
+ out_pages += man_page_name
+ if not fs.exists(man_page_name)
+ generated_man_pages_exist = false
+ endif
+endforeach
+
+if generated_man_pages_exist
+ install_man(out_pages)
+else
+ custom_target('docbook_to_man',
+ command : [
+ xmlto, '-x', files('custom.xsl'), '--skip-validation',
+ '-o', meson.current_build_dir(), 'man', book
+ ],
+ input : [
+ 'pax-utils.docbook.in', 'custom.xsl', 'fragment/reftail',
+ ] + pages,
+ output : out_pages,
+ install : true,
+ install_dir : get_option('mandir') / 'man1'
+ )
+endif
diff --git a/man/pax-utils.docbook b/man/pax-utils.docbook.in
index 79e6c12..a8fd7df 100644
--- a/man/pax-utils.docbook
+++ b/man/pax-utils.docbook.in
@@ -2,16 +2,14 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
- <!ENTITY date SYSTEM "fragment/date">
- <!ENTITY version SYSTEM "fragment/version">
- <!ENTITY reftail SYSTEM "fragment/reftail">
+ <!ENTITY reftail SYSTEM "@man_dir@/fragment/reftail">
<!ENTITY project "pax-utils">
- <!ENTITY dumpelf SYSTEM "dumpelf.docbook">
- <!ENTITY pspax SYSTEM "pspax.docbook">
- <!ENTITY scanelf SYSTEM "scanelf.docbook">
- <!ENTITY scanmacho SYSTEM "scanmacho.docbook">
+ <!ENTITY dumpelf SYSTEM "@man_dir@/dumpelf.docbook">
+ <!ENTITY pspax SYSTEM "@man_dir@/pspax.docbook">
+ <!ENTITY scanelf SYSTEM "@man_dir@/scanelf.docbook">
+ <!ENTITY scanmacho SYSTEM "@man_dir@/scanmacho.docbook">
]>
<book id="pax-utils" lang="en">
@@ -40,8 +38,7 @@
</author>
</authorgroup>
- &version;
- &date;
+ <releaseinfo>@version@</releaseinfo>
</bookinfo>
&dumpelf;
diff --git a/man/scanelf.docbook b/man/scanelf.docbook
index d9032a9..22503b2 100644
--- a/man/scanelf.docbook
+++ b/man/scanelf.docbook
@@ -214,6 +214,13 @@
listing ELFs.
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--ldcache</option> <replaceable>PATH</replaceable></term>
+ <listitem><para>
+ Use specified path instead of /etc/ld.so.cache. Generally paired with
+ options like -L or -n.
+ </para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/meson-build-dist-man.sh b/meson-build-dist-man.sh
new file mode 100755
index 0000000..699a380
--- /dev/null
+++ b/meson-build-dist-man.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+# This script should be invoked by meson itself (via 'meson dist')
+# See https://github.com/mesonbuild/meson/issues/2166 and more specifically,
+# https://github.com/mesonbuild/meson/issues/2166#issuecomment-629696911.
+set -eu
+
+cd "${MESON_DIST_ROOT}"
+mkdir build
+meson setup build -Dbuild_manpages=enabled
+meson compile -C build
+cp build/man/* man/
+rm -rf build
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..319e3de
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,174 @@
+project('pax-utils', 'c',
+ version : '1.3.7',
+ license : 'GPL-2.0-only',
+ default_options : [
+ 'warning_level=2',
+ 'c_std=gnu11',
+ ],
+)
+
+cc = meson.get_compiler('c')
+
+libcap = dependency('libcap', required : get_option('use_libcap'))
+if libcap.found()
+ add_project_arguments('-DWANT_SYSCAP', language : 'c')
+endif
+
+if get_option('use_seccomp')
+ add_project_arguments('-DWANT_SECCOMP', language : 'c')
+endif
+
+if get_option('buildtype') in ['debug', 'debugoptimized']
+ add_project_arguments('-DEBUG', language : 'c')
+endif
+
+# generate VCSID
+version_h = vcs_tag(input : 'version.h.in', output : 'pax_utils_version.h')
+# tell paxinc.h to use it
+add_project_arguments('-DINCLUDE_GENERATE_VERSION_H', language : 'c')
+add_project_arguments('-DVERSION="' + meson.project_version() + '"', language : 'c')
+
+add_project_arguments('-D_GNU_SOURCE', language : 'c')
+add_project_arguments('-D_FILE_OFFSET_BITS=64', language : 'c')
+
+# probe the platform...
+probe_results = configuration_data()
+
+## first, we check a bunch of headers
+foreach x : [
+ 'endian.h', 'byteswap.h', # GNU-likes
+ 'sys/endian.h', # BSDs,
+ 'sys/isa_defs.h', # Sun/Illumios
+ 'machine/endian.h', # Mach
+
+ 'linux/seccomp.h',
+ 'linux/securebits.h',
+ 'sys/prctl.h',
+ 'elf-hints.h',
+ 'glob.h',
+]
+ if cc.has_header(x)
+ probe_results.set('HAVE_' + x.to_upper().underscorify(), 1)
+ endif
+endforeach
+
+configure_file(
+ output : 'config.h',
+ configuration : probe_results,
+)
+
+
+# common code
+common_src = [
+ 'paxinc.c',
+ 'security.c',
+ 'xfuncs.c',
+ version_h,
+]
+common = static_library('common',
+ common_src,
+ install : false
+)
+
+if cc.get_define('__svr4__') == ''
+ executable('pspax',
+ 'paxelf.c',
+ 'paxldso.c',
+ 'pspax.c',
+ version_h,
+ dependencies : [libcap],
+ link_with : common,
+ install : true
+ )
+endif
+
+executable('scanelf',
+ 'paxelf.c',
+ 'paxldso.c',
+ 'scanelf.c',
+ version_h,
+ dependencies : [libcap],
+ link_with : common,
+ install : true
+)
+
+# dumpelf code (without the common code above)
+dumpelf_src = [
+ 'paxelf.c',
+ 'paxldso.c',
+ 'dumpelf.c',
+ version_h,
+]
+
+executable('dumpelf',
+ dumpelf_src,
+ dependencies : [libcap],
+ link_with : common,
+ install : true
+)
+
+executable('scanmacho',
+ 'paxmacho.c',
+ 'scanmacho.c',
+ version_h,
+ dependencies : [libcap],
+ link_with : common,
+ install : true
+)
+
+lddtree_impl = get_option('lddtree_implementation')
+if lddtree_impl != 'none'
+ if lddtree_impl == 'python'
+ suffix = '.py'
+ else
+ suffix = '.sh'
+ endif
+ install_data('lddtree' + suffix,
+ rename : 'lddtree',
+ install_dir : get_option('bindir')
+ )
+endif
+install_data('symtree.sh',
+ rename : 'symtree',
+ install_dir : get_option('bindir')
+)
+
+subdir('man')
+
+meson.add_dist_script('meson-build-dist-man.sh')
+
+do_tests = get_option('tests')
+if do_tests
+ subdir('tests/lddtree')
+ subdir('tests/scanelf')
+ subdir('tests/source')
+endif
+
+if do_tests and get_option('use_fuzzing')
+ ncc = meson.get_compiler('c', native : true)
+ fuzz_flags = [
+ '-g3', '-ggdb',
+ '-fsanitize=fuzzer', '-fsanitize-coverage=edge',
+ '-DPAX_UTILS_LIBFUZZ=1',
+ ]
+ if ncc.get_id() != 'clang'
+ warning('use_fuzzing requires Clang, due to LibFuzzer. Not building fuzzers')
+ else
+ dumpelf_fuzzer = executable('dumpelf.fuzz',
+ common_src + dumpelf_src,
+ override_options : [
+ 'buildtype=debug',
+ ],
+ c_args : fuzz_flags,
+ link_args : fuzz_flags,
+ install : false
+ )
+ test('fuzz-dumpelf', dumpelf_fuzzer,
+ args : [
+ '-close_fd_mask=3',
+ '-max_total_time=10',
+ '-print_final_stats',
+ ]
+ )
+ endif
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..04b51fe
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,17 @@
+option('lddtree_implementation', type : 'combo',
+ choices : ['python', 'sh', 'none'], value : 'python',
+ description : 'Which lddtree implementation to install?')
+option('use_libcap', type : 'feature', value : 'auto',
+ description : 'Enable listing capabilities in pspax output (requires libcap)'
+)
+option('use_seccomp', type : 'boolean', value : true,
+ description : 'Enable seccomp filters at runtime (does *not* require libseccomp, but does require kernel support)'
+)
+option('build_manpages', type : 'feature', value : 'auto',
+ description : 'Build manuals via DocBook (requires xmlto)')
+option('tests', type : 'boolean', value : true,
+ description : 'Enable testing (not guaranteed to work)'
+)
+option('use_fuzzing', type : 'boolean', value : true,
+ description : 'Also build LibFuzzer fuzzers as tests'
+)
diff --git a/paxelf.c b/paxelf.c
index dea3757..599d54f 100644
--- a/paxelf.c
+++ b/paxelf.c
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2012 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#include "paxinc.h"
@@ -276,6 +276,8 @@ static pairtype elf_emtypes[] = {
QUERY(EM_MICROBLAZE),
QUERY(EM_TILEGX),
QUERY(EM_ALPHA),
+ QUERY(EM_RISCV),
+ QUERY(EM_LOONGARCH),
{ 0, 0 }
};
@@ -582,7 +584,7 @@ free_elf_and_return:
/* check class and stuff */
if (!DO_WE_LIKE_ELF(elf->data)) {
- warn("we no likey %s: {%s,%s,%s,%s}",
+ warn("unknown ELF settings: %s: {%s,%s,%s,%s}",
filename,
get_elfeitype(EI_CLASS, elf->data[EI_CLASS]),
get_elfeitype(EI_DATA, elf->data[EI_DATA]),
@@ -618,6 +620,11 @@ free_elf_and_return:
char invalid; \
const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
Elf ## B ## _Off size; \
+ /* Need enough bytes for all of ehdr. */ \
+ if (elf->len < (off_t)sizeof(*ehdr)) { \
+ warn("%s: Incomplete ELF header", filename); \
+ goto free_elf_and_return; \
+ } \
/* verify program header */ \
invalid = 0; \
if (EGET(ehdr->e_phnum) <= 0) \
diff --git a/paxelf.h b/paxelf.h
index f252969..0c163d5 100644
--- a/paxelf.h
+++ b/paxelf.h
@@ -1,9 +1,9 @@
/*
- * Copyright 2005-2012 Gentoo Foundation
+ * Copyright 2005-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
*
* Make sure all of the common elf stuff is setup as we expect
*/
diff --git a/paxinc.c b/paxinc.c
index 64a3069..644c0d6 100644
--- a/paxinc.c
+++ b/paxinc.c
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2012 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
*/
/* stick common symbols here that are needed by paxinc.h */
@@ -50,14 +50,52 @@ archive_handle *ar_open(const char *filename, bool verbose)
return ret;
}
+static uint64_t ar_read_ascii_number(const char *numstr, size_t ndigits, int base)
+{
+ /* Largest field ar headers have is 16 bytes. */
+ char buf[17];
+ char *endp;
+ long long ret;
+
+ memcpy(buf, numstr, ndigits);
+ buf[ndigits] = '\0';
+
+ ret = strtoll(buf, &endp, base);
+ /* Numbers are padded with whitespace. */
+ if (*endp != '\0' && *endp != ' ') {
+ warn("ar: invalid number: %s", buf);
+ ret = 0;
+ }
+
+ /*
+ * Unsigned 64-bit numbers use up to 20 digits, and signed 64-bit numbers use
+ * up to 19 digits, but ndigits is always less than that. So we'd never handle
+ * a number that requires all 64-bits. If it's negative, it's because the input
+ * was negative e.g. "-1", and none of these fields should ever be negative.
+ */
+ if (ret < 0) {
+ warn("ar: invalid number: %s", buf);
+ ret = 0;
+ }
+
+ return ret;
+}
+#define read_octal_number(s, n) ar_read_ascii_number(s, n, 8)
+#define read_decimal_number(s, n) ar_read_ascii_number(s, n, 10)
+/* For char[] arrays rather than dynamic pointers. */
+#define read_octal_number_fixed(s) read_octal_number(s, sizeof(s))
+#define read_decimal_number_fixed(s) read_decimal_number(s, sizeof(s))
+
archive_member *ar_next(archive_handle *ar)
{
char *s;
+ char *heap_s = NULL;
ssize_t len = 0;
static archive_member ret;
if (ar->skip && lseek(ar->fd, ar->skip, SEEK_CUR) == -1) {
close_and_ret:
+ free(heap_s);
free(ar->extfn);
close(ar->fd);
ar->extfn = NULL;
@@ -84,12 +122,13 @@ close_and_ret:
goto close_and_ret;
}
+ /* System V extended filename section. */
if (ret.buf.formatted.name[0] == '/' && ret.buf.formatted.name[1] == '/') {
if (ar->extfn != NULL) {
warn("%s: Duplicate GNU extended filename section", ar->filename);
goto close_and_ret;
}
- len = atoi(ret.buf.formatted.size);
+ len = ar->extfn_len = read_decimal_number_fixed(ret.buf.formatted.size);
ar->extfn = xmalloc(sizeof(char) * (len + 1));
if (read(ar->fd, ar->extfn, len) != len)
goto close_and_ret;
@@ -104,12 +143,12 @@ close_and_ret:
s = ret.buf.formatted.name;
if (s[0] == '#' && s[1] == '1' && s[2] == '/') {
/* BSD extended filename, always in use on Darwin */
- len = atoi(s + 3);
+ len = read_decimal_number(s + 3, sizeof(ret.buf.formatted.name) - 3);
if (len <= (ssize_t)sizeof(ret.buf.formatted.name)) {
if (read(ar->fd, ret.buf.formatted.name, len) != len)
goto close_and_ret;
} else {
- s = alloca(sizeof(char) * len + 1);
+ s = heap_s = xmalloc(sizeof(char) * (len + 1));
if (read(ar->fd, s, len) != len)
goto close_and_ret;
s[len] = '\0';
@@ -120,18 +159,25 @@ close_and_ret:
warn("%s: GNU extended filename without special data section", ar->filename);
goto close_and_ret;
}
- s = ar->extfn + atoi(s + 1);
+ /* NB: We NUL terminated extfn above when reading it. */
+ int64_t off = read_decimal_number(s + 1, sizeof(ret.buf.formatted.name) - 1);
+ if (off >= ar->extfn_len) {
+ warn("%s: GNU extended filename has invalid offset", ar->filename);
+ goto close_and_ret;
+ }
+ s = ar->extfn + off;
}
snprintf(ret.name, sizeof(ret.name), "%s:%s", ar->filename, s);
+ free(heap_s);
ret.name[sizeof(ret.name) - 1] = '\0';
if ((s=strchr(ret.name+strlen(ar->filename), '/')) != NULL)
*s = '\0';
- ret.date = atoi(ret.buf.formatted.date);
- ret.uid = atoi(ret.buf.formatted.uid);
- ret.gid = atoi(ret.buf.formatted.gid);
- ret.mode = strtol(ret.buf.formatted.mode, NULL, 8);
- ret.size = atoi(ret.buf.formatted.size);
+ ret.date = read_decimal_number_fixed(ret.buf.formatted.date);
+ ret.uid = read_decimal_number_fixed(ret.buf.formatted.uid);
+ ret.gid = read_decimal_number_fixed(ret.buf.formatted.gid);
+ ret.mode = read_octal_number_fixed(ret.buf.formatted.mode);
+ ret.size = read_decimal_number_fixed(ret.buf.formatted.size);
ar->skip = ret.size - len;
return &ret;
@@ -198,3 +244,53 @@ const char *root_rel_path(const char *path)
return path;
}
+
+void pax_usage(
+ const char *header,
+ const char *args,
+ const char *parse_flags,
+ const struct option long_opts[],
+ const char * const opts_help[],
+ int status)
+{
+ const char a_arg[] = "<arg>";
+ size_t a_arg_len = strlen(a_arg) + 2;
+ size_t i;
+ int optlen;
+
+ printf("* %s\n\n"
+ "Usage: %s [options] %s\n\n", header, argv0, args);
+ printf("Options: -[%s]\n", parse_flags);
+
+ /* Prescan the --long opt length to auto-align. */
+ optlen = 0;
+ for (i = 0; long_opts[i].name; ++i) {
+ int l = strlen(long_opts[i].name);
+ if (long_opts[i].has_arg == a_argument)
+ l += a_arg_len;
+ optlen = max(l, optlen);
+ }
+ /* Use some reasonable min width. */
+ optlen = max(20, optlen);
+
+ for (i = 0; long_opts[i].name; ++i) {
+ /* First output the short flag if it has one. */
+ if (long_opts[i].val > '~')
+ printf(" ");
+ else
+ printf(" -%c, ", long_opts[i].val);
+
+ /* Then the long flag. */
+ if (long_opts[i].has_arg == no_argument)
+ printf("--%-*s", optlen, long_opts[i].name);
+ else
+ printf("--%s %s %*s", long_opts[i].name, a_arg,
+ (int)(optlen - strlen(long_opts[i].name) - a_arg_len), "");
+
+ /* Finally the help text. */
+ printf("* %s\n", opts_help[i]);
+ }
+
+ printf("\nFor more information, see the %s(1) manpage.\n", argv0);
+ exit(status);
+}
diff --git a/paxinc.h b/paxinc.h
index 6d433b9..b2d2b50 100644
--- a/paxinc.h
+++ b/paxinc.h
@@ -1,9 +1,9 @@
/*
- * Copyright 2005-2012 Gentoo Foundation
+ * Copyright 2005-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
*
* Make sure all of the common stuff is setup as we expect
*/
@@ -18,6 +18,9 @@
#ifndef VERSION
# define VERSION "git"
#endif
+#ifdef INCLUDE_GENERATE_VERSION_H
+# include "pax_utils_version.h"
+#endif
#ifndef VCSID
# define VCSID "<unknown>"
#endif
@@ -45,6 +48,7 @@ typedef struct {
const char *filename;
size_t skip;
char *extfn;
+ off_t extfn_len;
bool verbose;
} archive_handle;
#else
@@ -108,6 +112,12 @@ const char *strfileperms(const char *fname);
#define PTR_ALIGN_DOWN(base, size) ((__typeof__(base))ALIGN_DOWN((uintptr_t)(base), (size)))
#define PTR_ALIGN_UP(base, size) ((__typeof__(base))ALIGN_UP ((uintptr_t)(base), (size)))
+/* Support for libFuzzer: https://llvm.org/docs/LibFuzzer.html */
+#if PAX_UTILS_LIBFUZZ
+int LLVMFuzzerInitialize(__unused__ int *argc, __unused__ char ***argv);
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+#endif
+
/* helper functions for showing errors */
extern const char *NORM, *RED, *YELLOW;
void color_init(bool disable);
@@ -115,6 +125,17 @@ void color_init(bool disable);
/* constant pointer to a constant buffer ... each program needs to set this */
extern const char argv0[];
+/* Display usage and exit. */
+extern void pax_usage(
+ const char *header,
+ const char *args,
+ const char *parse_flags,
+ const struct option long_opts[],
+ const char * const opts_help[],
+ int status);
+
+#define a_argument required_argument
+
/* we need the space before the last comma or we trigger a bug in gcc-2 :( */
#define warn(fmt, args...) \
fprintf(stderr, "%s%s%s: " fmt "\n", RED, argv0, NORM , ## args)
diff --git a/paxldso.c b/paxldso.c
index 0cb7b01..5363134 100644
--- a/paxldso.c
+++ b/paxldso.c
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2016 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2004-2016 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#include "paxinc.h"
@@ -14,19 +14,28 @@
#if PAX_LDSO_CACHE
-static void *ldcache = NULL;
+/* Memory region containing a specific cache. Will be a subset of the mmap. */
+static const void *ldcache = NULL;
static size_t ldcache_size = 0;
+/* Entire memory mapped cache file. */
+static void *ldcache_mmap_base = NULL;
+static size_t ldcache_mmap_size = 0;
+
static char *ldso_cache_buf = NULL;
static size_t ldso_cache_buf_size = 0;
#if defined(__GLIBC__) || defined(__UCLIBC__)
/* Defines can be seen in glibc's sysdeps/generic/ldconfig.h */
-#define LDSO_CACHE_MAGIC "ld.so-"
-#define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1)
-#define LDSO_CACHE_VER "1.7.0"
-#define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1)
+#define LDSO_CACHE_MAGIC_OLD "ld.so-"
+#define LDSO_CACHE_MAGIC_OLD_LEN (sizeof LDSO_CACHE_MAGIC_OLD - 1)
+#define LDSO_CACHE_VER_OLD "1.7.0"
+#define LDSO_CACHE_VER_OLD_LEN (sizeof LDSO_CACHE_VER_OLD - 1)
+#define LDSO_CACHE_MAGIC_NEW "glibc-ld.so.cache"
+#define LDSO_CACHE_MAGIC_NEW_LEN (sizeof LDSO_CACHE_MAGIC_NEW - 1)
+#define LDSO_CACHE_VER_NEW "1.1"
+#define LDSO_CACHE_VER_NEW_LEN (sizeof LDSO_CACHE_VER_NEW - 1)
#define FLAG_ANY -1
#define FLAG_TYPE_MASK 0x00ff
#define FLAG_LIBC4 0x0000
@@ -48,14 +57,45 @@ static size_t ldso_cache_buf_size = 0;
#define FLAG_MIPS_LIB32_NAN2008 0x0c00
#define FLAG_MIPS64_LIBN32_NAN2008 0x0d00
#define FLAG_MIPS64_LIBN64_NAN2008 0x0e00
+#define FLAG_RISCV_FLOAT_ABI_SOFT 0x0f00
+#define FLAG_RISCV_FLOAT_ABI_DOUBLE 0x1000
typedef struct {
int flags;
unsigned int sooffset;
unsigned int liboffset;
-} libentry_t;
+} libentry_old_t;
+
+typedef struct {
+ const char magic[LDSO_CACHE_MAGIC_OLD_LEN];
+ const char version[LDSO_CACHE_VER_OLD_LEN];
+ unsigned int nlibs;
+ libentry_old_t libs[0];
+} header_old_t;
-static bool is_compatible(elfobj *elf, libentry_t *libent)
+typedef struct {
+ int32_t flags;
+ uint32_t sooffset;
+ uint32_t liboffset;
+ uint32_t osversion;
+ uint64_t hwcap;
+} libentry_new_t;
+
+typedef struct {
+ const char magic[LDSO_CACHE_MAGIC_NEW_LEN];
+ const char version[LDSO_CACHE_VER_NEW_LEN];
+ uint32_t nlibs;
+ uint32_t len_strings;
+ uint8_t flags;
+ uint8_t _pad_flags[3];
+ uint32_t extension_offset;
+ uint32_t _pad_ext[3];
+ libentry_new_t libs[0];
+} header_new_t;
+
+static bool ldcache_is_new;
+
+static bool is_compatible(elfobj *elf, const libentry_old_t *libent)
{
int flags = libent->flags & FLAG_REQUIRED_MASK;
@@ -136,74 +176,124 @@ static bool is_compatible(elfobj *elf, libentry_t *libent)
return false;
}
-char *ldso_cache_lookup_lib(elfobj *elf, const char *fname)
+static void ldso_cache_load(void)
{
- unsigned int nlib;
- char *ret = NULL;
- char *strs;
-
- typedef struct {
- char magic[LDSO_CACHE_MAGIC_LEN];
- char version[LDSO_CACHE_VER_LEN];
- unsigned int nlibs;
- } header_t;
- header_t *header;
+ int fd;
+ const char *cachefile;
+ struct stat st;
+ const header_old_t *header_old;
+ const header_new_t *header_new;
- libentry_t *libent;
+ if (ldcache_mmap_base != NULL)
+ return;
- if (fname == NULL)
- return NULL;
+ cachefile = root_rel_path(ldcache_path);
- if (ldcache == NULL) {
- int fd;
- const char *cachefile = root_rel_path("/etc/ld.so.cache");
- struct stat st;
+ if (fstatat(root_fd, cachefile, &st, 0))
+ return;
- if (fstatat(root_fd, cachefile, &st, 0))
- return NULL;
+ fd = openat(root_fd, cachefile, O_RDONLY);
+ if (fd == -1)
+ return;
- fd = openat(root_fd, cachefile, O_RDONLY);
- if (fd == -1)
- return NULL;
+ /* cache these values so we only map/unmap the cache file once */
+ ldcache_mmap_size = st.st_size;
+ ldcache_mmap_base = mmap(0, ldcache_mmap_size, PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
- /* cache these values so we only map/unmap the cache file once */
- ldcache_size = st.st_size;
- header = ldcache = mmap(0, ldcache_size, PROT_READ, MAP_SHARED, fd, 0);
- close(fd);
+ if (ldcache_mmap_base == MAP_FAILED) {
+ ldcache_mmap_base = NULL;
+ return;
+ }
- if (ldcache == MAP_FAILED) {
- ldcache = NULL;
- return NULL;
+ ldcache_size = ldcache_mmap_size;
+ ldcache = ldcache_mmap_base;
+ header_old = ldcache;
+ header_new = ldcache;
+#define memeq(mem1, mem2) (memcmp(mem1, mem2, sizeof(mem2) - 1) == 0)
+ if (memeq(header_new->magic, LDSO_CACHE_MAGIC_NEW) &&
+ memeq(header_new->version, LDSO_CACHE_VER_NEW)) {
+ ldcache_is_new = true;
+ } else if (memeq(header_old->magic, LDSO_CACHE_MAGIC_OLD) &&
+ memeq(header_old->version, LDSO_CACHE_VER_OLD)) {
+ /* See if the new cache format is appended after the old cache. */
+ uintptr_t end =
+ (uintptr_t)ldcache + sizeof(header_old_t) +
+ (header_old->nlibs * sizeof(libentry_old_t));
+ header_new = (const void *)ALIGN_UP(end, __alignof__(header_new_t));
+ if (memeq(header_new->magic, LDSO_CACHE_MAGIC_NEW) &&
+ memeq(header_new->version, LDSO_CACHE_VER_NEW)) {
+ ldcache_is_new = true;
+ ldcache_size -= ((uintptr_t)header_new - (uintptr_t)ldcache);
+ ldcache = header_new;
+ } else {
+ ldcache_is_new = false;
}
+ } else {
+ munmap(ldcache_mmap_base, ldcache_mmap_size);
+ ldcache_mmap_base = NULL;
+ return;
+ }
+#undef memq
- if (memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN) ||
- memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN))
- {
- munmap(ldcache, ldcache_size);
- ldcache = NULL;
- return NULL;
- }
+ ldso_cache_buf_size = 4096;
+ ldso_cache_buf = xrealloc(ldso_cache_buf, ldso_cache_buf_size);
+}
- ldso_cache_buf_size = 4096;
- ldso_cache_buf = xrealloc(ldso_cache_buf, ldso_cache_buf_size);
- } else
- header = ldcache;
+char *ldso_cache_lookup_lib(elfobj *elf, const char *fname)
+{
+ unsigned int nlib, nlibs;
+ char *ret = NULL;
+ const char *strs;
+ const libentry_old_t *libent_old;
+ const libentry_new_t *libent_new;
- libent = ldcache + sizeof(header_t);
- strs = (char *) &libent[header->nlibs];
+ if (fname == NULL)
+ return NULL;
- for (nlib = 0; nlib < header->nlibs; ++nlib) {
+ ldso_cache_load();
+ if (ldcache == NULL)
+ return NULL;
+
+ if (ldcache_is_new) {
+ const header_new_t *header = ldcache;
+ libent_old = NULL;
+ libent_new = &header->libs[0];
+ strs = (const char *)header;
+ nlibs = header->nlibs;
+ } else {
+ const header_old_t *header = ldcache;
+ libent_old = &header->libs[0];
+ libent_new = NULL;
+ strs = (const char *)&libent_old[header->nlibs];
+ nlibs = header->nlibs;
+ }
+
+ /*
+ * TODO: Should add memory range checking in case cache file is corrupt.
+ * TODO: We search the cache from start to finish, but since we know the cache
+ * is sorted, we really should be doing a binary search to speed it up.
+ */
+ for (nlib = 0; nlib < nlibs; ++nlib) {
const char *lib;
size_t lib_len;
- if (!is_compatible(elf, &libent[nlib]))
+ /* The first few fields are the same between new/old formats. */
+ const libentry_old_t *libent;
+ if (ldcache_is_new) {
+ libent = (void *)&libent_new[nlib];
+ } else {
+ libent = &libent_old[nlib];
+ }
+
+ if (!is_compatible(elf, libent))
continue;
- if (strcmp(fname, strs + libent[nlib].sooffset) != 0)
+ if (strcmp(fname, strs + libent->sooffset) != 0)
continue;
/* Return first hit because that is how the ldso rolls */
- lib = strs + libent[nlib].liboffset;
+ lib = strs + libent->liboffset;
lib_len = strlen(lib) + 1;
if (lib_len > ldso_cache_buf_size) {
ldso_cache_buf = xrealloc(ldso_cache_buf, ldso_cache_buf_size + 4096);
@@ -223,8 +313,8 @@ static void ldso_cache_cleanup(void)
{
free(ldso_cache_buf);
- if (ldcache != NULL)
- munmap(ldcache, ldcache_size);
+ if (ldcache_mmap_base != NULL)
+ munmap(ldcache_mmap_base, ldcache_mmap_size);
}
#else
@@ -267,7 +357,7 @@ int ldso_config_load(const char *fname)
size_t x;
const char *gpath;
- /* re-use existing path buffer ... need to be creative */
+ /* Reuse existing path buffer ... need to be creative. */
if (path[8] != '/')
gpath = memcpy(path + 3, "/etc/", 5);
else
@@ -369,3 +459,56 @@ void paxldso_cleanup(void)
ldso_config_cleanup();
}
#endif
+
+const char *ldcache_path = "/etc/ld.so.cache";
+
+#ifdef MAIN
+
+const char argv0[] = "paxldso";
+
+int main(int argc, char *argv[])
+{
+ elfobj *elf = readelf(argv[0]);
+ ldso_cache_load();
+ printf("cache file memory base is %p\n", ldcache_mmap_base);
+ printf("cache memory base is %p\n", ldcache);
+ for (int i = 1; i < argc; ++i) {
+ const char *search = argv[i];
+ const char *lib = ldso_cache_lookup_lib(elf, search);
+ printf("%s -> %s\n", search, lib);
+ }
+ unreadelf(elf);
+
+ if (ldcache) {
+ unsigned int nlib;
+ const char *strs, *s;
+
+ if (ldcache_is_new) {
+ const header_new_t *header = ldcache;
+ const libentry_new_t *libents = &header->libs[0];
+ strs = (const char *)header;
+ printf("dumping new cache format\n");
+
+ for (nlib = 0; nlib < header->nlibs; ++nlib) {
+ const libentry_new_t *libent = &libents[nlib];
+ s = strs + libent->sooffset;
+ printf("%p: %s\n", libent, s);
+ }
+ } else {
+ const header_old_t *header = ldcache;
+ const libentry_old_t *libents = &header->libs[0];
+ strs = (const char *)&libents[header->nlibs];
+ printf("dumping old cache format\n");
+
+ for (nlib = 0; nlib < header->nlibs; ++nlib) {
+ const libentry_old_t *libent = &libents[nlib];
+ s = strs + libent->sooffset;
+ printf("%p: %s\n", libent, s);
+ }
+ }
+ }
+
+ paxldso_cleanup();
+}
+
+#endif
diff --git a/paxldso.h b/paxldso.h
index 16cbbac..aba58fa 100644
--- a/paxldso.h
+++ b/paxldso.h
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2016 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2004-2016 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#ifndef _PAX_LDSO_H
@@ -66,4 +66,7 @@ extern void paxldso_cleanup(void);
# define paxldso_cleanup()
#endif
+/* Path to ld.so.cache. Usually overridden for tests. */
+extern const char *ldcache_path;
+
#endif
diff --git a/paxmacho.c b/paxmacho.c
index 638453a..75f9206 100644
--- a/paxmacho.c
+++ b/paxmacho.c
@@ -1,10 +1,10 @@
/*
- * Copyright 2003-2012 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
- * 2008-2012 Fabian Groffen - <grobian@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
+ * 2008-2021 Fabian Groffen - <grobian@gentoo.org>
*/
#include "paxinc.h"
@@ -17,6 +17,7 @@ static const char STR_PPC64[] = "ppc64";
static const char STR_I386[] = "i386";
static const char STR_X86_64[] = "x86_64";
static const char STR_ARM[] = "arm"; /* iPhone */
+static const char STR_ARM64[] = "arm64"; /* Apple M1 */
static const char STR_UNKNOWN[] = "unknown";
#define QUERY(n) { #n, n }
@@ -95,6 +96,7 @@ static pairtype macho_cputype[] = {
QUERY(CPU_TYPE_ARM),
QUERY(CPU_TYPE_POWERPC64),
QUERY(CPU_TYPE_X86_64),
+ QUERY(CPU_TYPE_ARM64),
{ 0, 0 }
};
const char *get_machocputype(fatobj *fobj)
@@ -383,6 +385,7 @@ const char *get_machomtype(fatobj *fobj)
case CPU_TYPE_ARM: return STR_ARM;
case CPU_TYPE_POWERPC64: return STR_PPC64;
case CPU_TYPE_X86_64: return STR_X86_64;
+ case CPU_TYPE_ARM64: return STR_ARM64;
default: return STR_UNKNOWN;
}
}
diff --git a/paxmacho.h b/paxmacho.h
index 48ac854..8ea1ece 100644
--- a/paxmacho.h
+++ b/paxmacho.h
@@ -1,9 +1,9 @@
/*
- * Copyright 2005-2012 Gentoo Foundation
+ * Copyright 2005-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
* 2008-2012 Fabian Groffen - <grobian@gentoo.org>
*
* Make sure all of the common mach-o stuff is setup as we expect
diff --git a/porting.h b/porting.h
index 636e862..6c0da01 100644
--- a/porting.h
+++ b/porting.h
@@ -1,9 +1,9 @@
/*
- * Copyright 2005-2012 Gentoo Foundation
+ * Copyright 2005-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2005-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org>
*
* Make sure all of the common elf stuff is setup as we expect
*/
@@ -11,9 +11,7 @@
#ifndef _PORTING_H
#define _PORTING_H
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*arr))
@@ -31,43 +29,44 @@
#include <regex.h>
#include <sched.h>
#include <signal.h>
+#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
-#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
#include "elf.h"
-#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
-# include <alloca.h>
-#endif
-#if defined(__linux__)
+#ifdef HAVE_SYS_PRCTL_H
# include <sys/prctl.h>
-# if !defined(HAVE_CONFIG_H) || defined(HAVE_LINUX_SECUREBITS_H)
+# ifdef HAVE_LINUX_SECCOMP_H
+# include <linux/seccomp.h>
+# endif
+# ifdef HAVE_LINUX_SECUREBITS_H
# include <linux/securebits.h>
# endif
#endif
-#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__ANDROID__)
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_BYTESWAP_H)
# include <byteswap.h>
# include <endian.h>
-#elif defined(__FreeBSD__)
+#elif defined(HAVE_SYS_ENDIAN_H)
# include <sys/endian.h>
-#elif defined(__sun__)
+#elif defined(HAVE_ISA_DEFS_H)
# include <sys/isa_defs.h>
-#elif defined(__MACH__)
+#elif defined(HAVE_MACHINE_ENDIAN_H)
# include <machine/endian.h>
#endif
-#if defined(__GLIBC__) || defined(__UCLIBC__)
+#ifdef HAVE_GLOB_H
# include <glob.h>
#endif
#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__NetBSD__)
# define __PAX_UTILS_DEFAULT_LD_CACHE_CONFIG "/etc/ld.so.conf"
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
+#elif defined(HAVE_ELF_HINTS_H)
# include <elf-hints.h>
# define __PAX_UTILS_DEFAULT_LD_CACHE_CONFIG _PATH_ELF_HINTS
#else
@@ -75,12 +74,12 @@
#endif
#undef PAX_UTILS_CLEANUP
-/* bounds checking code will fart on free(NULL) even though that
- * is valid usage. So let's wrap it if need be.
- */
-#ifdef __BOUNDS_CHECKING_ON
-# define free(ptr) do { if (ptr) free(ptr); } while (0)
-# define PAX_UTILS_CLEANUP 1
+#ifndef __SANITIZE_ADDRESS__
+# ifdef __has_feature
+# if __has_feature (address_sanitizer)
+# define __SANITIZE_ADDRESS__ 1
+# endif
+# endif
#endif
/* LSAN (Leak Sanitizer) will complain about things we leak. */
#ifdef __SANITIZE_ADDRESS__
@@ -94,6 +93,11 @@
# define PAX_UTILS_CLEANUP 0
#endif
+/* Support for libFuzzer: https://llvm.org/docs/LibFuzzer.html */
+#ifndef PAX_UTILS_LIBFUZZ
+# define PAX_UTILS_LIBFUZZ 0
+#endif
+
/* Few arches can safely do unaligned accesses */
#if defined(__cris__) || \
defined(__i386__) || \
@@ -160,7 +164,6 @@
# define __PAX_UTILS_PATH_MAX PATH_MAX
#endif
-/* fall back case for non-Linux hosts ... so lame */
#if !defined(ELF_DATA)
# if defined(BYTE_ORDER)
# if BYTE_ORDER == LITTLE_ENDIAN
@@ -192,7 +195,7 @@
#endif
/*
- * propably will never be official added to the toolchain.
+ * Probably will never be officially added to the toolchain.
* But none the less we should try to get 0x65041580 reserved
*/
#ifndef PT_PAX_FLAGS
diff --git a/pspax.c b/pspax.c
index 52bdd8d..4cd09b6 100644
--- a/pspax.c
+++ b/pspax.c
@@ -40,33 +40,12 @@ static pid_t show_pid = 0;
static uid_t show_uid = (uid_t)-1;
static gid_t show_gid = (gid_t)-1;
-static int proc_open(int pfd, const char *file)
-{
- return openat(pfd, file, O_RDONLY|O_CLOEXEC);
-}
-
-static FILE *proc_fopen(int pfd, const char *file)
-{
- int fd;
- FILE *fp;
-
- fd = proc_open(pfd, file);
- if (fd == -1)
- return NULL;
-
- fp = fdopen(fd, "re");
- if (fp == NULL)
- close(fd);
-
- return fp;
-}
-
static elfobj *proc_readelf(int pfd)
{
int fd;
elfobj *elf;
- fd = proc_open(pfd, "exe");
+ fd = openat(pfd, "exe", O_RDONLY|O_CLOEXEC);
if (fd == -1)
return NULL;
@@ -80,11 +59,11 @@ static const char *get_proc_name_cmdline(int pfd)
FILE *fp;
static char str[1024];
- fp = proc_fopen(pfd, "cmdline");
+ fp = fopenat_r(pfd, "cmdline");
if (fp == NULL)
return NULL;
- if (fscanf(fp, "%s.1023", str) != 1) {
+ if (fscanf(fp, "%1023s", str) != 1) {
fclose(fp);
return NULL;
}
@@ -96,38 +75,57 @@ static const char *get_proc_name_cmdline(int pfd)
static const char *get_proc_name(int pfd)
{
FILE *fp;
- static char str[BUFSIZ];
+ /*
+ * The stat file says process names are truncated to TASK_COMM_LEN (16) bytes.
+ * That includes the trailing NUL (\0) byte. This is true for userspace, but
+ * kernel processes seem to be unlimited. We don't care about those in this
+ * program though, so truncating them all the time is fine.
+ */
+ static char str[16];
if (wide_output)
return get_proc_name_cmdline(pfd);
- fp = proc_fopen(pfd, "stat");
+ fp = fopenat_r(pfd, "stat");
if (fp == NULL)
return NULL;
- if (fscanf(fp, "%*d %s.16", str) != 1) {
+ /*
+ * The format is:
+ * <pid> (<name>) ...more fields...
+ * For example:
+ * 1234 (bash) R ...
+ *
+ * Match the leading (, then read 15 bytes (since scanf writes, but doesn't count,
+ * NUL bytes, so it will write up to 16 bytes to str). Ignore the rest rather than
+ * look for closing ) since kernel processes can be longer.
+ */
+ if (fscanf(fp, "%*d (%15s", str) != 1) {
fclose(fp);
return NULL;
}
if (*str) {
- str[strlen(str) - 1] = '\0';
- str[16] = 0;
+ /* Discard trailing ) if it exists. */
+ size_t len = strlen(str);
+ if (str[len - 1] == ')')
+ str[len - 1] = '\0';
}
fclose(fp);
- return (str+1);
+ return str;
}
static int get_proc_maps(int pfd)
{
FILE *fp;
- static char str[BUFSIZ];
+ static char *str = NULL;
+ static size_t len = 0;
- if ((fp = proc_fopen(pfd, "maps")) == NULL)
+ if ((fp = fopenat_r(pfd, "maps")) == NULL)
return -1;
- while (fgets(str, sizeof(str), fp)) {
+ while (getline(&str, &len, fp) != -1) {
char *p;
if ((p = strchr(str, ' ')) != NULL) {
if (strlen(p) < 6)
@@ -158,12 +156,13 @@ static int get_proc_maps(int pfd)
static int print_executable_mappings(int pfd)
{
FILE *fp;
- static char str[BUFSIZ];
+ static char *str = NULL;
+ static size_t len = 0;
- if ((fp = proc_fopen(pfd, "maps")) == NULL)
+ if ((fp = fopenat_r(pfd, "maps")) == NULL)
return -1;
- while (fgets(str, sizeof(str), fp)) {
+ while (getline(&str, &len, fp) != -1) {
char *p;
if ((p = strchr(str, ' ')) != NULL) {
if (strlen(p) < 6)
@@ -189,15 +188,6 @@ static int print_executable_mappings(int pfd)
return 0;
}
-#ifdef __BOUNDS_CHECKING_ON
-# define NOTE_TO_SELF warn( \
- "This is bullshit but getpwuid() is leaking memory and I wasted a few hrs 1 day tracking it down in pspax\n" \
- "Later on I forgot I tracked it down before and saw pspax leaking memory so I tracked it down all over again (silly me)\n" \
- "Hopefully the getpwuid()/nis/nss/pam or whatever wont suck later on in the future.")
-#else
-# define NOTE_TO_SELF
-#endif
-
static const struct passwd *get_proc_passwd(int pfd)
{
struct stat st;
@@ -212,20 +202,21 @@ static const struct passwd *get_proc_passwd(int pfd)
static const char *get_proc_status(int pfd, const char *name)
{
FILE *fp;
- size_t len;
- static char str[BUFSIZ];
+ size_t name_len;
+ static char *str = NULL;
+ static size_t len = 0;
- if ((fp = proc_fopen(pfd, "status")) == NULL)
+ if ((fp = fopenat_r(pfd, "status")) == NULL)
return NULL;
- len = strlen(name);
- while (fgets(str, sizeof(str), fp)) {
- if (strncasecmp(str, name, len) != 0)
+ name_len = strlen(name);
+ while (getline(&str, &len, fp) != -1) {
+ if (strncasecmp(str, name, name_len) != 0)
continue;
- if (str[len] == ':') {
+ if (str[name_len] == ':') {
fclose(fp);
str[strlen(str) - 1] = 0;
- return (str + len + 2);
+ return (str + name_len + 2);
}
}
fclose(fp);
@@ -237,14 +228,20 @@ static const char *get_pid_attr(int pfd)
{
FILE *fp;
char *p;
- static char buf[BUFSIZ];
+ static char *buf = NULL;
+ static size_t len = 0;
- if ((fp = proc_fopen(pfd, "attr/current")) == NULL)
+ if ((fp = fopenat_r(pfd, "attr/current")) == NULL)
return NULL;
- if (fgets(buf, sizeof(buf), fp) != NULL)
- if ((p = strchr(buf, '\n')) != NULL)
- *p = 0;
+ if (getline(&buf, &len, fp) == -1) {
+ fclose(fp);
+ return NULL;
+ }
+
+ if ((p = strchr(buf, '\n')) != NULL)
+ *p = 0;
+
fclose(fp);
return buf;
@@ -254,14 +251,20 @@ static const char *get_pid_addr(int pfd)
{
FILE *fp;
char *p;
- static char buf[BUFSIZ];
+ static char *buf = NULL;
+ static size_t len = 0;
- if ((fp = proc_fopen(pfd, "ipaddr")) == NULL)
+ if ((fp = fopenat_r(pfd, "ipaddr")) == NULL)
return NULL;
- if (fgets(buf, sizeof(buf), fp) != NULL)
- if ((p = strchr(buf, '\n')) != NULL)
- *p = 0;
+ if (getline(&buf, &len, fp) == -1) {
+ fclose(fp);
+ return NULL;
+ }
+
+ if ((p = strchr(buf, '\n')) != NULL)
+ *p = 0;
+
fclose(fp);
return buf;
@@ -413,7 +416,7 @@ static void pspax(const char *find_name)
/* this is a non-POSIX function */
caps = NULL;
- WRAP_SYSCAP(capgetp(pfd, cap_d));
+ WRAP_SYSCAP(cap_d = cap_get_pid(pid));
WRAP_SYSCAP(caps = cap_to_text(cap_d, &length));
if (pwd && strlen(pwd->pw_name) >= 8)
@@ -445,7 +448,6 @@ static void pspax(const char *find_name)
/* usage / invocation handling functions */
#define PARSE_FLAGS "aeip:u:g:nwWvCBhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"all", no_argument, NULL, 'a'},
{"header", no_argument, NULL, 'e'},
@@ -485,22 +487,16 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- int i;
- printf("* List ELF/PaX information about running processes\n\n"
- "Usage: %s [options]\n\n", argv0);
- fputs("Options:\n", stdout);
- for (i = 0; long_opts[i].name; ++i)
- printf(" -%c, --%-12s* %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
-#ifdef MANLYPAGE
- for (i = 0; long_opts[i].name; ++i)
- printf(".TP\n\\fB\\-%c, \\-\\-%s\\fR\n%s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
-#endif
- exit(status);
+ pax_usage(
+ "List ELF/PaX information about running processes",
+ "",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
-/* parse command line arguments and preform needed actions */
+/* parse command line arguments and perform needed actions */
static void parseargs(int argc, char *argv[])
{
int flag;
@@ -577,6 +573,5 @@ int main(int argc, char *argv[])
pspax(name);
- NOTE_TO_SELF;
return EXIT_SUCCESS;
}
diff --git a/pylint b/pylint
index 0098e06..29e8b5e 100755
--- a/pylint
+++ b/pylint
@@ -1,49 +1,46 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Copyright 1999-2017 Gentoo Foundation
+#!/usr/bin/env python
+# Copyright 1999-2024 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
"""Run pylint with the right settings."""
-from __future__ import print_function
-
import os
import sys
def find_all_modules(source_root):
- """Locate all python modules in the tree for scanning"""
- ret = []
+ """Locate all python modules in the tree for scanning"""
+ ret = []
- for root, _dirs, files in os.walk(source_root, topdown=False):
- # Add all of the .py modules in the tree.
- ret += [os.path.join(root, x) for x in files if x.endswith('.py')]
+ for root, _dirs, files in os.walk(source_root, topdown=False):
+ # Add all of the .py modules in the tree.
+ ret += [os.path.join(root, x) for x in files if x.endswith(".py")]
- # Add the main scripts that don't end in .py.
- ret += [os.path.join(source_root, x) for x in ('pylint',)]
+ # Add the main scripts that don't end in .py.
+ ret += [os.path.join(source_root, x) for x in ("pylint",)]
- return ret
+ return ret
def main(argv):
- """The main entry point"""
- source_root = os.path.dirname(os.path.realpath(__file__))
+ """The main entry point"""
+ source_root = os.path.dirname(os.path.realpath(__file__))
- if not argv:
- argv = find_all_modules(source_root)
+ if not argv:
+ argv = find_all_modules(source_root)
- pympath = source_root
- pythonpath = os.environ.get('PYTHONPATH')
- if pythonpath is None:
- pythonpath = pympath
- else:
- pythonpath = pympath + ':' + pythonpath
- os.environ['PYTHONPATH'] = pythonpath
+ pympath = source_root
+ pythonpath = os.environ.get("PYTHONPATH")
+ if pythonpath is None:
+ pythonpath = pympath
+ else:
+ pythonpath = pympath + ":" + pythonpath
+ os.environ["PYTHONPATH"] = pythonpath
- pylintrc = os.path.join(source_root, '.pylintrc')
- cmd = ['pylint', '--rcfile', pylintrc]
- os.execvp(cmd[0], cmd + argv)
+ pylintrc = os.path.join(source_root, "pyproject.toml")
+ cmd = ["pylint", "--rcfile", pylintrc]
+ os.execvp(cmd[0], cmd + argv)
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..d3ae4e0
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,121 @@
+# Copyright 2024 Gentoo Foundation
+# Copyright 2024 Mike Frysinger <vapier@gentoo.org>
+# Copyright 2024 The ChromiumOS Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
+
+
+# https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html
+[tool.black]
+line-length = 88
+target-version = ["py38"]
+
+
+# https://github.com/codespell-project/codespell?tab=readme-ov-file#using-a-config-file
+[tool.codespell]
+# eles: We use variable name as short for "elements".
+# Ned: Author's name.
+ignore-words-list = "eles,ned"
+
+# Imported from glibc.
+skip = "elf.h"
+
+
+# https://pycqa.github.io/isort/docs/configuration/options
+[tool.isort]
+py_version = "38"
+
+# Be compatible with `black` since it also matches what we want.
+profile = "black"
+
+line_length = 88
+length_sort = false
+force_single_line = true
+lines_after_imports = 2
+from_first = false
+case_sensitive = false
+force_sort_within_sections = true
+order_by_type = false
+
+# Allow importing multiple classes on a single line from these modules.
+# https://google.github.io/styleguide/pyguide#s2.2-imports
+single_line_exclusions = [
+ "abc",
+ "collections.abc",
+ "typing",
+]
+
+
+# https://mypy.readthedocs.io/en/stable/config_file.html
+[tool.mypy]
+python_version = "3.8"
+
+
+# https://pylint.pycqa.org/en/latest/user_guide/usage/run.html
+[tool.pylint."MASTER"]
+py-version = "3.8"
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins = [
+ "pylint.extensions.bad_builtin",
+ "pylint.extensions.check_elif",
+ "pylint.extensions.docstyle",
+ "pylint.extensions.overlapping_exceptions",
+ "pylint.extensions.redefined_variable_type",
+]
+
+# Run everything in parallel.
+jobs = 0
+
+# https://pylint.pycqa.org/en/latest/user_guide/messages/index.html
+[tool.pylint."MESSAGES CONTROL"]
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifier separated by comma (,) or put this option
+# multiple times (only on the command line, not in the configuration file where
+# it should appear only once).
+disable = [
+ "too-many-lines",
+ "too-many-branches",
+ "too-many-statements",
+ "too-few-public-methods",
+ "too-many-instance-attributes",
+ "too-many-public-methods",
+ "too-many-locals",
+ "too-many-arguments",
+ "fixme",
+ "invalid-name",
+]
+
+[tool.pylint."REPORTS"]
+reports = false
+score = false
+
+[tool.pylint."FORMAT"]
+max-line-length = 100
+indent-string = " "
+
+[tool.pylint."BASIC"]
+bad-functions = [
+ "exit",
+ "filter",
+ "input",
+ "map",
+ "quit",
+]
+
+[tool.pylint."SIMILARITIES"]
+min-similarity-lines = 20
+
+[tool.pylint."VARIABLES"]
+dummy-variables-rgx = "_"
+
+[tool.pylint."DESIGN"]
+max-parents = 10
+
+[tool.pylint."IMPORTS"]
+deprecated-modules = [
+ "mox",
+ "optparse",
+]
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 0000000..9f4869c
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,12 @@
+# Copyright 2024 Gentoo Foundation
+# Copyright 2024 Mike Frysinger <vapier@gentoo.org>
+# Copyright 2024 The ChromiumOS Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# Deps needed to run tests/linters/etc...
+# https://pip.pypa.io/en/stable/reference/requirements-file-format/
+
+black==23.*
+isort==5.*
+mypy==1.*
+pylint==3.0.*
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..540976b
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,9 @@
+# Copyright 2024 Gentoo Foundation
+# Copyright 2024 Mike Frysinger <vapier@gentoo.org>
+# Copyright 2024 The ChromiumOS Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# Deps needed to run Python scripts after installed.
+# https://pip.pypa.io/en/stable/reference/requirements-file-format/
+
+pyelftools
diff --git a/scanelf.c b/scanelf.c
index 440a193..0ee1bad 100644
--- a/scanelf.c
+++ b/scanelf.c
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2012 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org>
*/
const char argv0[] = "scanelf";
@@ -315,9 +315,9 @@ static void scanelf_file_get_symtabs(elfobj *elf, const void **sym, const void *
Elf32_Word sym_idx; \
Elf32_Word chained; \
\
- if (!VALID_RANGE(elf, offset, nbuckets * 4)) \
+ if (!VALID_RANGE(elf, hash_offset, nbuckets * (uint64_t)4)) \
goto corrupt_hash; \
- if (!VALID_RANGE(elf, offset, nchains * 4)) \
+ if (!VALID_RANGE(elf, hash_offset, nchains * (uint64_t)4)) \
goto corrupt_hash; \
\
for (b = 0; b < nbuckets; ++b) { \
@@ -707,7 +707,8 @@ static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char
printf("%s", elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
else \
printf("(memory/data?)"); \
- printf(" [0x%lX]", (unsigned long)r_offset); \
+ printf(" [r_offset=0x%lX]", (unsigned long)r_offset); \
+ printf(" r_type=%lu", (unsigned long)ELF ## B ## _ST_TYPE(r_info)); \
/* now try to find the closest symbol that this rel is probably in */ \
sym = SYM ## B (elf->vdata + EGET(symtab->sh_offset)); \
func = NULL; \
@@ -730,9 +731,9 @@ static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char
} else \
printf("(missing symbols)"); \
} else \
- printf("(optimized out)"); \
- printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
- if (be_verbose && objdump) { \
+ printf("(optimized out?)"); \
+ printf(" [closest_prev_sym=0x%lX]\n", (unsigned long)offset_tmp); \
+ if (be_verbose && objdump && func) { \
Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \
char *sysbuf; \
int ret; \
@@ -760,7 +761,7 @@ static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char
if (symtab_void && elf->phdr)
SCANELF_ELF_SIZED(SHOW_TEXTRELS);
if (!*found_textrels)
- warnf("ELF %s has TEXTREL markings but doesnt appear to have any real TEXTREL's !?", elf->filename);
+ warnf("ELF %s has TEXTREL markings but doesn't appear to have any real TEXTREL's !?", elf->filename);
return NULL;
}
@@ -1153,7 +1154,7 @@ static const char *scanelf_file_soname(elfobj *elf, char *found_soname)
* STV group: STV_DEFAULT:p STV_INTERNAL:i STV_HIDDEN:h STV_PROTECTED:P
* SHN group: SHN_UNDEF:u SHN_ABS:a SHN_COMMON:c {defined}:d
* The "defined" value in the SHN group does not correspond to a SHN_xxx define.
- * You can search for multiple symbols at once by seperating with a comma (",").
+ * You can search for multiple symbols at once by separating with a comma (",").
*
* Some examples:
* ELFs with a weak function "foo":
@@ -1827,10 +1828,10 @@ static void scanelf_envpath(void)
/* usage / invocation handling functions */ /* Free Flags: c d j u w G H J K P Q U W */
#define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DIYO:ZCBhV"
-#define a_argument required_argument
static struct option const long_opts[] = {
{"path", no_argument, NULL, 'p'},
{"ldpath", no_argument, NULL, 'l'},
+ {"ldcache", a_argument, NULL, 130},
{"use-ldpath",no_argument, NULL, 129},
{"root", a_argument, NULL, 128},
{"recursive", no_argument, NULL, 'R'},
@@ -1876,6 +1877,7 @@ static struct option const long_opts[] = {
static const char * const opts_help[] = {
"Scan all directories in PATH environment",
"Scan all directories in /etc/ld.so.conf",
+ "Use alternate ld.so.cache specified in <arg>",
"Use ld.so.conf to show full path (use with -r/-n)",
"Root directory (use with -l or -p)",
"Scan directories recursively",
@@ -1921,46 +1923,16 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- const char a_arg[] = "<arg>";
- size_t a_arg_len = strlen(a_arg) + 2;
- size_t i;
- int optlen;
- printf("* Scan ELF binaries for stuff\n\n"
- "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0);
- printf("Options: -[%s]\n", PARSE_FLAGS);
-
- /* prescan the --long opt length to auto-align */
- optlen = 0;
- for (i = 0; long_opts[i].name; ++i) {
- int l = strlen(long_opts[i].name);
- if (long_opts[i].has_arg == a_argument)
- l += a_arg_len;
- optlen = max(l, optlen);
- }
-
- for (i = 0; long_opts[i].name; ++i) {
- /* first output the short flag if it has one */
- if (long_opts[i].val > '~')
- printf(" ");
- else
- printf(" -%c, ", long_opts[i].val);
-
- /* then the long flag */
- if (long_opts[i].has_arg == no_argument)
- printf("--%-*s", optlen, long_opts[i].name);
- else
- printf("--%s %s %*s", long_opts[i].name, a_arg,
- (int)(optlen - strlen(long_opts[i].name) - a_arg_len), "");
-
- /* finally the help text */
- printf("* %s\n", opts_help[i]);
- }
-
- puts("\nFor more information, see the scanelf(1) manpage");
- exit(status);
+ pax_usage(
+ "Scan ELF binaries for stuff",
+ "<dir1/file1> [dir2 dirN file2 fileN ...]",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
-/* parse command line arguments and preform needed actions */
+/* parse command line arguments and perform needed actions */
#define do_pax_state(option, flag) \
if (islower(option)) { \
flags &= ~PF_##flag; \
@@ -2119,6 +2091,7 @@ static int parseargs(int argc, char *argv[])
err("Could not open root: %s", optarg);
break;
case 129: load_cache_config = use_ldpath = 1; break;
+ case 130: ldcache_path = optarg; break;
case ':':
err("Option '%c' is missing parameter", optopt);
case '?':
diff --git a/scanmacho.c b/scanmacho.c
index 71b1593..d33a440 100644
--- a/scanmacho.c
+++ b/scanmacho.c
@@ -1,12 +1,12 @@
/*
- * Copyright 2008-2012 Gentoo Foundation
+ * Copyright 2008-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* based on scanelf by:
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org>
* for Darwin specific fun:
- * 2008-2013 Fabian Groffen - <grobian@gentoo.org>
+ * 2008-2021 Fabian Groffen - <grobian@gentoo.org>
*/
const char argv0[] = "scanmacho";
@@ -37,6 +37,7 @@ static char show_rpath = 0;
static char show_needed = 0;
static char show_interp = 0;
static char show_bind = 0;
+static char show_uuid = 0;
static char show_soname = 0;
static char show_banner = 1;
static char show_endian = 0;
@@ -181,18 +182,54 @@ static char *macho_file_soname(fatobj *fobj, char *found_soname)
return NULL;
}
+static char *macho_file_uuid(fatobj *fobj, char *found_uuid)
+{
+ loadcmd *lcmd;
+ uint32_t lc_uuid;
+ static char uuid_buf[32 + 4 + 1];
+
+ if (!show_uuid)
+ return NULL;
+
+ lcmd = firstloadcmd(fobj);
+ lc_uuid = MGET(fobj->swapped, LC_UUID);
+
+ do {
+ if (lcmd->lcmd->cmd == lc_uuid) {
+ struct uuid_command *ucmd = lcmd->data;
+ unsigned char *uuid;
+ uuid = (unsigned char *)(ucmd->uuid);
+ *found_uuid = 1;
+ free(lcmd);
+ if (be_wewy_wewy_quiet)
+ return NULL;
+ snprintf(uuid_buf, sizeof(uuid_buf),
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
+ "%02x%02x%02x%02x%02x%02x",
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5],
+ uuid[6], uuid[7],
+ uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
+ return uuid_buf;
+ }
+ } while (nextloadcmd(lcmd));
+
+ return NULL;
+}
+
/* scan a macho file and show all the fun stuff */
#define prints(str) ({ ssize_t ret = write(fileno(stdout), str, strlen(str)); ret; })
static int scanmacho_fatobj(fatobj *fobj)
{
unsigned long i;
char found_rpath, found_needed, found_interp, found_soname,
- found_lib, found_file;
+ found_lib, found_file, found_uuid;
static char *out_buffer = NULL;
static size_t out_len;
found_rpath = found_needed = found_interp = found_soname = \
- found_lib = found_file = 0;
+ found_lib = found_file = found_uuid = 0;
if (be_verbose > 2)
printf("%s: scanning file {%s,%s}\n", fobj->filename,
@@ -228,6 +265,7 @@ static int scanmacho_fatobj(fatobj *fobj)
case 'b': prints("FLAGS "); break;
case 'Z': prints("SIZE "); break;
case 'S': prints("INSTALLNAME "); break;
+ case 'U': prints("UUID "); break;
case 'N': prints("LIB "); break;
case 'a': prints("ARCH "); break;
case 'O': prints("PERM "); break;
@@ -293,6 +331,7 @@ static int scanmacho_fatobj(fatobj *fobj)
case 'i': out = macho_file_interp(fobj, &found_interp); break;
case 'b': get_machomhflags(fobj, &out_buffer, &out_len); break;
case 'S': out = macho_file_soname(fobj, &found_soname); break;
+ case 'U': out = macho_file_uuid(fobj, &found_uuid); break;
case 'a': out = get_machomtype(fobj); break;
case 'Z': snprintf(ubuf, sizeof(ubuf), "%llu", (unsigned long long int)fobj->len); out = ubuf; break;;
default: warnf("'%c' has no scan code?", out_format[i]);
@@ -532,9 +571,8 @@ static void scanmacho_envpath(void)
free(path);
}
-/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T U W X Y */
-#define PARSE_FLAGS "pRmyArnibSN:gE:M:DO:ZaqvF:f:o:CBhV"
-#define a_argument required_argument
+/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T W X Y */
+#define PARSE_FLAGS "pRmyArnibSUN:gE:M:DO:ZaqvF:f:o:CBhV"
static struct option const long_opts[] = {
{"path", no_argument, NULL, 'p'},
{"recursive", no_argument, NULL, 'R'},
@@ -546,6 +584,7 @@ static struct option const long_opts[] = {
{"interp", no_argument, NULL, 'i'},
{"bind", no_argument, NULL, 'b'},
{"soname", no_argument, NULL, 'S'},
+ {"uuid", no_argument, NULL, 'U'},
{"lib", a_argument, NULL, 'N'},
{"gmatch", no_argument, NULL, 'g'},
{"etype", a_argument, NULL, 'E'},
@@ -577,10 +616,11 @@ static const char * const opts_help[] = {
"Print LC_LOAD_DYLINKER information (ELF: INTERP)",
"Print flags from mach_header (ELF: BIND)",
"Print LC_ID_DYLIB information (ELF: SONAME)",
+ "Print LC_UUID information",
"Find a specified library",
"Use strncmp to match libraries. (use with -N)",
"Print only Mach-O files matching mach_header\n"
- " MH_OBJECT,MH_EXECUTE ... (ELF: etype)",
+ " MH_OBJECT,MH_EXECUTE ... (ELF: etype)",
"Print only Mach-O files matching numeric bits",
"Print Endianness",
"Print only Mach-O files matching octal permissions",
@@ -601,23 +641,16 @@ static const char * const opts_help[] = {
/* display usage and exit */
static void usage(int status)
{
- unsigned long i;
- printf("* Scan Mach-O binaries for stuff\n\n"
- "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0);
- printf("Options: -[%s]\n", PARSE_FLAGS);
- for (i = 0; long_opts[i].name; ++i)
- if (long_opts[i].has_arg == no_argument)
- printf(" -%c, --%-14s* %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
- else
- printf(" -%c, --%-7s <arg> * %s\n", long_opts[i].val,
- long_opts[i].name, opts_help[i]);
-
- puts("\nFor more information, see the scanmacho(1) manpage");
- exit(status);
+ pax_usage(
+ "Scan Mach-O binaries for stuff",
+ "<dir1/file1> [dir2 dirN file2 fileN ...]",
+ PARSE_FLAGS,
+ long_opts,
+ opts_help,
+ status);
}
-/* parse command line arguments and preform needed actions */
+/* parse command line arguments and perform needed actions */
static int parseargs(int argc, char *argv[])
{
int i;
@@ -678,6 +711,7 @@ static int parseargs(int argc, char *argv[])
case 'i': show_interp = 1; break;
case 'b': show_bind = 1; break;
case 'S': show_soname = 1; break;
+ case 'U': show_uuid = 1; break;
case 'q': be_quiet = 1; break;
case 'v': be_verbose = (be_verbose % 20) + 1; break;
case 'a': show_perms = show_endian = show_bind = 1; break;
@@ -717,6 +751,7 @@ static int parseargs(int argc, char *argv[])
case 'i': show_interp = 1; break;
case 'b': show_bind = 1; break;
case 'S': show_soname = 1; break;
+ case 'U': show_uuid = 1; break;
default:
err("Invalid format specifier '%c' (byte %i)",
out_format[i], i+1);
@@ -738,6 +773,7 @@ static int parseargs(int argc, char *argv[])
if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);
if (show_bind) xstrcat(&out_format, "%b ", &fmt_len);
if (show_soname) xstrcat(&out_format, "%S ", &fmt_len);
+ if (show_uuid) xstrcat(&out_format, "%U ", &fmt_len);
if (find_lib) xstrcat(&out_format, "%N ", &fmt_len);
if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len);
}
diff --git a/seccomp-bpf.c b/seccomp-bpf.c
new file mode 100644
index 0000000..b56e9e4
--- /dev/null
+++ b/seccomp-bpf.c
@@ -0,0 +1,277 @@
+/*
+ * Generate the bpf rules ahead of time to speed up runtime.
+ *
+ * Copyright 2015-2024 Gentoo Foundation
+ * Distributed under the terms of the GNU General Public License v2
+ *
+ * Copyright 2015-2024 Mike Frysinger - <vapier@gentoo.org>
+ */
+
+const char argv0[] = "seccomp-bpf";
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include <seccomp.h>
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+static const struct {
+ const char *name;
+ uint32_t arch;
+ const char *ifdef;
+} gen_seccomp_arches[] = {
+#define A(arch, ifdef) { #arch, SCMP_ARCH_##arch, ifdef }
+ A(AARCH64, "defined(__aarch64__)"),
+ A(ARM, "defined(__arm__)"),
+ A(MIPS, "defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIO32)"),
+ A(MIPS64, "defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABI64)"),
+ A(MIPS64N32, "defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIN32)"),
+ A(MIPSEL, "defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIO32)"),
+ A(MIPSEL64, "defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABI64)"),
+ A(MIPSEL64N32, "defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIN32)"),
+ A(PARISC, "defined(__hppa__) && !defined(__hppa64__)"),
+ A(PARISC64, "defined(__hppa__) && defined(__hppa64__)"),
+ A(PPC, "defined(__powerpc__) && !defined(__powerpc64__) && defined(__BIG_ENDIAN__)"),
+ A(PPC64, "defined(__powerpc__) && defined(__powerpc64__) && defined(__BIG_ENDIAN__)"),
+ A(PPC64LE, "defined(__powerpc__) && defined(__powerpc64__) && !defined(__BIG_ENDIAN__)"),
+ A(RISCV64, "defined(__riscv) && __riscv_xlen == 64"),
+ A(S390, "defined(__s390__) && !defined(__s390x__)"),
+ A(S390X, "defined(__s390__) && defined(__s390x__)"),
+ A(X86, "defined(__i386__)"),
+ A(X32, "defined(__x86_64__) && defined(__ILP32__)"),
+ A(X86_64, "defined(__x86_64__) && !defined(__ILP32__)"),
+#undef A
+};
+
+/* Simple helper to add all of the syscalls in an array. */
+static int gen_seccomp_rules_add(scmp_filter_ctx ctx, const int syscalls[], size_t num)
+{
+ static uint8_t prio;
+ size_t i;
+ for (i = 0; i < num; ++i) {
+ if (seccomp_syscall_priority(ctx, syscalls[i], prio++) < 0) {
+ warn("seccomp_syscall_priority failed");
+ return -1;
+ }
+ if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) < 0) {
+ warn("seccomp_rule_add failed");
+ return -1;
+ }
+ }
+ return 0;
+}
+#define gen_seccomp_rules_add(ctx, syscalls) gen_seccomp_rules_add(ctx, syscalls, ARRAY_SIZE(syscalls))
+
+static void gen_seccomp_dump(scmp_filter_ctx ctx, const char *name)
+{
+ unsigned char buf[32768 * 8];
+ ssize_t i, len;
+ int fd;
+
+ fd = memfd_create("bpf", MFD_CLOEXEC);
+ if (fd < 0)
+ err(1, "memfd_create failed");
+ if (seccomp_export_bpf(ctx, fd) < 0)
+ err(1, "seccomp_export_bpf_mem failed");
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ err(1, "seek failed");
+ len = read(fd, buf, sizeof(buf));
+ if (len <= 0)
+ err(1, "read failed");
+
+ printf("static const unsigned char seccomp_bpf_blks_%s[] = {\n\t", name);
+ for (i = 0; i < len; ++i)
+ printf("%u,", buf[i]);
+ printf("\n};\n");
+}
+
+static void gen_seccomp_program(const char *name)
+{
+ printf(
+ "static const seccomp_bpf_program_t seccomp_bpf_program_%s = {\n"
+ " .cnt = sizeof(seccomp_bpf_blks_%s) / 8,\n"
+ " .bpf = seccomp_bpf_blks_%s,\n"
+ "};\n", name, name, name);
+}
+
+int main(void)
+{
+ /* Order determines priority (first == lowest prio). */
+ static const int base_syscalls[] = {
+ /* We write the most w/scanelf. */
+ SCMP_SYS(write),
+ SCMP_SYS(writev),
+ SCMP_SYS(pwrite64),
+ SCMP_SYS(pwritev),
+
+ /* Then the stat family of functions. */
+ SCMP_SYS(newfstatat),
+ SCMP_SYS(fstat),
+ SCMP_SYS(fstat64),
+ SCMP_SYS(fstatat64),
+ SCMP_SYS(lstat),
+ SCMP_SYS(lstat64),
+ SCMP_SYS(stat),
+ SCMP_SYS(stat64),
+ SCMP_SYS(statx),
+
+ /* Then the fd close func. */
+ SCMP_SYS(close),
+
+ /* Then fd open family of functions. */
+ SCMP_SYS(open),
+ SCMP_SYS(openat),
+
+ /* Then the memory mapping functions. */
+ SCMP_SYS(mmap),
+ SCMP_SYS(mmap2),
+ SCMP_SYS(munmap),
+
+ /* Then the directory reading functions. */
+ SCMP_SYS(getdents),
+ SCMP_SYS(getdents64),
+
+ /* Then the file reading functions. */
+ SCMP_SYS(pread64),
+ SCMP_SYS(read),
+ SCMP_SYS(readv),
+ SCMP_SYS(preadv),
+
+ /* Then the fd manipulation functions. */
+ SCMP_SYS(fcntl),
+ SCMP_SYS(fcntl64),
+
+ /* After this point, just sort the list alphabetically. */
+ SCMP_SYS(access),
+ SCMP_SYS(brk),
+ SCMP_SYS(capget),
+ SCMP_SYS(chdir),
+ SCMP_SYS(dup),
+ SCMP_SYS(dup2),
+ SCMP_SYS(dup3),
+ SCMP_SYS(exit),
+ SCMP_SYS(exit_group),
+ SCMP_SYS(faccessat),
+#ifndef __SNR_faccessat2
+/* faccessat2 is not yet defined in libseccomp-2.5.1 */
+# define __SNR_faccessat2 __NR_faccessat2
+#endif
+ SCMP_SYS(faccessat2),
+ SCMP_SYS(fchdir),
+ SCMP_SYS(getpid),
+ SCMP_SYS(gettid),
+ SCMP_SYS(ioctl),
+ SCMP_SYS(lseek),
+ SCMP_SYS(_llseek),
+ SCMP_SYS(mprotect),
+
+ /* Syscalls listed because of compiler settings. */
+ SCMP_SYS(futex),
+
+ /* Syscalls listed because of sandbox. */
+ SCMP_SYS(readlink),
+ SCMP_SYS(readlinkat),
+ SCMP_SYS(getcwd),
+
+ /* Syscalls listed because of fakeroot. */
+ SCMP_SYS(msgget),
+ SCMP_SYS(msgrcv),
+ SCMP_SYS(msgsnd),
+ SCMP_SYS(semget),
+ SCMP_SYS(semop),
+ SCMP_SYS(semtimedop),
+ /*
+ * Some targets (e.g. ppc & i386) implement the above functions
+ * as ipc() subcalls. #675378
+ */
+ SCMP_SYS(ipc),
+
+ /* glibc-2.34+ uses it as part of mem alloc functions. */
+ SCMP_SYS(getrandom),
+
+ /* glibc-2.35+ uses it when GLIBC_TUNABLES=glibc.malloc.hugetlb=1. */
+ SCMP_SYS(madvise),
+ };
+ static const int fork_syscalls[] = {
+ SCMP_SYS(clone),
+ SCMP_SYS(execve),
+ SCMP_SYS(fork),
+ SCMP_SYS(rt_sigaction),
+ SCMP_SYS(rt_sigprocmask),
+ SCMP_SYS(unshare),
+ SCMP_SYS(vfork),
+ SCMP_SYS(wait4),
+ SCMP_SYS(waitid),
+ SCMP_SYS(waitpid),
+ };
+
+ /* TODO: Handle debug and KILL vs TRAP. */
+
+ scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
+ if (!ctx)
+ err(1, "seccomp_init failed");
+
+ printf("/* AUTO GENERATED FILE. To regenerate run:\n");
+ printf(" * $ $EDITOR seccomp-bpf.c\n");
+ printf(" * $ make seccomp-bpf.h\n");
+ printf(" * See seccomp-bpf.c for details. */\n");
+ printf("#undef SECCOMP_BPF_AVAILABLE\n");
+
+ if (seccomp_arch_remove(ctx, seccomp_arch_native()) < 0)
+ err(1, "seccomp_arch_remove failed");
+
+ for (size_t i = 0; i < ARRAY_SIZE(gen_seccomp_arches); ++i) {
+ uint32_t arch = gen_seccomp_arches[i].arch;
+
+ seccomp_reset(ctx, SCMP_ACT_KILL);
+
+ if (arch != seccomp_arch_native()) {
+ if (seccomp_arch_remove(ctx, seccomp_arch_native()) < 0)
+ err(1, "seccomp_arch_remove failed");
+ if (seccomp_arch_add(ctx, arch) < 0)
+ err(1, "seccomp_arch_add failed");
+ }
+
+ printf("\n#if %s\n", gen_seccomp_arches[i].ifdef);
+ printf("/* %s */\n", gen_seccomp_arches[i].name);
+ printf("#define SECCOMP_BPF_AVAILABLE\n");
+
+ if (gen_seccomp_rules_add(ctx, base_syscalls) < 0)
+ err(1, "seccomp_rules_add failed");
+ gen_seccomp_dump(ctx, "base");
+
+ if (gen_seccomp_rules_add(ctx, fork_syscalls) < 0)
+ err(1, "seccomp_rules_add failed");
+ gen_seccomp_dump(ctx, "fork");
+
+ if (0) {
+ printf("/*\n");
+ fflush(stdout);
+ seccomp_export_pfc(ctx, 1);
+ fflush(stdout);
+ printf("*/\n");
+ }
+
+ printf("#endif\n");
+ }
+
+ printf(
+ "\n"
+ "#ifdef SECCOMP_BPF_AVAILABLE\n"
+ "typedef struct {\n"
+ " uint16_t cnt;\n"
+ " const void *bpf;\n"
+ "} seccomp_bpf_program_t;\n");
+ gen_seccomp_program("base");
+ gen_seccomp_program("fork");
+ printf("#endif\n");
+
+ seccomp_release(ctx);
+
+ return 0;
+}
diff --git a/seccomp-bpf.h b/seccomp-bpf.h
new file mode 100644
index 0000000..80d6d94
--- /dev/null
+++ b/seccomp-bpf.h
@@ -0,0 +1,229 @@
+/* AUTO GENERATED FILE. To regenerate run:
+ * $ $EDITOR seccomp-bpf.c
+ * $ make seccomp-bpf.h
+ * See seccomp-bpf.c for details. */
+#undef SECCOMP_BPF_AVAILABLE
+
+#if defined(__aarch64__)
+/* AARCH64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,45,183,0,0,192,32,0,0,0,0,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,52,183,0,0,192,32,0,0,0,0,0,0,0,21,0,49,0,95,0,0,0,21,0,48,0,4,1,0,0,21,0,47,0,97,0,0,0,21,0,46,0,135,0,0,0,21,0,45,0,134,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,220,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__arm__)
+/* ARM */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,57,40,0,0,64,32,0,0,0,0,0,0,0,21,0,54,0,220,0,0,0,21,0,53,0,128,1,0,0,21,0,52,0,56,1,0,0,21,0,51,0,42,1,0,0,21,0,50,0,43,1,0,0,21,0,49,0,45,1,0,0,21,0,48,0,46,1,0,0,21,0,47,0,47,1,0,0,21,0,46,0,183,0,0,0,21,0,45,0,76,1,0,0,21,0,44,0,85,0,0,0,21,0,43,0,240,0,0,0,21,0,42,0,125,0,0,0,21,0,41,0,140,0,0,0,21,0,40,0,19,0,0,0,21,0,39,0,54,0,0,0,21,0,38,0,224,0,0,0,21,0,37,0,20,0,0,0,21,0,36,0,133,0,0,0,21,0,35,0,183,1,0,0,21,0,34,0,78,1,0,0,21,0,33,0,248,0,0,0,21,0,32,0,1,0,0,0,21,0,31,0,102,1,0,0,21,0,30,0,63,0,0,0,21,0,29,0,41,0,0,0,21,0,28,0,12,0,0,0,21,0,27,0,184,0,0,0,21,0,26,0,45,0,0,0,21,0,25,0,33,0,0,0,21,0,24,0,221,0,0,0,21,0,23,0,55,0,0,0,21,0,22,0,105,1,0,0,21,0,21,0,145,0,0,0,21,0,20,0,3,0,0,0,21,0,19,0,180,0,0,0,21,0,18,0,217,0,0,0,21,0,17,0,141,0,0,0,21,0,16,0,91,0,0,0,21,0,15,0,192,0,0,0,21,0,14,0,66,1,0,0,21,0,13,0,5,0,0,0,21,0,12,0,6,0,0,0,21,0,11,0,141,1,0,0,21,0,10,0,195,0,0,0,21,0,9,0,106,0,0,0,21,0,8,0,196,0,0,0,21,0,7,0,107,0,0,0,21,0,6,0,71,1,0,0,21,0,5,0,197,0,0,0,21,0,4,0,108,0,0,0,21,0,3,0,106,1,0,0,21,0,2,0,181,0,0,0,21,0,1,0,146,0,0,0,21,0,0,1,4,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,66,40,0,0,64,32,0,0,0,0,0,0,0,21,0,63,0,24,1,0,0,21,0,62,0,114,0,0,0,21,0,61,0,190,0,0,0,21,0,60,0,81,1,0,0,21,0,59,0,175,0,0,0,21,0,58,0,174,0,0,0,21,0,57,0,2,0,0,0,21,0,56,0,11,0,0,0,21,0,55,0,120,0,0,0,21,0,54,0,220,0,0,0,21,0,53,0,128,1,0,0,21,0,52,0,56,1,0,0,21,0,51,0,42,1,0,0,21,0,50,0,43,1,0,0,21,0,49,0,45,1,0,0,21,0,48,0,46,1,0,0,21,0,47,0,47,1,0,0,21,0,46,0,183,0,0,0,21,0,45,0,76,1,0,0,21,0,44,0,85,0,0,0,21,0,43,0,240,0,0,0,21,0,42,0,125,0,0,0,21,0,41,0,140,0,0,0,21,0,40,0,19,0,0,0,21,0,39,0,54,0,0,0,21,0,38,0,224,0,0,0,21,0,37,0,20,0,0,0,21,0,36,0,133,0,0,0,21,0,35,0,183,1,0,0,21,0,34,0,78,1,0,0,21,0,33,0,248,0,0,0,21,0,32,0,1,0,0,0,21,0,31,0,102,1,0,0,21,0,30,0,63,0,0,0,21,0,29,0,41,0,0,0,21,0,28,0,12,0,0,0,21,0,27,0,184,0,0,0,21,0,26,0,45,0,0,0,21,0,25,0,33,0,0,0,21,0,24,0,221,0,0,0,21,0,23,0,55,0,0,0,21,0,22,0,105,1,0,0,21,0,21,0,145,0,0,0,21,0,20,0,3,0,0,0,21,0,19,0,180,0,0,0,21,0,18,0,217,0,0,0,21,0,17,0,141,0,0,0,21,0,16,0,91,0,0,0,21,0,15,0,192,0,0,0,21,0,14,0,66,1,0,0,21,0,13,0,5,0,0,0,21,0,12,0,6,0,0,0,21,0,11,0,141,1,0,0,21,0,10,0,195,0,0,0,21,0,9,0,106,0,0,0,21,0,8,0,196,0,0,0,21,0,7,0,107,0,0,0,21,0,6,0,71,1,0,0,21,0,5,0,197,0,0,0,21,0,4,0,108,0,0,0,21,0,3,0,106,1,0,0,21,0,2,0,181,0,0,0,21,0,1,0,146,0,0,0,21,0,0,1,4,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIO32)
+/* MIPS */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,57,0,0,0,8,0,32,0,0,0,0,0,0,0,21,54,0,0,0,16,122,0,21,53,0,0,0,17,1,0,21,52,0,0,0,16,21,0,21,51,0,0,0,16,107,0,21,50,0,0,0,16,202,0,21,49,0,0,0,15,245,0,21,48,0,0,0,16,142,0,21,47,0,0,0,16,29,0,21,46,0,0,0,16,44,0,21,45,0,0,0,15,179,0,21,44,0,0,0,15,214,0,21,43,0,0,0,16,126,0,21,42,0,0,0,15,180,0,21,41,0,0,0,16,37,0,21,40,0,0,0,17,87,0,21,39,0,0,0,16,204,0,21,38,0,0,0,16,150,0,21,37,0,0,0,15,161,0,21,36,0,0,0,16,231,0,21,35,0,0,0,15,223,0,21,34,0,0,0,15,201,0,21,33,0,0,0,15,172,0,21,32,0,0,0,16,108,0,21,31,0,0,0,15,205,0,21,30,0,0,0,15,193,0,21,29,0,0,0,16,124,0,21,28,0,0,0,15,215,0,21,27,0,0,0,16,234,0,21,26,0,0,0,16,49,0,21,25,0,0,0,15,163,0,21,24,0,0,0,16,104,0,21,23,0,0,0,16,123,0,21,22,0,0,0,16,45,0,21,21,0,0,0,15,251,0,21,20,0,0,0,16,114,0,21,19,0,0,0,15,250,0,21,18,0,0,0,16,192,0,21,17,0,0,0,15,165,0,21,16,0,0,0,15,166,0,21,15,0,0,0,17,14,0,21,14,0,0,0,16,117,0,21,13,0,0,0,16,10,0,21,12,0,0,0,16,118,0,21,11,0,0,0,16,11,0,21,10,0,0,0,16,197,0,21,9,0,0,0,16,119,0,21,8,0,0,0,16,12,0,21,7,0,0,0,16,235,0,21,6,0,0,0,16,105,0,21,5,0,0,0,16,50,0,21,4,0,0,0,15,164,0,21,3,0,0,0,17,41,0,21,2,0,0,0,17,47,0,21,1,0,0,0,17,48,0,21,0,1,0,0,17,49,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,66,0,0,0,8,0,32,0,0,0,0,0,0,0,21,63,0,0,0,15,167,0,21,62,0,0,0,16,182,0,21,61,0,0,0,16,18,0,21,60,0,0,0,16,207,0,21,59,0,0,0,16,99,0,21,58,0,0,0,16,98,0,21,57,0,0,0,15,162,0,21,56,0,0,0,15,171,0,21,55,0,0,0,16,24,0,21,54,0,0,0,16,122,0,21,53,0,0,0,17,1,0,21,52,0,0,0,16,21,0,21,51,0,0,0,16,107,0,21,50,0,0,0,16,202,0,21,49,0,0,0,15,245,0,21,48,0,0,0,16,142,0,21,47,0,0,0,16,29,0,21,46,0,0,0,16,44,0,21,45,0,0,0,15,179,0,21,44,0,0,0,15,214,0,21,43,0,0,0,16,126,0,21,42,0,0,0,15,180,0,21,41,0,0,0,16,37,0,21,40,0,0,0,17,87,0,21,39,0,0,0,16,204,0,21,38,0,0,0,16,150,0,21,37,0,0,0,15,161,0,21,36,0,0,0,16,231,0,21,35,0,0,0,15,223,0,21,34,0,0,0,15,201,0,21,33,0,0,0,15,172,0,21,32,0,0,0,16,108,0,21,31,0,0,0,15,205,0,21,30,0,0,0,15,193,0,21,29,0,0,0,16,124,0,21,28,0,0,0,15,215,0,21,27,0,0,0,16,234,0,21,26,0,0,0,16,49,0,21,25,0,0,0,15,163,0,21,24,0,0,0,16,104,0,21,23,0,0,0,16,123,0,21,22,0,0,0,16,45,0,21,21,0,0,0,15,251,0,21,20,0,0,0,16,114,0,21,19,0,0,0,15,250,0,21,18,0,0,0,16,192,0,21,17,0,0,0,15,165,0,21,16,0,0,0,15,166,0,21,15,0,0,0,17,14,0,21,14,0,0,0,16,117,0,21,13,0,0,0,16,10,0,21,12,0,0,0,16,118,0,21,11,0,0,0,16,11,0,21,10,0,0,0,16,197,0,21,9,0,0,0,16,119,0,21,8,0,0,0,16,12,0,21,7,0,0,0,16,235,0,21,6,0,0,0,16,105,0,21,5,0,0,0,16,50,0,21,4,0,0,0,15,164,0,21,3,0,0,0,17,41,0,21,2,0,0,0,17,47,0,21,1,0,0,0,17,48,0,21,0,1,0,0,17,49,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABI64)
+/* MIPS64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,52,128,0,0,8,0,32,0,0,0,0,0,0,0,21,49,0,0,0,19,203,0,21,48,0,0,0,19,204,0,21,47,0,0,0,19,202,0,21,46,0,0,0,19,213,0,21,45,0,0,0,20,137,0,21,44,0,0,0,19,223,0,21,43,0,0,0,20,74,0,21,42,0,0,0,19,146,0,21,41,0,0,0,19,144,0,21,40,0,0,0,19,151,0,21,39,0,0,0,20,58,0,21,38,0,0,0,19,174,0,21,37,0,0,0,19,215,0,21,36,0,0,0,21,63,0,21,35,0,0,0,20,139,0,21,34,0,0,0,20,85,0,21,33,0,0,0,19,194,0,21,32,0,0,0,20,166,0,21,31,0,0,0,19,168,0,21,30,0,0,0,19,167,0,21,29,0,0,0,19,214,0,21,28,0,0,0,20,3,0,21,27,0,0,0,19,148,0,21,26,0,0,0,19,156,0,21,25,0,0,0,19,206,0,21,24,0,0,0,20,169,0,21,23,0,0,0,19,154,0,21,22,0,0,0,19,136,0,21,21,0,0,0,19,152,0,21,20,0,0,0,20,188,0,21,19,0,0,0,19,212,0,21,18,0,0,0,19,147,0,21,17,0,0,0,19,145,0,21,16,0,0,0,20,127,0,21,15,0,0,0,19,138,0,21,14,0,0,0,19,139,0,21,13,0,0,0,20,206,0,21,12,0,0,0,19,140,0,21,11,0,0,0,19,142,0,21,10,0,0,0,19,141,0,21,9,0,0,0,20,132,0,21,8,0,0,0,20,170,0,21,7,0,0,0,19,153,0,21,6,0,0,0,19,155,0,21,5,0,0,0,19,137,0,21,4,0,0,0,19,163,0,21,3,0,0,0,20,193,0,21,2,0,0,0,20,94,0,21,1,0,0,0,19,199,0,21,0,1,0,0,19,198,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,60,128,0,0,8,0,32,0,0,0,0,0,0,0,21,57,0,0,0,19,203,0,21,56,0,0,0,19,204,0,21,55,0,0,0,19,202,0,21,54,0,0,0,19,213,0,21,53,0,0,0,20,137,0,21,52,0,0,0,19,223,0,21,51,0,0,0,20,74,0,21,50,0,0,0,19,146,0,21,49,0,0,0,19,144,0,21,48,0,0,0,19,151,0,21,47,0,0,0,20,58,0,21,46,0,0,0,19,174,0,21,45,0,0,0,19,215,0,21,44,0,0,0,21,63,0,21,43,0,0,0,20,139,0,21,42,0,0,0,20,85,0,21,41,0,0,0,19,194,0,21,40,0,0,0,20,166,0,21,39,0,0,0,19,168,0,21,38,0,0,0,19,167,0,21,37,0,0,0,19,214,0,21,36,0,0,0,20,3,0,21,35,0,0,0,19,148,0,21,34,0,0,0,19,156,0,21,33,0,0,0,19,206,0,21,32,0,0,0,20,169,0,21,31,0,0,0,19,154,0,21,30,0,0,0,19,136,0,21,29,0,0,0,19,152,0,21,28,0,0,0,20,188,0,21,27,0,0,0,19,212,0,21,26,0,0,0,19,147,0,21,25,0,0,0,19,145,0,21,24,0,0,0,20,127,0,21,23,0,0,0,19,138,0,21,22,0,0,0,19,139,0,21,21,0,0,0,20,206,0,21,20,0,0,0,19,140,0,21,19,0,0,0,19,142,0,21,18,0,0,0,19,141,0,21,17,0,0,0,20,132,0,21,16,0,0,0,20,170,0,21,15,0,0,0,19,153,0,21,14,0,0,0,19,155,0,21,13,0,0,0,19,137,0,21,12,0,0,0,20,117,0,21,11,0,0,0,19,195,0,21,10,0,0,0,20,142,0,21,9,0,0,0,19,150,0,21,8,0,0,0,19,149,0,21,7,0,0,0,19,192,0,21,6,0,0,0,19,193,0,21,5,0,0,0,19,191,0,21,4,0,0,0,19,163,0,21,3,0,0,0,20,193,0,21,2,0,0,0,20,94,0,21,1,0,0,0,19,199,0,21,0,1,0,0,19,198,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIN32)
+/* MIPS64N32 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,53,160,0,0,8,0,32,0,0,0,0,0,0,0,21,50,0,0,0,23,139,0,21,49,0,0,0,24,173,0,21,48,0,0,0,24,71,0,21,47,0,0,0,23,175,0,21,46,0,0,0,23,174,0,21,45,0,0,0,23,179,0,21,44,0,0,0,23,180,0,21,43,0,0,0,23,178,0,21,42,0,0,0,23,189,0,21,41,0,0,0,24,117,0,21,40,0,0,0,23,199,0,21,39,0,0,0,24,50,0,21,38,0,0,0,23,122,0,21,37,0,0,0,23,120,0,21,36,0,0,0,23,127,0,21,35,0,0,0,24,34,0,21,34,0,0,0,23,150,0,21,33,0,0,0,23,191,0,21,32,0,0,0,25,39,0,21,31,0,0,0,24,119,0,21,30,0,0,0,24,61,0,21,29,0,0,0,23,170,0,21,28,0,0,0,24,146,0,21,27,0,0,0,23,144,0,21,26,0,0,0,23,143,0,21,25,0,0,0,23,190,0,21,24,0,0,0,23,235,0,21,23,0,0,0,23,124,0,21,22,0,0,0,23,132,0,21,21,0,0,0,24,68,0,21,20,0,0,0,23,182,0,21,19,0,0,0,24,149,0,21,18,0,0,0,23,130,0,21,17,0,0,0,23,112,0,21,16,0,0,0,23,128,0,21,15,0,0,0,24,155,0,21,14,0,0,0,23,188,0,21,13,0,0,0,23,123,0,21,12,0,0,0,23,121,0,21,11,0,0,0,24,107,0,21,10,0,0,0,23,114,0,21,9,0,0,0,23,115,0,21,8,0,0,0,24,186,0,21,7,0,0,0,23,116,0,21,6,0,0,0,23,118,0,21,5,0,0,0,23,117,0,21,4,0,0,0,24,112,0,21,3,0,0,0,24,150,0,21,2,0,0,0,23,129,0,21,1,0,0,0,23,131,0,21,0,1,0,0,23,113,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,61,160,0,0,8,0,32,0,0,0,0,0,0,0,21,58,0,0,0,24,97,0,21,57,0,0,0,23,171,0,21,56,0,0,0,24,122,0,21,55,0,0,0,23,126,0,21,54,0,0,0,23,125,0,21,53,0,0,0,23,168,0,21,52,0,0,0,23,169,0,21,51,0,0,0,23,167,0,21,50,0,0,0,23,139,0,21,49,0,0,0,24,173,0,21,48,0,0,0,24,71,0,21,47,0,0,0,23,175,0,21,46,0,0,0,23,174,0,21,45,0,0,0,23,179,0,21,44,0,0,0,23,180,0,21,43,0,0,0,23,178,0,21,42,0,0,0,23,189,0,21,41,0,0,0,24,117,0,21,40,0,0,0,23,199,0,21,39,0,0,0,24,50,0,21,38,0,0,0,23,122,0,21,37,0,0,0,23,120,0,21,36,0,0,0,23,127,0,21,35,0,0,0,24,34,0,21,34,0,0,0,23,150,0,21,33,0,0,0,23,191,0,21,32,0,0,0,25,39,0,21,31,0,0,0,24,119,0,21,30,0,0,0,24,61,0,21,29,0,0,0,23,170,0,21,28,0,0,0,24,146,0,21,27,0,0,0,23,144,0,21,26,0,0,0,23,143,0,21,25,0,0,0,23,190,0,21,24,0,0,0,23,235,0,21,23,0,0,0,23,124,0,21,22,0,0,0,23,132,0,21,21,0,0,0,24,68,0,21,20,0,0,0,23,182,0,21,19,0,0,0,24,149,0,21,18,0,0,0,23,130,0,21,17,0,0,0,23,112,0,21,16,0,0,0,23,128,0,21,15,0,0,0,24,155,0,21,14,0,0,0,23,188,0,21,13,0,0,0,23,123,0,21,12,0,0,0,23,121,0,21,11,0,0,0,24,107,0,21,10,0,0,0,23,114,0,21,9,0,0,0,23,115,0,21,8,0,0,0,24,186,0,21,7,0,0,0,23,116,0,21,6,0,0,0,23,118,0,21,5,0,0,0,23,117,0,21,4,0,0,0,24,112,0,21,3,0,0,0,24,150,0,21,2,0,0,0,23,129,0,21,1,0,0,0,23,131,0,21,0,1,0,0,23,113,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIO32)
+/* MIPSEL */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,57,8,0,0,64,32,0,0,0,0,0,0,0,21,0,54,0,122,16,0,0,21,0,53,0,1,17,0,0,21,0,52,0,21,16,0,0,21,0,51,0,107,16,0,0,21,0,50,0,202,16,0,0,21,0,49,0,245,15,0,0,21,0,48,0,142,16,0,0,21,0,47,0,29,16,0,0,21,0,46,0,44,16,0,0,21,0,45,0,179,15,0,0,21,0,44,0,214,15,0,0,21,0,43,0,126,16,0,0,21,0,42,0,180,15,0,0,21,0,41,0,37,16,0,0,21,0,40,0,87,17,0,0,21,0,39,0,204,16,0,0,21,0,38,0,150,16,0,0,21,0,37,0,161,15,0,0,21,0,36,0,231,16,0,0,21,0,35,0,223,15,0,0,21,0,34,0,201,15,0,0,21,0,33,0,172,15,0,0,21,0,32,0,108,16,0,0,21,0,31,0,205,15,0,0,21,0,30,0,193,15,0,0,21,0,29,0,124,16,0,0,21,0,28,0,215,15,0,0,21,0,27,0,234,16,0,0,21,0,26,0,49,16,0,0,21,0,25,0,163,15,0,0,21,0,24,0,104,16,0,0,21,0,23,0,123,16,0,0,21,0,22,0,45,16,0,0,21,0,21,0,251,15,0,0,21,0,20,0,114,16,0,0,21,0,19,0,250,15,0,0,21,0,18,0,192,16,0,0,21,0,17,0,165,15,0,0,21,0,16,0,166,15,0,0,21,0,15,0,14,17,0,0,21,0,14,0,117,16,0,0,21,0,13,0,10,16,0,0,21,0,12,0,118,16,0,0,21,0,11,0,11,16,0,0,21,0,10,0,197,16,0,0,21,0,9,0,119,16,0,0,21,0,8,0,12,16,0,0,21,0,7,0,235,16,0,0,21,0,6,0,105,16,0,0,21,0,5,0,50,16,0,0,21,0,4,0,164,15,0,0,21,0,3,0,41,17,0,0,21,0,2,0,47,17,0,0,21,0,1,0,48,17,0,0,21,0,0,1,49,17,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,66,8,0,0,64,32,0,0,0,0,0,0,0,21,0,63,0,167,15,0,0,21,0,62,0,182,16,0,0,21,0,61,0,18,16,0,0,21,0,60,0,207,16,0,0,21,0,59,0,99,16,0,0,21,0,58,0,98,16,0,0,21,0,57,0,162,15,0,0,21,0,56,0,171,15,0,0,21,0,55,0,24,16,0,0,21,0,54,0,122,16,0,0,21,0,53,0,1,17,0,0,21,0,52,0,21,16,0,0,21,0,51,0,107,16,0,0,21,0,50,0,202,16,0,0,21,0,49,0,245,15,0,0,21,0,48,0,142,16,0,0,21,0,47,0,29,16,0,0,21,0,46,0,44,16,0,0,21,0,45,0,179,15,0,0,21,0,44,0,214,15,0,0,21,0,43,0,126,16,0,0,21,0,42,0,180,15,0,0,21,0,41,0,37,16,0,0,21,0,40,0,87,17,0,0,21,0,39,0,204,16,0,0,21,0,38,0,150,16,0,0,21,0,37,0,161,15,0,0,21,0,36,0,231,16,0,0,21,0,35,0,223,15,0,0,21,0,34,0,201,15,0,0,21,0,33,0,172,15,0,0,21,0,32,0,108,16,0,0,21,0,31,0,205,15,0,0,21,0,30,0,193,15,0,0,21,0,29,0,124,16,0,0,21,0,28,0,215,15,0,0,21,0,27,0,234,16,0,0,21,0,26,0,49,16,0,0,21,0,25,0,163,15,0,0,21,0,24,0,104,16,0,0,21,0,23,0,123,16,0,0,21,0,22,0,45,16,0,0,21,0,21,0,251,15,0,0,21,0,20,0,114,16,0,0,21,0,19,0,250,15,0,0,21,0,18,0,192,16,0,0,21,0,17,0,165,15,0,0,21,0,16,0,166,15,0,0,21,0,15,0,14,17,0,0,21,0,14,0,117,16,0,0,21,0,13,0,10,16,0,0,21,0,12,0,118,16,0,0,21,0,11,0,11,16,0,0,21,0,10,0,197,16,0,0,21,0,9,0,119,16,0,0,21,0,8,0,12,16,0,0,21,0,7,0,235,16,0,0,21,0,6,0,105,16,0,0,21,0,5,0,50,16,0,0,21,0,4,0,164,15,0,0,21,0,3,0,41,17,0,0,21,0,2,0,47,17,0,0,21,0,1,0,48,17,0,0,21,0,0,1,49,17,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABI64)
+/* MIPSEL64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,52,8,0,0,192,32,0,0,0,0,0,0,0,21,0,49,0,163,19,0,0,21,0,48,0,193,20,0,0,21,0,47,0,94,20,0,0,21,0,46,0,199,19,0,0,21,0,45,0,198,19,0,0,21,0,44,0,203,19,0,0,21,0,43,0,204,19,0,0,21,0,42,0,202,19,0,0,21,0,41,0,213,19,0,0,21,0,40,0,137,20,0,0,21,0,39,0,223,19,0,0,21,0,38,0,74,20,0,0,21,0,37,0,146,19,0,0,21,0,36,0,144,19,0,0,21,0,35,0,151,19,0,0,21,0,34,0,58,20,0,0,21,0,33,0,174,19,0,0,21,0,32,0,215,19,0,0,21,0,31,0,63,21,0,0,21,0,30,0,139,20,0,0,21,0,29,0,85,20,0,0,21,0,28,0,194,19,0,0,21,0,27,0,166,20,0,0,21,0,26,0,168,19,0,0,21,0,25,0,167,19,0,0,21,0,24,0,214,19,0,0,21,0,23,0,3,20,0,0,21,0,22,0,148,19,0,0,21,0,21,0,156,19,0,0,21,0,20,0,206,19,0,0,21,0,19,0,169,20,0,0,21,0,18,0,154,19,0,0,21,0,17,0,136,19,0,0,21,0,16,0,152,19,0,0,21,0,15,0,188,20,0,0,21,0,14,0,212,19,0,0,21,0,13,0,147,19,0,0,21,0,12,0,145,19,0,0,21,0,11,0,127,20,0,0,21,0,10,0,138,19,0,0,21,0,9,0,139,19,0,0,21,0,8,0,206,20,0,0,21,0,7,0,140,19,0,0,21,0,6,0,142,19,0,0,21,0,5,0,141,19,0,0,21,0,4,0,132,20,0,0,21,0,3,0,170,20,0,0,21,0,2,0,153,19,0,0,21,0,1,0,155,19,0,0,21,0,0,1,137,19,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,60,8,0,0,192,32,0,0,0,0,0,0,0,21,0,57,0,117,20,0,0,21,0,56,0,195,19,0,0,21,0,55,0,142,20,0,0,21,0,54,0,150,19,0,0,21,0,53,0,149,19,0,0,21,0,52,0,192,19,0,0,21,0,51,0,193,19,0,0,21,0,50,0,191,19,0,0,21,0,49,0,163,19,0,0,21,0,48,0,193,20,0,0,21,0,47,0,94,20,0,0,21,0,46,0,199,19,0,0,21,0,45,0,198,19,0,0,21,0,44,0,203,19,0,0,21,0,43,0,204,19,0,0,21,0,42,0,202,19,0,0,21,0,41,0,213,19,0,0,21,0,40,0,137,20,0,0,21,0,39,0,223,19,0,0,21,0,38,0,74,20,0,0,21,0,37,0,146,19,0,0,21,0,36,0,144,19,0,0,21,0,35,0,151,19,0,0,21,0,34,0,58,20,0,0,21,0,33,0,174,19,0,0,21,0,32,0,215,19,0,0,21,0,31,0,63,21,0,0,21,0,30,0,139,20,0,0,21,0,29,0,85,20,0,0,21,0,28,0,194,19,0,0,21,0,27,0,166,20,0,0,21,0,26,0,168,19,0,0,21,0,25,0,167,19,0,0,21,0,24,0,214,19,0,0,21,0,23,0,3,20,0,0,21,0,22,0,148,19,0,0,21,0,21,0,156,19,0,0,21,0,20,0,206,19,0,0,21,0,19,0,169,20,0,0,21,0,18,0,154,19,0,0,21,0,17,0,136,19,0,0,21,0,16,0,152,19,0,0,21,0,15,0,188,20,0,0,21,0,14,0,212,19,0,0,21,0,13,0,147,19,0,0,21,0,12,0,145,19,0,0,21,0,11,0,127,20,0,0,21,0,10,0,138,19,0,0,21,0,9,0,139,19,0,0,21,0,8,0,206,20,0,0,21,0,7,0,140,19,0,0,21,0,6,0,142,19,0,0,21,0,5,0,141,19,0,0,21,0,4,0,132,20,0,0,21,0,3,0,170,20,0,0,21,0,2,0,153,19,0,0,21,0,1,0,155,19,0,0,21,0,0,1,137,19,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIN32)
+/* MIPSEL64N32 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,53,8,0,0,224,32,0,0,0,0,0,0,0,21,0,50,0,61,24,0,0,21,0,49,0,170,23,0,0,21,0,48,0,146,24,0,0,21,0,47,0,144,23,0,0,21,0,46,0,143,23,0,0,21,0,45,0,190,23,0,0,21,0,44,0,235,23,0,0,21,0,43,0,124,23,0,0,21,0,42,0,132,23,0,0,21,0,41,0,68,24,0,0,21,0,40,0,182,23,0,0,21,0,39,0,149,24,0,0,21,0,38,0,130,23,0,0,21,0,37,0,112,23,0,0,21,0,36,0,128,23,0,0,21,0,35,0,155,24,0,0,21,0,34,0,188,23,0,0,21,0,33,0,123,23,0,0,21,0,32,0,121,23,0,0,21,0,31,0,107,24,0,0,21,0,30,0,114,23,0,0,21,0,29,0,115,23,0,0,21,0,28,0,186,24,0,0,21,0,27,0,116,23,0,0,21,0,26,0,118,23,0,0,21,0,25,0,117,23,0,0,21,0,24,0,112,24,0,0,21,0,23,0,150,24,0,0,21,0,22,0,129,23,0,0,21,0,21,0,131,23,0,0,21,0,20,0,113,23,0,0,21,0,19,0,139,23,0,0,21,0,18,0,173,24,0,0,21,0,17,0,71,24,0,0,21,0,16,0,175,23,0,0,21,0,15,0,174,23,0,0,21,0,14,0,179,23,0,0,21,0,13,0,180,23,0,0,21,0,12,0,178,23,0,0,21,0,11,0,189,23,0,0,21,0,10,0,117,24,0,0,21,0,9,0,199,23,0,0,21,0,8,0,50,24,0,0,21,0,7,0,122,23,0,0,21,0,6,0,120,23,0,0,21,0,5,0,127,23,0,0,21,0,4,0,34,24,0,0,21,0,3,0,150,23,0,0,21,0,2,0,191,23,0,0,21,0,1,0,39,25,0,0,21,0,0,1,119,24,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,61,8,0,0,224,32,0,0,0,0,0,0,0,21,0,58,0,61,24,0,0,21,0,57,0,170,23,0,0,21,0,56,0,146,24,0,0,21,0,55,0,144,23,0,0,21,0,54,0,143,23,0,0,21,0,53,0,190,23,0,0,21,0,52,0,235,23,0,0,21,0,51,0,124,23,0,0,21,0,50,0,132,23,0,0,21,0,49,0,68,24,0,0,21,0,48,0,182,23,0,0,21,0,47,0,149,24,0,0,21,0,46,0,130,23,0,0,21,0,45,0,112,23,0,0,21,0,44,0,128,23,0,0,21,0,43,0,155,24,0,0,21,0,42,0,188,23,0,0,21,0,41,0,123,23,0,0,21,0,40,0,121,23,0,0,21,0,39,0,107,24,0,0,21,0,38,0,114,23,0,0,21,0,37,0,115,23,0,0,21,0,36,0,186,24,0,0,21,0,35,0,116,23,0,0,21,0,34,0,118,23,0,0,21,0,33,0,117,23,0,0,21,0,32,0,112,24,0,0,21,0,31,0,150,24,0,0,21,0,30,0,129,23,0,0,21,0,29,0,131,23,0,0,21,0,28,0,113,23,0,0,21,0,27,0,97,24,0,0,21,0,26,0,171,23,0,0,21,0,25,0,122,24,0,0,21,0,24,0,126,23,0,0,21,0,23,0,125,23,0,0,21,0,22,0,168,23,0,0,21,0,21,0,169,23,0,0,21,0,20,0,167,23,0,0,21,0,19,0,139,23,0,0,21,0,18,0,173,24,0,0,21,0,17,0,71,24,0,0,21,0,16,0,175,23,0,0,21,0,15,0,174,23,0,0,21,0,14,0,179,23,0,0,21,0,13,0,180,23,0,0,21,0,12,0,178,23,0,0,21,0,11,0,189,23,0,0,21,0,10,0,117,24,0,0,21,0,9,0,199,23,0,0,21,0,8,0,50,24,0,0,21,0,7,0,122,23,0,0,21,0,6,0,120,23,0,0,21,0,5,0,127,23,0,0,21,0,4,0,34,24,0,0,21,0,3,0,150,23,0,0,21,0,2,0,191,23,0,0,21,0,1,0,39,25,0,0,21,0,0,1,119,24,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__hppa__) && !defined(__hppa64__)
+/* PARISC */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,58,0,0,0,15,0,32,0,0,0,0,0,0,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,68,0,0,0,15,0,32,0,0,0,0,0,0,0,21,65,0,0,0,0,7,0,21,64,0,0,0,0,235,0,21,63,0,0,0,0,114,0,21,62,0,0,0,0,113,0,21,61,0,0,0,1,32,0,21,60,0,0,0,0,175,0,21,59,0,0,0,0,174,0,21,58,0,0,0,0,2,0,21,57,0,0,0,0,11,0,21,56,0,0,0,0,120,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__hppa__) && defined(__hppa64__)
+/* PARISC64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,58,128,0,0,15,0,32,0,0,0,0,0,0,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,68,128,0,0,15,0,32,0,0,0,0,0,0,0,21,65,0,0,0,0,7,0,21,64,0,0,0,0,235,0,21,63,0,0,0,0,114,0,21,62,0,0,0,0,113,0,21,61,0,0,0,1,32,0,21,60,0,0,0,0,175,0,21,59,0,0,0,0,174,0,21,58,0,0,0,0,2,0,21,57,0,0,0,0,11,0,21,56,0,0,0,0,120,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__powerpc__) && !defined(__powerpc64__) && defined(__BIG_ENDIAN__)
+/* PPC */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,57,0,0,0,20,0,32,0,0,0,0,0,0,0,21,54,0,0,0,0,205,0,21,53,0,0,0,1,103,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,182,0,21,50,0,0,0,1,40,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,221,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,207,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,42,0,21,38,0,0,0,0,234,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,60,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,183,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,204,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,64,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,179,0,21,23,0,0,0,0,202,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,30,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,127,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,35,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,65,0,21,6,0,0,0,0,180,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,67,0,0,0,20,0,32,0,0,0,0,0,0,0,21,64,0,0,0,0,7,0,21,63,0,0,0,1,16,0,21,62,0,0,0,0,114,0,21,61,0,0,0,0,189,0,21,60,0,0,0,1,26,0,21,59,0,0,0,0,174,0,21,58,0,0,0,0,173,0,21,57,0,0,0,0,2,0,21,56,0,0,0,0,11,0,21,55,0,0,0,0,120,0,21,54,0,0,0,0,205,0,21,53,0,0,0,1,103,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,182,0,21,50,0,0,0,1,40,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,221,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,207,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,42,0,21,38,0,0,0,0,234,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,60,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,183,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,204,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,64,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,179,0,21,23,0,0,0,0,202,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,30,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,127,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,35,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,65,0,21,6,0,0,0,0,180,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__powerpc__) && defined(__powerpc64__) && defined(__BIG_ENDIAN__)
+/* PPC64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,53,128,0,0,21,0,32,0,0,0,0,0,0,0,21,50,0,0,0,0,141,0,21,49,0,0,0,0,91,0,21,48,0,0,0,0,90,0,21,47,0,0,0,1,30,0,21,46,0,0,0,0,5,0,21,45,0,0,0,0,6,0,21,44,0,0,0,1,127,0,21,43,0,0,0,0,106,0,21,42,0,0,0,0,107,0,21,41,0,0,0,0,108,0,21,40,0,0,0,1,35,0,21,39,0,0,0,1,65,0,21,38,0,0,0,0,180,0,21,37,0,0,0,0,146,0,21,36,0,0,0,0,4,0,21,35,0,0,0,0,205,0,21,34,0,0,0,1,103,0,21,33,0,0,0,0,117,0,21,32,0,0,0,0,182,0,21,31,0,0,0,1,40,0,21,30,0,0,0,0,85,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,125,0,21,27,0,0,0,0,140,0,21,26,0,0,0,0,19,0,21,25,0,0,0,0,54,0,21,24,0,0,0,0,207,0,21,23,0,0,0,0,20,0,21,22,0,0,0,0,133,0,21,21,0,0,0,1,183,0,21,20,0,0,0,1,42,0,21,19,0,0,0,0,234,0,21,18,0,0,0,0,1,0,21,17,0,0,0,1,60,0,21,16,0,0,0,0,63,0,21,15,0,0,0,0,41,0,21,14,0,0,0,0,12,0,21,13,0,0,0,0,183,0,21,12,0,0,0,0,45,0,21,11,0,0,0,0,33,0,21,10,0,0,0,0,55,0,21,9,0,0,0,1,64,0,21,8,0,0,0,0,145,0,21,7,0,0,0,0,3,0,21,6,0,0,0,0,179,0,21,5,0,0,0,0,202,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,63,128,0,0,21,0,32,0,0,0,0,0,0,0,21,60,0,0,0,0,141,0,21,59,0,0,0,0,91,0,21,58,0,0,0,0,90,0,21,57,0,0,0,1,30,0,21,56,0,0,0,0,5,0,21,55,0,0,0,0,6,0,21,54,0,0,0,1,127,0,21,53,0,0,0,0,106,0,21,52,0,0,0,0,107,0,21,51,0,0,0,0,108,0,21,50,0,0,0,1,35,0,21,49,0,0,0,1,65,0,21,48,0,0,0,0,180,0,21,47,0,0,0,0,146,0,21,46,0,0,0,0,4,0,21,45,0,0,0,0,7,0,21,44,0,0,0,1,16,0,21,43,0,0,0,0,114,0,21,42,0,0,0,0,189,0,21,41,0,0,0,1,26,0,21,40,0,0,0,0,174,0,21,39,0,0,0,0,173,0,21,38,0,0,0,0,2,0,21,37,0,0,0,0,11,0,21,36,0,0,0,0,120,0,21,35,0,0,0,0,205,0,21,34,0,0,0,1,103,0,21,33,0,0,0,0,117,0,21,32,0,0,0,0,182,0,21,31,0,0,0,1,40,0,21,30,0,0,0,0,85,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,125,0,21,27,0,0,0,0,140,0,21,26,0,0,0,0,19,0,21,25,0,0,0,0,54,0,21,24,0,0,0,0,207,0,21,23,0,0,0,0,20,0,21,22,0,0,0,0,133,0,21,21,0,0,0,1,183,0,21,20,0,0,0,1,42,0,21,19,0,0,0,0,234,0,21,18,0,0,0,0,1,0,21,17,0,0,0,1,60,0,21,16,0,0,0,0,63,0,21,15,0,0,0,0,41,0,21,14,0,0,0,0,12,0,21,13,0,0,0,0,183,0,21,12,0,0,0,0,45,0,21,11,0,0,0,0,33,0,21,10,0,0,0,0,55,0,21,9,0,0,0,1,64,0,21,8,0,0,0,0,145,0,21,7,0,0,0,0,3,0,21,6,0,0,0,0,179,0,21,5,0,0,0,0,202,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__powerpc__) && defined(__powerpc64__) && !defined(__BIG_ENDIAN__)
+/* PPC64LE */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,53,21,0,0,192,32,0,0,0,0,0,0,0,21,0,50,0,205,0,0,0,21,0,49,0,103,1,0,0,21,0,48,0,117,0,0,0,21,0,47,0,182,0,0,0,21,0,46,0,40,1,0,0,21,0,45,0,85,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,125,0,0,0,21,0,42,0,140,0,0,0,21,0,41,0,19,0,0,0,21,0,40,0,54,0,0,0,21,0,39,0,207,0,0,0,21,0,38,0,20,0,0,0,21,0,37,0,133,0,0,0,21,0,36,0,183,1,0,0,21,0,35,0,42,1,0,0,21,0,34,0,234,0,0,0,21,0,33,0,1,0,0,0,21,0,32,0,60,1,0,0,21,0,31,0,63,0,0,0,21,0,30,0,41,0,0,0,21,0,29,0,12,0,0,0,21,0,28,0,183,0,0,0,21,0,27,0,45,0,0,0,21,0,26,0,33,0,0,0,21,0,25,0,55,0,0,0,21,0,24,0,64,1,0,0,21,0,23,0,145,0,0,0,21,0,22,0,3,0,0,0,21,0,21,0,179,0,0,0,21,0,20,0,202,0,0,0,21,0,19,0,141,0,0,0,21,0,18,0,91,0,0,0,21,0,17,0,90,0,0,0,21,0,16,0,30,1,0,0,21,0,15,0,5,0,0,0,21,0,14,0,6,0,0,0,21,0,13,0,127,1,0,0,21,0,12,0,106,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,108,0,0,0,21,0,9,0,35,1,0,0,21,0,8,0,65,1,0,0,21,0,7,0,180,0,0,0,21,0,6,0,146,0,0,0,21,0,5,0,4,0,0,0,21,0,4,0,136,1,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,63,21,0,0,192,32,0,0,0,0,0,0,0,21,0,60,0,7,0,0,0,21,0,59,0,16,1,0,0,21,0,58,0,114,0,0,0,21,0,57,0,189,0,0,0,21,0,56,0,26,1,0,0,21,0,55,0,174,0,0,0,21,0,54,0,173,0,0,0,21,0,53,0,2,0,0,0,21,0,52,0,11,0,0,0,21,0,51,0,120,0,0,0,21,0,50,0,205,0,0,0,21,0,49,0,103,1,0,0,21,0,48,0,117,0,0,0,21,0,47,0,182,0,0,0,21,0,46,0,40,1,0,0,21,0,45,0,85,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,125,0,0,0,21,0,42,0,140,0,0,0,21,0,41,0,19,0,0,0,21,0,40,0,54,0,0,0,21,0,39,0,207,0,0,0,21,0,38,0,20,0,0,0,21,0,37,0,133,0,0,0,21,0,36,0,183,1,0,0,21,0,35,0,42,1,0,0,21,0,34,0,234,0,0,0,21,0,33,0,1,0,0,0,21,0,32,0,60,1,0,0,21,0,31,0,63,0,0,0,21,0,30,0,41,0,0,0,21,0,29,0,12,0,0,0,21,0,28,0,183,0,0,0,21,0,27,0,45,0,0,0,21,0,26,0,33,0,0,0,21,0,25,0,55,0,0,0,21,0,24,0,64,1,0,0,21,0,23,0,145,0,0,0,21,0,22,0,3,0,0,0,21,0,21,0,179,0,0,0,21,0,20,0,202,0,0,0,21,0,19,0,141,0,0,0,21,0,18,0,91,0,0,0,21,0,17,0,90,0,0,0,21,0,16,0,30,1,0,0,21,0,15,0,5,0,0,0,21,0,14,0,6,0,0,0,21,0,13,0,127,1,0,0,21,0,12,0,106,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,108,0,0,0,21,0,9,0,35,1,0,0,21,0,8,0,65,1,0,0,21,0,7,0,180,0,0,0,21,0,6,0,146,0,0,0,21,0,5,0,4,0,0,0,21,0,4,0,136,1,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__riscv) && __riscv_xlen == 64
+/* RISCV64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,45,243,0,0,192,32,0,0,0,0,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,52,243,0,0,192,32,0,0,0,0,0,0,0,21,0,49,0,95,0,0,0,21,0,48,0,4,1,0,0,21,0,47,0,97,0,0,0,21,0,46,0,135,0,0,0,21,0,45,0,134,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,220,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__s390__) && !defined(__s390x__)
+/* S390 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,57,0,0,0,22,0,32,0,0,0,0,0,0,0,21,54,0,0,0,0,219,0,21,53,0,0,0,1,93,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,183,0,21,50,0,0,0,1,42,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,238,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,236,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,44,0,21,38,0,0,0,0,248,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,70,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,184,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,72,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,180,0,21,23,0,0,0,0,220,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,32,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,123,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,37,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,73,0,21,6,0,0,0,0,181,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,66,0,0,0,22,0,32,0,0,0,0,0,0,0,21,63,0,0,0,1,25,0,21,62,0,0,0,0,114,0,21,61,0,0,0,0,190,0,21,60,0,0,0,1,47,0,21,59,0,0,0,0,175,0,21,58,0,0,0,0,174,0,21,57,0,0,0,0,2,0,21,56,0,0,0,0,11,0,21,55,0,0,0,0,120,0,21,54,0,0,0,0,219,0,21,53,0,0,0,1,93,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,183,0,21,50,0,0,0,1,42,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,238,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,236,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,44,0,21,38,0,0,0,0,248,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,70,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,184,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,72,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,180,0,21,23,0,0,0,0,220,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,32,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,123,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,37,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,73,0,21,6,0,0,0,0,181,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__s390__) && defined(__s390x__)
+/* S390X */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,52,128,0,0,22,0,32,0,0,0,0,0,0,0,21,49,0,0,0,1,73,0,21,48,0,0,0,0,181,0,21,47,0,0,0,0,146,0,21,46,0,0,0,0,4,0,21,45,0,0,0,0,219,0,21,44,0,0,0,1,93,0,21,43,0,0,0,0,117,0,21,42,0,0,0,0,183,0,21,41,0,0,0,1,42,0,21,40,0,0,0,0,85,0,21,39,0,0,0,0,238,0,21,38,0,0,0,0,125,0,21,37,0,0,0,0,19,0,21,36,0,0,0,0,54,0,21,35,0,0,0,0,236,0,21,34,0,0,0,0,20,0,21,33,0,0,0,0,133,0,21,32,0,0,0,1,183,0,21,31,0,0,0,1,44,0,21,30,0,0,0,0,248,0,21,29,0,0,0,0,1,0,21,28,0,0,0,1,70,0,21,27,0,0,0,0,63,0,21,26,0,0,0,0,41,0,21,25,0,0,0,0,12,0,21,24,0,0,0,0,184,0,21,23,0,0,0,0,45,0,21,22,0,0,0,0,33,0,21,21,0,0,0,0,55,0,21,20,0,0,0,1,72,0,21,19,0,0,0,0,145,0,21,18,0,0,0,0,3,0,21,17,0,0,0,0,180,0,21,16,0,0,0,0,220,0,21,15,0,0,0,0,141,0,21,14,0,0,0,0,91,0,21,13,0,0,0,0,90,0,21,12,0,0,0,1,32,0,21,11,0,0,0,0,5,0,21,10,0,0,0,0,6,0,21,9,0,0,0,1,123,0,21,8,0,0,0,0,106,0,21,7,0,0,0,0,107,0,21,6,0,0,0,0,108,0,21,5,0,0,0,1,37,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 0,32,0,0,0,0,0,4,0,21,0,61,128,0,0,22,0,32,0,0,0,0,0,0,0,21,58,0,0,0,1,73,0,21,57,0,0,0,0,181,0,21,56,0,0,0,0,146,0,21,55,0,0,0,0,4,0,21,54,0,0,0,1,25,0,21,53,0,0,0,0,114,0,21,52,0,0,0,0,190,0,21,51,0,0,0,1,47,0,21,50,0,0,0,0,175,0,21,49,0,0,0,0,174,0,21,48,0,0,0,0,2,0,21,47,0,0,0,0,11,0,21,46,0,0,0,0,120,0,21,45,0,0,0,0,219,0,21,44,0,0,0,1,93,0,21,43,0,0,0,0,117,0,21,42,0,0,0,0,183,0,21,41,0,0,0,1,42,0,21,40,0,0,0,0,85,0,21,39,0,0,0,0,238,0,21,38,0,0,0,0,125,0,21,37,0,0,0,0,19,0,21,36,0,0,0,0,54,0,21,35,0,0,0,0,236,0,21,34,0,0,0,0,20,0,21,33,0,0,0,0,133,0,21,32,0,0,0,1,183,0,21,31,0,0,0,1,44,0,21,30,0,0,0,0,248,0,21,29,0,0,0,0,1,0,21,28,0,0,0,1,70,0,21,27,0,0,0,0,63,0,21,26,0,0,0,0,41,0,21,25,0,0,0,0,12,0,21,24,0,0,0,0,184,0,21,23,0,0,0,0,45,0,21,22,0,0,0,0,33,0,21,21,0,0,0,0,55,0,21,20,0,0,0,1,72,0,21,19,0,0,0,0,145,0,21,18,0,0,0,0,3,0,21,17,0,0,0,0,180,0,21,16,0,0,0,0,220,0,21,15,0,0,0,0,141,0,21,14,0,0,0,0,91,0,21,13,0,0,0,0,90,0,21,12,0,0,0,1,32,0,21,11,0,0,0,0,5,0,21,10,0,0,0,0,6,0,21,9,0,0,0,1,123,0,21,8,0,0,0,0,106,0,21,7,0,0,0,0,107,0,21,6,0,0,0,0,108,0,21,5,0,0,0,1,37,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__i386__)
+/* X86 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,57,3,0,0,64,32,0,0,0,0,0,0,0,21,0,54,0,219,0,0,0,21,0,53,0,99,1,0,0,21,0,52,0,117,0,0,0,21,0,51,0,183,0,0,0,21,0,50,0,49,1,0,0,21,0,49,0,85,0,0,0,21,0,48,0,240,0,0,0,21,0,47,0,125,0,0,0,21,0,46,0,140,0,0,0,21,0,45,0,19,0,0,0,21,0,44,0,54,0,0,0,21,0,43,0,224,0,0,0,21,0,42,0,20,0,0,0,21,0,41,0,133,0,0,0,21,0,40,0,183,1,0,0,21,0,39,0,51,1,0,0,21,0,38,0,252,0,0,0,21,0,37,0,1,0,0,0,21,0,36,0,74,1,0,0,21,0,35,0,63,0,0,0,21,0,34,0,41,0,0,0,21,0,33,0,12,0,0,0,21,0,32,0,184,0,0,0,21,0,31,0,45,0,0,0,21,0,30,0,33,0,0,0,21,0,29,0,221,0,0,0,21,0,28,0,55,0,0,0,21,0,27,0,77,1,0,0,21,0,26,0,145,0,0,0,21,0,25,0,3,0,0,0,21,0,24,0,180,0,0,0,21,0,23,0,220,0,0,0,21,0,22,0,141,0,0,0,21,0,21,0,91,0,0,0,21,0,20,0,192,0,0,0,21,0,19,0,90,0,0,0,21,0,18,0,39,1,0,0,21,0,17,0,5,0,0,0,21,0,16,0,6,0,0,0,21,0,15,0,127,1,0,0,21,0,14,0,195,0,0,0,21,0,13,0,106,0,0,0,21,0,12,0,196,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,44,1,0,0,21,0,9,0,197,0,0,0,21,0,8,0,108,0,0,0,21,0,7,0,78,1,0,0,21,0,6,0,181,0,0,0,21,0,5,0,146,0,0,0,21,0,4,0,4,0,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,67,3,0,0,64,32,0,0,0,0,0,0,0,21,0,64,0,7,0,0,0,21,0,63,0,28,1,0,0,21,0,62,0,114,0,0,0,21,0,61,0,190,0,0,0,21,0,60,0,54,1,0,0,21,0,59,0,175,0,0,0,21,0,58,0,174,0,0,0,21,0,57,0,2,0,0,0,21,0,56,0,11,0,0,0,21,0,55,0,120,0,0,0,21,0,54,0,219,0,0,0,21,0,53,0,99,1,0,0,21,0,52,0,117,0,0,0,21,0,51,0,183,0,0,0,21,0,50,0,49,1,0,0,21,0,49,0,85,0,0,0,21,0,48,0,240,0,0,0,21,0,47,0,125,0,0,0,21,0,46,0,140,0,0,0,21,0,45,0,19,0,0,0,21,0,44,0,54,0,0,0,21,0,43,0,224,0,0,0,21,0,42,0,20,0,0,0,21,0,41,0,133,0,0,0,21,0,40,0,183,1,0,0,21,0,39,0,51,1,0,0,21,0,38,0,252,0,0,0,21,0,37,0,1,0,0,0,21,0,36,0,74,1,0,0,21,0,35,0,63,0,0,0,21,0,34,0,41,0,0,0,21,0,33,0,12,0,0,0,21,0,32,0,184,0,0,0,21,0,31,0,45,0,0,0,21,0,30,0,33,0,0,0,21,0,29,0,221,0,0,0,21,0,28,0,55,0,0,0,21,0,27,0,77,1,0,0,21,0,26,0,145,0,0,0,21,0,25,0,3,0,0,0,21,0,24,0,180,0,0,0,21,0,23,0,220,0,0,0,21,0,22,0,141,0,0,0,21,0,21,0,91,0,0,0,21,0,20,0,192,0,0,0,21,0,19,0,90,0,0,0,21,0,18,0,39,1,0,0,21,0,17,0,5,0,0,0,21,0,16,0,6,0,0,0,21,0,15,0,127,1,0,0,21,0,14,0,195,0,0,0,21,0,13,0,106,0,0,0,21,0,12,0,196,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,44,1,0,0,21,0,9,0,197,0,0,0,21,0,8,0,108,0,0,0,21,0,7,0,78,1,0,0,21,0,6,0,181,0,0,0,21,0,5,0,146,0,0,0,21,0,4,0,4,0,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__x86_64__) && defined(__ILP32__)
+/* X32 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,53,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,51,0,0,0,64,21,0,49,0,28,0,0,64,21,0,48,0,62,1,0,64,21,0,47,0,220,0,0,64,21,0,46,0,65,0,0,64,21,0,45,0,64,0,0,64,21,0,44,0,69,0,0,64,21,0,43,0,70,0,0,64,21,0,42,0,68,0,0,64,21,0,41,0,79,0,0,64,21,0,40,0,11,1,0,64,21,0,39,0,89,0,0,64,21,0,38,0,202,0,0,64,21,0,37,0,10,0,0,64,21,0,36,0,8,0,0,64,21,0,35,0,2,2,0,64,21,0,34,0,186,0,0,64,21,0,33,0,39,0,0,64,21,0,32,0,81,0,0,64,21,0,31,0,183,1,0,64,21,0,30,0,13,1,0,64,21,0,29,0,231,0,0,64,21,0,28,0,60,0,0,64,21,0,27,0,36,1,0,64,21,0,26,0,33,0,0,64,21,0,25,0,32,0,0,64,21,0,24,0,80,0,0,64,21,0,23,0,125,0,0,64,21,0,22,0,12,0,0,64,21,0,21,0,21,0,0,64,21,0,20,0,72,0,0,64,21,0,19,0,22,2,0,64,21,0,18,0,3,2,0,64,21,0,17,0,0,0,0,64,21,0,16,0,17,0,0,64,21,0,15,0,217,0,0,64,21,0,14,0,78,0,0,64,21,0,13,0,11,0,0,64,21,0,12,0,9,0,0,64,21,0,11,0,1,1,0,64,21,0,10,0,2,0,0,64,21,0,9,0,3,0,0,64,21,0,8,0,76,1,0,64,21,0,7,0,4,0,0,64,21,0,6,0,6,0,0,64,21,0,5,0,5,0,0,64,21,0,4,0,6,1,0,64,21,0,3,0,23,2,0,64,21,0,2,0,18,0,0,64,21,0,1,0,4,2,0,64,21,0,0,1,1,0,0,64,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,62,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,60,0,0,0,64,21,0,58,0,17,2,0,64,21,0,57,0,61,0,0,64,21,0,56,0,58,0,0,64,21,0,55,0,16,1,0,64,21,0,54,0,14,0,0,64,21,0,53,0,0,2,0,64,21,0,52,0,57,0,0,64,21,0,51,0,8,2,0,64,21,0,50,0,56,0,0,64,21,0,49,0,28,0,0,64,21,0,48,0,62,1,0,64,21,0,47,0,220,0,0,64,21,0,46,0,65,0,0,64,21,0,45,0,64,0,0,64,21,0,44,0,69,0,0,64,21,0,43,0,70,0,0,64,21,0,42,0,68,0,0,64,21,0,41,0,79,0,0,64,21,0,40,0,11,1,0,64,21,0,39,0,89,0,0,64,21,0,38,0,202,0,0,64,21,0,37,0,10,0,0,64,21,0,36,0,8,0,0,64,21,0,35,0,2,2,0,64,21,0,34,0,186,0,0,64,21,0,33,0,39,0,0,64,21,0,32,0,81,0,0,64,21,0,31,0,183,1,0,64,21,0,30,0,13,1,0,64,21,0,29,0,231,0,0,64,21,0,28,0,60,0,0,64,21,0,27,0,36,1,0,64,21,0,26,0,33,0,0,64,21,0,25,0,32,0,0,64,21,0,24,0,80,0,0,64,21,0,23,0,125,0,0,64,21,0,22,0,12,0,0,64,21,0,21,0,21,0,0,64,21,0,20,0,72,0,0,64,21,0,19,0,22,2,0,64,21,0,18,0,3,2,0,64,21,0,17,0,0,0,0,64,21,0,16,0,17,0,0,64,21,0,15,0,217,0,0,64,21,0,14,0,78,0,0,64,21,0,13,0,11,0,0,64,21,0,12,0,9,0,0,64,21,0,11,0,1,1,0,64,21,0,10,0,2,0,0,64,21,0,9,0,3,0,0,64,21,0,8,0,76,1,0,64,21,0,7,0,4,0,0,64,21,0,6,0,6,0,0,64,21,0,5,0,5,0,0,64,21,0,4,0,6,1,0,64,21,0,3,0,23,2,0,64,21,0,2,0,18,0,0,64,21,0,1,0,4,2,0,64,21,0,0,1,1,0,0,64,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#if defined(__x86_64__) && !defined(__ILP32__)
+/* X86_64 */
+#define SECCOMP_BPF_AVAILABLE
+static const unsigned char seccomp_bpf_blks_base[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,54,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,1,0,0,0,64,21,0,0,51,255,255,255,255,21,0,49,0,220,0,0,0,21,0,48,0,65,0,0,0,21,0,47,0,64,0,0,0,21,0,46,0,69,0,0,0,21,0,45,0,70,0,0,0,21,0,44,0,68,0,0,0,21,0,43,0,79,0,0,0,21,0,42,0,11,1,0,0,21,0,41,0,89,0,0,0,21,0,40,0,202,0,0,0,21,0,39,0,10,0,0,0,21,0,38,0,8,0,0,0,21,0,37,0,16,0,0,0,21,0,36,0,186,0,0,0,21,0,35,0,39,0,0,0,21,0,34,0,81,0,0,0,21,0,33,0,183,1,0,0,21,0,32,0,13,1,0,0,21,0,31,0,231,0,0,0,21,0,30,0,60,0,0,0,21,0,29,0,36,1,0,0,21,0,28,0,33,0,0,0,21,0,27,0,32,0,0,0,21,0,26,0,80,0,0,0,21,0,25,0,125,0,0,0,21,0,24,0,12,0,0,0,21,0,23,0,21,0,0,0,21,0,22,0,72,0,0,0,21,0,21,0,39,1,0,0,21,0,20,0,19,0,0,0,21,0,19,0,0,0,0,0,21,0,18,0,17,0,0,0,21,0,17,0,217,0,0,0,21,0,16,0,78,0,0,0,21,0,15,0,11,0,0,0,21,0,14,0,9,0,0,0,21,0,13,0,1,1,0,0,21,0,12,0,2,0,0,0,21,0,11,0,3,0,0,0,21,0,10,0,76,1,0,0,21,0,9,0,4,0,0,0,21,0,8,0,6,0,0,0,21,0,7,0,5,0,0,0,21,0,6,0,6,1,0,0,21,0,5,0,40,1,0,0,21,0,4,0,18,0,0,0,21,0,3,0,20,0,0,0,21,0,2,0,1,0,0,0,21,0,1,0,28,0,0,0,21,0,0,1,62,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+static const unsigned char seccomp_bpf_blks_fork[] = {
+ 32,0,0,0,4,0,0,0,21,0,0,63,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,1,0,0,0,64,21,0,0,60,255,255,255,255,21,0,58,0,220,0,0,0,21,0,57,0,65,0,0,0,21,0,56,0,64,0,0,0,21,0,55,0,69,0,0,0,21,0,54,0,70,0,0,0,21,0,53,0,68,0,0,0,21,0,52,0,79,0,0,0,21,0,51,0,11,1,0,0,21,0,50,0,89,0,0,0,21,0,49,0,202,0,0,0,21,0,48,0,10,0,0,0,21,0,47,0,8,0,0,0,21,0,46,0,16,0,0,0,21,0,45,0,186,0,0,0,21,0,44,0,39,0,0,0,21,0,43,0,81,0,0,0,21,0,42,0,183,1,0,0,21,0,41,0,13,1,0,0,21,0,40,0,231,0,0,0,21,0,39,0,60,0,0,0,21,0,38,0,36,1,0,0,21,0,37,0,33,0,0,0,21,0,36,0,32,0,0,0,21,0,35,0,80,0,0,0,21,0,34,0,125,0,0,0,21,0,33,0,12,0,0,0,21,0,32,0,21,0,0,0,21,0,31,0,72,0,0,0,21,0,30,0,39,1,0,0,21,0,29,0,19,0,0,0,21,0,28,0,0,0,0,0,21,0,27,0,17,0,0,0,21,0,26,0,217,0,0,0,21,0,25,0,78,0,0,0,21,0,24,0,11,0,0,0,21,0,23,0,9,0,0,0,21,0,22,0,1,1,0,0,21,0,21,0,2,0,0,0,21,0,20,0,3,0,0,0,21,0,19,0,76,1,0,0,21,0,18,0,4,0,0,0,21,0,17,0,6,0,0,0,21,0,16,0,5,0,0,0,21,0,15,0,6,1,0,0,21,0,14,0,40,1,0,0,21,0,13,0,18,0,0,0,21,0,12,0,20,0,0,0,21,0,11,0,1,0,0,0,21,0,10,0,247,0,0,0,21,0,9,0,61,0,0,0,21,0,8,0,58,0,0,0,21,0,7,0,16,1,0,0,21,0,6,0,14,0,0,0,21,0,5,0,13,0,0,0,21,0,4,0,57,0,0,0,21,0,3,0,59,0,0,0,21,0,2,0,56,0,0,0,21,0,1,0,28,0,0,0,21,0,0,1,62,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0,
+};
+#endif
+
+#ifdef SECCOMP_BPF_AVAILABLE
+typedef struct {
+ uint16_t cnt;
+ const void *bpf;
+} seccomp_bpf_program_t;
+static const seccomp_bpf_program_t seccomp_bpf_program_base = {
+ .cnt = sizeof(seccomp_bpf_blks_base) / 8,
+ .bpf = seccomp_bpf_blks_base,
+};
+static const seccomp_bpf_program_t seccomp_bpf_program_fork = {
+ .cnt = sizeof(seccomp_bpf_blks_fork) / 8,
+ .bpf = seccomp_bpf_blks_fork,
+};
+#endif
diff --git a/security.c b/security.c
index a86f375..171c46c 100644
--- a/security.c
+++ b/security.c
@@ -1,11 +1,12 @@
/*
- * Copyright 2015 Gentoo Foundation
+ * Copyright 2015-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
- * Copyright 2015 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2015-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#include "paxinc.h"
+#include "seccomp-bpf.h"
#ifdef __linux__
@@ -26,189 +27,27 @@
#define CLONE_NEWUTS 0
#endif
+#ifndef PR_SET_SECCOMP
+#define PR_SET_SECCOMP 22
+#endif
+#ifndef SECCOMP_MODE_FILTER
+#define SECCOMP_MODE_FILTER 2
+#endif
+
#ifdef __SANITIZE_ADDRESS__
/* ASAN does some weird stuff. */
# define ALLOW_PIDNS 0
+# undef WANT_SECCOMP
#else
# define ALLOW_PIDNS 1
#endif
-#ifdef WANT_SECCOMP
-# include <seccomp.h>
-
-/* Simple helper to add all of the syscalls in an array. */
-static int pax_seccomp_rules_add(scmp_filter_ctx ctx, int syscalls[], size_t num)
-{
- static uint8_t prio;
- size_t i;
- for (i = 0; i < num; ++i) {
- if (syscalls[i] < 0)
- continue;
-
- if (seccomp_syscall_priority(ctx, syscalls[i], prio++) < 0) {
- warnp("seccomp_syscall_priority failed");
- return -1;
- }
- if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) < 0) {
- warnp("seccomp_rule_add failed");
- return -1;
- }
- }
- return 0;
-}
-#define pax_seccomp_rules_add(ctx, syscalls) pax_seccomp_rules_add(ctx, syscalls, ARRAY_SIZE(syscalls))
-
-static void
-pax_seccomp_sigal(__unused__ int signo, siginfo_t *info, __unused__ void *context)
-{
-#ifdef si_syscall
- warn("seccomp violated: syscall %i", info->si_syscall);
- fflush(stderr);
- warn(" syscall = %s",
- seccomp_syscall_resolve_num_arch(seccomp_arch_native(), info->si_syscall));
- fflush(stderr);
-#else
- warn("seccomp violated: syscall unknown (no si_syscall)");
-#endif
- kill(getpid(), SIGSYS);
- _exit(1);
-}
-
-static void pax_seccomp_signal_init(void)
-{
- struct sigaction act;
- sigemptyset(&act.sa_mask);
- act.sa_sigaction = pax_seccomp_sigal,
- act.sa_flags = SA_SIGINFO | SA_RESETHAND;
- sigaction(SIGSYS, &act, NULL);
-}
-
-static void pax_seccomp_init(bool allow_forking)
-{
- /* Order determines priority (first == lowest prio). */
- int base_syscalls[] = {
- /* We write the most w/scanelf. */
- SCMP_SYS(write),
- SCMP_SYS(writev),
- SCMP_SYS(pwrite64),
- SCMP_SYS(pwritev),
-
- /* Then the stat family of functions. */
- SCMP_SYS(newfstatat),
- SCMP_SYS(fstat),
- SCMP_SYS(fstat64),
- SCMP_SYS(fstatat64),
- SCMP_SYS(lstat),
- SCMP_SYS(lstat64),
- SCMP_SYS(stat),
- SCMP_SYS(stat64),
-
- /* Then the fd close func. */
- SCMP_SYS(close),
-
- /* Then fd open family of functions. */
- SCMP_SYS(open),
- SCMP_SYS(openat),
-
- /* Then the memory mapping functions. */
- SCMP_SYS(mmap),
- SCMP_SYS(mmap2),
- SCMP_SYS(munmap),
-
- /* Then the directory reading functions. */
- SCMP_SYS(getdents),
- SCMP_SYS(getdents64),
-
- /* Then the file reading functions. */
- SCMP_SYS(pread64),
- SCMP_SYS(read),
- SCMP_SYS(readv),
- SCMP_SYS(preadv),
-
- /* Then the fd manipulation functions. */
- SCMP_SYS(fcntl),
- SCMP_SYS(fcntl64),
-
- /* After this point, just sort the list alphabetically. */
- SCMP_SYS(access),
- SCMP_SYS(brk),
- SCMP_SYS(capget),
- SCMP_SYS(chdir),
- SCMP_SYS(dup),
- SCMP_SYS(dup2),
- SCMP_SYS(dup3),
- SCMP_SYS(exit),
- SCMP_SYS(exit_group),
- SCMP_SYS(faccessat),
- SCMP_SYS(fchdir),
- SCMP_SYS(getpid),
- SCMP_SYS(gettid),
- SCMP_SYS(ioctl),
- SCMP_SYS(lseek),
- SCMP_SYS(_llseek),
- SCMP_SYS(mprotect),
-
- /* Syscalls listed because of compiler settings. */
- SCMP_SYS(futex),
-
- /* Syscalls listed because of sandbox. */
- SCMP_SYS(readlink),
- SCMP_SYS(readlinkat),
- SCMP_SYS(getcwd),
-
- /* Syscalls listed because of fakeroot. */
- SCMP_SYS(msgget),
- SCMP_SYS(msgrcv),
- SCMP_SYS(msgsnd),
- SCMP_SYS(semget),
- SCMP_SYS(semop),
- };
- int fork_syscalls[] = {
- SCMP_SYS(clone),
- SCMP_SYS(execve),
- SCMP_SYS(fork),
- SCMP_SYS(rt_sigaction),
- SCMP_SYS(rt_sigprocmask),
- SCMP_SYS(unshare),
- SCMP_SYS(vfork),
- SCMP_SYS(wait4),
- SCMP_SYS(waitid),
- SCMP_SYS(waitpid),
- };
- scmp_filter_ctx ctx = seccomp_init(USE_DEBUG ? SCMP_ACT_TRAP : SCMP_ACT_KILL);
- if (!ctx) {
- warnp("seccomp_init failed");
- return;
- }
-
- if (pax_seccomp_rules_add(ctx, base_syscalls) < 0)
- goto done;
-
- if (allow_forking)
- if (pax_seccomp_rules_add(ctx, fork_syscalls) < 0)
- goto done;
-
- /* We already called prctl. */
- seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0);
-
- if (USE_DEBUG)
- pax_seccomp_signal_init();
-
-#ifndef __SANITIZE_ADDRESS__
- /* ASAN does some weird stuff. */
- if (seccomp_load(ctx) < 0) {
- /* We have to assume that EINVAL == CONFIG_SECCOMP is disabled. */
- if (errno != EINVAL)
- warnp("seccomp_load failed");
- }
+#ifndef SECCOMP_BPF_AVAILABLE
+# undef WANT_SECCOMP
#endif
- done:
- seccomp_release(ctx);
-}
-
-#else
-# define pax_seccomp_init(allow_forking)
+#if PAX_UTILS_LIBFUZZ
+# undef WANT_SECCOMP
#endif
static int ns_unshare(int flags)
@@ -259,6 +98,7 @@ void security_init_pid(void)
void security_init(bool allow_forking)
{
+ (void) allow_forking;
int flags;
if (!ALLOW_PIDNS)
@@ -295,7 +135,19 @@ void security_init(bool allow_forking)
_exit(0);
}
- pax_seccomp_init(allow_forking);
+#ifdef WANT_SECCOMP
+ {
+ int ret;
+
+ if (allow_forking)
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_bpf_program_fork);
+ else
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_bpf_program_base);
+
+ if (ret)
+ warn("enabling seccomp failed");
+ }
+#endif
}
#endif
diff --git a/security.h b/security.h
index c93ec3e..d2625e2 100644
--- a/security.h
+++ b/security.h
@@ -1,9 +1,9 @@
/* Various security related features.
*
- * Copyright 2015 Gentoo Foundation
+ * Copyright 2015-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
- * Copyright 2015 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2015-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#ifndef _PAX_SECURITY_H
@@ -22,7 +22,7 @@ void security_init(bool allow_forking);
/* Disable forking; usable only when allow_forking above was true. */
void security_init_pid(void);
#else
-static inline void security_init(bool allow_forking) {}
+static inline void security_init(bool allow_forking) { (void) allow_forking; }
static inline void security_init_pid(void) {}
#endif
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
index f4b81e8..0000000
--- a/tests/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-SUBDIRS = $(patsubst %/Makefile,%,$(wildcard */Makefile))
-abs_top_srcdir = $(realpath $(PWD)/..)
-abs_top_builddir = $(realpath $(PWD)/..)
-# DO NOT STARE AT THE SUN
-all:
-%:; $(MAKE) `printf '%s_$@_ ' $(SUBDIRS)`
-_words = $(subst _, ,$1)
-_dir = $(firstword $(call _words,$@))
-_targ = $(lastword $(call _words,$@))
-%_:; $(MAKE) -C $(_dir) $(_targ) srcdir=$(abs_top_srcdir)/tests/$(_dir) builddir=$(abs_top_builddir)/tests/$(_dir)
diff --git a/tests/lddtree/Makefile b/tests/lddtree/Makefile
deleted file mode 100644
index 3a13e28..0000000
--- a/tests/lddtree/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: check
-
-%.check:
- ./dotest-$(@:.check=)
-
-test check: sh.check
-ifneq ($(USE_PYTHON),no)
-test check: py.check cmp.check
-endif
-
-clean:
-
-.PHONY: all check clean test
diff --git a/tests/lddtree/meson.build b/tests/lddtree/meson.build
new file mode 100644
index 0000000..256998e
--- /dev/null
+++ b/tests/lddtree/meson.build
@@ -0,0 +1,10 @@
+foreach sfx : ['sh', 'py', 'cmp']
+ test('lddtree-' + sfx, files('dotest-' + sfx),
+ workdir : meson.current_source_dir(),
+ env : {
+ 'builddir' : meson.project_build_root(),
+ 'srcdir' : meson.project_source_root(),
+ 'current_srcdir' : meson.current_source_dir(),
+ }
+ )
+endforeach
diff --git a/tests/lib.sh b/tests/lib.sh
index 927e503..0dab3fa 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -1,17 +1,8 @@
-if [[ -z ${abs_top_builddir} ]] ; then
- srcdir=$(cd "${0%/*}" && pwd)
- top_srcdir=$(cd "${srcdir}/../.." && pwd)
- builddir=${srcdir}
- top_builddir=${top_srcdir}
-else
- mkdir -p "${builddir}"
- top_srcdir=${abs_top_srcdir}
- top_builddir=${abs_top_builddir}
-fi
+GOOD=$'\e[32;1m'
+BAD=$'\e[31;1m'
+NORMAL=$'\e[m'
-[ -e /etc/init.d/functions.sh ] && source /etc/init.d/functions.sh
-
-PATH="${top_srcdir}:${top_builddir}:${PATH}"
+PATH="$(realpath "${srcdir}" "${builddir}" | tr '\n' ':'):${PATH}"
unset ROOT # who knows!
ret=0
diff --git a/tests/scanelf/Makefile b/tests/scanelf/Makefile
deleted file mode 100644
index 62084f0..0000000
--- a/tests/scanelf/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-all: check
-
-test check:
- ./dotest
-
-clean:
-
-.PHONY: all check clean test
diff --git a/tests/scanelf/dotest b/tests/scanelf/dotest
index d06f086..fdfd2a2 100755
--- a/tests/scanelf/dotest
+++ b/tests/scanelf/dotest
@@ -5,9 +5,9 @@
#
# simple scanelf symbol checks
#
-scanelf -qsmain -F'%s %f' "${top_builddir}"/scanelf \
- > "${builddir}"/scanelf.simple
-testit scanelf.simple{,.good}
+${MESON_EXE_WRAPPER} "${builddir}/scanelf" -qsmain -F'%s %f' \
+ "${builddir}"/scanelf > "${builddir}"/scanelf.simple
+testit scanelf.simple tests/scanelf/scanelf.simple.good
diff --git a/tests/scanelf/meson.build b/tests/scanelf/meson.build
new file mode 100644
index 0000000..af632fd
--- /dev/null
+++ b/tests/scanelf/meson.build
@@ -0,0 +1,8 @@
+test('scanelf-test', files('dotest'),
+ workdir : meson.current_source_dir(),
+ env : {
+ 'builddir' : meson.project_build_root(),
+ 'srcdir' : meson.project_source_root(),
+ 'current_srcdir' : meson.current_source_dir(),
+ }
+)
diff --git a/tests/source/Makefile b/tests/source/Makefile
deleted file mode 100644
index 62084f0..0000000
--- a/tests/source/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-all: check
-
-test check:
- ./dotest
-
-clean:
-
-.PHONY: all check clean test
diff --git a/tests/source/dotest b/tests/source/dotest
index 4cbb54a..c97e8cb 100755
--- a/tests/source/dotest
+++ b/tests/source/dotest
@@ -9,35 +9,6 @@ findfiles() {
}
#
-# check for misc common typos
-#
-find "${top_srcdir}" \
- '(' -type d -a '(' -name .git -o -name tests ')' -prune ')' \
- -o '(' -type f -a -print0 ')' | xargs -0 \
- grep -n -I \
- -e '\<compatability\>' \
- -e '\<compatable\>' \
- -e '\<fordeground\>' \
- -e '\<depency\>' \
- -e '\<defalt\>' \
- -e '\<remaing\>' \
- -e '\<queuing\>' \
- -e '\<detatch\>' \
- -e '\<sempahore\>' \
- -e '\<reprenstative\>' \
- -e '\<overriden\>' \
- -e '\<readed\>' \
- -e '\<formated\>' \
- -e '\<algorithic\>' \
- -e '\<deamon\>' \
- -e '\<derefernce\>' \
- -e '\<lenght\>' \
- | sed -e "s:^\.\./\.\./::g" > "${builddir}"/src.typos
-testit src.typos
-
-
-
-#
# don't allow obsolete functions
#
findfiles | xargs -0 \
diff --git a/tests/source/meson.build b/tests/source/meson.build
new file mode 100644
index 0000000..f435679
--- /dev/null
+++ b/tests/source/meson.build
@@ -0,0 +1,8 @@
+test('source tests', files('dotest'),
+ workdir : meson.current_source_dir(),
+ env : {
+ 'builddir' : meson.project_build_root(),
+ 'srcdir' : meson.project_source_root(),
+ 'current_srcdir' : meson.current_source_dir(),
+ }
+)
diff --git a/travis/autotools.tar.xz b/travis/autotools.tar.xz
deleted file mode 100644
index 1c0c854..0000000
--- a/travis/autotools.tar.xz
+++ /dev/null
Binary files differ
diff --git a/travis/lib.sh b/travis/lib.sh
deleted file mode 100644
index 687ed41..0000000
--- a/travis/lib.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-# Common funcs for working w/Travis.
-
-travis_fold() {
- if [[ -n ${TRAVIS_OS_NAME} ]] ; then
- printf 'travis_fold:%s:%s\r\n' "$@" | sed 's: :_:g'
- fi
-}
-
-if [[ -n ${TRAVIS_OS_NAME} ]] ; then
- whitebg=$(tput setab 7)
- blackfg=$(tput setaf 0)
- normal=$(tput sgr0)
-else
- whitebg=
- blackbg=
- normal=
-fi
-v() {
- local fold=""
- case $1 in
- --fold=*) fold=${1:7}; shift;;
- esac
- if [[ -n ${fold} ]] ; then
- travis_fold start "${fold}"
- echo "\$ $*"
- "$@"
- travis_fold end "${fold}"
- else
- echo "${whitebg}${blackfg}\$ $*${normal}"
- "$@"
- fi
-}
-
-ncpus=$(getconf _NPROCESSORS_ONLN)
-m() {
- v make -j${ncpus} "$@"
-}
diff --git a/travis/main.sh b/travis/main.sh
deleted file mode 100755
index 50e8a2f..0000000
--- a/travis/main.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/bash -e
-
-. "${0%/*}"/lib.sh
-
-# We have to do this by hand rather than use the coverity addon because of
-# matrix explosion: https://github.com/travis-ci/travis-ci/issues/1975
-# We also do it by hand because when we're throttled, the addon will exit
-# the build immediately and skip the main script!
-coverity_scan() {
- local reason
- [[ ${TRAVIS_JOB_NUMBER} != *.1 ]] && reason="not first build job"
- [[ -n ${TRAVIS_TAG} ]] && reason="git tag"
- [[ ${TRAVIS_PULL_REQUEST} == "true" ]] && reason="pull request"
- if [[ -n ${reason} ]] ; then
- echo "Skipping coverity scan due to: ${reason}"
- return
- fi
-
- export COVERITY_SCAN_PROJECT_NAME="${TRAVIS_REPO_SLUG}"
- export COVERITY_SCAN_NOTIFICATION_EMAIL="vapier@gentoo.org"
- export COVERITY_SCAN_BUILD_COMMAND="make -j${ncpus}"
- export COVERITY_SCAN_BUILD_COMMAND_PREPEND="git clean -q -x -d -f; git checkout -f"
- export COVERITY_SCAN_BRANCH_PATTERN="master"
-
- curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash || :
-}
-
-main() {
- if [[ ${TRAVIS_OS_NAME} == "osx" ]] ; then
- # Note: Linux deps are maintained in .travis.yml.
- v --fold="brew_update" brew update
- v --fold="brew_install" brew install xmlto xz
- fi
-
- # See if we have to bootstrap gnulib. This is the case on OS X, and on
- # Linux until they whitelist the package:
- # https://github.com/travis-ci/apt-package-whitelist/issues/727
- if ! gnulib-tool --version >&/dev/null ; then
- if [[ ! -d ../gnulib ]] ; then
- v --fold="git_clone_gnulib" \
- git clone --depth=1 https://github.com/coreutils/gnulib.git ../gnulib
- else
- pushd ../gnulib
- v --fold="git_pull_gnulib" git pull
- popd
- fi
- export PATH="${PATH}:${PWD}/../gnulib"
- fi
-
- if [[ ${TRAVIS_OS_NAME} == "linux" ]] ; then
- # Standard optimized build.
- m
- m check
-
- # Debug build w/ASAN and such enabled.
- m debug
- m check
- fi
-
- # Autotools based build.
- v ./autogen.sh
- if [[ ${TRAVIS_OS_NAME} == "linux" ]] ; then
- v --fold="configure" ./configure
- m V=1 distcheck
- else
- # ELF checks don't work on OS X -- no ELFs!
- v ./configure
- m V=1
- fi
-
- # Do scans last as they like to dirty the tree and some tests
- # expect a clean tree (like code style checks).
- v --fold="coverity_scan" coverity_scan
-}
-main "$@"
diff --git a/version.h.in b/version.h.in
new file mode 100644
index 0000000..eac885b
--- /dev/null
+++ b/version.h.in
@@ -0,0 +1 @@
+#define VCSID "@VCS_TAG@"
diff --git a/xfuncs.c b/xfuncs.c
index cd73dfa..694cc21 100644
--- a/xfuncs.c
+++ b/xfuncs.c
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2012 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#include "paxinc.h"
diff --git a/xfuncs.h b/xfuncs.h
index 61577ec..afe35ac 100644
--- a/xfuncs.h
+++ b/xfuncs.h
@@ -1,9 +1,9 @@
/*
- * Copyright 2003-2012 Gentoo Foundation
+ * Copyright 2003-2024 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
*
* Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
- * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
+ * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org>
*/
#ifndef __XFUNCS_H__